Changeset 23384


Ignore:
Timestamp:
Jun 20, 2013, 5:38:47 AM (11 years ago)
Author:
rvelices
Message:

smarty 3 - first pass for tests

Location:
trunk
Files:
99 added
25 deleted
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin/themes/default/template/configuration.tpl

    r23029 r23384  
    106106       
    107107        {foreach from=$main.order_by item=order}
    108         <span class="filter {if $ORDER_BY_IS_CUSTOM}transparent{/if}">         
    109           <select name="order_by[]" {if $ORDER_BY_IS_CUSTOM}disabled{/if}>
     108        <span class="filter {if isset($ORDER_BY_IS_CUSTOM)}transparent{/if}">         
     109          <select name="order_by[]" {if isset($ORDER_BY_IS_CUSTOM)}disabled{/if}>
    110110            {html_options options=$main.order_by_options selected=$order}
    111111          </select>
     
    114114        {/foreach}
    115115       
    116         {if !$ORDER_BY_IS_CUSTOM}
     116        {if !isset($ORDER_BY_IS_CUSTOM)}
    117117          <a class="addFilter">{'Add a criteria'|@translate}</a>
    118118        {else}
     
    121121    </li>
    122122   
    123 {if !$ORDER_BY_IS_CUSTOM}
     123{if !isset($ORDER_BY_IS_CUSTOM)}
    124124{footer_script require='jquery'}
    125125// counters for displaying of addFilter link
     
    384384
    385385<div class="showDetails">
    386   <a href="#" id="showDetails"{if $show_details or isset($ferrors)} style="display:none"{/if}>{'show details'|@translate}</a>
     386  <a href="#" id="showDetails"{if isset($ferrors)} style="display:none"{/if}>{'show details'|@translate}</a>
    387387</div>
    388388
  • trunk/include/functions.inc.php

    r23372 r23384  
    3333include_once( PHPWG_ROOT_PATH .'include/derivative_std_params.inc.php');
    3434include_once( PHPWG_ROOT_PATH .'include/derivative.inc.php');
    35 require_once( PHPWG_ROOT_PATH .'include/smarty/libs/Smarty.class.php');
     35//require_once( PHPWG_ROOT_PATH .'include/smarty/libs/Smarty.class.php');
     36require_once( PHPWG_ROOT_PATH .'include/smarty/libs/SmartyBC.class.php');
    3637include_once( PHPWG_ROOT_PATH .'include/template.class.php');
    3738
  • trunk/include/smarty/COPYING.lib

    r2216 r23384  
    1                   GNU LESSER GENERAL PUBLIC LICENSE
    2                        Version 2.1, February 1999
     1                   GNU LESSER GENERAL PUBLIC LICENSE
     2                       Version 3, 29 June 2007
    33
    4  Copyright (C) 1991, 1999 Free Software Foundation, Inc.
    5      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
    65 Everyone is permitted to copy and distribute verbatim copies
    76 of this license document, but changing it is not allowed.
    87
    9 [This is the first released version of the Lesser GPL.  It also counts
    10  as the successor of the GNU Library Public License, version 2, hence
    11  the version number 2.1.]
    128
    13                             Preamble
     9  This version of the GNU Lesser General Public License incorporates
     10the terms and conditions of version 3 of the GNU General Public
     11License, supplemented by the additional permissions listed below.
    1412
    15   The licenses for most software are designed to take away your
    16 freedom to share and change it.  By contrast, the GNU General Public
    17 Licenses are intended to guarantee your freedom to share and change
    18 free software--to make sure the software is free for all its users.
     13  0. Additional Definitions.
    1914
    20   This license, the Lesser General Public License, applies to some
    21 specially designated software packages--typically libraries--of the
    22 Free Software Foundation and other authors who decide to use it.  You
    23 can use it too, but we suggest you first think carefully about whether
    24 this license or the ordinary General Public License is the better
    25 strategy to use in any particular case, based on the explanations below.
     15  As used herein, "this License" refers to version 3 of the GNU Lesser
     16General Public License, and the "GNU GPL" refers to version 3 of the GNU
     17General Public License.
    2618
    27   When we speak of free software, we are referring to freedom of use,
    28 not price.  Our General Public Licenses are designed to make sure that
    29 you have the freedom to distribute copies of free software (and charge
    30 for this service if you wish); that you receive source code or can get
    31 it if you want it; that you can change the software and use pieces of
    32 it in new free programs; and that you are informed that you can do
    33 these things.
     19  "The Library" refers to a covered work governed by this License,
     20other than an Application or a Combined Work as defined below.
    3421
    35   To protect your rights, we need to make restrictions that forbid
    36 distributors to deny you these rights or to ask you to surrender these
    37 rights.  These restrictions translate to certain responsibilities for
    38 you if you distribute copies of the library or if you modify it.
     22  An "Application" is any work that makes use of an interface provided
     23by the Library, but which is not otherwise based on the Library.
     24Defining a subclass of a class defined by the Library is deemed a mode
     25of using an interface provided by the Library.
    3926
    40   For example, if you distribute copies of the library, whether gratis
    41 or for a fee, you must give the recipients all the rights that we gave
    42 you.  You must make sure that they, too, receive or can get the source
    43 code.  If you link other code with the library, you must provide
    44 complete object files to the recipients, so that they can relink them
    45 with the library after making changes to the library and recompiling
    46 it.  And you must show them these terms so they know their rights.
     27  A "Combined Work" is a work produced by combining or linking an
     28Application with the Library.  The particular version of the Library
     29with which the Combined Work was made is also called the "Linked
     30Version".
    4731
    48   We protect your rights with a two-step method: (1) we copyright the
    49 library, and (2) we offer you this license, which gives you legal
    50 permission to copy, distribute and/or modify the library.
     32  The "Minimal Corresponding Source" for a Combined Work means the
     33Corresponding Source for the Combined Work, excluding any source code
     34for portions of the Combined Work that, considered in isolation, are
     35based on the Application, and not on the Linked Version.
    5136
    52   To protect each distributor, we want to make it very clear that
    53 there is no warranty for the free library.  Also, if the library is
    54 modified by someone else and passed on, the recipients should know
    55 that what they have is not the original version, so that the original
    56 author's reputation will not be affected by problems that might be
    57 introduced by others.
     37  The "Corresponding Application Code" for a Combined Work means the
     38object code and/or source code for the Application, including any data
     39and utility programs needed for reproducing the Combined Work from the
     40Application, but excluding the System Libraries of the Combined Work.
    5841
     42  1. Exception to Section 3 of the GNU GPL.
    5943
    60   Finally, software patents pose a constant threat to the existence of
    61 any free program.  We wish to make sure that a company cannot
    62 effectively restrict the users of a free program by obtaining a
    63 restrictive license from a patent holder.  Therefore, we insist that
    64 any patent license obtained for a version of the library must be
    65 consistent with the full freedom of use specified in this license.
     44  You may convey a covered work under sections 3 and 4 of this License
     45without being bound by section 3 of the GNU GPL.
    6646
    67   Most GNU software, including some libraries, is covered by the
    68 ordinary GNU General Public License.  This license, the GNU Lesser
    69 General Public License, applies to certain designated libraries, and
    70 is quite different from the ordinary General Public License.  We use
    71 this license for certain libraries in order to permit linking those
    72 libraries into non-free programs.
     47  2. Conveying Modified Versions.
    7348
    74   When a program is linked with a library, whether statically or using
    75 a shared library, the combination of the two is legally speaking a
    76 combined work, a derivative of the original library.  The ordinary
    77 General Public License therefore permits such linking only if the
    78 entire combination fits its criteria of freedom.  The Lesser General
    79 Public License permits more lax criteria for linking other code with
    80 the library.
     49  If you modify a copy of the Library, and, in your modifications, a
     50facility refers to a function or data to be supplied by an Application
     51that uses the facility (other than as an argument passed when the
     52facility is invoked), then you may convey a copy of the modified
     53version:
    8154
    82   We call this license the "Lesser" General Public License because it
    83 does Less to protect the user's freedom than the ordinary General
    84 Public License.  It also provides other free software developers Less
    85 of an advantage over competing non-free programs.  These disadvantages
    86 are the reason we use the ordinary General Public License for many
    87 libraries.  However, the Lesser license provides advantages in certain
    88 special circumstances.
     55   a) under this License, provided that you make a good faith effort to
     56   ensure that, in the event an Application does not supply the
     57   function or data, the facility still operates, and performs
     58   whatever part of its purpose remains meaningful, or
    8959
    90   For example, on rare occasions, there may be a special need to
    91 encourage the widest possible use of a certain library, so that it becomes
    92 a de-facto standard.  To achieve this, non-free programs must be
    93 allowed to use the library.  A more frequent case is that a free
    94 library does the same job as widely used non-free libraries.  In this
    95 case, there is little to gain by limiting the free library to free
    96 software only, so we use the Lesser General Public License.
     60   b) under the GNU GPL, with none of the additional permissions of
     61   this License applicable to that copy.
    9762
    98   In other cases, permission to use a particular library in non-free
    99 programs enables a greater number of people to use a large body of
    100 free software.  For example, permission to use the GNU C Library in
    101 non-free programs enables many more people to use the whole GNU
    102 operating system, as well as its variant, the GNU/Linux operating
    103 system.
     63  3. Object Code Incorporating Material from Library Header Files.
    10464
    105   Although the Lesser General Public License is Less protective of the
    106 users' freedom, it does ensure that the user of a program that is
    107 linked with the Library has the freedom and the wherewithal to run
    108 that program using a modified version of the Library.
     65  The object code form of an Application may incorporate material from
     66a header file that is part of the Library.  You may convey such object
     67code under terms of your choice, provided that, if the incorporated
     68material is not limited to numerical parameters, data structure
     69layouts and accessors, or small macros, inline functions and templates
     70(ten or fewer lines in length), you do both of the following:
    10971
    110   The precise terms and conditions for copying, distribution and
    111 modification follow.  Pay close attention to the difference between a
    112 "work based on the library" and a "work that uses the library".  The
    113 former contains code derived from the library, whereas the latter must
    114 be combined with the library in order to run.
     72   a) Give prominent notice with each copy of the object code that the
     73   Library is used in it and that the Library and its use are
     74   covered by this License.
    11575
     76   b) Accompany the object code with a copy of the GNU GPL and this license
     77   document.
    11678
    117                   GNU LESSER GENERAL PUBLIC LICENSE
    118    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
     79  4. Combined Works.
    11980
    120   0. This License Agreement applies to any software library or other
    121 program which contains a notice placed by the copyright holder or
    122 other authorized party saying it may be distributed under the terms of
    123 this Lesser General Public License (also called "this License").
    124 Each licensee is addressed as "you".
     81  You may convey a Combined Work under terms of your choice that,
     82taken together, effectively do not restrict modification of the
     83portions of the Library contained in the Combined Work and reverse
     84engineering for debugging such modifications, if you also do each of
     85the following:
    12586
    126   A "library" means a collection of software functions and/or data
    127 prepared so as to be conveniently linked with application programs
    128 (which use some of those functions and data) to form executables.
     87   a) Give prominent notice with each copy of the Combined Work that
     88   the Library is used in it and that the Library and its use are
     89   covered by this License.
    12990
    130   The "Library", below, refers to any such software library or work
    131 which has been distributed under these terms.  A "work based on the
    132 Library" means either the Library or any derivative work under
    133 copyright law: that is to say, a work containing the Library or a
    134 portion of it, either verbatim or with modifications and/or translated
    135 straightforwardly into another language.  (Hereinafter, translation is
    136 included without limitation in the term "modification".)
     91   b) Accompany the Combined Work with a copy of the GNU GPL and this license
     92   document.
    13793
    138   "Source code" for a work means the preferred form of the work for
    139 making modifications to it.  For a library, complete source code means
    140 all the source code for all modules it contains, plus any associated
    141 interface definition files, plus the scripts used to control compilation
    142 and installation of the library.
     94   c) For a Combined Work that displays copyright notices during
     95   execution, include the copyright notice for the Library among
     96   these notices, as well as a reference directing the user to the
     97   copies of the GNU GPL and this license document.
    14398
    144   Activities other than copying, distribution and modification are not
    145 covered by this License; they are outside its scope.  The act of
    146 running a program using the Library is not restricted, and output from
    147 such a program is covered only if its contents constitute a work based
    148 on the Library (independent of the use of the Library in a tool for
    149 writing it).  Whether that is true depends on what the Library does
    150 and what the program that uses the Library does.
    151  
    152   1. You may copy and distribute verbatim copies of the Library's
    153 complete source code as you receive it, in any medium, provided that
    154 you conspicuously and appropriately publish on each copy an
    155 appropriate copyright notice and disclaimer of warranty; keep intact
    156 all the notices that refer to this License and to the absence of any
    157 warranty; and distribute a copy of this License along with the
     99   d) Do one of the following:
     100
     101       0) Convey the Minimal Corresponding Source under the terms of this
     102       License, and the Corresponding Application Code in a form
     103       suitable for, and under terms that permit, the user to
     104       recombine or relink the Application with a modified version of
     105       the Linked Version to produce a modified Combined Work, in the
     106       manner specified by section 6 of the GNU GPL for conveying
     107       Corresponding Source.
     108
     109       1) Use a suitable shared library mechanism for linking with the
     110       Library.  A suitable mechanism is one that (a) uses at run time
     111       a copy of the Library already present on the user's computer
     112       system, and (b) will operate properly with a modified version
     113       of the Library that is interface-compatible with the Linked
     114       Version.
     115
     116   e) Provide Installation Information, but only if you would otherwise
     117   be required to provide such information under section 6 of the
     118   GNU GPL, and only to the extent that such information is
     119   necessary to install and execute a modified version of the
     120   Combined Work produced by recombining or relinking the
     121   Application with a modified version of the Linked Version. (If
     122   you use option 4d0, the Installation Information must accompany
     123   the Minimal Corresponding Source and Corresponding Application
     124   Code. If you use option 4d1, you must provide the Installation
     125   Information in the manner specified by section 6 of the GNU GPL
     126   for conveying Corresponding Source.)
     127
     128  5. Combined Libraries.
     129
     130  You may place library facilities that are a work based on the
     131Library side by side in a single library together with other library
     132facilities that are not Applications and are not covered by this
     133License, and convey such a combined library under terms of your
     134choice, if you do both of the following:
     135
     136   a) Accompany the combined library with a copy of the same work based
     137   on the Library, uncombined with any other library facilities,
     138   conveyed under the terms of this License.
     139
     140   b) Give prominent notice with the combined library that part of it
     141   is a work based on the Library, and explaining where to find the
     142   accompanying uncombined form of the same work.
     143
     144  6. Revised Versions of the GNU Lesser General Public License.
     145
     146  The Free Software Foundation may publish revised and/or new versions
     147of the GNU Lesser General Public License from time to time. Such new
     148versions will be similar in spirit to the present version, but may
     149differ in detail to address new problems or concerns.
     150
     151  Each version is given a distinguishing version number. If the
     152Library as you received it specifies that a certain numbered version
     153of the GNU Lesser General Public License "or any later version"
     154applies to it, you have the option of following the terms and
     155conditions either of that published version or of any later version
     156published by the Free Software Foundation. If the Library as you
     157received it does not specify a version number of the GNU Lesser
     158General Public License, you may choose any version of the GNU Lesser
     159General Public License ever published by the Free Software Foundation.
     160
     161  If the Library as you received it specifies that a proxy can decide
     162whether future versions of the GNU Lesser General Public License shall
     163apply, that proxy's public statement of acceptance of any version is
     164permanent authorization for you to choose that version for the
    158165Library.
    159 
    160   You may charge a fee for the physical act of transferring a copy,
    161 and you may at your option offer warranty protection in exchange for a
    162 fee.
    163 
    164 
    165   2. You may modify your copy or copies of the Library or any portion
    166 of it, thus forming a work based on the Library, and copy and
    167 distribute such modifications or work under the terms of Section 1
    168 above, provided that you also meet all of these conditions:
    169 
    170     a) The modified work must itself be a software library.
    171 
    172     b) You must cause the files modified to carry prominent notices
    173     stating that you changed the files and the date of any change.
    174 
    175     c) You must cause the whole of the work to be licensed at no
    176     charge to all third parties under the terms of this License.
    177 
    178     d) If a facility in the modified Library refers to a function or a
    179     table of data to be supplied by an application program that uses
    180     the facility, other than as an argument passed when the facility
    181     is invoked, then you must make a good faith effort to ensure that,
    182     in the event an application does not supply such function or
    183     table, the facility still operates, and performs whatever part of
    184     its purpose remains meaningful.
    185 
    186     (For example, a function in a library to compute square roots has
    187     a purpose that is entirely well-defined independent of the
    188     application.  Therefore, Subsection 2d requires that any
    189     application-supplied function or table used by this function must
    190     be optional: if the application does not supply it, the square
    191     root function must still compute square roots.)
    192 
    193 These requirements apply to the modified work as a whole.  If
    194 identifiable sections of that work are not derived from the Library,
    195 and can be reasonably considered independent and separate works in
    196 themselves, then this License, and its terms, do not apply to those
    197 sections when you distribute them as separate works.  But when you
    198 distribute the same sections as part of a whole which is a work based
    199 on the Library, the distribution of the whole must be on the terms of
    200 this License, whose permissions for other licensees extend to the
    201 entire whole, and thus to each and every part regardless of who wrote
    202 it.
    203 
    204 Thus, it is not the intent of this section to claim rights or contest
    205 your rights to work written entirely by you; rather, the intent is to
    206 exercise the right to control the distribution of derivative or
    207 collective works based on the Library.
    208 
    209 In addition, mere aggregation of another work not based on the Library
    210 with the Library (or with a work based on the Library) on a volume of
    211 a storage or distribution medium does not bring the other work under
    212 the scope of this License.
    213 
    214   3. You may opt to apply the terms of the ordinary GNU General Public
    215 License instead of this License to a given copy of the Library.  To do
    216 this, you must alter all the notices that refer to this License, so
    217 that they refer to the ordinary GNU General Public License, version 2,
    218 instead of to this License.  (If a newer version than version 2 of the
    219 ordinary GNU General Public License has appeared, then you can specify
    220 that version instead if you wish.)  Do not make any other change in
    221 these notices.
    222 
    223 
    224   Once this change is made in a given copy, it is irreversible for
    225 that copy, so the ordinary GNU General Public License applies to all
    226 subsequent copies and derivative works made from that copy.
    227 
    228   This option is useful when you wish to copy part of the code of
    229 the Library into a program that is not a library.
    230 
    231   4. You may copy and distribute the Library (or a portion or
    232 derivative of it, under Section 2) in object code or executable form
    233 under the terms of Sections 1 and 2 above provided that you accompany
    234 it with the complete corresponding machine-readable source code, which
    235 must be distributed under the terms of Sections 1 and 2 above on a
    236 medium customarily used for software interchange.
    237 
    238   If distribution of object code is made by offering access to copy
    239 from a designated place, then offering equivalent access to copy the
    240 source code from the same place satisfies the requirement to
    241 distribute the source code, even though third parties are not
    242 compelled to copy the source along with the object code.
    243 
    244   5. A program that contains no derivative of any portion of the
    245 Library, but is designed to work with the Library by being compiled or
    246 linked with it, is called a "work that uses the Library".  Such a
    247 work, in isolation, is not a derivative work of the Library, and
    248 therefore falls outside the scope of this License.
    249 
    250   However, linking a "work that uses the Library" with the Library
    251 creates an executable that is a derivative of the Library (because it
    252 contains portions of the Library), rather than a "work that uses the
    253 library".  The executable is therefore covered by this License.
    254 Section 6 states terms for distribution of such executables.
    255 
    256   When a "work that uses the Library" uses material from a header file
    257 that is part of the Library, the object code for the work may be a
    258 derivative work of the Library even though the source code is not.
    259 Whether this is true is especially significant if the work can be
    260 linked without the Library, or if the work is itself a library.  The
    261 threshold for this to be true is not precisely defined by law.
    262 
    263   If such an object file uses only numerical parameters, data
    264 structure layouts and accessors, and small macros and small inline
    265 functions (ten lines or less in length), then the use of the object
    266 file is unrestricted, regardless of whether it is legally a derivative
    267 work.  (Executables containing this object code plus portions of the
    268 Library will still fall under Section 6.)
    269 
    270   Otherwise, if the work is a derivative of the Library, you may
    271 distribute the object code for the work under the terms of Section 6.
    272 Any executables containing that work also fall under Section 6,
    273 whether or not they are linked directly with the Library itself.
    274 
    275 
    276   6. As an exception to the Sections above, you may also combine or
    277 link a "work that uses the Library" with the Library to produce a
    278 work containing portions of the Library, and distribute that work
    279 under terms of your choice, provided that the terms permit
    280 modification of the work for the customer's own use and reverse
    281 engineering for debugging such modifications.
    282 
    283   You must give prominent notice with each copy of the work that the
    284 Library is used in it and that the Library and its use are covered by
    285 this License.  You must supply a copy of this License.  If the work
    286 during execution displays copyright notices, you must include the
    287 copyright notice for the Library among them, as well as a reference
    288 directing the user to the copy of this License.  Also, you must do one
    289 of these things:
    290 
    291     a) Accompany the work with the complete corresponding
    292     machine-readable source code for the Library including whatever
    293     changes were used in the work (which must be distributed under
    294     Sections 1 and 2 above); and, if the work is an executable linked
    295     with the Library, with the complete machine-readable "work that
    296     uses the Library", as object code and/or source code, so that the
    297     user can modify the Library and then relink to produce a modified
    298     executable containing the modified Library.  (It is understood
    299     that the user who changes the contents of definitions files in the
    300     Library will not necessarily be able to recompile the application
    301     to use the modified definitions.)
    302 
    303     b) Use a suitable shared library mechanism for linking with the
    304     Library.  A suitable mechanism is one that (1) uses at run time a
    305     copy of the library already present on the user's computer system,
    306     rather than copying library functions into the executable, and (2)
    307     will operate properly with a modified version of the library, if
    308     the user installs one, as long as the modified version is
    309     interface-compatible with the version that the work was made with.
    310 
    311     c) Accompany the work with a written offer, valid for at
    312     least three years, to give the same user the materials
    313     specified in Subsection 6a, above, for a charge no more
    314     than the cost of performing this distribution.
    315 
    316     d) If distribution of the work is made by offering access to copy
    317     from a designated place, offer equivalent access to copy the above
    318     specified materials from the same place.
    319 
    320     e) Verify that the user has already received a copy of these
    321     materials or that you have already sent this user a copy.
    322 
    323   For an executable, the required form of the "work that uses the
    324 Library" must include any data and utility programs needed for
    325 reproducing the executable from it.  However, as a special exception,
    326 the materials to be distributed need not include anything that is
    327 normally distributed (in either source or binary form) with the major
    328 components (compiler, kernel, and so on) of the operating system on
    329 which the executable runs, unless that component itself accompanies
    330 the executable.
    331 
    332   It may happen that this requirement contradicts the license
    333 restrictions of other proprietary libraries that do not normally
    334 accompany the operating system.  Such a contradiction means you cannot
    335 use both them and the Library together in an executable that you
    336 distribute.
    337 
    338 
    339   7. You may place library facilities that are a work based on the
    340 Library side-by-side in a single library together with other library
    341 facilities not covered by this License, and distribute such a combined
    342 library, provided that the separate distribution of the work based on
    343 the Library and of the other library facilities is otherwise
    344 permitted, and provided that you do these two things:
    345 
    346     a) Accompany the combined library with a copy of the same work
    347     based on the Library, uncombined with any other library
    348     facilities.  This must be distributed under the terms of the
    349     Sections above.
    350 
    351     b) Give prominent notice with the combined library of the fact
    352     that part of it is a work based on the Library, and explaining
    353     where to find the accompanying uncombined form of the same work.
    354 
    355   8. You may not copy, modify, sublicense, link with, or distribute
    356 the Library except as expressly provided under this License.  Any
    357 attempt otherwise to copy, modify, sublicense, link with, or
    358 distribute the Library is void, and will automatically terminate your
    359 rights under this License.  However, parties who have received copies,
    360 or rights, from you under this License will not have their licenses
    361 terminated so long as such parties remain in full compliance.
    362 
    363   9. You are not required to accept this License, since you have not
    364 signed it.  However, nothing else grants you permission to modify or
    365 distribute the Library or its derivative works.  These actions are
    366 prohibited by law if you do not accept this License.  Therefore, by
    367 modifying or distributing the Library (or any work based on the
    368 Library), you indicate your acceptance of this License to do so, and
    369 all its terms and conditions for copying, distributing or modifying
    370 the Library or works based on it.
    371 
    372   10. Each time you redistribute the Library (or any work based on the
    373 Library), the recipient automatically receives a license from the
    374 original licensor to copy, distribute, link with or modify the Library
    375 subject to these terms and conditions.  You may not impose any further
    376 restrictions on the recipients' exercise of the rights granted herein.
    377 You are not responsible for enforcing compliance by third parties with
    378 this License.
    379 
    380 
    381   11. If, as a consequence of a court judgment or allegation of patent
    382 infringement or for any other reason (not limited to patent issues),
    383 conditions are imposed on you (whether by court order, agreement or
    384 otherwise) that contradict the conditions of this License, they do not
    385 excuse you from the conditions of this License.  If you cannot
    386 distribute so as to satisfy simultaneously your obligations under this
    387 License and any other pertinent obligations, then as a consequence you
    388 may not distribute the Library at all.  For example, if a patent
    389 license would not permit royalty-free redistribution of the Library by
    390 all those who receive copies directly or indirectly through you, then
    391 the only way you could satisfy both it and this License would be to
    392 refrain entirely from distribution of the Library.
    393 
    394 If any portion of this section is held invalid or unenforceable under any
    395 particular circumstance, the balance of the section is intended to apply,
    396 and the section as a whole is intended to apply in other circumstances.
    397 
    398 It is not the purpose of this section to induce you to infringe any
    399 patents or other property right claims or to contest validity of any
    400 such claims; this section has the sole purpose of protecting the
    401 integrity of the free software distribution system which is
    402 implemented by public license practices.  Many people have made
    403 generous contributions to the wide range of software distributed
    404 through that system in reliance on consistent application of that
    405 system; it is up to the author/donor to decide if he or she is willing
    406 to distribute software through any other system and a licensee cannot
    407 impose that choice.
    408 
    409 This section is intended to make thoroughly clear what is believed to
    410 be a consequence of the rest of this License.
    411 
    412   12. If the distribution and/or use of the Library is restricted in
    413 certain countries either by patents or by copyrighted interfaces, the
    414 original copyright holder who places the Library under this License may add
    415 an explicit geographical distribution limitation excluding those countries,
    416 so that distribution is permitted only in or among countries not thus
    417 excluded.  In such case, this License incorporates the limitation as if
    418 written in the body of this License.
    419 
    420   13. The Free Software Foundation may publish revised and/or new
    421 versions of the Lesser General Public License from time to time.
    422 Such new versions will be similar in spirit to the present version,
    423 but may differ in detail to address new problems or concerns.
    424 
    425 Each version is given a distinguishing version number.  If the Library
    426 specifies a version number of this License which applies to it and
    427 "any later version", you have the option of following the terms and
    428 conditions either of that version or of any later version published by
    429 the Free Software Foundation.  If the Library does not specify a
    430 license version number, you may choose any version ever published by
    431 the Free Software Foundation.
    432 
    433 
    434   14. If you wish to incorporate parts of the Library into other free
    435 programs whose distribution conditions are incompatible with these,
    436 write to the author to ask for permission.  For software which is
    437 copyrighted by the Free Software Foundation, write to the Free
    438 Software Foundation; we sometimes make exceptions for this.  Our
    439 decision will be guided by the two goals of preserving the free status
    440 of all derivatives of our free software and of promoting the sharing
    441 and reuse of software generally.
    442 
    443                             NO WARRANTY
    444 
    445   15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
    446 WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
    447 EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
    448 OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
    449 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
    450 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    451 PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
    452 LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
    453 THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
    454 
    455   16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
    456 WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
    457 AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
    458 FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
    459 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
    460 LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
    461 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
    462 FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
    463 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    464 DAMAGES.
    465 
    466                      END OF TERMS AND CONDITIONS
  • trunk/include/smarty/README

    r3584 r23384  
    1 
    2 NAME:
    3 
    4     Smarty - the PHP compiling template engine
    5 
    6 VERSION: 2.6.26
    7 
    8 AUTHORS:
    9    
    10     Monte Ohrt <monte at ohrt dot com>
    11     Andrei Zmievski <andrei@php.net>
    12 
    13 MAILING LISTS:
    14 
    15     We have a few mailing lists. "discussion" for you to share your ideas or ask
    16         questions, "developers" for those interested in the development efforts of Smarty,
    17         and "svn" for those that would like to track the updates made in the svn
    18         repository.
    19 
    20     send a blank e-mail message to:
    21       smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list)
    22       smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list)
    23       smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest)
    24       smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest)
    25       smarty-developers-subscribe@googlecode.com (subscribe to the dev list)
    26       smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list)
    27       smarty-svn-subscribe@googlecode.com (subscribe to the svn list)
    28       smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list)
    29 
    30     You can also browse the mailing list archives at
    31     http://groups.google.com/group/smarty-discussion
    32     http://groups.google.com/group/smarty-developers
    33 
    34     and the OLD list archives at
    35     http://marc.theaimsgroup.com/?l=smarty&r=1&w=2
    36 
    37 SYNOPSIS:
    38 
    39     require("Smarty.class.php");
    40 
    41     $smarty = new Smarty;
    42 
    43     $smarty->assign("Title","My Homepage");
    44     $smarty->assign("Names",array("John","Gary","Gregg","James"));
    45 
    46     $smarty->display("index.tpl");
    47 
    48 
    49 DESCRIPTION:
    50 
    51     What is Smarty?
    52 
    53     Smarty is a template engine for PHP. Many other template engines for PHP
    54     provide basic variable substitution and dynamic block functionality.
    55     Smarty takes a step further to be a "smart" template engine, adding
    56     features such as configuration files, template functions, and variable
    57     modifiers, and making all of this functionality as easy as possible to
    58     use for both programmers and template designers. Smarty also converts
    59     the templates into PHP scripts, eliminating the need to parse the
    60     templates on every invocation. This makes Smarty extremely scalable and
    61     manageable for large application needs.
    62 
    63     Some of Smarty's features:
    64 
    65     * it is extremely fast
    66     * no template parsing overhead, only compiles once.
    67         * it is smart about recompiling only the template files that have
    68           changed.
    69     * the template language is remarkably extensible via the plugin
    70       architecture.
    71     * configurable template delimiter tag syntax, so you can use
    72       {}, {{}}, <!--{}-->, or whatever you like.
    73     * built-in caching of template output.
    74     * arbitrary template sources (filesystem, databases, etc.)
    75     * template if/elseif/else/endif constructs are passed to the PHP parser,
    76       so the if syntax can be as simple or as complex as you like.
    77     * unlimited nesting of sections, conditionals, etc. allowed
    78     * it is possible to embed PHP code right in your template files,
    79       although not recommended and doubtfully needed since the engine
    80       is so customizable.
    81     * and many more.
    82 
    83 COPYRIGHT:
    84     Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved.
    85     This software is released under the GNU Lesser General Public License.
    86     Please read the disclaimer at the top of the Smarty.class.php file.
     1Smarty 3.1.13
     2
     3Author: Monte Ohrt <monte at ohrt dot com >
     4Author: Uwe Tews
     5
     6AN INTRODUCTION TO SMARTY 3
     7
     8NOTICE FOR 3.1 release:
     9
     10Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution.
     11
     12NOTICE for 3.0.5 release:
     13
     14Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior:
     15
     16$smarty->error_reporting = E_ALL & ~E_NOTICE;
     17
     18NOTICE for 3.0 release:
     19
     20IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release.
     21We felt it is better to make these now instead of after a 3.0 release, then have to
     22immediately deprecate APIs in 3.1. Online documentation has been updated
     23to reflect these changes. Specifically:
     24
     25---- API CHANGES RC4 -> 3.0 ----
     26
     27$smarty->register->*
     28$smarty->unregister->*
     29$smarty->utility->*
     30$samrty->cache->*
     31
     32Have all been changed to local method calls such as:
     33
     34$smarty->clearAllCache()
     35$smarty->registerFoo()
     36$smarty->unregisterFoo()
     37$smarty->testInstall()
     38etc.
     39
     40Registration of function, block, compiler, and modifier plugins have been
     41consolidated under two API calls:
     42
     43$smarty->registerPlugin(...)
     44$smarty->unregisterPlugin(...)
     45
     46Registration of pre, post, output and variable filters have been
     47consolidated under two API calls:
     48
     49$smarty->registerFilter(...)
     50$smarty->unregisterFilter(...)
     51
     52Please refer to the online documentation for all specific changes:
     53
     54http://www.smarty.net/documentation
     55
     56----
     57
     58The Smarty 3 API has been refactored to a syntax geared
     59for consistency and modularity. The Smarty 2 API syntax is still supported, but
     60will throw a deprecation notice. You can disable the notices, but it is highly
     61recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run
     62through an extra rerouting wrapper.
     63
     64Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also,
     65all Smarty properties now have getters and setters. So for example, the property
     66$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be
     67retrieved with $smarty->getCacheDir().
     68
     69Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were
     70just duplicate functions of the now available "get*" methods.
     71
     72Here is a rundown of the Smarty 3 API:
     73
     74$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null)
     75$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null)
     76$smarty->isCached($template, $cache_id = null, $compile_id = null)
     77$smarty->createData($parent = null)
     78$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
     79$smarty->enableSecurity()
     80$smarty->disableSecurity()
     81$smarty->setTemplateDir($template_dir)
     82$smarty->addTemplateDir($template_dir)
     83$smarty->templateExists($resource_name)
     84$smarty->loadPlugin($plugin_name, $check = true)
     85$smarty->loadFilter($type, $name)
     86$smarty->setExceptionHandler($handler)
     87$smarty->addPluginsDir($plugins_dir)
     88$smarty->getGlobal($varname = null)
     89$smarty->getRegisteredObject($name)
     90$smarty->getDebugTemplate()
     91$smarty->setDebugTemplate($tpl_name)
     92$smarty->assign($tpl_var, $value = null, $nocache = false)
     93$smarty->assignGlobal($varname, $value = null, $nocache = false)
     94$smarty->assignByRef($tpl_var, &$value, $nocache = false)
     95$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false)
     96$smarty->appendByRef($tpl_var, &$value, $merge = false)
     97$smarty->clearAssign($tpl_var)
     98$smarty->clearAllAssign()
     99$smarty->configLoad($config_file, $sections = null)
     100$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
     101$smarty->getConfigVariable($variable)
     102$smarty->getStreamVariable($variable)
     103$smarty->getConfigVars($varname = null)
     104$smarty->clearConfig($varname = null)
     105$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
     106$smarty->clearAllCache($exp_time = null, $type = null)
     107$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
     108
     109$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array())
     110
     111$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
     112
     113$smarty->registerFilter($type, $function_name)
     114$smarty->registerResource($resource_type, $function_names)
     115$smarty->registerDefaultPluginHandler($function_name)
     116$smarty->registerDefaultTemplateHandler($function_name)
     117
     118$smarty->unregisterPlugin($type, $tag)
     119$smarty->unregisterObject($object_name)
     120$smarty->unregisterFilter($type, $function_name)
     121$smarty->unregisterResource($resource_type)
     122
     123$smarty->compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
     124$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
     125$smarty->testInstall()
     126
     127// then all the getters/setters, available for all properties. Here are a few:
     128
     129$caching = $smarty->getCaching();      // get $smarty->caching
     130$smarty->setCaching(true);             // set $smarty->caching
     131$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices
     132$smarty->setCacheId($id);              // set $smarty->cache_id
     133$debugging = $smarty->getDebugging();  // get $smarty->debugging
     134
     135
     136FILE STRUCTURE
     137
     138The Smarty 3 file structure is similar to Smarty 2:
     139
     140/libs/
     141  Smarty.class.php
     142/libs/sysplugins/
     143  internal.*
     144/libs/plugins/
     145  function.mailto.php
     146  modifier.escape.php
     147  ...
     148
     149A lot of Smarty 3 core functionality lies in the sysplugins directory; you do
     150not need to change any files here. The /libs/plugins/ folder is where Smarty
     151plugins are located. You can add your own here, or create a separate plugin
     152directory, just the same as Smarty 2. You will still need to create your own
     153/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and
     154/templates_c/ are writable.
     155
     156The typical way to use Smarty 3 should also look familiar:
     157
     158require('Smarty.class.php');
     159$smarty = new Smarty;
     160$smarty->assign('foo','bar');
     161$smarty->display('index.tpl');
     162
     163
     164However, Smarty 3 works completely different on the inside. Smarty 3 is mostly
     165backward compatible with Smarty 2, except for the following items:
     166
     167*) Smarty 3 is PHP 5 only. It will not work with PHP 4.
     168*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true.
     169*) Delimiters surrounded by whitespace are no longer treated as Smarty tags.
     170   Therefore, { foo } will not compile as a tag, you must use {foo}. This change
     171   Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
     172   This can be disabled by setting $smarty->auto_literal = false;
     173*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated
     174   but still work. You will want to update your calls to Smarty 3 for maximum
     175   efficiency.
     176
     177
     178There are many things that are new to Smarty 3. Here are the notable items:
     179   
     180LEXER/PARSER
     181============
     182
     183Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this
     184means Smarty has some syntax additions that make life easier such as in-template
     185math, shorter/intuitive function parameter options, infinite function recursion,
     186more accurate error handling, etc.
     187
     188
     189WHAT IS NEW IN SMARTY TEMPLATE SYNTAX
     190=====================================
     191
     192Smarty 3 allows expressions almost anywhere. Expressions can include PHP
     193functions as long as they are not disabled by the security policy, object
     194methods and properties, etc. The {math} plugin is no longer necessary but
     195is still supported for BC.
     196
     197Examples:
     198{$x+$y}                           will output the sum of x and y.
     199{$foo = strlen($bar)}             function in assignment
     200{assign var=foo value= $x+$y}     in attributes
     201{$foo = myfunct( ($x+$y)*3 )}     as function parameter
     202{$foo[$x+3]}                      as array index
     203
     204Smarty tags can be used as values within other tags.
     205Example:  {$foo={counter}+3}
     206
     207Smarty tags can also be used inside double quoted strings.
     208Example:  {$foo="this is message {counter}"}
     209
     210You can define arrays within templates.
     211Examples:
     212{assign var=foo value=[1,2,3]}
     213{assign var=foo value=['y'=>'yellow','b'=>'blue']}
     214Arrays can be nested.
     215{assign var=foo value=[1,[9,8],3]}
     216
     217There is a new short syntax supported for assigning variables.
     218Example: {$foo=$bar+2}
     219
     220You can assign a value to a specific array element. If the variable exists but
     221is not an array, it is converted to an array before the new values are assigned.
     222Examples:
     223{$foo['bar']=1}
     224{$foo['bar']['blar']=1}
     225
     226You can append values to an array. If the variable exists but is not an array,
     227it is converted to an array before the new values are assigned.
     228Example: {$foo[]=1}
     229
     230You can use a PHP-like syntax for accessing array elements, as well as the
     231original "dot" notation.
     232Examples:
     233{$foo[1]}             normal access
     234{$foo['bar']}
     235{$foo['bar'][1]}
     236{$foo[$x+$x]}         index may contain any expression
     237{$foo[$bar[1]]}       nested index
     238{$foo[section_name]}  smarty section access, not array access!
     239
     240The original "dot" notation stays, and with improvements.
     241Examples:
     242{$foo.a.b.c}        =>  $foo['a']['b']['c']
     243{$foo.a.$b.c}       =>  $foo['a'][$b]['c']        with variable index
     244{$foo.a.{$b+4}.c}   =>  $foo['a'][$b+4]['c']       with expression as index
     245{$foo.a.{$b.c}}     =>  $foo['a'][$b['c']]         with nested index
     246
     247note that { and } are used to address ambiguties when nesting the dot syntax.
     248
     249Variable names themselves can be variable and contain expressions.
     250Examples:
     251$foo         normal variable
     252$foo_{$bar}  variable name containing other variable
     253$foo_{$x+$y} variable name containing expressions
     254$foo_{$bar}_buh_{$blar}  variable name with multiple segments
     255{$foo_{$x}}  will output the variable $foo_1 if $x has a value of 1.
     256
     257Object method chaining is implemented.
     258Example: {$object->method1($x)->method2($y)}
     259
     260{for} tag added for looping (replacement for {section} tag):
     261{for $x=0, $y=count($foo); $x<$y; $x++}  ....  {/for}
     262Any number of statements can be used separated by comma as the first
     263inital expression at {for}.
     264
     265{for $x = $start to $end step $step} ... {/for}is in the SVN now .
     266You can use also
     267{for $x = $start to $end} ... {/for}
     268In this case the step value will be automaticall 1 or -1 depending on the start and end values.
     269Instead of $start and $end you can use any valid expression.
     270Inside the loop the following special vars can be accessed:
     271$x@iteration = number of iteration
     272$x@total = total number of iterations
     273$x@first = true on first iteration
     274$x@last = true on last iteration
     275
     276
     277The Smarty 2 {section} syntax is still supported.
     278
     279New shorter {foreach} syntax to loop over an array.
     280Example: {foreach $myarray as $var}...{/foreach}
     281
     282Within the foreach loop, properties are access via:
     283
     284$var@key            foreach $var array key
     285$var@iteration      foreach current iteration count (1,2,3...)
     286$var@index          foreach current index count (0,1,2...)
     287$var@total          foreach $var array total
     288$var@first          true on first iteration
     289$var@last           true on last iteration
     290
     291The Smarty 2 {foreach} tag syntax is still supported.
     292
     293NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo.
     294If you want to access an array element with index foo, you must use quotes
     295such as {$bar['foo']}, or use the dot syntax {$bar.foo}.
     296
     297while block tag is now implemented:
     298{while $foo}...{/while}
     299{while $x lt 10}...{/while}
     300
     301Direct access to PHP functions:
     302Just as you can use PHP functions as modifiers directly, you can now access
     303PHP functions directly, provided they are permitted by security settings:
     304{time()}
     305
     306There is a new {function}...{/function} block tag to implement a template function.
     307This enables reuse of code sequences like a plugin function. It can call itself recursively.
     308Template function must be called with the new {call name=foo...} tag.
     309
     310Example:
     311
     312Template file:
     313{function name=menu level=0}
     314  <ul class="level{$level}">
     315  {foreach $data as $entry}
     316    {if is_array($entry)}
     317      <li>{$entry@key}</li>
     318       {call name=menu data=$entry level=$level+1}
     319    {else}
     320      <li>{$entry}</li>
     321    {/if}
     322  {/foreach}
     323  </ul>
     324{/function}
     325
     326{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
     327  ['item3-3-1','item3-3-2']],'item4']}
     328
     329{call name=menu data=$menu}
     330
     331
     332Generated output:
     333    * item1
     334    * item2
     335    * item3
     336          o item3-1
     337          o item3-2
     338          o item3-3
     339                + item3-3-1
     340                + item3-3-2
     341    * item4
     342
     343The function tag itself must have the "name" attribute. This name is the tag
     344name when calling the function. The function tag may have any number of
     345additional attributes. These will be default settings for local variables.
     346
     347New {nocache} block function:
     348{nocache}...{/nocache} will declare a section of the template to be non-cached
     349when template caching is enabled.
     350
     351New nocache attribute:
     352You can declare variable/function output as non-cached with the nocache attribute.
     353Examples:
     354
     355{$foo nocache=true}
     356{$foo nocache} /* same */
     357
     358{foo bar="baz" nocache=true}
     359{foo bar="baz" nocache} /* same */
     360
     361{time() nocache=true}
     362{time() nocache} /* same */
     363
     364Or you can also assign the variable in your script as nocache:
     365$smarty->assign('foo',$something,true); // third param is nocache setting
     366{$foo} /* non-cached */
     367
     368$smarty.current_dir returns the directory name of the current template.
     369
     370You can use strings directly as templates with the "string" resource type.
     371Examples:
     372$smarty->display('string:This is my template, {$foo}!'); // php
     373{include file="string:This is my template, {$foo}!"} // template
     374
     375
     376
     377VARIABLE SCOPE / VARIABLE STORAGE
     378=================================
     379
     380In Smarty 2, all assigned variables were stored within the Smarty object.
     381Therefore, all variables assigned in PHP were accessible by all subsequent
     382fetch and display template calls.
     383
     384In Smarty 3, we have the choice to assign variables to the main Smarty object,
     385to user-created data objects, and to user-created template objects.
     386These objects can be chained. The object at the end of a chain can access all
     387variables belonging to that template and all variables within the parent objects.
     388The Smarty object can only be the root of a chain, but a chain can be isolated
     389from the Smarty object.
     390
     391All known Smarty assignment interfaces will work on the data and template objects.
     392
     393Besides the above mentioned objects, there is also a special storage area for
     394global variables.
     395
     396A Smarty data object can be created as follows:
     397$data = $smarty->createData();    // create root data object
     398$data->assign('foo','bar');       // assign variables as usual
     399$data->config_load('my.conf');                                                                   // load config file   
     400
     401$data= $smarty->createData($smarty);  // create data object having a parent link to
     402the Smarty object
     403
     404$data2= $smarty->createData($data);   // create data object having a parent link to
     405the $data data object
     406
     407A template object can be created by using the createTemplate method. It has the
     408same parameter assignments as the fetch() or display() method.
     409Function definition:
     410function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
     411
     412The first parameter can be a template name, a smarty object or a data object.
     413
     414Examples:
     415$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent
     416$tpl->assign('foo','bar');                   // directly assign variables
     417$tpl->config_load('my.conf');                                                                    // load config file   
     418
     419$tpl = $smarty->createTemplate('mytpl.tpl',$smarty);  // create template having a parent link to the Smarty object
     420$tpl = $smarty->createTemplate('mytpl.tpl',$data);    // create template having a parent link to the $data object
     421
     422The standard fetch() and display() methods will implicitly create a template object.
     423If the $parent parameter is not specified in these method calls, the template object
     424is will link back to the Smarty object as it's parent.
     425
     426If a template is called by an {include...} tag from another template, the
     427subtemplate links back to the calling template as it's parent.
     428
     429All variables assigned locally or from a parent template are accessible. If the
     430template creates or modifies a variable by using the {assign var=foo...} or
     431{$foo=...} tags, these new values are only known locally (local scope). When the
     432template exits, none of the new variables or modifications can be seen in the
     433parent template(s). This is same behavior as in Smarty 2.
     434
     435With Smarty 3, we can assign variables with a scope attribute which allows the
     436availablility of these new variables or modifications globally (ie in the parent
     437templates.)
     438
     439Possible scopes are local, parent, root and global.
     440Examples:
     441{assign var=foo value='bar'}       // no scope is specified, the default 'local'
     442{$foo='bar'}                       // same, local scope
     443{assign var=foo value='bar' scope='local'} // same, local scope
     444
     445{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object
     446{$foo='bar' scope='parent'}                 // (normally the calling template)
     447
     448{assign var=foo value='bar' scope='root'}   // Values will be exported up to the root object, so they can
     449{$foo='bar' scope='root'}                   // be seen from all templates using the same root.
     450
     451{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage,
     452{$foo='bar' scope='global'}                 // they are available to any and all templates.
     453
     454
     455The scope attribute can also be attached to the {include...} tag. In this case,
     456the specified scope will be the default scope for all assignments within the
     457included template.
     458
     459
     460PLUGINS
     461=======
     462
     463Smarty3 are following the same coding rules as in Smarty2.
     464The only difference is that the template object is passed as additional third parameter.
     465
     466smarty_plugintype_name (array $params, object $smarty, object $template)
     467
     468The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty2 internals.
     469
     470
     471TEMPLATE INHERITANCE:
     472=====================
     473
     474With template inheritance you can define blocks, which are areas that can be
     475overriden by child templates, so your templates could look like this:
     476
     477parent.tpl:
     478<html>
     479  <head>
     480    <title>{block name='title'}My site name{/block}</title>
     481  </head>
     482  <body>
     483    <h1>{block name='page-title'}Default page title{/block}</h1>
     484    <div id="content">
     485      {block name='content'}
     486        Default content
     487      {/block}
     488    </div>
     489  </body>
     490</html>
     491
     492child.tpl:
     493{extends file='parent.tpl'}
     494{block name='title'}
     495Child title
     496{/block}
     497
     498grandchild.tpl:
     499{extends file='child.tpl'}
     500{block name='title'}Home - {$smarty.block.parent}{/block}
     501{block name='page-title'}My home{/block}
     502{block name='content'}
     503  {foreach $images as $img}
     504    <img src="{$img.url}" alt="{$img.description}" />
     505  {/foreach}
     506{/block}
     507
     508We redefined all the blocks here, however in the title block we used {$smarty.block.parent},
     509which tells Smarty to insert the default content from the parent template in its place.
     510The content block was overriden to display the image files, and page-title has also be
     511overriden to display a completely different title.
     512
     513If we render grandchild.tpl we will get this:
     514<html>
     515  <head>
     516    <title>Home - Child title</title>
     517  </head>
     518  <body>
     519    <h1>My home</h1>
     520    <div id="content">
     521      <img src="/example.jpg" alt="image" />
     522      <img src="/example2.jpg" alt="image" />
     523      <img src="/example3.jpg" alt="image" />
     524    </div>
     525  </body>
     526</html>
     527
     528NOTE: In the child templates everything outside the {extends} or {block} tag sections
     529is ignored.
     530
     531The inheritance tree can be as big as you want (meaning you can extend a file that
     532extends another one that extends another one and so on..), but be aware that all files
     533have to be checked for modifications at runtime so the more inheritance the more overhead you add.
     534
     535Instead of defining the parent/child relationships with the {extends} tag in the child template you
     536can use the resource as follow:
     537
     538$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
     539
     540Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content
     541is appended or prepended to the child block content.
     542
     543{block name='title' append} My title {/block}
     544
     545
     546PHP STREAMS:
     547============
     548
     549(see online documentation)
     550
     551VARIBLE FILTERS:
     552================
     553
     554(see online documentation)
     555
     556
     557STATIC CLASS ACCESS AND NAMESPACE SUPPORT
     558=========================================
     559
     560You can register a class with optional namespace for the use in the template like:
     561
     562$smarty->register->templateClass('foo','name\name2\myclass');
     563
     564In the template you can use it like this:
     565{foo::method()}  etc.
     566
     567
     568=======================
     569
     570Please look through it and send any questions/suggestions/etc to the forums.
     571
     572http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168
     573
     574Monte and Uwe
  • trunk/include/smarty/libs/Smarty.class.php

    r3703 r23384  
    11<?php
    2 
    32/**
    43 * Project:     Smarty: the PHP compiling template engine
    54 * File:        Smarty.class.php
     5 * SVN:         $Id: Smarty.class.php 4694 2013-01-13 21:13:14Z uwe.tews@googlemail.com $
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    2424 *
    2525 * @link http://www.smarty.net/
    26  * @copyright 2001-2005 New Digital Group, Inc.
     26 * @copyright 2008 New Digital Group, Inc.
    2727 * @author Monte Ohrt <monte at ohrt dot com>
    28  * @author Andrei Zmievski <andrei@php.net>
     28 * @author Uwe Tews
     29 * @author Rodney Rehm
    2930 * @package Smarty
    30  * @version 2.6.26
     31 * @version 3.1.13
    3132 */
    3233
    33 /* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */
    34 
    3534/**
    36  * DIR_SEP isn't used anymore, but third party apps might
     35 * define shorthand directory separator constant
    3736 */
    38 if(!defined('DIR_SEP')) {
    39     define('DIR_SEP', DIRECTORY_SEPARATOR);
     37if (!defined('DS')) {
     38    define('DS', DIRECTORY_SEPARATOR);
    4039}
    4140
    4241/**
    4342 * set SMARTY_DIR to absolute path to Smarty library files.
    44  * if not defined, include_path will be used. Sets SMARTY_DIR only if user
    45  * application has not already defined it.
     43 * Sets SMARTY_DIR only if user application has not already defined it.
    4644 */
    47 
    4845if (!defined('SMARTY_DIR')) {
    49     define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
     46    define('SMARTY_DIR', dirname(__FILE__) . DS);
    5047}
    5148
    52 if (!defined('SMARTY_CORE_DIR')) {
    53     define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR);
     49/**
     50 * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins.
     51 * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it.
     52 */
     53if (!defined('SMARTY_SYSPLUGINS_DIR')) {
     54    define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS);
    5455}
    55 
    56 define('SMARTY_PHP_PASSTHRU',   0);
    57 define('SMARTY_PHP_QUOTE',      1);
    58 define('SMARTY_PHP_REMOVE',     2);
    59 define('SMARTY_PHP_ALLOW',      3);
     56if (!defined('SMARTY_PLUGINS_DIR')) {
     57    define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
     58}
     59if (!defined('SMARTY_MBSTRING')) {
     60    define('SMARTY_MBSTRING', function_exists('mb_split'));
     61}
     62if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
     63    // UTF-8 can only be done properly when mbstring is available!
     64    /**
     65     * @deprecated in favor of Smarty::$_CHARSET
     66     */
     67    define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1');
     68}
     69if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
     70    /**
     71     * @deprecated in favor of Smarty::$_DATE_FORMAT
     72     */
     73    define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
     74}
    6075
    6176/**
     77 * register the class autoloader
     78 */
     79if (!defined('SMARTY_SPL_AUTOLOAD')) {
     80    define('SMARTY_SPL_AUTOLOAD', 0);
     81}
     82
     83if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) {
     84    $registeredAutoLoadFunctions = spl_autoload_functions();
     85    if (!isset($registeredAutoLoadFunctions['spl_autoload'])) {
     86        spl_autoload_register();
     87    }
     88} else {
     89    spl_autoload_register('smartyAutoload');
     90}
     91
     92/**
     93 * Load always needed external class files
     94 */
     95include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php';
     96include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php';
     97include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php';
     98include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php';
     99include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php';
     100include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php';
     101include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php';
     102
     103/**
     104 * This is the main Smarty class
    62105 * @package Smarty
    63106 */
    64 class Smarty
    65 {
     107class Smarty extends Smarty_Internal_TemplateBase {
     108
    66109    /**#@+
    67      * Smarty Configuration Section
    68      */
    69 
    70     /**
    71      * The name of the directory where templates are located.
    72      *
     110     * constant definitions
     111     */
     112
     113    /**
     114     * smarty version
     115     */
     116    const SMARTY_VERSION = 'Smarty-3.1.13';
     117
     118    /**
     119     * define variable scopes
     120     */
     121    const SCOPE_LOCAL = 0;
     122    const SCOPE_PARENT = 1;
     123    const SCOPE_ROOT = 2;
     124    const SCOPE_GLOBAL = 3;
     125    /**
     126     * define caching modes
     127     */
     128    const CACHING_OFF = 0;
     129    const CACHING_LIFETIME_CURRENT = 1;
     130    const CACHING_LIFETIME_SAVED = 2;
     131    /**
     132     * define compile check modes
     133     */
     134    const COMPILECHECK_OFF = 0;
     135    const COMPILECHECK_ON = 1;
     136    const COMPILECHECK_CACHEMISS = 2;
     137    /**
     138     * modes for handling of "<?php ... ?>" tags in templates.
     139     */
     140    const PHP_PASSTHRU = 0; //-> print tags as plain text
     141    const PHP_QUOTE = 1; //-> escape tags as entities
     142    const PHP_REMOVE = 2; //-> escape tags as entities
     143    const PHP_ALLOW = 3; //-> escape tags as entities
     144    /**
     145     * filter types
     146     */
     147    const FILTER_POST = 'post';
     148    const FILTER_PRE = 'pre';
     149    const FILTER_OUTPUT = 'output';
     150    const FILTER_VARIABLE = 'variable';
     151    /**
     152     * plugin types
     153     */
     154    const PLUGIN_FUNCTION = 'function';
     155    const PLUGIN_BLOCK = 'block';
     156    const PLUGIN_COMPILER = 'compiler';
     157    const PLUGIN_MODIFIER = 'modifier';
     158    const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler';
     159
     160    /**#@-*/
     161
     162    /**
     163     * assigned global tpl vars
     164     */
     165    public static $global_tpl_vars = array();
     166
     167    /**
     168     * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors()
     169     */
     170    public static $_previous_error_handler = null;
     171    /**
     172     * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
     173     */
     174    public static $_muted_directories = array();
     175    /**
     176     * Flag denoting if Multibyte String functions are available
     177     */
     178    public static $_MBSTRING = SMARTY_MBSTRING;
     179    /**
     180     * The character set to adhere to (e.g. "UTF-8")
     181     */
     182    public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET;
     183    /**
     184     * The date format to be used internally
     185     * (accepts date() and strftime())
     186     */
     187    public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT;
     188    /**
     189     * Flag denoting if PCRE should run in UTF-8 mode
     190     */
     191    public static $_UTF8_MODIFIER = 'u';
     192
     193    /**
     194     * Flag denoting if operating system is windows
     195     */
     196    public static $_IS_WINDOWS = false;
     197
     198    /**#@+
     199     * variables
     200     */
     201
     202    /**
     203     * auto literal on delimiters with whitspace
     204     * @var boolean
     205     */
     206    public $auto_literal = true;
     207    /**
     208     * display error on not assigned variables
     209     * @var boolean
     210     */
     211    public $error_unassigned = false;
     212    /**
     213     * look up relative filepaths in include_path
     214     * @var boolean
     215     */
     216    public $use_include_path = false;
     217    /**
     218     * template directory
     219     * @var array
     220     */
     221    private $template_dir = array();
     222    /**
     223     * joined template directory string used in cache keys
    73224     * @var string
    74225     */
    75     var $template_dir    =  'templates';
    76 
    77     /**
    78      * The directory where compiled templates are located.
    79      *
     226    public $joined_template_dir = null;
     227    /**
     228     * joined config directory string used in cache keys
    80229     * @var string
    81230     */
    82     var $compile_dir     =  'templates_c';
    83 
    84     /**
    85      * The directory where config files are located.
    86      *
     231    public $joined_config_dir = null;
     232    /**
     233     * default template handler
     234     * @var callable
     235     */
     236    public $default_template_handler_func = null;
     237    /**
     238     * default config handler
     239     * @var callable
     240     */
     241    public $default_config_handler_func = null;
     242    /**
     243     * default plugin handler
     244     * @var callable
     245     */
     246    public $default_plugin_handler_func = null;
     247    /**
     248     * compile directory
    87249     * @var string
    88250     */
    89     var $config_dir      =  'configs';
    90 
    91     /**
    92      * An array of directories searched for plugins.
    93      *
    94      * @var array
    95      */
    96     var $plugins_dir     =  array('plugins');
    97 
    98     /**
    99      * If debugging is enabled, a debug console window will display
    100      * when the page loads (make sure your browser allows unrequested
    101      * popup windows)
    102      *
    103      * @var boolean
    104      */
    105     var $debugging       =  false;
    106 
    107     /**
    108      * When set, smarty does uses this value as error_reporting-level.
    109      *
     251    private $compile_dir = null;
     252    /**
     253     * plugins directory
     254     * @var array
     255     */
     256    private $plugins_dir = array();
     257    /**
     258     * cache directory
     259     * @var string
     260     */
     261    private $cache_dir = null;
     262    /**
     263     * config directory
     264     * @var array
     265     */
     266    private $config_dir = array();
     267    /**
     268     * force template compiling?
     269     * @var boolean
     270     */
     271    public $force_compile = false;
     272    /**
     273     * check template for modifications?
     274     * @var boolean
     275     */
     276    public $compile_check = true;
     277    /**
     278     * use sub dirs for compiled/cached files?
     279     * @var boolean
     280     */
     281    public $use_sub_dirs = false;
     282    /**
     283     * allow ambiguous resources (that are made unique by the resource handler)
     284     * @var boolean
     285     */
     286    public $allow_ambiguous_resources = false;
     287    /**
     288     * caching enabled
     289     * @var boolean
     290     */
     291    public $caching = false;
     292    /**
     293     * merge compiled includes
     294     * @var boolean
     295     */
     296    public $merge_compiled_includes = false;
     297    /**
     298     * cache lifetime in seconds
    110299     * @var integer
    111300     */
    112     var $error_reporting  =  null;
    113 
    114     /**
    115      * This is the path to the debug console template. If not set,
    116      * the default one will be used.
     301    public $cache_lifetime = 3600;
     302    /**
     303     * force cache file creation
     304     * @var boolean
     305     */
     306    public $force_cache = false;
     307    /**
     308     * Set this if you want different sets of cache files for the same
     309     * templates.
    117310     *
    118311     * @var string
    119312     */
    120     var $debug_tpl       =  '';
    121 
     313    public $cache_id = null;
     314    /**
     315     * Set this if you want different sets of compiled files for the same
     316     * templates.
     317     *
     318     * @var string
     319     */
     320    public $compile_id = null;
     321    /**
     322     * template left-delimiter
     323     * @var string
     324     */
     325    public $left_delimiter = "{";
     326    /**
     327     * template right-delimiter
     328     * @var string
     329     */
     330    public $right_delimiter = "}";
     331    /**#@+
     332     * security
     333     */
     334    /**
     335     * class name
     336     *
     337     * This should be instance of Smarty_Security.
     338     *
     339     * @var string
     340     * @see Smarty_Security
     341     */
     342    public $security_class = 'Smarty_Security';
     343    /**
     344     * implementation of security class
     345     *
     346     * @var Smarty_Security
     347     */
     348    public $security_policy = null;
     349    /**
     350     * controls handling of PHP-blocks
     351     *
     352     * @var integer
     353     */
     354    public $php_handling = self::PHP_PASSTHRU;
     355    /**
     356     * controls if the php template file resource is allowed
     357     *
     358     * @var bool
     359     */
     360    public $allow_php_templates = false;
     361    /**
     362     * Should compiled-templates be prevented from being called directly?
     363     *
     364     * {@internal
     365     * Currently used by Smarty_Internal_Template only.
     366     * }}
     367     *
     368     * @var boolean
     369     */
     370    public $direct_access_security = true;
     371    /**#@-*/
     372    /**
     373     * debug mode
     374     *
     375     * Setting this to true enables the debug-console.
     376     *
     377     * @var boolean
     378     */
     379    public $debugging = false;
    122380    /**
    123381     * This determines if debugging is enable-able from the browser.
     
    126384     *  <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
    127385     * </ul>
    128      * @link http://www.foo.dom/index.php?SMARTY_DEBUG
    129386     * @var string
    130387     */
    131     var $debugging_ctrl  =  'NONE';
    132 
    133     /**
    134      * This tells Smarty whether to check for recompiling or not. Recompiling
    135      * does not need to happen unless a template or config file is changed.
    136      * Typically you enable this during development, and disable for
    137      * production.
    138      *
    139      * @var boolean
    140      */
    141     var $compile_check   =  true;
    142 
    143     /**
    144      * This forces templates to compile every time. Useful for development
    145      * or debugging.
    146      *
    147      * @var boolean
    148      */
    149     var $force_compile   =  false;
    150 
    151     /**
    152      * This enables template caching.
    153      * <ul>
    154      *  <li>0 = no caching</li>
    155      *  <li>1 = use class cache_lifetime value</li>
    156      *  <li>2 = use cache_lifetime in cache file</li>
    157      * </ul>
    158      * @var integer
    159      */
    160     var $caching         =  0;
    161 
    162     /**
    163      * The name of the directory for cache files.
    164      *
     388    public $debugging_ctrl = 'NONE';
     389    /**
     390     * Name of debugging URL-param.
     391     *
     392     * Only used when $debugging_ctrl is set to 'URL'.
     393     * The name of the URL-parameter that activates debugging.
     394     *
     395     * @var type
     396     */
     397    public $smarty_debug_id = 'SMARTY_DEBUG';
     398    /**
     399     * Path of debug template.
    165400     * @var string
    166401     */
    167     var $cache_dir       =  'cache';
    168 
    169     /**
    170      * This is the number of seconds cached content will persist.
    171      * <ul>
    172      *  <li>0 = always regenerate cache</li>
    173      *  <li>-1 = never expires</li>
    174      * </ul>
    175      *
    176      * @var integer
    177      */
    178     var $cache_lifetime  =  3600;
    179 
    180     /**
    181      * Only used when $caching is enabled. If true, then If-Modified-Since headers
    182      * are respected with cached content, and appropriate HTTP headers are sent.
    183      * This way repeated hits to a cached page do not send the entire page to the
    184      * client every time.
    185      *
    186      * @var boolean
    187      */
    188     var $cache_modified_check = false;
    189 
    190     /**
    191      * This determines how Smarty handles "<?php ... ?>" tags in templates.
    192      * possible values:
    193      * <ul>
    194      *  <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
    195      *  <li>SMARTY_PHP_QUOTE    -> escape tags as entities</li>
    196      *  <li>SMARTY_PHP_REMOVE   -> remove php tags</li>
    197      *  <li>SMARTY_PHP_ALLOW    -> execute php tags</li>
    198      * </ul>
    199      *
    200      * @var integer
    201      */
    202     var $php_handling    =  SMARTY_PHP_PASSTHRU;
    203 
    204     /**
    205      * This enables template security. When enabled, many things are restricted
    206      * in the templates that normally would go unchecked. This is useful when
    207      * untrusted parties are editing templates and you want a reasonable level
    208      * of security. (no direct execution of PHP in templates for example)
    209      *
    210      * @var boolean
    211      */
    212     var $security       =   false;
    213 
    214     /**
    215      * This is the list of template directories that are considered secure. This
    216      * is used only if {@link $security} is enabled. One directory per array
    217      * element.  {@link $template_dir} is in this list implicitly.
    218      *
    219      * @var array
    220      */
    221     var $secure_dir     =   array();
    222 
    223     /**
    224      * These are the security settings for Smarty. They are used only when
    225      * {@link $security} is enabled.
    226      *
    227      * @var array
    228      */
    229     var $security_settings  = array(
    230                                     'PHP_HANDLING'    => false,
    231                                     'IF_FUNCS'        => array('array', 'list',
    232                                                                'isset', 'empty',
    233                                                                'count', 'sizeof',
    234                                                                'in_array', 'is_array',
    235                                                                'true', 'false', 'null'),
    236                                     'INCLUDE_ANY'     => false,
    237                                     'PHP_TAGS'        => false,
    238                                     'MODIFIER_FUNCS'  => array('count'),
    239                                     'ALLOW_CONSTANTS'  => false,
    240                                     'ALLOW_SUPER_GLOBALS' => true
    241                                    );
    242 
    243     /**
    244      * This is an array of directories where trusted php scripts reside.
    245      * {@link $security} is disabled during their inclusion/execution.
    246      *
    247      * @var array
    248      */
    249     var $trusted_dir        = array();
    250 
    251     /**
    252      * The left delimiter used for the template tags.
    253      *
     402    public $debug_tpl = null;
     403    /**
     404     * When set, smarty uses this value as error_reporting-level.
     405     * @var int
     406     */
     407    public $error_reporting = null;
     408    /**
     409     * Internal flag for getTags()
     410     * @var boolean
     411     */
     412    public $get_used_tags = false;
     413
     414    /**#@+
     415     * config var settings
     416     */
     417
     418    /**
     419     * Controls whether variables with the same name overwrite each other.
     420     * @var boolean
     421     */
     422    public $config_overwrite = true;
     423    /**
     424     * Controls whether config values of on/true/yes and off/false/no get converted to boolean.
     425     * @var boolean
     426     */
     427    public $config_booleanize = true;
     428    /**
     429     * Controls whether hidden config sections/vars are read from the file.
     430     * @var boolean
     431     */
     432    public $config_read_hidden = false;
     433
     434    /**#@-*/
     435
     436    /**#@+
     437     * resource locking
     438     */
     439
     440    /**
     441     * locking concurrent compiles
     442     * @var boolean
     443     */
     444    public $compile_locking = true;
     445    /**
     446     * Controls whether cache resources should emply locking mechanism
     447     * @var boolean
     448     */
     449    public $cache_locking = false;
     450    /**
     451     * seconds to wait for acquiring a lock before ignoring the write lock
     452     * @var float
     453     */
     454    public $locking_timeout = 10;
     455
     456    /**#@-*/
     457
     458    /**
     459     * global template functions
     460     * @var array
     461     */
     462    public $template_functions = array();
     463    /**
     464     * resource type used if none given
     465     *
     466     * Must be an valid key of $registered_resources.
    254467     * @var string
    255468     */
    256     var $left_delimiter  =  '{';
    257 
    258     /**
    259      * The right delimiter used for the template tags.
     469    public $default_resource_type = 'file';
     470    /**
     471     * caching type
     472     *
     473     * Must be an element of $cache_resource_types.
    260474     *
    261475     * @var string
    262476     */
    263     var $right_delimiter =  '}';
    264 
    265     /**
    266      * The order in which request variables are registered, similar to
    267      * variables_order in php.ini E = Environment, G = GET, P = POST,
    268      * C = Cookies, S = Server
    269      *
     477    public $caching_type = 'file';
     478    /**
     479     * internal config properties
     480     * @var array
     481     */
     482    public $properties = array();
     483    /**
     484     * config type
    270485     * @var string
    271486     */
    272     var $request_vars_order    = 'EGPCS';
    273 
    274     /**
    275      * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
    276      * are uses as request-vars or $_*[]-vars. note: if
    277      * request_use_auto_globals is true, then $request_vars_order has
    278      * no effect, but the php-ini-value "gpc_order"
    279      *
    280      * @var boolean
    281      */
    282     var $request_use_auto_globals      = true;
    283 
    284     /**
    285      * Set this if you want different sets of compiled files for the same
    286      * templates. This is useful for things like different languages.
    287      * Instead of creating separate sets of templates per language, you
    288      * set different compile_ids like 'en' and 'de'.
    289      *
     487    public $default_config_type = 'file';
     488    /**
     489     * cached template objects
     490     * @var array
     491     */
     492    public $template_objects = array();
     493    /**
     494     * check If-Modified-Since headers
     495     * @var boolean
     496     */
     497    public $cache_modified_check = false;
     498    /**
     499     * registered plugins
     500     * @var array
     501     */
     502    public $registered_plugins = array();
     503    /**
     504     * plugin search order
     505     * @var array
     506     */
     507    public $plugin_search_order = array('function', 'block', 'compiler', 'class');
     508    /**
     509     * registered objects
     510     * @var array
     511     */
     512    public $registered_objects = array();
     513    /**
     514     * registered classes
     515     * @var array
     516     */
     517    public $registered_classes = array();
     518    /**
     519     * registered filters
     520     * @var array
     521     */
     522    public $registered_filters = array();
     523    /**
     524     * registered resources
     525     * @var array
     526     */
     527    public $registered_resources = array();
     528    /**
     529     * resource handler cache
     530     * @var array
     531     */
     532    public $_resource_handlers = array();
     533    /**
     534     * registered cache resources
     535     * @var array
     536     */
     537    public $registered_cache_resources = array();
     538    /**
     539     * cache resource handler cache
     540     * @var array
     541     */
     542    public $_cacheresource_handlers = array();
     543    /**
     544     * autoload filter
     545     * @var array
     546     */
     547    public $autoload_filters = array();
     548    /**
     549     * default modifier
     550     * @var array
     551     */
     552    public $default_modifiers = array();
     553    /**
     554     * autoescape variable output
     555     * @var boolean
     556     */
     557    public $escape_html = false;
     558    /**
     559     * global internal smarty vars
     560     * @var array
     561     */
     562    public static $_smarty_vars = array();
     563    /**
     564     * start time for execution time calculation
     565     * @var int
     566     */
     567    public $start_time = 0;
     568    /**
     569     * default file permissions
     570     * @var int
     571     */
     572    public $_file_perms = 0644;
     573    /**
     574     * default dir permissions
     575     * @var int
     576     */
     577    public $_dir_perms = 0771;
     578    /**
     579     * block tag hierarchy
     580     * @var array
     581     */
     582    public $_tag_stack = array();
     583    /**
     584     * self pointer to Smarty object
     585     * @var Smarty
     586     */
     587    public $smarty;
     588    /**
     589     * required by the compiler for BC
    290590     * @var string
    291591     */
    292     var $compile_id            = null;
    293 
    294     /**
    295      * This tells Smarty whether or not to use sub dirs in the cache/ and
    296      * templates_c/ directories. sub directories better organized, but
    297      * may not work well with PHP safe mode enabled.
    298      *
    299      * @var boolean
    300      *
    301      */
    302     var $use_sub_dirs          = false;
    303 
    304     /**
    305      * This is a list of the modifiers to apply to all template variables.
    306      * Put each modifier in a separate array element in the order you want
    307      * them applied. example: <code>array('escape:"htmlall"');</code>
    308      *
    309      * @var array
    310      */
    311     var $default_modifiers        = array();
    312 
    313     /**
    314      * This is the resource type to be used when not specified
    315      * at the beginning of the resource path. examples:
    316      * $smarty->display('file:index.tpl');
    317      * $smarty->display('db:index.tpl');
    318      * $smarty->display('index.tpl'); // will use default resource type
    319      * {include file="file:index.tpl"}
    320      * {include file="db:index.tpl"}
    321      * {include file="index.tpl"} {* will use default resource type *}
    322      *
    323      * @var array
    324      */
    325     var $default_resource_type    = 'file';
    326 
    327     /**
    328      * The function used for cache file handling. If not set, built-in caching is used.
    329      *
    330      * @var null|string function name
    331      */
    332     var $cache_handler_func   = null;
    333 
    334     /**
    335      * This indicates which filters are automatically loaded into Smarty.
    336      *
    337      * @var array array of filter names
    338      */
    339     var $autoload_filters = array();
    340 
    341     /**#@+
    342      * @var boolean
    343      */
    344     /**
    345      * This tells if config file vars of the same name overwrite each other or not.
    346      * if disabled, same name variables are accumulated in an array.
    347      */
    348     var $config_overwrite = true;
    349 
    350     /**
    351      * This tells whether or not to automatically booleanize config file variables.
    352      * If enabled, then the strings "on", "true", and "yes" are treated as boolean
    353      * true, and "off", "false" and "no" are treated as boolean false.
    354      */
    355     var $config_booleanize = true;
    356 
    357     /**
    358      * This tells whether hidden sections [.foobar] are readable from the
    359      * tempalates or not. Normally you would never allow this since that is
    360      * the point behind hidden sections: the application can access them, but
    361      * the templates cannot.
    362      */
    363     var $config_read_hidden = false;
    364 
    365     /**
    366      * This tells whether or not automatically fix newlines in config files.
    367      * It basically converts \r (mac) or \r\n (dos) to \n
    368      */
    369     var $config_fix_newlines = true;
     592    public $_current_file = null;
     593    /**
     594     * internal flag to enable parser debugging
     595     * @var bool
     596     */
     597    public $_parserdebug = false;
     598    /**
     599     * Saved parameter of merged templates during compilation
     600     *
     601     * @var array
     602     */
     603    public $merged_templates_func = array();
    370604    /**#@-*/
    371605
    372606    /**
    373      * If a template cannot be found, this PHP function will be executed.
    374      * Useful for creating templates on-the-fly or other special action.
    375      *
    376      * @var string function name
    377      */
    378     var $default_template_handler_func = '';
    379 
    380     /**
    381      * The file that contains the compiler class. This can a full
    382      * pathname, or relative to the php_include path.
    383      *
    384      * @var string
    385      */
    386     var $compiler_file        =    'Smarty_Compiler.class.php';
    387 
    388     /**
    389      * The class used for compiling templates.
    390      *
    391      * @var string
    392      */
    393     var $compiler_class        =   'Smarty_Compiler';
    394 
    395     /**
    396      * The class used to load config vars.
    397      *
    398      * @var string
    399      */
    400     var $config_class          =   'Config_File';
    401 
    402 /**#@+
    403  * END Smarty Configuration Section
    404  * There should be no need to touch anything below this line.
    405  * @access private
    406  */
    407     /**
    408      * where assigned template vars are kept
    409      *
    410      * @var array
    411      */
    412     var $_tpl_vars             = array();
    413 
    414     /**
    415      * stores run-time $smarty.* vars
    416      *
    417      * @var null|array
    418      */
    419     var $_smarty_vars          = null;
    420 
    421     /**
    422      * keeps track of sections
    423      *
    424      * @var array
    425      */
    426     var $_sections             = array();
    427 
    428     /**
    429      * keeps track of foreach blocks
    430      *
    431      * @var array
    432      */
    433     var $_foreach              = array();
    434 
    435     /**
    436      * keeps track of tag hierarchy
    437      *
    438      * @var array
    439      */
    440     var $_tag_stack            = array();
    441 
    442     /**
    443      * configuration object
    444      *
    445      * @var Config_file
    446      */
    447     var $_conf_obj             = null;
    448 
    449     /**
    450      * loaded configuration settings
    451      *
    452      * @var array
    453      */
    454     var $_config               = array(array('vars'  => array(), 'files' => array()));
    455 
    456     /**
    457      * md5 checksum of the string 'Smarty'
    458      *
    459      * @var string
    460      */
    461     var $_smarty_md5           = 'f8d698aea36fcbead2b9d5359ffca76f';
    462 
    463     /**
    464      * Smarty version number
    465      *
    466      * @var string
    467      */
    468     var $_version              = '2.6.26';
    469 
    470     /**
    471      * current template inclusion depth
    472      *
    473      * @var integer
    474      */
    475     var $_inclusion_depth      = 0;
    476 
    477     /**
    478      * for different compiled templates
    479      *
    480      * @var string
    481      */
    482     var $_compile_id           = null;
    483 
    484     /**
    485      * text in URL to enable debug mode
    486      *
    487      * @var string
    488      */
    489     var $_smarty_debug_id      = 'SMARTY_DEBUG';
    490 
    491     /**
    492      * debugging information for debug console
    493      *
    494      * @var array
    495      */
    496     var $_smarty_debug_info    = array();
    497 
    498     /**
    499      * info that makes up a cache file
    500      *
    501      * @var array
    502      */
    503     var $_cache_info           = array();
    504 
    505     /**
    506      * default file permissions
    507      *
    508      * @var integer
    509      */
    510     var $_file_perms           = 0644;
    511 
    512     /**
    513      * default dir permissions
    514      *
    515      * @var integer
    516      */
    517     var $_dir_perms               = 0771;
    518 
    519     /**
    520      * registered objects
    521      *
    522      * @var array
    523      */
    524     var $_reg_objects           = array();
    525 
    526     /**
    527      * table keeping track of plugins
    528      *
    529      * @var array
    530      */
    531     var $_plugins              = array(
    532                                        'modifier'      => array(),
    533                                        'function'      => array(),
    534                                        'block'         => array(),
    535                                        'compiler'      => array(),
    536                                        'prefilter'     => array(),
    537                                        'postfilter'    => array(),
    538                                        'outputfilter'  => array(),
    539                                        'resource'      => array(),
    540                                        'insert'        => array());
    541 
    542 
    543     /**
    544      * cache serials
    545      *
    546      * @var array
    547      */
    548     var $_cache_serials = array();
    549 
    550     /**
    551      * name of optional cache include file
    552      *
    553      * @var string
    554      */
    555     var $_cache_include = null;
    556 
    557     /**
    558      * indicate if the current code is used in a compiled
    559      * include
    560      *
    561      * @var string
    562      */
    563     var $_cache_including = false;
    564 
    565     /**#@-*/
    566     /**
    567      * The class constructor.
    568      */
    569     function Smarty()
    570     {
    571       $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
    572                     : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
    573     }
    574 
    575     /**
    576      * assigns values to template variables
    577      *
    578      * @param array|string $tpl_var the template variable name(s)
    579      * @param mixed $value the value to assign
    580      */
    581     function assign($tpl_var, $value = null)
    582     {
    583         if (is_array($tpl_var)){
    584             foreach ($tpl_var as $key => $val) {
    585                 if ($key != '') {
    586                     $this->_tpl_vars[$key] = $val;
     607     * Initialize new Smarty object
     608     *
     609     */
     610    public function __construct()
     611    {
     612        // selfpointer needed by some other class methods
     613        $this->smarty = $this;
     614        if (is_callable('mb_internal_encoding')) {
     615            mb_internal_encoding(Smarty::$_CHARSET);
     616        }
     617        $this->start_time = microtime(true);
     618        // set default dirs
     619        $this->setTemplateDir('.' . DS . 'templates' . DS)
     620            ->setCompileDir('.' . DS . 'templates_c' . DS)
     621            ->setPluginsDir(SMARTY_PLUGINS_DIR)
     622            ->setCacheDir('.' . DS . 'cache' . DS)
     623            ->setConfigDir('.' . DS . 'configs' . DS);
     624
     625        $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl';
     626        if (isset($_SERVER['SCRIPT_NAME'])) {
     627            $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
     628        }
     629    }
     630
     631
     632    /**
     633     * Class destructor
     634     */
     635    public function __destruct()
     636    {
     637        // intentionally left blank
     638    }
     639
     640    /**
     641     * <<magic>> set selfpointer on cloned object
     642     */
     643    public function __clone()
     644    {
     645        $this->smarty = $this;
     646    }
     647
     648
     649    /**
     650     * <<magic>> Generic getter.
     651     *
     652     * Calls the appropriate getter function.
     653     * Issues an E_USER_NOTICE if no valid getter is found.
     654     *
     655     * @param string $name property name
     656     * @return mixed
     657     */
     658    public function __get($name)
     659    {
     660        $allowed = array(
     661        'template_dir' => 'getTemplateDir',
     662        'config_dir' => 'getConfigDir',
     663        'plugins_dir' => 'getPluginsDir',
     664        'compile_dir' => 'getCompileDir',
     665        'cache_dir' => 'getCacheDir',
     666        );
     667
     668        if (isset($allowed[$name])) {
     669            return $this->{$allowed[$name]}();
     670        } else {
     671            trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE);
     672        }
     673    }
     674
     675    /**
     676     * <<magic>> Generic setter.
     677     *
     678     * Calls the appropriate setter function.
     679     * Issues an E_USER_NOTICE if no valid setter is found.
     680     *
     681     * @param string $name  property name
     682     * @param mixed  $value parameter passed to setter
     683     */
     684    public function __set($name, $value)
     685    {
     686        $allowed = array(
     687        'template_dir' => 'setTemplateDir',
     688        'config_dir' => 'setConfigDir',
     689        'plugins_dir' => 'setPluginsDir',
     690        'compile_dir' => 'setCompileDir',
     691        'cache_dir' => 'setCacheDir',
     692        );
     693
     694        if (isset($allowed[$name])) {
     695            $this->{$allowed[$name]}($value);
     696        } else {
     697            trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
     698        }
     699    }
     700
     701    /**
     702     * Check if a template resource exists
     703     *
     704     * @param string $resource_name template name
     705     * @return boolean status
     706     */
     707    public function templateExists($resource_name)
     708    {
     709        // create template object
     710        $save = $this->template_objects;
     711        $tpl = new $this->template_class($resource_name, $this);
     712        // check if it does exists
     713        $result = $tpl->source->exists;
     714        $this->template_objects = $save;
     715        return $result;
     716    }
     717
     718    /**
     719     * Returns a single or all global  variables
     720     *
     721     * @param object $smarty
     722     * @param string $varname variable name or null
     723     * @return string variable value or or array of variables
     724     */
     725    public function getGlobal($varname = null)
     726    {
     727        if (isset($varname)) {
     728            if (isset(self::$global_tpl_vars[$varname])) {
     729                return self::$global_tpl_vars[$varname]->value;
     730            } else {
     731                return '';
     732            }
     733        } else {
     734            $_result = array();
     735            foreach (self::$global_tpl_vars AS $key => $var) {
     736                $_result[$key] = $var->value;
     737            }
     738            return $_result;
     739        }
     740    }
     741
     742    /**
     743     * Empty cache folder
     744     *
     745     * @param integer $exp_time expiration time
     746     * @param string  $type     resource type
     747     * @return integer number of cache files deleted
     748     */
     749    function clearAllCache($exp_time = null, $type = null)
     750    {
     751        // load cache resource and call clearAll
     752        $_cache_resource = Smarty_CacheResource::load($this, $type);
     753        Smarty_CacheResource::invalidLoadedCache($this);
     754        return $_cache_resource->clearAll($this, $exp_time);
     755    }
     756
     757    /**
     758     * Empty cache for a specific template
     759     *
     760     * @param string  $template_name template name
     761     * @param string  $cache_id      cache id
     762     * @param string  $compile_id    compile id
     763     * @param integer $exp_time      expiration time
     764     * @param string  $type          resource type
     765     * @return integer number of cache files deleted
     766     */
     767    public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
     768    {
     769        // load cache resource and call clear
     770        $_cache_resource = Smarty_CacheResource::load($this, $type);
     771        Smarty_CacheResource::invalidLoadedCache($this);
     772        return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time);
     773    }
     774
     775    /**
     776     * Loads security class and enables security
     777     *
     778     * @param string|Smarty_Security $security_class if a string is used, it must be class-name
     779     * @return Smarty current Smarty instance for chaining
     780     * @throws SmartyException when an invalid class name is provided
     781     */
     782    public function enableSecurity($security_class = null)
     783    {
     784        if ($security_class instanceof Smarty_Security) {
     785            $this->security_policy = $security_class;
     786            return $this;
     787        } elseif (is_object($security_class)) {
     788            throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security.");
     789        }
     790        if ($security_class == null) {
     791            $security_class = $this->security_class;
     792        }
     793        if (!class_exists($security_class)) {
     794            throw new SmartyException("Security class '$security_class' is not defined");
     795        } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) {
     796            throw new SmartyException("Class '$security_class' must extend Smarty_Security.");
     797        } else {
     798            $this->security_policy = new $security_class($this);
     799        }
     800
     801        return $this;
     802    }
     803
     804    /**
     805     * Disable security
     806     * @return Smarty current Smarty instance for chaining
     807     */
     808    public function disableSecurity()
     809    {
     810        $this->security_policy = null;
     811
     812        return $this;
     813    }
     814
     815    /**
     816     * Set template directory
     817     *
     818     * @param string|array $template_dir directory(s) of template sources
     819     * @return Smarty current Smarty instance for chaining
     820     */
     821    public function setTemplateDir($template_dir)
     822    {
     823        $this->template_dir = array();
     824        foreach ((array) $template_dir as $k => $v) {
     825            $this->template_dir[$k] = rtrim($v, '/\\') . DS;
     826        }
     827
     828        $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
     829        return $this;
     830    }
     831
     832    /**
     833     * Add template directory(s)
     834     *
     835     * @param string|array $template_dir directory(s) of template sources
     836     * @param string       $key          of the array element to assign the template dir to
     837     * @return Smarty current Smarty instance for chaining
     838     * @throws SmartyException when the given template directory is not valid
     839     */
     840    public function addTemplateDir($template_dir, $key=null)
     841    {
     842        // make sure we're dealing with an array
     843        $this->template_dir = (array) $this->template_dir;
     844
     845        if (is_array($template_dir)) {
     846            foreach ($template_dir as $k => $v) {
     847                if (is_int($k)) {
     848                    // indexes are not merged but appended
     849                    $this->template_dir[] = rtrim($v, '/\\') . DS;
     850                } else {
     851                    // string indexes are overridden
     852                    $this->template_dir[$k] = rtrim($v, '/\\') . DS;
     853                }
     854            }
     855        } elseif ($key !== null) {
     856            // override directory at specified index
     857            $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS;
     858        } else {
     859            // append new directory
     860            $this->template_dir[] = rtrim($template_dir, '/\\') . DS;
     861        }
     862        $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
     863        return $this;
     864    }
     865
     866    /**
     867     * Get template directories
     868     *
     869     * @param mixed index of directory to get, null to get all
     870     * @return array|string list of template directories, or directory of $index
     871     */
     872    public function getTemplateDir($index=null)
     873    {
     874        if ($index !== null) {
     875            return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
     876        }
     877
     878        return (array)$this->template_dir;
     879    }
     880
     881    /**
     882     * Set config directory
     883     *
     884     * @param string|array $template_dir directory(s) of configuration sources
     885     * @return Smarty current Smarty instance for chaining
     886     */
     887    public function setConfigDir($config_dir)
     888    {
     889        $this->config_dir = array();
     890        foreach ((array) $config_dir as $k => $v) {
     891            $this->config_dir[$k] = rtrim($v, '/\\') . DS;
     892        }
     893
     894        $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
     895        return $this;
     896    }
     897
     898    /**
     899     * Add config directory(s)
     900     *
     901     * @param string|array $config_dir directory(s) of config sources
     902     * @param string key of the array element to assign the config dir to
     903     * @return Smarty current Smarty instance for chaining
     904     */
     905    public function addConfigDir($config_dir, $key=null)
     906    {
     907        // make sure we're dealing with an array
     908        $this->config_dir = (array) $this->config_dir;
     909
     910        if (is_array($config_dir)) {
     911            foreach ($config_dir as $k => $v) {
     912                if (is_int($k)) {
     913                    // indexes are not merged but appended
     914                    $this->config_dir[] = rtrim($v, '/\\') . DS;
     915                } else {
     916                    // string indexes are overridden
     917                    $this->config_dir[$k] = rtrim($v, '/\\') . DS;
     918                }
     919            }
     920        } elseif( $key !== null ) {
     921            // override directory at specified index
     922            $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS;
     923        } else {
     924            // append new directory
     925            $this->config_dir[] = rtrim($config_dir, '/\\') . DS;
     926        }
     927
     928        $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
     929        return $this;
     930    }
     931
     932    /**
     933     * Get config directory
     934     *
     935     * @param mixed index of directory to get, null to get all
     936     * @return array|string configuration directory
     937     */
     938    public function getConfigDir($index=null)
     939    {
     940        if ($index !== null) {
     941            return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
     942        }
     943
     944        return (array)$this->config_dir;
     945    }
     946
     947    /**
     948     * Set plugins directory
     949     *
     950     * @param string|array $plugins_dir directory(s) of plugins
     951     * @return Smarty current Smarty instance for chaining
     952     */
     953    public function setPluginsDir($plugins_dir)
     954    {
     955        $this->plugins_dir = array();
     956        foreach ((array)$plugins_dir as $k => $v) {
     957            $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
     958        }
     959
     960        return $this;
     961    }
     962
     963    /**
     964     * Adds directory of plugin files
     965     *
     966     * @param object $smarty
     967     * @param string $ |array $ plugins folder
     968     * @return Smarty current Smarty instance for chaining
     969     */
     970    public function addPluginsDir($plugins_dir)
     971    {
     972        // make sure we're dealing with an array
     973        $this->plugins_dir = (array) $this->plugins_dir;
     974
     975        if (is_array($plugins_dir)) {
     976            foreach ($plugins_dir as $k => $v) {
     977                if (is_int($k)) {
     978                    // indexes are not merged but appended
     979                    $this->plugins_dir[] = rtrim($v, '/\\') . DS;
     980                } else {
     981                    // string indexes are overridden
     982                    $this->plugins_dir[$k] = rtrim($v, '/\\') . DS;
    587983                }
    588984            }
    589985        } else {
    590             if ($tpl_var != '')
    591                 $this->_tpl_vars[$tpl_var] = $value;
    592         }
    593     }
    594 
    595     /**
    596      * assigns values to template variables by reference
    597      *
    598      * @param string $tpl_var the template variable name
    599      * @param mixed $value the referenced value to assign
    600      */
    601     function assign_by_ref($tpl_var, &$value)
    602     {
    603         if ($tpl_var != '')
    604             $this->_tpl_vars[$tpl_var] = &$value;
    605     }
    606 
    607     /**
    608      * appends values to template variables
    609      *
    610      * @param array|string $tpl_var the template variable name(s)
    611      * @param mixed $value the value to append
    612      */
    613     function append($tpl_var, $value=null, $merge=false)
    614     {
    615         if (is_array($tpl_var)) {
    616             // $tpl_var is an array, ignore $value
    617             foreach ($tpl_var as $_key => $_val) {
    618                 if ($_key != '') {
    619                     if(!@is_array($this->_tpl_vars[$_key])) {
    620                         settype($this->_tpl_vars[$_key],'array');
     986            // append new directory
     987            $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS;
     988        }
     989
     990        $this->plugins_dir = array_unique($this->plugins_dir);
     991        return $this;
     992    }
     993
     994    /**
     995     * Get plugin directories
     996     *
     997     * @return array list of plugin directories
     998     */
     999    public function getPluginsDir()
     1000    {
     1001        return (array)$this->plugins_dir;
     1002    }
     1003
     1004    /**
     1005     * Set compile directory
     1006     *
     1007     * @param string $compile_dir directory to store compiled templates in
     1008     * @return Smarty current Smarty instance for chaining
     1009     */
     1010    public function setCompileDir($compile_dir)
     1011    {
     1012        $this->compile_dir = rtrim($compile_dir, '/\\') . DS;
     1013        if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
     1014            Smarty::$_muted_directories[$this->compile_dir] = null;
     1015        }
     1016        return $this;
     1017    }
     1018
     1019    /**
     1020     * Get compiled directory
     1021     *
     1022     * @return string path to compiled templates
     1023     */
     1024    public function getCompileDir()
     1025    {
     1026        return $this->compile_dir;
     1027    }
     1028
     1029    /**
     1030     * Set cache directory
     1031     *
     1032     * @param string $cache_dir directory to store cached templates in
     1033     * @return Smarty current Smarty instance for chaining
     1034     */
     1035    public function setCacheDir($cache_dir)
     1036    {
     1037        $this->cache_dir = rtrim($cache_dir, '/\\') . DS;
     1038        if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
     1039            Smarty::$_muted_directories[$this->cache_dir] = null;
     1040        }
     1041        return $this;
     1042    }
     1043
     1044    /**
     1045     * Get cache directory
     1046     *
     1047     * @return string path of cache directory
     1048     */
     1049    public function getCacheDir()
     1050    {
     1051        return $this->cache_dir;
     1052    }
     1053
     1054    /**
     1055     * Set default modifiers
     1056     *
     1057     * @param array|string $modifiers modifier or list of modifiers to set
     1058     * @return Smarty current Smarty instance for chaining
     1059     */
     1060    public function setDefaultModifiers($modifiers)
     1061    {
     1062        $this->default_modifiers = (array) $modifiers;
     1063        return $this;
     1064    }
     1065
     1066    /**
     1067     * Add default modifiers
     1068     *
     1069     * @param array|string $modifiers modifier or list of modifiers to add
     1070     * @return Smarty current Smarty instance for chaining
     1071     */
     1072    public function addDefaultModifiers($modifiers)
     1073    {
     1074        if (is_array($modifiers)) {
     1075            $this->default_modifiers = array_merge($this->default_modifiers, $modifiers);
     1076        } else {
     1077            $this->default_modifiers[] = $modifiers;
     1078        }
     1079
     1080        return $this;
     1081    }
     1082
     1083    /**
     1084     * Get default modifiers
     1085     *
     1086     * @return array list of default modifiers
     1087     */
     1088    public function getDefaultModifiers()
     1089    {
     1090        return $this->default_modifiers;
     1091    }
     1092
     1093
     1094    /**
     1095     * Set autoload filters
     1096     *
     1097     * @param array $filters filters to load automatically
     1098     * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
     1099     * @return Smarty current Smarty instance for chaining
     1100     */
     1101    public function setAutoloadFilters($filters, $type=null)
     1102    {
     1103        if ($type !== null) {
     1104            $this->autoload_filters[$type] = (array) $filters;
     1105        } else {
     1106            $this->autoload_filters = (array) $filters;
     1107        }
     1108
     1109        return $this;
     1110    }
     1111
     1112    /**
     1113     * Add autoload filters
     1114     *
     1115     * @param array $filters filters to load automatically
     1116     * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types
     1117     * @return Smarty current Smarty instance for chaining
     1118     */
     1119    public function addAutoloadFilters($filters, $type=null)
     1120    {
     1121        if ($type !== null) {
     1122            if (!empty($this->autoload_filters[$type])) {
     1123                $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters);
     1124            } else {
     1125                $this->autoload_filters[$type] = (array) $filters;
     1126            }
     1127        } else {
     1128            foreach ((array) $filters as $key => $value) {
     1129                if (!empty($this->autoload_filters[$key])) {
     1130                    $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value);
     1131                } else {
     1132                    $this->autoload_filters[$key] = (array) $value;
     1133                }
     1134            }
     1135        }
     1136
     1137        return $this;
     1138    }
     1139
     1140    /**
     1141     * Get autoload filters
     1142     *
     1143     * @param string $type type of filter to get autoloads for. Defaults to all autoload filters
     1144     * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified
     1145     */
     1146    public function getAutoloadFilters($type=null)
     1147    {
     1148        if ($type !== null) {
     1149            return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array();
     1150        }
     1151
     1152        return $this->autoload_filters;
     1153    }
     1154
     1155    /**
     1156     * return name of debugging template
     1157     *
     1158     * @return string
     1159     */
     1160    public function getDebugTemplate()
     1161    {
     1162        return $this->debug_tpl;
     1163    }
     1164
     1165    /**
     1166     * set the debug template
     1167     *
     1168     * @param string $tpl_name
     1169     * @return Smarty current Smarty instance for chaining
     1170     * @throws SmartyException if file is not readable
     1171     */
     1172    public function setDebugTemplate($tpl_name)
     1173    {
     1174        if (!is_readable($tpl_name)) {
     1175            throw new SmartyException("Unknown file '{$tpl_name}'");
     1176        }
     1177        $this->debug_tpl = $tpl_name;
     1178
     1179        return $this;
     1180    }
     1181
     1182    /**
     1183     * creates a template object
     1184     *
     1185     * @param string $template the resource handle of the template file
     1186     * @param mixed $cache_id cache id to be used with this template
     1187     * @param mixed $compile_id compile id to be used with this template
     1188     * @param object $parent next higher level of Smarty variables
     1189     * @param boolean $do_clone flag is Smarty object shall be cloned
     1190     * @return object template object
     1191     */
     1192    public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true)
     1193    {
     1194        if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) {
     1195            $parent = $cache_id;
     1196            $cache_id = null;
     1197        }
     1198        if (!empty($parent) && is_array($parent)) {
     1199            $data = $parent;
     1200            $parent = null;
     1201        } else {
     1202            $data = null;
     1203        }
     1204        // default to cache_id and compile_id of Smarty object
     1205        $cache_id = $cache_id === null ? $this->cache_id : $cache_id;
     1206        $compile_id = $compile_id === null ? $this->compile_id : $compile_id;
     1207        // already in template cache?
     1208        if ($this->allow_ambiguous_resources) {
     1209            $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
     1210        } else {
     1211            $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id;
     1212        }
     1213        if (isset($_templateId[150])) {
     1214            $_templateId = sha1($_templateId);
     1215        }
     1216        if ($do_clone) {
     1217            if (isset($this->template_objects[$_templateId])) {
     1218                // return cached template object
     1219                $tpl = clone $this->template_objects[$_templateId];
     1220                $tpl->smarty = clone $tpl->smarty;
     1221                $tpl->parent = $parent;
     1222                $tpl->tpl_vars = array();
     1223                $tpl->config_vars = array();
     1224            } else {
     1225                $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id);
     1226            }
     1227        } else {
     1228            if (isset($this->template_objects[$_templateId])) {
     1229                // return cached template object
     1230                $tpl = $this->template_objects[$_templateId];
     1231                $tpl->parent = $parent;
     1232                $tpl->tpl_vars = array();
     1233                $tpl->config_vars = array();
     1234            } else {
     1235                $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
     1236            }
     1237        }
     1238        // fill data if present
     1239        if (!empty($data) && is_array($data)) {
     1240            // set up variable values
     1241            foreach ($data as $_key => $_val) {
     1242                $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
     1243            }
     1244        }
     1245        return $tpl;
     1246    }
     1247
     1248
     1249    /**
     1250     * Takes unknown classes and loads plugin files for them
     1251     * class name format: Smarty_PluginType_PluginName
     1252     * plugin filename format: plugintype.pluginname.php
     1253     *
     1254     * @param string $plugin_name    class plugin name to load
     1255     * @param bool   $check          check if already loaded
     1256     * @return string |boolean filepath of loaded file or false
     1257     */
     1258    public function loadPlugin($plugin_name, $check = true)
     1259    {
     1260        // if function or class exists, exit silently (already loaded)
     1261        if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) {
     1262            return true;
     1263        }
     1264        // Plugin name is expected to be: Smarty_[Type]_[Name]
     1265        $_name_parts = explode('_', $plugin_name, 3);
     1266        // class name must have three parts to be valid plugin
     1267        // count($_name_parts) < 3 === !isset($_name_parts[2])
     1268        if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') {
     1269            throw new SmartyException("plugin {$plugin_name} is not a valid name format");
     1270            return false;
     1271        }
     1272        // if type is "internal", get plugin from sysplugins
     1273        if (strtolower($_name_parts[1]) == 'internal') {
     1274            $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php';
     1275            if (file_exists($file)) {
     1276                require_once($file);
     1277                return $file;
     1278            } else {
     1279                return false;
     1280            }
     1281        }
     1282        // plugin filename is expected to be: [type].[name].php
     1283        $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
     1284
     1285        $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
     1286
     1287        // loop through plugin dirs and find the plugin
     1288        foreach($this->getPluginsDir() as $_plugin_dir) {
     1289            $names = array(
     1290                $_plugin_dir . $_plugin_filename,
     1291                $_plugin_dir . strtolower($_plugin_filename),
     1292            );
     1293            foreach ($names as $file) {
     1294                if (file_exists($file)) {
     1295                    require_once($file);
     1296                    return $file;
     1297                }
     1298                if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
     1299                    // try PHP include_path
     1300                    if ($_stream_resolve_include_path) {
     1301                        $file = stream_resolve_include_path($file);
     1302                    } else {
     1303                        $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
    6211304                    }
    622                     if($merge && is_array($_val)) {
    623                         foreach($_val as $_mkey => $_mval) {
    624                             $this->_tpl_vars[$_key][$_mkey] = $_mval;
    625                         }
    626                     } else {
    627                         $this->_tpl_vars[$_key][] = $_val;
     1305
     1306                    if ($file !== false) {
     1307                        require_once($file);
     1308                        return $file;
    6281309                    }
    6291310                }
    6301311            }
    631         } else {
    632             if ($tpl_var != '' && isset($value)) {
    633                 if(!@is_array($this->_tpl_vars[$tpl_var])) {
    634                     settype($this->_tpl_vars[$tpl_var],'array');
     1312        }
     1313        // no plugin loaded
     1314        return false;
     1315    }
     1316
     1317    /**
     1318     * Compile all template files
     1319     *
     1320     * @param string $extension file extension
     1321     * @param bool $force_compile force all to recompile
     1322     * @param int $time_limit
     1323     * @param int $max_errors
     1324     * @return integer number of template files recompiled
     1325     */
     1326    public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
     1327    {
     1328        return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this);
     1329    }
     1330
     1331    /**
     1332     * Compile all config files
     1333     *
     1334     * @param string $extension file extension
     1335     * @param bool $force_compile force all to recompile
     1336     * @param int $time_limit
     1337     * @param int $max_errors
     1338     * @return integer number of template files recompiled
     1339     */
     1340    public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
     1341    {
     1342        return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this);
     1343    }
     1344
     1345    /**
     1346     * Delete compiled template file
     1347     *
     1348     * @param string $resource_name template name
     1349     * @param string $compile_id compile id
     1350     * @param integer $exp_time expiration time
     1351     * @return integer number of template files deleted
     1352     */
     1353    public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
     1354    {
     1355        return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this);
     1356    }
     1357
     1358
     1359    /**
     1360     * Return array of tag/attributes of all tags used by an template
     1361     *
     1362     * @param object $templae template object
     1363     * @return array of tag/attributes
     1364     */
     1365    public function getTags(Smarty_Internal_Template $template)
     1366    {
     1367        return Smarty_Internal_Utility::getTags($template);
     1368    }
     1369
     1370    /**
     1371     * Run installation test
     1372     *
     1373     * @param array $errors Array to write errors into, rather than outputting them
     1374     * @return boolean true if setup is fine, false if something is wrong
     1375     */
     1376    public function testInstall(&$errors=null)
     1377    {
     1378        return Smarty_Internal_Utility::testInstall($this, $errors);
     1379    }
     1380
     1381    /**
     1382     * Error Handler to mute expected messages
     1383     *
     1384     * @link http://php.net/set_error_handler
     1385     * @param integer $errno Error level
     1386     * @return boolean
     1387     */
     1388    public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext)
     1389    {
     1390        $_is_muted_directory = false;
     1391
     1392        // add the SMARTY_DIR to the list of muted directories
     1393        if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
     1394            $smarty_dir = realpath(SMARTY_DIR);
     1395            if ($smarty_dir !== false) {
     1396                Smarty::$_muted_directories[SMARTY_DIR] = array(
     1397                    'file' => $smarty_dir,
     1398                    'length' => strlen($smarty_dir),
     1399                );
     1400            }
     1401        }
     1402
     1403        // walk the muted directories and test against $errfile
     1404        foreach (Smarty::$_muted_directories as $key => &$dir) {
     1405            if (!$dir) {
     1406                // resolve directory and length for speedy comparisons
     1407                $file = realpath($key);
     1408                if ($file === false) {
     1409                    // this directory does not exist, remove and skip it
     1410                    unset(Smarty::$_muted_directories[$key]);
     1411                    continue;
    6351412                }
    636                 if($merge && is_array($value)) {
    637                     foreach($value as $_mkey => $_mval) {
    638                         $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
    639                     }
    640                 } else {
    641                     $this->_tpl_vars[$tpl_var][] = $value;
    642                 }
     1413                $dir = array(
     1414                    'file' => $file,
     1415                    'length' => strlen($file),
     1416                );
    6431417            }
    644         }
    645     }
    646 
    647     /**
    648      * appends values to template variables by reference
    649      *
    650      * @param string $tpl_var the template variable name
    651      * @param mixed $value the referenced value to append
    652      */
    653     function append_by_ref($tpl_var, &$value, $merge=false)
    654     {
    655         if ($tpl_var != '' && isset($value)) {
    656             if(!@is_array($this->_tpl_vars[$tpl_var])) {
    657              settype($this->_tpl_vars[$tpl_var],'array');
     1418            if (!strncmp($errfile, $dir['file'], $dir['length'])) {
     1419                $_is_muted_directory = true;
     1420                break;
    6581421            }
    659             if ($merge && is_array($value)) {
    660                 foreach($value as $_key => $_val) {
    661                     $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
    662                 }
     1422        }
     1423
     1424        // pass to next error handler if this error did not occur inside SMARTY_DIR
     1425        // or the error was within smarty but masked to be ignored
     1426        if (!$_is_muted_directory || ($errno && $errno & error_reporting())) {
     1427            if (Smarty::$_previous_error_handler) {
     1428                return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext);
    6631429            } else {
    664                 $this->_tpl_vars[$tpl_var][] = &$value;
    665             }
    666         }
    667     }
    668 
    669 
    670     /**
    671      * clear the given assigned template variable.
    672      *
    673      * @param string $tpl_var the template variable to clear
    674      */
    675     function clear_assign($tpl_var)
    676     {
    677         if (is_array($tpl_var))
    678             foreach ($tpl_var as $curr_var)
    679                 unset($this->_tpl_vars[$curr_var]);
    680         else
    681             unset($this->_tpl_vars[$tpl_var]);
    682     }
    683 
    684 
    685     /**
    686      * Registers custom function to be used in templates
    687      *
    688      * @param string $function the name of the template function
    689      * @param string $function_impl the name of the PHP function to register
    690      */
    691     function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
    692     {
    693         $this->_plugins['function'][$function] =
    694             array($function_impl, null, null, false, $cacheable, $cache_attrs);
    695 
    696     }
    697 
    698     /**
    699      * Unregisters custom function
    700      *
    701      * @param string $function name of template function
    702      */
    703     function unregister_function($function)
    704     {
    705         unset($this->_plugins['function'][$function]);
    706     }
    707 
    708     /**
    709      * Registers object to be used in templates
    710      *
    711      * @param string $object name of template object
    712      * @param object &$object_impl the referenced PHP object to register
    713      * @param null|array $allowed list of allowed methods (empty = all)
    714      * @param boolean $smarty_args smarty argument format, else traditional
    715      * @param null|array $block_functs list of methods that are block format
    716      */
    717     function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
    718     {
    719         settype($allowed, 'array');
    720         settype($smarty_args, 'boolean');
    721         $this->_reg_objects[$object] =
    722             array(&$object_impl, $allowed, $smarty_args, $block_methods);
    723     }
    724 
    725     /**
    726      * Unregisters object
    727      *
    728      * @param string $object name of template object
    729      */
    730     function unregister_object($object)
    731     {
    732         unset($this->_reg_objects[$object]);
    733     }
    734 
    735 
    736     /**
    737      * Registers block function to be used in templates
    738      *
    739      * @param string $block name of template block
    740      * @param string $block_impl PHP function to register
    741      */
    742     function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
    743     {
    744         $this->_plugins['block'][$block] =
    745             array($block_impl, null, null, false, $cacheable, $cache_attrs);
    746     }
    747 
    748     /**
    749      * Unregisters block function
    750      *
    751      * @param string $block name of template function
    752      */
    753     function unregister_block($block)
    754     {
    755         unset($this->_plugins['block'][$block]);
    756     }
    757 
    758     /**
    759      * Registers compiler function
    760      *
    761      * @param string $function name of template function
    762      * @param string $function_impl name of PHP function to register
    763      */
    764     function register_compiler_function($function, $function_impl, $cacheable=true)
    765     {
    766         $this->_plugins['compiler'][$function] =
    767             array($function_impl, null, null, false, $cacheable);
    768     }
    769 
    770     /**
    771      * Unregisters compiler function
    772      *
    773      * @param string $function name of template function
    774      */
    775     function unregister_compiler_function($function)
    776     {
    777         unset($this->_plugins['compiler'][$function]);
    778     }
    779 
    780     /**
    781      * Registers modifier to be used in templates
    782      *
    783      * @param string $modifier name of template modifier
    784      * @param string $modifier_impl name of PHP function to register
    785      */
    786     function register_modifier($modifier, $modifier_impl)
    787     {
    788         $this->_plugins['modifier'][$modifier] =
    789             array($modifier_impl, null, null, false);
    790     }
    791 
    792     /**
    793      * Unregisters modifier
    794      *
    795      * @param string $modifier name of template modifier
    796      */
    797     function unregister_modifier($modifier)
    798     {
    799         unset($this->_plugins['modifier'][$modifier]);
    800     }
    801 
    802     /**
    803      * Registers a resource to fetch a template
    804      *
    805      * @param string $type name of resource
    806      * @param array $functions array of functions to handle resource
    807      */
    808     function register_resource($type, $functions)
    809     {
    810         if (count($functions)==4) {
    811             $this->_plugins['resource'][$type] =
    812                 array($functions, false);
    813 
    814         } elseif (count($functions)==5) {
    815             $this->_plugins['resource'][$type] =
    816                 array(array(array(&$functions[0], $functions[1])
    817                             ,array(&$functions[0], $functions[2])
    818                             ,array(&$functions[0], $functions[3])
    819                             ,array(&$functions[0], $functions[4]))
    820                       ,false);
    821 
    822         } else {
    823             $this->trigger_error("malformed function-list for '$type' in register_resource");
    824 
    825         }
    826     }
    827 
    828     /**
    829      * Unregisters a resource
    830      *
    831      * @param string $type name of resource
    832      */
    833     function unregister_resource($type)
    834     {
    835         unset($this->_plugins['resource'][$type]);
    836     }
    837 
    838     /**
    839      * Registers a prefilter function to apply
    840      * to a template before compiling
    841      *
    842      * @param callback $function
    843      */
    844     function register_prefilter($function)
    845     {
    846         $this->_plugins['prefilter'][$this->_get_filter_name($function)]
    847             = array($function, null, null, false);
    848     }
    849 
    850     /**
    851      * Unregisters a prefilter function
    852      *
    853      * @param callback $function
    854      */
    855     function unregister_prefilter($function)
    856     {
    857         unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
    858     }
    859 
    860     /**
    861      * Registers a postfilter function to apply
    862      * to a compiled template after compilation
    863      *
    864      * @param callback $function
    865      */
    866     function register_postfilter($function)
    867     {
    868         $this->_plugins['postfilter'][$this->_get_filter_name($function)]
    869             = array($function, null, null, false);
    870     }
    871 
    872     /**
    873      * Unregisters a postfilter function
    874      *
    875      * @param callback $function
    876      */
    877     function unregister_postfilter($function)
    878     {
    879         unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
    880     }
    881 
    882     /**
    883      * Registers an output filter function to apply
    884      * to a template output
    885      *
    886      * @param callback $function
    887      */
    888     function register_outputfilter($function)
    889     {
    890         $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
    891             = array($function, null, null, false);
    892     }
    893 
    894     /**
    895      * Unregisters an outputfilter function
    896      *
    897      * @param callback $function
    898      */
    899     function unregister_outputfilter($function)
    900     {
    901         unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
    902     }
    903 
    904     /**
    905      * load a filter of specified type and name
    906      *
    907      * @param string $type filter type
    908      * @param string $name filter name
    909      */
    910     function load_filter($type, $name)
    911     {
    912         switch ($type) {
    913             case 'output':
    914                 $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
    915                 require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
    916                 smarty_core_load_plugins($_params, $this);
    917                 break;
    918 
    919             case 'pre':
    920             case 'post':
    921                 if (!isset($this->_plugins[$type . 'filter'][$name]))
    922                     $this->_plugins[$type . 'filter'][$name] = false;
    923                 break;
    924         }
    925     }
    926 
    927     /**
    928      * clear cached content for the given template and cache id
    929      *
    930      * @param string $tpl_file name of template file
    931      * @param string $cache_id name of cache_id
    932      * @param string $compile_id name of compile_id
    933      * @param string $exp_time expiration time
    934      * @return boolean
    935      */
    936     function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
    937     {
    938 
    939         if (!isset($compile_id))
    940             $compile_id = $this->compile_id;
    941 
    942         if (!isset($tpl_file))
    943             $compile_id = null;
    944 
    945         $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
    946 
    947         if (!empty($this->cache_handler_func)) {
    948             return call_user_func_array($this->cache_handler_func,
    949                                   array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
    950         } else {
    951             $_params = array('auto_base' => $this->cache_dir,
    952                             'auto_source' => $tpl_file,
    953                             'auto_id' => $_auto_id,
    954                             'exp_time' => $exp_time);
    955             require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
    956             return smarty_core_rm_auto($_params, $this);
    957         }
    958 
    959     }
    960 
    961 
    962     /**
    963      * clear the entire contents of cache (all templates)
    964      *
    965      * @param string $exp_time expire time
    966      * @return boolean results of {@link smarty_core_rm_auto()}
    967      */
    968     function clear_all_cache($exp_time = null)
    969     {
    970         return $this->clear_cache(null, null, null, $exp_time);
    971     }
    972 
    973 
    974     /**
    975      * test to see if valid cache exists for this template
    976      *
    977      * @param string $tpl_file name of template file
    978      * @param string $cache_id
    979      * @param string $compile_id
    980      * @return string|false results of {@link _read_cache_file()}
    981      */
    982     function is_cached($tpl_file, $cache_id = null, $compile_id = null)
    983     {
    984         if (!$this->caching)
    985             return false;
    986 
    987         if (!isset($compile_id))
    988             $compile_id = $this->compile_id;
    989 
    990         $_params = array(
    991             'tpl_file' => $tpl_file,
    992             'cache_id' => $cache_id,
    993             'compile_id' => $compile_id
    994         );
    995         require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
    996         return smarty_core_read_cache_file($_params, $this);
    997     }
    998 
    999 
    1000     /**
    1001      * clear all the assigned template variables.
    1002      *
    1003      */
    1004     function clear_all_assign()
    1005     {
    1006         $this->_tpl_vars = array();
    1007     }
    1008 
    1009     /**
    1010      * clears compiled version of specified template resource,
    1011      * or all compiled template files if one is not specified.
    1012      * This function is for advanced use only, not normally needed.
    1013      *
    1014      * @param string $tpl_file
    1015      * @param string $compile_id
    1016      * @param string $exp_time
    1017      * @return boolean results of {@link smarty_core_rm_auto()}
    1018      */
    1019     function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
    1020     {
    1021         if (!isset($compile_id)) {
    1022             $compile_id = $this->compile_id;
    1023         }
    1024         $_params = array('auto_base' => $this->compile_dir,
    1025                         'auto_source' => $tpl_file,
    1026                         'auto_id' => $compile_id,
    1027                         'exp_time' => $exp_time,
    1028                         'extensions' => array('.inc', '.php'));
    1029         require_once(SMARTY_CORE_DIR . 'core.rm_auto.php');
    1030         return smarty_core_rm_auto($_params, $this);
    1031     }
    1032 
    1033     /**
    1034      * Checks whether requested template exists.
    1035      *
    1036      * @param string $tpl_file
    1037      * @return boolean
    1038      */
    1039     function template_exists($tpl_file)
    1040     {
    1041         $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
    1042         return $this->_fetch_resource_info($_params);
    1043     }
    1044 
    1045     /**
    1046      * Returns an array containing template variables
    1047      *
    1048      * @param string $name
    1049      * @param string $type
    1050      * @return array
    1051      */
    1052     function &get_template_vars($name=null)
    1053     {
    1054         if(!isset($name)) {
    1055             return $this->_tpl_vars;
    1056         } elseif(isset($this->_tpl_vars[$name])) {
    1057             return $this->_tpl_vars[$name];
    1058         } else {
    1059             // var non-existant, return valid reference
    1060             $_tmp = null;
    1061             return $_tmp;
    1062         }
    1063     }
    1064 
    1065     /**
    1066      * Returns an array containing config variables
    1067      *
    1068      * @param string $name
    1069      * @param string $type
    1070      * @return array
    1071      */
    1072     function &get_config_vars($name=null)
    1073     {
    1074         if(!isset($name) && is_array($this->_config[0])) {
    1075             return $this->_config[0]['vars'];
    1076         } else if(isset($this->_config[0]['vars'][$name])) {
    1077             return $this->_config[0]['vars'][$name];
    1078         } else {
    1079             // var non-existant, return valid reference
    1080             $_tmp = null;
    1081             return $_tmp;
    1082         }
    1083     }
    1084 
    1085     /**
    1086      * trigger Smarty error
    1087      *
    1088      * @param string $error_msg
    1089      * @param integer $error_type
    1090      */
    1091     function trigger_error($error_msg, $error_type = E_USER_WARNING)
    1092     {
    1093         trigger_error("Smarty error: $error_msg", $error_type);
    1094     }
    1095 
    1096 
    1097     /**
    1098      * executes & displays the template results
    1099      *
    1100      * @param string $resource_name
    1101      * @param string $cache_id
    1102      * @param string $compile_id
    1103      */
    1104     function display($resource_name, $cache_id = null, $compile_id = null)
    1105     {
    1106         $this->fetch($resource_name, $cache_id, $compile_id, true);
    1107     }
    1108 
    1109     /**
    1110      * executes & returns or displays the template results
    1111      *
    1112      * @param string $resource_name
    1113      * @param string $cache_id
    1114      * @param string $compile_id
    1115      * @param boolean $display
    1116      */
    1117     function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
    1118     {
    1119         static $_cache_info = array();
    1120 
    1121         $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
    1122                ? $this->error_reporting : error_reporting() & ~E_NOTICE);
    1123 
    1124         if (!$this->debugging && $this->debugging_ctrl == 'URL') {
    1125             $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
    1126             if (@strstr($_query_string, $this->_smarty_debug_id)) {
    1127                 if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
    1128                     // enable debugging for this browser session
    1129                     @setcookie('SMARTY_DEBUG', true);
    1130                     $this->debugging = true;
    1131                 } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
    1132                     // disable debugging for this browser session
    1133                     @setcookie('SMARTY_DEBUG', false);
    1134                     $this->debugging = false;
    1135                 } else {
    1136                     // enable debugging for this page
    1137                     $this->debugging = true;
    1138                 }
    1139             } else {
    1140                 $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']);
    1141             }
    1142         }
    1143 
    1144         if ($this->debugging) {
    1145             // capture time for debugging info
    1146             $_params = array();
    1147             require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
    1148             $_debug_start_time = smarty_core_get_microtime($_params, $this);
    1149             $this->_smarty_debug_info[] = array('type'      => 'template',
    1150                                                 'filename'  => $resource_name,
    1151                                                 'depth'     => 0);
    1152             $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
    1153         }
    1154 
    1155         if (!isset($compile_id)) {
    1156             $compile_id = $this->compile_id;
    1157         }
    1158 
    1159         $this->_compile_id = $compile_id;
    1160         $this->_inclusion_depth = 0;
    1161 
    1162         if ($this->caching) {
    1163             // save old cache_info, initialize cache_info
    1164             array_push($_cache_info, $this->_cache_info);
    1165             $this->_cache_info = array();
    1166             $_params = array(
    1167                 'tpl_file' => $resource_name,
    1168                 'cache_id' => $cache_id,
    1169                 'compile_id' => $compile_id,
    1170                 'results' => null
    1171             );
    1172             require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php');
    1173             if (smarty_core_read_cache_file($_params, $this)) {
    1174                 $_smarty_results = $_params['results'];
    1175                 if (!empty($this->_cache_info['insert_tags'])) {
    1176                     $_params = array('plugins' => $this->_cache_info['insert_tags']);
    1177                     require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');
    1178                     smarty_core_load_plugins($_params, $this);
    1179                     $_params = array('results' => $_smarty_results);
    1180                     require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
    1181                     $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
    1182                 }
    1183                 if (!empty($this->_cache_info['cache_serials'])) {
    1184                     $_params = array('results' => $_smarty_results);
    1185                     require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php');
    1186                     $_smarty_results = smarty_core_process_compiled_include($_params, $this);
    1187                 }
    1188 
    1189 
    1190                 if ($display) {
    1191                     if ($this->debugging)
    1192                     {
    1193                         // capture time for debugging info
    1194                         $_params = array();
    1195                         require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
    1196                         $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
    1197                         require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
    1198                         $_smarty_results .= smarty_core_display_debug_console($_params, $this);
    1199                     }
    1200                     if ($this->cache_modified_check) {
    1201                         $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
    1202                         $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
    1203                         $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
    1204                         if (@count($this->_cache_info['insert_tags']) == 0
    1205                             && !$this->_cache_serials
    1206                             && $_gmt_mtime == $_last_modified_date) {
    1207                             if (php_sapi_name()=='cgi')
    1208                                 header('Status: 304 Not Modified');
    1209                             else
    1210                                 header('HTTP/1.1 304 Not Modified');
    1211 
    1212                         } else {
    1213                             header('Last-Modified: '.$_gmt_mtime);
    1214                             echo $_smarty_results;
    1215                         }
    1216                     } else {
    1217                             echo $_smarty_results;
    1218                     }
    1219                     error_reporting($_smarty_old_error_level);
    1220                     // restore initial cache_info
    1221                     $this->_cache_info = array_pop($_cache_info);
    1222                     return true;
    1223                 } else {
    1224                     error_reporting($_smarty_old_error_level);
    1225                     // restore initial cache_info
    1226                     $this->_cache_info = array_pop($_cache_info);
    1227                     return $_smarty_results;
    1228                 }
    1229             } else {
    1230                 $this->_cache_info['template'][$resource_name] = true;
    1231                 if ($this->cache_modified_check && $display) {
    1232                     header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
    1233                 }
    1234             }
    1235         }
    1236 
    1237         // load filters that are marked as autoload
    1238         if (count($this->autoload_filters)) {
    1239             foreach ($this->autoload_filters as $_filter_type => $_filters) {
    1240                 foreach ($_filters as $_filter) {
    1241                     $this->load_filter($_filter_type, $_filter);
    1242                 }
    1243             }
    1244         }
    1245 
    1246         $_smarty_compile_path = $this->_get_compile_path($resource_name);
    1247 
    1248         // if we just need to display the results, don't perform output
    1249         // buffering - for speed
    1250         $_cache_including = $this->_cache_including;
    1251         $this->_cache_including = false;
    1252         if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
    1253             if ($this->_is_compiled($resource_name, $_smarty_compile_path)
    1254                     || $this->_compile_resource($resource_name, $_smarty_compile_path))
    1255             {
    1256                 include($_smarty_compile_path);
    1257             }
    1258         } else {
    1259             ob_start();
    1260             if ($this->_is_compiled($resource_name, $_smarty_compile_path)
    1261                     || $this->_compile_resource($resource_name, $_smarty_compile_path))
    1262             {
    1263                 include($_smarty_compile_path);
    1264             }
    1265             $_smarty_results = ob_get_contents();
    1266             ob_end_clean();
    1267 
    1268             foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
    1269                 $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
    1270             }
    1271         }
    1272 
    1273         if ($this->caching) {
    1274             $_params = array('tpl_file' => $resource_name,
    1275                         'cache_id' => $cache_id,
    1276                         'compile_id' => $compile_id,
    1277                         'results' => $_smarty_results);
    1278             require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php');
    1279             smarty_core_write_cache_file($_params, $this);
    1280             require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php');
    1281             $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
    1282 
    1283             if ($this->_cache_serials) {
    1284                 // strip nocache-tags from output
    1285                 $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
    1286                                                 ,''
    1287                                                 ,$_smarty_results);
    1288             }
    1289             // restore initial cache_info
    1290             $this->_cache_info = array_pop($_cache_info);
    1291         }
    1292         $this->_cache_including = $_cache_including;
    1293 
    1294         if ($display) {
    1295             if (isset($_smarty_results)) { echo $_smarty_results; }
    1296             if ($this->debugging) {
    1297                 // capture time for debugging info
    1298                 $_params = array();
    1299                 require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
    1300                 $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
    1301                 require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
    1302                 echo smarty_core_display_debug_console($_params, $this);
    1303             }
    1304             error_reporting($_smarty_old_error_level);
    1305             return;
    1306         } else {
    1307             if ($this->debugging) {
    1308                 // capture time for debugging info
    1309                 require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
    1310                 $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime(array(), $this) - $_debug_start_time);
    1311             }
    1312             error_reporting($_smarty_old_error_level);
    1313             if (isset($_smarty_results)) { return $_smarty_results; }
    1314         }
    1315     }
    1316 
    1317     /**
    1318      * load configuration values
    1319      *
    1320      * @param string $file
    1321      * @param string $section
    1322      * @param string $scope
    1323      */
    1324     function config_load($file, $section = null, $scope = 'global')
    1325     {
    1326         require_once($this->_get_plugin_filepath('function', 'config_load'));
    1327         smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
    1328     }
    1329 
    1330     /**
    1331      * return a reference to a registered object
    1332      *
    1333      * @param string $name
    1334      * @return object
    1335      */
    1336     function &get_registered_object($name) {
    1337         if (!isset($this->_reg_objects[$name]))
    1338         $this->_trigger_fatal_error("'$name' is not a registered object");
    1339 
    1340         if (!is_object($this->_reg_objects[$name][0]))
    1341         $this->_trigger_fatal_error("registered '$name' is not an object");
    1342 
    1343         return $this->_reg_objects[$name][0];
    1344     }
    1345 
    1346     /**
    1347      * clear configuration values
    1348      *
    1349      * @param string $var
    1350      */
    1351     function clear_config($var = null)
    1352     {
    1353         if(!isset($var)) {
    1354             // clear all values
    1355             $this->_config = array(array('vars'  => array(),
    1356                                          'files' => array()));
    1357         } else {
    1358             unset($this->_config[0]['vars'][$var]);
    1359         }
    1360     }
    1361 
    1362     /**
    1363      * get filepath of requested plugin
    1364      *
    1365      * @param string $type
    1366      * @param string $name
    1367      * @return string|false
    1368      */
    1369     function _get_plugin_filepath($type, $name)
    1370     {
    1371         $_params = array('type' => $type, 'name' => $name);
    1372         require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php');
    1373         return smarty_core_assemble_plugin_filepath($_params, $this);
    1374     }
    1375 
    1376    /**
    1377      * test if resource needs compiling
    1378      *
    1379      * @param string $resource_name
    1380      * @param string $compile_path
    1381      * @return boolean
    1382      */
    1383     function _is_compiled($resource_name, $compile_path)
    1384     {
    1385         if (!$this->force_compile && file_exists($compile_path)) {
    1386             if (!$this->compile_check) {
    1387                 // no need to check compiled file
    1388                 return true;
    1389             } else {
    1390                 // get file source and timestamp
    1391                 $_params = array('resource_name' => $resource_name, 'get_source'=>false);
    1392                 if (!$this->_fetch_resource_info($_params)) {
    1393                     return false;
    1394                 }
    1395                 if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
    1396                     // template not expired, no recompile
    1397                     return true;
    1398                 } else {
    1399                     // compile template
    1400                     return false;
    1401                 }
    1402             }
    1403         } else {
    1404             // compiled template does not exist, or forced compile
    1405             return false;
    1406         }
    1407     }
    1408 
    1409    /**
    1410      * compile the template
    1411      *
    1412      * @param string $resource_name
    1413      * @param string $compile_path
    1414      * @return boolean
    1415      */
    1416     function _compile_resource($resource_name, $compile_path)
    1417     {
    1418 
    1419         $_params = array('resource_name' => $resource_name);
    1420         if (!$this->_fetch_resource_info($_params)) {
    1421             return false;
    1422         }
    1423 
    1424         $_source_content = $_params['source_content'];
    1425         $_cache_include    = substr($compile_path, 0, -4).'.inc';
    1426 
    1427         if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
    1428             // if a _cache_serial was set, we also have to write an include-file:
    1429             if ($this->_cache_include_info) {
    1430                 require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php');
    1431                 smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)),  $this);
    1432             }
    1433 
    1434             $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content);
    1435             require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
    1436             smarty_core_write_compiled_resource($_params, $this);
    1437 
    1438             return true;
    1439         } else {
    1440             return false;
    1441         }
    1442 
    1443     }
    1444 
    1445    /**
    1446      * compile the given source
    1447      *
    1448      * @param string $resource_name
    1449      * @param string $source_content
    1450      * @param string $compiled_content
    1451      * @return boolean
    1452      */
    1453     function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
    1454     {
    1455         if (file_exists(SMARTY_DIR . $this->compiler_file)) {
    1456             require_once(SMARTY_DIR . $this->compiler_file);
    1457         } else {
    1458             // use include_path
    1459             require_once($this->compiler_file);
    1460         }
    1461 
    1462 
    1463         $smarty_compiler = new $this->compiler_class;
    1464 
    1465         $smarty_compiler->template_dir      = $this->template_dir;
    1466         $smarty_compiler->compile_dir       = $this->compile_dir;
    1467         $smarty_compiler->plugins_dir       = $this->plugins_dir;
    1468         $smarty_compiler->config_dir        = $this->config_dir;
    1469         $smarty_compiler->force_compile     = $this->force_compile;
    1470         $smarty_compiler->caching           = $this->caching;
    1471         $smarty_compiler->php_handling      = $this->php_handling;
    1472         $smarty_compiler->left_delimiter    = $this->left_delimiter;
    1473         $smarty_compiler->right_delimiter   = $this->right_delimiter;
    1474         $smarty_compiler->_version          = $this->_version;
    1475         $smarty_compiler->security          = $this->security;
    1476         $smarty_compiler->secure_dir        = $this->secure_dir;
    1477         $smarty_compiler->security_settings = $this->security_settings;
    1478         $smarty_compiler->trusted_dir       = $this->trusted_dir;
    1479         $smarty_compiler->use_sub_dirs      = $this->use_sub_dirs;
    1480         $smarty_compiler->_reg_objects      = &$this->_reg_objects;
    1481         $smarty_compiler->_plugins          = &$this->_plugins;
    1482         $smarty_compiler->_tpl_vars         = &$this->_tpl_vars;
    1483         $smarty_compiler->default_modifiers = $this->default_modifiers;
    1484         $smarty_compiler->compile_id        = $this->_compile_id;
    1485         $smarty_compiler->_config            = $this->_config;
    1486         $smarty_compiler->request_use_auto_globals  = $this->request_use_auto_globals;
    1487 
    1488         if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) {
    1489             $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path];
    1490         }
    1491         $smarty_compiler->_cache_include = $cache_include_path;
    1492 
    1493 
    1494         $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
    1495 
    1496         if ($smarty_compiler->_cache_serial) {
    1497             $this->_cache_include_info = array(
    1498                 'cache_serial'=>$smarty_compiler->_cache_serial
    1499                 ,'plugins_code'=>$smarty_compiler->_plugins_code
    1500                 ,'include_file_path' => $cache_include_path);
    1501 
    1502         } else {
    1503             $this->_cache_include_info = null;
    1504 
    1505         }
    1506 
    1507         return $_results;
    1508     }
    1509 
    1510     /**
    1511      * Get the compile path for this resource
    1512      *
    1513      * @param string $resource_name
    1514      * @return string results of {@link _get_auto_filename()}
    1515      */
    1516     function _get_compile_path($resource_name)
    1517     {
    1518         return $this->_get_auto_filename($this->compile_dir, $resource_name,
    1519                                          $this->_compile_id) . '.php';
    1520     }
    1521 
    1522     /**
    1523      * fetch the template info. Gets timestamp, and source
    1524      * if get_source is true
    1525      *
    1526      * sets $source_content to the source of the template, and
    1527      * $resource_timestamp to its time stamp
    1528      * @param string $resource_name
    1529      * @param string $source_content
    1530      * @param integer $resource_timestamp
    1531      * @param boolean $get_source
    1532      * @param boolean $quiet
    1533      * @return boolean
    1534      */
    1535 
    1536     function _fetch_resource_info(&$params)
    1537     {
    1538         if(!isset($params['get_source'])) { $params['get_source'] = true; }
    1539         if(!isset($params['quiet'])) { $params['quiet'] = false; }
    1540 
    1541         $_return = false;
    1542         $_params = array('resource_name' => $params['resource_name']) ;
    1543         if (isset($params['resource_base_path']))
    1544             $_params['resource_base_path'] = $params['resource_base_path'];
    1545         else
    1546             $_params['resource_base_path'] = $this->template_dir;
    1547 
    1548         if ($this->_parse_resource_name($_params)) {
    1549             $_resource_type = $_params['resource_type'];
    1550             $_resource_name = $_params['resource_name'];
    1551             switch ($_resource_type) {
    1552                 case 'file':
    1553                     if ($params['get_source']) {
    1554                         $params['source_content'] = $this->_read_file($_resource_name);
    1555                     }
    1556                     $params['resource_timestamp'] = filemtime($_resource_name);
    1557                     $_return = is_file($_resource_name) && is_readable($_resource_name);
    1558                     break;
    1559 
    1560                 default:
    1561                     // call resource functions to fetch the template source and timestamp
    1562                     if ($params['get_source']) {
    1563                         $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
    1564                             call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
    1565                                                  array($_resource_name, &$params['source_content'], &$this));
    1566                     } else {
    1567                         $_source_return = true;
    1568                     }
    1569 
    1570                     $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
    1571                         call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
    1572                                              array($_resource_name, &$params['resource_timestamp'], &$this));
    1573 
    1574                     $_return = $_source_return && $_timestamp_return;
    1575                     break;
    1576             }
    1577         }
    1578 
    1579         if (!$_return) {
    1580             // see if we can get a template with the default template handler
    1581             if (!empty($this->default_template_handler_func)) {
    1582                 if (!is_callable($this->default_template_handler_func)) {
    1583                     $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
    1584                 } else {
    1585                     $_return = call_user_func_array(
    1586                         $this->default_template_handler_func,
    1587                         array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
    1588                 }
    1589             }
    1590         }
    1591 
    1592         if (!$_return) {
    1593             if (!$params['quiet']) {
    1594                 $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
    1595             }
    1596         } else if ($_return && $this->security) {
    1597             require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
    1598             if (!smarty_core_is_secure($_params, $this)) {
    1599                 if (!$params['quiet'])
    1600                     $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
    1601                 $params['source_content'] = null;
    1602                 $params['resource_timestamp'] = null;
    16031430                return false;
    16041431            }
    16051432        }
    1606         return $_return;
    1607     }
    1608 
    1609 
    1610     /**
    1611      * parse out the type and name from the resource
    1612      *
    1613      * @param string $resource_base_path
    1614      * @param string $resource_name
    1615      * @param string $resource_type
    1616      * @param string $resource_name
    1617      * @return boolean
    1618      */
    1619 
    1620     function _parse_resource_name(&$params)
    1621     {
    1622 
    1623         // split tpl_path by the first colon
    1624         $_resource_name_parts = explode(':', $params['resource_name'], 2);
    1625 
    1626         if (count($_resource_name_parts) == 1) {
    1627             // no resource type given
    1628             $params['resource_type'] = $this->default_resource_type;
    1629             $params['resource_name'] = $_resource_name_parts[0];
    1630         } else {
    1631             if(strlen($_resource_name_parts[0]) == 1) {
    1632                 // 1 char is not resource type, but part of filepath
    1633                 $params['resource_type'] = $this->default_resource_type;
    1634                 $params['resource_name'] = $params['resource_name'];
    1635             } else {
    1636                 $params['resource_type'] = $_resource_name_parts[0];
    1637                 $params['resource_name'] = $_resource_name_parts[1];
    1638             }
    1639         }
    1640 
    1641         if ($params['resource_type'] == 'file') {
    1642             if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) {
    1643                 // relative pathname to $params['resource_base_path']
    1644                 // use the first directory where the file is found
    1645                 foreach ((array)$params['resource_base_path'] as $_curr_path) {
    1646                     $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
    1647                     if (file_exists($_fullpath) && is_file($_fullpath)) {
    1648                         $params['resource_name'] = $_fullpath;
    1649                         return true;
    1650                     }
    1651                     // didn't find the file, try include_path
    1652                     $_params = array('file_path' => $_fullpath);
    1653                     require_once(SMARTY_CORE_DIR . 'core.get_include_path.php');
    1654                     if(smarty_core_get_include_path($_params, $this)) {
    1655                         $params['resource_name'] = $_params['new_file_path'];
    1656                         return true;
    1657                     }
    1658                 }
    1659                 return false;
    1660             } else {
    1661                 /* absolute path */
    1662                 return file_exists($params['resource_name']);
    1663             }
    1664         } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
    1665             $_params = array('type' => $params['resource_type']);
    1666             require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php');
    1667             smarty_core_load_resource_plugin($_params, $this);
    1668         }
    1669 
    1670         return true;
    1671     }
    1672 
    1673 
    1674     /**
    1675      * Handle modifiers
    1676      *
    1677      * @param string|null $modifier_name
    1678      * @param array|null $map_array
    1679      * @return string result of modifiers
    1680      */
    1681     function _run_mod_handler()
    1682     {
    1683         $_args = func_get_args();
    1684         list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
    1685         list($_func_name, $_tpl_file, $_tpl_line) =
    1686             $this->_plugins['modifier'][$_modifier_name];
    1687 
    1688         $_var = $_args[0];
    1689         foreach ($_var as $_key => $_val) {
    1690             $_args[0] = $_val;
    1691             $_var[$_key] = call_user_func_array($_func_name, $_args);
    1692         }
    1693         return $_var;
    1694     }
    1695 
    1696     /**
    1697      * Remove starting and ending quotes from the string
    1698      *
    1699      * @param string $string
    1700      * @return string
    1701      */
    1702     function _dequote($string)
    1703     {
    1704         if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
    1705             substr($string, -1) == substr($string, 0, 1))
    1706             return substr($string, 1, -1);
    1707         else
    1708             return $string;
    1709     }
    1710 
    1711 
    1712     /**
    1713      * read in a file
    1714      *
    1715      * @param string $filename
    1716      * @return string
    1717      */
    1718     function _read_file($filename)
    1719     {
    1720         if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) {
    1721             $contents = '';
    1722             while (!feof($fd)) {
    1723                 $contents .= fread($fd, 8192);
    1724             }
    1725             fclose($fd);
    1726             return $contents;
    1727         } else {
    1728             return false;
    1729         }
    1730     }
    1731 
    1732     /**
    1733      * get a concrete filename for automagically created content
    1734      *
    1735      * @param string $auto_base
    1736      * @param string $auto_source
    1737      * @param string $auto_id
    1738      * @return string
    1739      * @staticvar string|null
    1740      * @staticvar string|null
    1741      */
    1742     function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
    1743     {
    1744         $_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
    1745         $_return = $auto_base . DIRECTORY_SEPARATOR;
    1746 
    1747         if(isset($auto_id)) {
    1748             // make auto_id safe for directory names
    1749             $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
    1750             // split into separate directories
    1751             $_return .= $auto_id . $_compile_dir_sep;
    1752         }
    1753 
    1754         if(isset($auto_source)) {
    1755             // make source name safe for filename
    1756             $_filename = urlencode(basename($auto_source));
    1757             $_crc32 = sprintf('%08X', crc32($auto_source));
    1758             // prepend %% to avoid name conflicts with
    1759             // with $params['auto_id'] names
    1760             $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
    1761                       substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
    1762             $_return .= '%%' . $_crc32 . '%%' . $_filename;
    1763         }
    1764 
    1765         return $_return;
    1766     }
    1767 
    1768     /**
    1769      * unlink a file, possibly using expiration time
    1770      *
    1771      * @param string $resource
    1772      * @param integer $exp_time
    1773      */
    1774     function _unlink($resource, $exp_time = null)
    1775     {
    1776         if(isset($exp_time)) {
    1777             if(time() - @filemtime($resource) >= $exp_time) {
    1778                 return @unlink($resource);
    1779             }
    1780         } else {
    1781             return @unlink($resource);
    1782         }
    1783     }
    1784 
    1785     /**
    1786      * returns an auto_id for auto-file-functions
    1787      *
    1788      * @param string $cache_id
    1789      * @param string $compile_id
    1790      * @return string|null
    1791      */
    1792     function _get_auto_id($cache_id=null, $compile_id=null) {
    1793     if (isset($cache_id))
    1794         return (isset($compile_id)) ? $cache_id . '|' . $compile_id  : $cache_id;
    1795     elseif(isset($compile_id))
    1796         return $compile_id;
    1797     else
    1798         return null;
    1799     }
    1800 
    1801     /**
    1802      * trigger Smarty plugin error
    1803      *
    1804      * @param string $error_msg
    1805      * @param string $tpl_file
    1806      * @param integer $tpl_line
    1807      * @param string $file
    1808      * @param integer $line
    1809      * @param integer $error_type
    1810      */
    1811     function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
    1812             $file = null, $line = null, $error_type = E_USER_ERROR)
    1813     {
    1814         if(isset($file) && isset($line)) {
    1815             $info = ' ('.basename($file).", line $line)";
    1816         } else {
    1817             $info = '';
    1818         }
    1819         if (isset($tpl_line) && isset($tpl_file)) {
    1820             $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
    1821         } else {
    1822             $this->trigger_error($error_msg . $info, $error_type);
    1823         }
    1824     }
    1825 
    1826 
    1827     /**
    1828      * callback function for preg_replace, to call a non-cacheable block
    1829      * @return string
    1830      */
    1831     function _process_compiled_include_callback($match) {
    1832         $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
    1833         ob_start();
    1834         $_func($this);
    1835         $_ret = ob_get_contents();
    1836         ob_end_clean();
    1837         return $_ret;
    1838     }
    1839 
    1840 
    1841     /**
    1842      * called for included templates
    1843      *
    1844      * @param string $_smarty_include_tpl_file
    1845      * @param string $_smarty_include_vars
    1846      */
    1847 
    1848     // $_smarty_include_tpl_file, $_smarty_include_vars
    1849 
    1850     function _smarty_include($params)
    1851     {
    1852         if ($this->debugging) {
    1853             $_params = array();
    1854             require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
    1855             $debug_start_time = smarty_core_get_microtime($_params, $this);
    1856             $this->_smarty_debug_info[] = array('type'      => 'template',
    1857                                                   'filename'  => $params['smarty_include_tpl_file'],
    1858                                                   'depth'     => ++$this->_inclusion_depth);
    1859             $included_tpls_idx = count($this->_smarty_debug_info) - 1;
    1860         }
    1861 
    1862         $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
    1863 
    1864         // config vars are treated as local, so push a copy of the
    1865         // current ones onto the front of the stack
    1866         array_unshift($this->_config, $this->_config[0]);
    1867 
    1868         $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
    1869 
    1870 
    1871         if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
    1872             || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
    1873         {
    1874             include($_smarty_compile_path);
    1875         }
    1876 
    1877         // pop the local vars off the front of the stack
    1878         array_shift($this->_config);
    1879 
    1880         $this->_inclusion_depth--;
    1881 
    1882         if ($this->debugging) {
    1883             // capture time for debugging info
    1884             $_params = array();
    1885             require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
    1886             $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
    1887         }
    1888 
    1889         if ($this->caching) {
    1890             $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
    1891         }
    1892     }
    1893 
    1894 
    1895     /**
    1896      * get or set an array of cached attributes for function that is
    1897      * not cacheable
    1898      * @return array
    1899      */
    1900     function &_smarty_cache_attrs($cache_serial, $count) {
    1901         $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
    1902 
    1903         if ($this->_cache_including) {
    1904             /* return next set of cache_attrs */
    1905             $_return = current($_cache_attrs);
    1906             next($_cache_attrs);
    1907             return $_return;
    1908 
    1909         } else {
    1910             /* add a reference to a new set of cache_attrs */
    1911             $_cache_attrs[] = array();
    1912             return $_cache_attrs[count($_cache_attrs)-1];
    1913 
    1914         }
    1915 
    1916     }
    1917 
    1918 
    1919     /**
    1920      * wrapper for include() retaining $this
    1921      * @return mixed
    1922      */
    1923     function _include($filename, $once=false, $params=null)
    1924     {
    1925         if ($once) {
    1926             return include_once($filename);
    1927         } else {
    1928             return include($filename);
    1929         }
    1930     }
    1931 
    1932 
    1933     /**
    1934      * wrapper for eval() retaining $this
    1935      * @return mixed
    1936      */
    1937     function _eval($code, $params=null)
    1938     {
    1939         return eval($code);
    1940     }
    1941 
    1942     /**
    1943      * Extracts the filter name from the given callback
    1944      *
    1945      * @param callback $function
    1946      * @return string
    1947      */
    1948         function _get_filter_name($function)
    1949         {
    1950                 if (is_array($function)) {
    1951                         $_class_name = (is_object($function[0]) ?
    1952                                 get_class($function[0]) : $function[0]);
    1953                         return $_class_name . '_' . $function[1];
    1954                 }
    1955                 else {
    1956                         return $function;
    1957                 }
    1958         }
    1959 
    1960     /**#@-*/
    1961 
     1433    }
     1434
     1435    /**
     1436     * Enable error handler to mute expected messages
     1437     *
     1438     * @return void
     1439     */
     1440    public static function muteExpectedErrors()
     1441    {
     1442        /*
     1443            error muting is done because some people implemented custom error_handlers using
     1444            http://php.net/set_error_handler and for some reason did not understand the following paragraph:
     1445
     1446                It is important to remember that the standard PHP error handler is completely bypassed for the
     1447                error types specified by error_types unless the callback function returns FALSE.
     1448                error_reporting() settings will have no effect and your error handler will be called regardless -
     1449                however you are still able to read the current value of error_reporting and act appropriately.
     1450                Of particular note is that this value will be 0 if the statement that caused the error was
     1451                prepended by the @ error-control operator.
     1452
     1453            Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include
     1454                - @filemtime() is almost twice as fast as using an additional file_exists()
     1455                - between file_exists() and filemtime() a possible race condition is opened,
     1456                  which does not exist using the simple @filemtime() approach.
     1457        */
     1458        $error_handler = array('Smarty', 'mutingErrorHandler');
     1459        $previous = set_error_handler($error_handler);
     1460
     1461        // avoid dead loops
     1462        if ($previous !== $error_handler) {
     1463            Smarty::$_previous_error_handler = $previous;
     1464        }
     1465    }
     1466
     1467    /**
     1468     * Disable error handler muting expected messages
     1469     *
     1470     * @return void
     1471     */
     1472    public static function unmuteExpectedErrors()
     1473    {
     1474        restore_error_handler();
     1475    }
    19621476}
    19631477
    1964 /* vim: set expandtab: */
     1478// Check if we're running on windows
     1479Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
     1480
     1481// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
     1482if (Smarty::$_CHARSET !== 'UTF-8') {
     1483    Smarty::$_UTF8_MODIFIER = '';
     1484}
     1485
     1486/**
     1487 * Smarty exception class
     1488 * @package Smarty
     1489 */
     1490class SmartyException extends Exception {
     1491    public static $escape = true;
     1492    public function __construct($message) {
     1493        $this->message = self::$escape ? htmlentities($message) : $message;
     1494    }
     1495}
     1496
     1497/**
     1498 * Smarty compiler exception class
     1499 * @package Smarty
     1500 */
     1501class SmartyCompilerException extends SmartyException  {
     1502}
     1503
     1504/**
     1505 * Autoloader
     1506 */
     1507function smartyAutoload($class)
     1508{
     1509    $_class = strtolower($class);
     1510    $_classes = array(
     1511        'smarty_config_source' => true,
     1512        'smarty_config_compiled' => true,
     1513        'smarty_security' => true,
     1514        'smarty_cacheresource' => true,
     1515        'smarty_cacheresource_custom' => true,
     1516        'smarty_cacheresource_keyvaluestore' => true,
     1517        'smarty_resource' => true,
     1518        'smarty_resource_custom' => true,
     1519        'smarty_resource_uncompiled' => true,
     1520        'smarty_resource_recompiled' => true,
     1521    );
     1522
     1523    if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
     1524        include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
     1525    }
     1526}
    19651527
    19661528?>
  • trunk/include/smarty/libs/debug.tpl

    r3282 r23384  
    1 {* Smarty *}
    2 {* debug.tpl, last updated version 2.1.0 *}
    3 {assign_debug_info}
    4 {capture assign=debug_output}
     1{capture name='_smarty_debug' assign=debug_output}
    52<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    63<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    74<head>
    85    <title>Smarty Debug Console</title>
     6<style type="text/css">
    97{literal}
    10 <style type="text/css">
    11 /* <![CDATA[ */
    128body, h1, h2, td, th, p {
    139    font-family: sans-serif;
     
    8682    color: maroon;
    8783}
    88 /* ]]> */
     84{/literal}
    8985</style>
    90 {/literal}
    9186</head>
    9287<body>
    9388
    94 <h1>Smarty Debug Console</h1>
     89<h1>Smarty Debug Console  -  {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1>
    9590
     91{if !empty($template_data)}
    9692<h2>included templates &amp; config files (load time in seconds)</h2>
    9793
    9894<div>
    99 {section name=templates loop=$_debug_tpls}
    100     {section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
    101     <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
    102         {$_debug_tpls[templates].filename|escape:html}</font>
    103     {if isset($_debug_tpls[templates].exec_time)}
    104         <span class="exectime">
    105         ({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
    106         {if %templates.index% eq 0}(total){/if}
    107         </span>
    108     {/if}
    109     <br />
    110 {sectionelse}
    111     <p>no templates included</p>
    112 {/section}
     95{foreach $template_data as $template}
     96  <font color=brown>{$template.name}</font>
     97  <span class="exectime">
     98   (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"})
     99  </span>
     100  <br>
     101{/foreach}
    113102</div>
     103{/if}
    114104
    115105<h2>assigned template variables</h2>
    116106
    117107<table id="table_assigned_vars">
    118     {section name=vars loop=$_debug_keys}
    119         <tr class="{cycle values="odd,even"}">
    120             <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
    121             <td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
    122     {sectionelse}
    123         <tr><td><p>no template variables assigned</p></td></tr>
    124     {/section}
     108    {foreach $assigned_vars as $vars}
     109       <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">   
     110       <th>${$vars@key|escape:'html'}</th>
     111       <td>{$vars|debug_print_var nofilter}</td></tr>
     112    {/foreach}
    125113</table>
    126114
     
    128116
    129117<table id="table_config_vars">
    130     {section name=config_vars loop=$_debug_config_keys}
    131         <tr class="{cycle values="odd,even"}">
    132             <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
    133             <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
    134     {sectionelse}
    135         <tr><td><p>no config vars assigned</p></td></tr>
    136     {/section}
     118    {foreach $config_vars as $vars}
     119       <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}">   
     120       <th>{$vars@key|escape:'html'}</th>
     121       <td>{$vars|debug_print_var nofilter}</td></tr>
     122    {/foreach}
     123
    137124</table>
    138125</body>
    139126</html>
    140127{/capture}
    141 {if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
    142     {$debug_output}
    143 {else}
    144128<script type="text/javascript">
    145 // <![CDATA[
    146     if ( self.name == '' ) {ldelim}
    147        var title = 'Console';
    148     {rdelim}
    149     else {ldelim}
    150        var title = 'Console_' + self.name;
    151     {rdelim}
    152     _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
    153     _smarty_console.document.write('{$debug_output|escape:'javascript'}');
     129{$id = $template_name|default:''|md5}
     130    _smarty_console = window.open("","console{$id}","width=680,height=600,resizable,scrollbars=yes");
     131    _smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}");
    154132    _smarty_console.document.close();
    155 // ]]>
    156133</script>
    157 {/if}
  • trunk/include/smarty/libs/plugins/block.textformat.php

    r3282 r23384  
    11<?php
    22/**
    3  * Smarty plugin
     3 * Smarty plugin to format text blocks
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsBlock
    67 */
    78
     
    1314 * Purpose:  format text a certain way with preset styles
    1415 *           or custom wrap/indent settings<br>
    15  * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
     16 * Params:
     17 * <pre>
     18 * - style         - string (email)
     19 * - indent        - integer (0)
     20 * - wrap          - integer (80)
     21 * - wrap_char     - string ("\n")
     22 * - indent_char   - string (" ")
     23 * - wrap_boundary - boolean (true)
     24 * </pre>
     25 *
     26 * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat}
    1627 *       (Smarty online manual)
    17  * @param array
    18  * <pre>
    19  * Params:   style: string (email)
    20  *           indent: integer (0)
    21  *           wrap: integer (80)
    22  *           wrap_char string ("\n")
    23  *           indent_char: string (" ")
    24  *           wrap_boundary: boolean (true)
    25  * </pre>
     28 * @param array                    $params   parameters
     29 * @param string                   $content  contents of the block
     30 * @param Smarty_Internal_Template $template template object
     31 * @param boolean                  &$repeat  repeat flag
     32 * @return string content re-formatted
    2633 * @author Monte Ohrt <monte at ohrt dot com>
    27  * @param string contents of the block
    28  * @param Smarty clever simulation of a method
    29  * @return string string $content re-formatted
    3034 */
    31 function smarty_block_textformat($params, $content, &$smarty)
     35function smarty_block_textformat($params, $content, $template, &$repeat)
    3236{
    3337    if (is_null($content)) {
     
    4347    $wrap_cut = false;
    4448    $assign = null;
    45    
     49
    4650    foreach ($params as $_key => $_val) {
    4751        switch ($_key) {
     
    6468
    6569            default:
    66                 $smarty->trigger_error("textformat: unknown attribute '$_key'");
     70                trigger_error("textformat: unknown attribute '$_key'");
    6771        }
    6872    }
     
    7175        $wrap = 72;
    7276    }
    73 
    7477    // split into paragraphs
    75     $_paragraphs = preg_split('![\r\n][\r\n]!',$content);
     78    $_paragraphs = preg_split('![\r\n]{2}!', $content);
    7679    $_output = '';
    7780
    78     for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) {
    79         if ($_paragraphs[$_x] == '') {
     81
     82    foreach ($_paragraphs as &$_paragraph) {
     83        if (!$_paragraph) {
    8084            continue;
    8185        }
    8286        // convert mult. spaces & special chars to single space
    83         $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]);
     87        $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph);
    8488        // indent first line
    85         if($indent_first > 0) {
    86             $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x];
     89        if ($indent_first > 0) {
     90            $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph;
    8791        }
    8892        // wordwrap sentences
    89         $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut);
     93        if (Smarty::$_MBSTRING) {
     94            require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php');
     95            $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
     96        } else {
     97            $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
     98        }
    9099        // indent lines
    91         if($indent > 0) {
    92             $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]);
     100        if ($indent > 0) {
     101            $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph);
    93102        }
    94103    }
    95104    $_output = implode($wrap_char . $wrap_char, $_paragraphs);
    96 
    97     return $assign ? $smarty->assign($assign, $_output) : $_output;
    98 
     105   
     106    if ($assign) {
     107        $template->assign($assign, $_output);
     108    } else {
     109        return $_output;
     110    }
    99111}
    100112
    101 /* vim: set expandtab: */
    102 
    103113?>
  • trunk/include/smarty/libs/plugins/function.counter.php

    r3282 r23384  
    33 * Smarty plugin
    44 * @package Smarty
    5  * @subpackage plugins
     5 * @subpackage PluginsFunction
    66 */
    7 
    87
    98/**
     
    1312 * Name:     counter<br>
    1413 * Purpose:  print out a counter value
     14 *
    1515 * @author Monte Ohrt <monte at ohrt dot com>
    16  * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
     16 * @link http://www.smarty.net/manual/en/language.function.counter.php {counter}
    1717 *       (Smarty online manual)
    18  * @param array parameters
    19  * @param Smarty
     18 * @param array                    $params   parameters
     19 * @param Smarty_Internal_Template $template template object
    2020 * @return string|null
    2121 */
    22 function smarty_function_counter($params, &$smarty)
     22function smarty_function_counter($params, $template)
    2323{
    2424    static $counters = array();
     
    4444
    4545    if (isset($counter['assign'])) {
    46         $smarty->assign($counter['assign'], $counter['count']);
     46        $template->assign($counter['assign'], $counter['count']);
    4747    }
    4848   
     
    7676}
    7777
    78 /* vim: set expandtab: */
    79 
    8078?>
  • trunk/include/smarty/libs/plugins/function.cycle.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    78
     
    1314 * Date:     May 3, 2002<br>
    1415 * Purpose:  cycle through given values<br>
    15  * Input:
    16  *         - name = name of cycle (optional)
    17  *         - values = comma separated list of values to cycle,
    18  *                    or an array of values to cycle
    19  *                    (this can be left out for subsequent calls)
    20  *         - reset = boolean - resets given var to true
    21  *         - print = boolean - print var or not. default is true
    22  *         - advance = boolean - whether or not to advance the cycle
    23  *         - delimiter = the value delimiter, default is ","
    24  *         - assign = boolean, assigns to template var instead of
    25  *                    printed.
    26  *
     16 * Params:
     17 * <pre>
     18 * - name      - name of cycle (optional)
     19 * - values    - comma separated list of values to cycle, or an array of values to cycle
     20 *               (this can be left out for subsequent calls)
     21 * - reset     - boolean - resets given var to true
     22 * - print     - boolean - print var or not. default is true
     23 * - advance   - boolean - whether or not to advance the cycle
     24 * - delimiter - the value delimiter, default is ","
     25 * - assign    - boolean, assigns to template var instead of printed.
     26 * </pre>
    2727 * Examples:<br>
    2828 * <pre>
     
    3131 * {cycle name=row}
    3232 * </pre>
    33  * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
     33 *
     34 * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle}
    3435 *       (Smarty online manual)
    3536 * @author Monte Ohrt <monte at ohrt dot com>
     
    3839 * @author credit to Jason Sweat <jsweat_php@yahoo.com>
    3940 * @version  1.3
    40  * @param array
    41  * @param Smarty
     41 * @param array                    $params   parameters
     42 * @param Smarty_Internal_Template $template template object
    4243 * @return string|null
    4344 */
    44 function smarty_function_cycle($params, &$smarty)
     45
     46function smarty_function_cycle($params, $template)
    4547{
    4648    static $cycle_vars;
    47    
     49
    4850    $name = (empty($params['name'])) ? 'default' : $params['name'];
    4951    $print = (isset($params['print'])) ? (bool)$params['print'] : true;
    5052    $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
    5153    $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
    52            
    53     if (!in_array('values', array_keys($params))) {
     54
     55    if (!isset($params['values'])) {
    5456        if(!isset($cycle_vars[$name]['values'])) {
    55             $smarty->trigger_error("cycle: missing 'values' parameter");
     57            trigger_error("cycle: missing 'values' parameter");
    5658            return;
    5759        }
     
    6466    }
    6567
    66     $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
    67    
     68    if (isset($params['delimiter'])) {
     69        $cycle_vars[$name]['delimiter'] = $params['delimiter'];
     70    } elseif (!isset($cycle_vars[$name]['delimiter'])) {
     71        $cycle_vars[$name]['delimiter'] = ',';
     72    }
     73
    6874    if(is_array($cycle_vars[$name]['values'])) {
    6975        $cycle_array = $cycle_vars[$name]['values'];
     
    7177        $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
    7278    }
    73    
     79
    7480    if(!isset($cycle_vars[$name]['index']) || $reset ) {
    7581        $cycle_vars[$name]['index'] = 0;
    7682    }
    77    
     83
    7884    if (isset($params['assign'])) {
    7985        $print = false;
    80         $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
     86        $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
    8187    }
    82        
     88
    8389    if($print) {
    8490        $retval = $cycle_array[$cycle_vars[$name]['index']];
     
    94100        }
    95101    }
    96    
     102
    97103    return $retval;
    98104}
    99105
    100 /* vim: set expandtab: */
    101 
    102106?>
  • trunk/include/smarty/libs/plugins/function.fetch.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
     
    1313 * Name:     fetch<br>
    1414 * Purpose:  fetch file, web or ftp data and display results
    15  * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
     15 *
     16 * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch}
    1617 *       (Smarty online manual)
    1718 * @author Monte Ohrt <monte at ohrt dot com>
    18  * @param array
    19  * @param Smarty
    20  * @return string|null if the assign parameter is passed, Smarty assigns the
    21  *                     result to a template variable
     19 * @param array                    $params   parameters
     20 * @param Smarty_Internal_Template $template template object
     21 * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable
    2222 */
    23 function smarty_function_fetch($params, &$smarty)
     23function smarty_function_fetch($params, $template)
    2424{
    2525    if (empty($params['file'])) {
    26         $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
     26        trigger_error("[plugin] fetch parameter 'file' cannot be empty",E_USER_NOTICE);
    2727        return;
    2828    }
     29   
     30    // strip file protocol
     31    if (stripos($params['file'], 'file://') === 0) {
     32        $params['file'] = substr($params['file'], 7);
     33    }
     34   
     35    $protocol = strpos($params['file'], '://');
     36    if ($protocol !== false) {
     37        $protocol = strtolower(substr($params['file'], 0, $protocol));
     38    }
     39   
     40    if (isset($template->smarty->security_policy)) {
     41        if ($protocol) {
     42            // remote resource (or php stream, …)
     43            if(!$template->smarty->security_policy->isTrustedUri($params['file'])) {
     44                return;
     45            }
     46        } else {
     47            // local file
     48            if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
     49                return;
     50            }
     51        }
     52    }
    2953
    3054    $content = '';
    31     if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
    32         $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
    33         require_once(SMARTY_CORE_DIR . 'core.is_secure.php');
    34         if(!smarty_core_is_secure($_params, $smarty)) {
    35             $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
    36             return;
    37         }
    38        
    39         // fetch the file
    40         if($fp = @fopen($params['file'],'r')) {
    41             while(!feof($fp)) {
    42                 $content .= fgets ($fp,4096);
    43             }
    44             fclose($fp);
     55    if ($protocol == 'http') {
     56        // http fetch
     57        if($uri_parts = parse_url($params['file'])) {
     58            // set defaults
     59            $host = $server_name = $uri_parts['host'];
     60            $timeout = 30;
     61            $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
     62            $agent = "Smarty Template Engine ". Smarty::SMARTY_VERSION;
     63            $referer = "";
     64            $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
     65            $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
     66            $_is_proxy = false;
     67            if(empty($uri_parts['port'])) {
     68                $port = 80;
     69            } else {
     70                $port = $uri_parts['port'];
     71            }
     72            if(!empty($uri_parts['user'])) {
     73                $user = $uri_parts['user'];
     74            }
     75            if(!empty($uri_parts['pass'])) {
     76                $pass = $uri_parts['pass'];
     77            }
     78            // loop through parameters, setup headers
     79            foreach($params as $param_key => $param_value) {
     80                switch($param_key) {
     81                    case "file":
     82                    case "assign":
     83                    case "assign_headers":
     84                        break;
     85                    case "user":
     86                        if(!empty($param_value)) {
     87                            $user = $param_value;
     88                        }
     89                        break;
     90                    case "pass":
     91                        if(!empty($param_value)) {
     92                            $pass = $param_value;
     93                        }
     94                        break;
     95                    case "accept":
     96                        if(!empty($param_value)) {
     97                            $accept = $param_value;
     98                        }
     99                        break;
     100                    case "header":
     101                        if(!empty($param_value)) {
     102                            if(!preg_match('![\w\d-]+: .+!',$param_value)) {
     103                                trigger_error("[plugin] invalid header format '".$param_value."'",E_USER_NOTICE);
     104                                return;
     105                            } else {
     106                                $extra_headers[] = $param_value;
     107                            }
     108                        }
     109                        break;
     110                    case "proxy_host":
     111                        if(!empty($param_value)) {
     112                            $proxy_host = $param_value;
     113                        }
     114                        break;
     115                    case "proxy_port":
     116                        if(!preg_match('!\D!', $param_value)) {
     117                            $proxy_port = (int) $param_value;
     118                        } else {
     119                            trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE);
     120                            return;
     121                        }
     122                        break;
     123                    case "agent":
     124                        if(!empty($param_value)) {
     125                            $agent = $param_value;
     126                        }
     127                        break;
     128                    case "referer":
     129                        if(!empty($param_value)) {
     130                            $referer = $param_value;
     131                        }
     132                        break;
     133                    case "timeout":
     134                        if(!preg_match('!\D!', $param_value)) {
     135                            $timeout = (int) $param_value;
     136                        } else {
     137                            trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE);
     138                            return;
     139                        }
     140                        break;
     141                    default:
     142                        trigger_error("[plugin] unrecognized attribute '".$param_key."'",E_USER_NOTICE);
     143                        return;
     144                }
     145            }
     146            if(!empty($proxy_host) && !empty($proxy_port)) {
     147                $_is_proxy = true;
     148                $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
     149            } else {
     150                $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
     151            }
     152
     153            if(!$fp) {
     154                trigger_error("[plugin] unable to fetch: $errstr ($errno)",E_USER_NOTICE);
     155                return;
     156            } else {
     157                if($_is_proxy) {
     158                    fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
     159                } else {
     160                    fputs($fp, "GET $uri HTTP/1.0\r\n");
     161                }
     162                if(!empty($host)) {
     163                    fputs($fp, "Host: $host\r\n");
     164                }
     165                if(!empty($accept)) {
     166                    fputs($fp, "Accept: $accept\r\n");
     167                }
     168                if(!empty($agent)) {
     169                    fputs($fp, "User-Agent: $agent\r\n");
     170                }
     171                if(!empty($referer)) {
     172                    fputs($fp, "Referer: $referer\r\n");
     173                }
     174                if(isset($extra_headers) && is_array($extra_headers)) {
     175                    foreach($extra_headers as $curr_header) {
     176                        fputs($fp, $curr_header."\r\n");
     177                    }
     178                }
     179                if(!empty($user) && !empty($pass)) {
     180                    fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
     181                }
     182
     183                fputs($fp, "\r\n");
     184                while(!feof($fp)) {
     185                    $content .= fgets($fp,4096);
     186                }
     187                fclose($fp);
     188                $csplit = preg_split("!\r\n\r\n!",$content,2);
     189
     190                $content = $csplit[1];
     191
     192                if(!empty($params['assign_headers'])) {
     193                    $template->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0]));
     194                }
     195            }
    45196        } else {
    46             $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
     197            trigger_error("[plugin fetch] unable to parse URL, check syntax",E_USER_NOTICE);
    47198            return;
    48199        }
    49200    } else {
    50         // not a local file
    51         if(preg_match('!^http://!i',$params['file'])) {
    52             // http fetch
    53             if($uri_parts = parse_url($params['file'])) {
    54                 // set defaults
    55                 $host = $server_name = $uri_parts['host'];
    56                 $timeout = 30;
    57                 $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
    58                 $agent = "Smarty Template Engine ".$smarty->_version;
    59                 $referer = "";
    60                 $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
    61                 $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
    62                 $_is_proxy = false;
    63                 if(empty($uri_parts['port'])) {
    64                     $port = 80;
    65                 } else {
    66                     $port = $uri_parts['port'];
    67                 }
    68                 if(!empty($uri_parts['user'])) {
    69                     $user = $uri_parts['user'];
    70                 }
    71                 if(!empty($uri_parts['pass'])) {
    72                     $pass = $uri_parts['pass'];
    73                 }
    74                 // loop through parameters, setup headers
    75                 foreach($params as $param_key => $param_value) {
    76                     switch($param_key) {
    77                         case "file":
    78                         case "assign":
    79                         case "assign_headers":
    80                             break;
    81                         case "user":
    82                             if(!empty($param_value)) {
    83                                 $user = $param_value;
    84                             }
    85                             break;
    86                         case "pass":
    87                             if(!empty($param_value)) {
    88                                 $pass = $param_value;
    89                             }
    90                             break;
    91                         case "accept":
    92                             if(!empty($param_value)) {
    93                                 $accept = $param_value;
    94                             }
    95                             break;
    96                         case "header":
    97                             if(!empty($param_value)) {
    98                                 if(!preg_match('![\w\d-]+: .+!',$param_value)) {
    99                                     $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
    100                                     return;
    101                                 } else {
    102                                     $extra_headers[] = $param_value;
    103                                 }
    104                             }
    105                             break;
    106                         case "proxy_host":
    107                             if(!empty($param_value)) {
    108                                 $proxy_host = $param_value;
    109                             }
    110                             break;
    111                         case "proxy_port":
    112                             if(!preg_match('!\D!', $param_value)) {
    113                                 $proxy_port = (int) $param_value;
    114                             } else {
    115                                 $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
    116                                 return;
    117                             }
    118                             break;
    119                         case "agent":
    120                             if(!empty($param_value)) {
    121                                 $agent = $param_value;
    122                             }
    123                             break;
    124                         case "referer":
    125                             if(!empty($param_value)) {
    126                                 $referer = $param_value;
    127                             }
    128                             break;
    129                         case "timeout":
    130                             if(!preg_match('!\D!', $param_value)) {
    131                                 $timeout = (int) $param_value;
    132                             } else {
    133                                 $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
    134                                 return;
    135                             }
    136                             break;
    137                         default:
    138                             $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
    139                             return;
    140                     }
    141                 }
    142                 if(!empty($proxy_host) && !empty($proxy_port)) {
    143                     $_is_proxy = true;
    144                     $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
    145                 } else {
    146                     $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
    147                 }
    148 
    149                 if(!$fp) {
    150                     $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
    151                     return;
    152                 } else {
    153                     if($_is_proxy) {
    154                         fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
    155                     } else {
    156                         fputs($fp, "GET $uri HTTP/1.0\r\n");
    157                     }
    158                     if(!empty($host)) {
    159                         fputs($fp, "Host: $host\r\n");
    160                     }
    161                     if(!empty($accept)) {
    162                         fputs($fp, "Accept: $accept\r\n");
    163                     }
    164                     if(!empty($agent)) {
    165                         fputs($fp, "User-Agent: $agent\r\n");
    166                     }
    167                     if(!empty($referer)) {
    168                         fputs($fp, "Referer: $referer\r\n");
    169                     }
    170                     if(isset($extra_headers) && is_array($extra_headers)) {
    171                         foreach($extra_headers as $curr_header) {
    172                             fputs($fp, $curr_header."\r\n");
    173                         }
    174                     }
    175                     if(!empty($user) && !empty($pass)) {
    176                         fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
    177                     }
    178 
    179                     fputs($fp, "\r\n");
    180                     while(!feof($fp)) {
    181                         $content .= fgets($fp,4096);
    182                     }
    183                     fclose($fp);
    184                     $csplit = split("\r\n\r\n",$content,2);
    185 
    186                     $content = $csplit[1];
    187 
    188                     if(!empty($params['assign_headers'])) {
    189                         $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
    190                     }
    191                 }
    192             } else {
    193                 $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
    194                 return;
    195             }
    196         } else {
    197             // ftp fetch
    198             if($fp = @fopen($params['file'],'r')) {
    199                 while(!feof($fp)) {
    200                     $content .= fgets ($fp,4096);
    201                 }
    202                 fclose($fp);
    203             } else {
    204                 $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
    205                 return;
    206             }
     201        $content = @file_get_contents($params['file']);
     202        if ($content === false) {
     203            throw new SmartyException("{fetch} cannot read resource '" . $params['file'] ."'");
    207204        }
    208 
    209     }
    210 
     205    }
    211206
    212207    if (!empty($params['assign'])) {
    213         $smarty->assign($params['assign'],$content);
     208        $template->assign($params['assign'], $content);
    214209    } else {
    215210        return $content;
     
    217212}
    218213
    219 /* vim: set expandtab: */
    220 
    221214?>
  • trunk/include/smarty/libs/plugins/function.html_checkboxes.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
     
    1515 * Date:       24.Feb.2003<br>
    1616 * Purpose:    Prints out a list of checkbox input types<br>
    17  * Input:<br>
    18  *           - name       (optional) - string default "checkbox"
    19  *           - values     (required) - array
    20  *           - options    (optional) - associative array
    21  *           - checked    (optional) - array default not set
    22  *           - separator  (optional) - ie <br> or &nbsp;
    23  *           - output     (optional) - the output next to each checkbox
    24  *           - assign     (optional) - assign the output as an array to this variable
    2517 * Examples:
    2618 * <pre>
     
    2921 * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
    3022 * </pre>
    31  * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
     23 * Params:
     24 * <pre>
     25 * - name       (optional) - string default "checkbox"
     26 * - values     (required) - array
     27 * - options    (optional) - associative array
     28 * - checked    (optional) - array default not set
     29 * - separator  (optional) - ie <br> or &nbsp;
     30 * - output     (optional) - the output next to each checkbox
     31 * - assign     (optional) - assign the output as an array to this variable
     32 * - escape     (optional) - escape the content (not value), defaults to true
     33 * </pre>
     34 *
     35 * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
    3236 *      (Smarty online manual)
    3337 * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
    3438 * @author credits to Monte Ohrt <monte at ohrt dot com>
    3539 * @version    1.0
    36  * @param array
    37  * @param Smarty
     40 * @param array $params parameters
     41 * @param object $template template object
    3842 * @return string
    3943 * @uses smarty_function_escape_special_chars()
    4044 */
    41 function smarty_function_html_checkboxes($params, &$smarty)
     45function smarty_function_html_checkboxes($params, $template)
    4246{
    43     require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
     47    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
    4448
    4549    $name = 'checkbox';
    4650    $values = null;
    4751    $options = null;
    48     $selected = null;
     52    $selected = array();
    4953    $separator = '';
     54    $escape = true;
    5055    $labels = true;
     56    $label_ids = false;
    5157    $output = null;
    5258
     
    5763            case 'name':
    5864            case 'separator':
    59                 $$_key = $_val;
    60                 break;
    61 
     65                $$_key = (string) $_val;
     66                break;
     67
     68            case 'escape':
    6269            case 'labels':
    63                 $$_key = (bool)$_val;
     70            case 'label_ids':
     71                $$_key = (bool) $_val;
    6472                break;
    6573
    6674            case 'options':
    67                 $$_key = (array)$_val;
     75                $$_key = (array) $_val;
    6876                break;
    6977
    7078            case 'values':
    7179            case 'output':
    72                 $$_key = array_values((array)$_val);
     80                $$_key = array_values((array) $_val);
    7381                break;
    7482
    7583            case 'checked':
    7684            case 'selected':
    77                 $selected = array_map('strval', array_values((array)$_val));
     85                if (is_array($_val)) {
     86                    $selected = array();
     87                    foreach ($_val as $_sel) {
     88                        if (is_object($_sel)) {
     89                            if (method_exists($_sel, "__toString")) {
     90                                $_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
     91                            } else {
     92                                trigger_error("html_checkboxes: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE);
     93                                continue;
     94                            }
     95                        } else {
     96                            $_sel = smarty_function_escape_special_chars((string) $_sel);
     97                        }
     98                        $selected[$_sel] = true;
     99                    }
     100                } elseif (is_object($_val)) {
     101                    if (method_exists($_val, "__toString")) {
     102                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
     103                    } else {
     104                        trigger_error("html_checkboxes: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
     105                    }
     106                } else {
     107                    $selected = smarty_function_escape_special_chars((string) $_val);
     108                }
    78109                break;
    79110
    80111            case 'checkboxes':
    81                 $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
    82                 $options = (array)$_val;
     112                trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
     113                $options = (array) $_val;
    83114                break;
    84115
    85116            case 'assign':
    86117                break;
     118
     119            case 'strict': break;
     120
     121            case 'disabled':
     122            case 'readonly':
     123                if (!empty($params['strict'])) {
     124                    if (!is_scalar($_val)) {
     125                        trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
     126                    }
     127
     128                    if ($_val === true || $_val === $_key) {
     129                        $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
     130                    }
     131
     132                    break;
     133                }
     134                // omit break; to fall through!
    87135
    88136            default:
     
    90138                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
    91139                } else {
    92                     $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     140                    trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
    93141                }
    94142                break;
     
    99147        return ''; /* raise error here? */
    100148
    101     settype($selected, 'array');
    102149    $_html_result = array();
    103150
    104151    if (isset($options)) {
    105 
    106         foreach ($options as $_key=>$_val)
    107             $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
    108 
    109 
     152        foreach ($options as $_key=>$_val) {
     153            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
     154        }
    110155    } else {
    111156        foreach ($values as $_i=>$_key) {
    112157            $_val = isset($output[$_i]) ? $output[$_i] : '';
    113             $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
    114         }
    115 
     158            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
     159        }
    116160    }
    117161
    118162    if(!empty($params['assign'])) {
    119         $smarty->assign($params['assign'], $_html_result);
    120     } else {
    121         return implode("\n",$_html_result);
     163        $template->assign($params['assign'], $_html_result);
     164    } else {
     165        return implode("\n", $_html_result);
    122166    }
    123167
    124168}
    125169
    126 function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
     170function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape=true) {
    127171    $_output = '';
    128     if ($labels) $_output .= '<label>';
    129     $_output .= '<input type="checkbox" name="'
    130         . smarty_function_escape_special_chars($name) . '[]" value="'
    131         . smarty_function_escape_special_chars($value) . '"';
    132 
    133     if (in_array((string)$value, $selected)) {
     172   
     173    if (is_object($value)) {
     174        if (method_exists($value, "__toString")) {
     175            $value = (string) $value->__toString();
     176        } else {
     177            trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
     178            return '';
     179        }
     180    } else {
     181        $value = (string) $value;
     182    }
     183   
     184    if (is_object($output)) {
     185        if (method_exists($output, "__toString")) {
     186            $output = (string) $output->__toString();
     187        } else {
     188            trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE);
     189            return '';
     190        }
     191    } else {
     192        $output = (string) $output;
     193    }
     194   
     195    if ($labels) {
     196        if ($label_ids) {
     197            $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
     198            $_output .= '<label for="' . $_id . '">';
     199        } else {
     200            $_output .= '<label>';
     201        }
     202    }
     203   
     204    $name = smarty_function_escape_special_chars($name);
     205    $value = smarty_function_escape_special_chars($value);
     206    if ($escape) {
     207        $output = smarty_function_escape_special_chars($output);
     208    }
     209   
     210    $_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"';
     211   
     212    if ($labels && $label_ids) {
     213        $_output .= ' id="' . $_id . '"';
     214    }
     215   
     216    if (is_array($selected)) {
     217        if (isset($selected[$value])) {
     218            $_output .= ' checked="checked"';
     219        }
     220    } elseif ($value === $selected) {
    134221        $_output .= ' checked="checked"';
    135222    }
    136     $_output .= $extra . '>' . $output;
    137     if ($labels) $_output .= '</label>';
     223   
     224    $_output .= $extra . ' />' . $output;
     225    if ($labels) {
     226        $_output .= '</label>';
     227    }
     228   
    138229    $_output .=  $separator;
    139 
    140230    return $_output;
    141231}
  • trunk/include/smarty/libs/plugins/function.html_image.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
    1010 * Smarty {html_image} function plugin
    11  *
     11 * 
    1212 * Type:     function<br>
    1313 * Name:     html_image<br>
    1414 * Date:     Feb 24, 2003<br>
    1515 * Purpose:  format HTML tags for the image<br>
    16  * Input:<br>
    17  *         - file = file (and path) of image (required)
    18  *         - height = image height (optional, default actual height)
    19  *         - width = image width (optional, default actual width)
    20  *         - basedir = base directory for absolute paths, default
    21  *                     is environment variable DOCUMENT_ROOT
    22  *         - path_prefix = prefix for path output (optional, default empty)
    23  *
    24  * Examples: {html_image file="/images/masthead.gif"}
    25  * Output:   <img src="/images/masthead.gif" width=400 height=23>
    26  * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
     16 * Examples: {html_image file="/images/masthead.gif"}<br>
     17 * Output:   <img src="/images/masthead.gif" width=400 height=23><br>
     18 * Params:
     19 * <pre>
     20 * - file        - (required) - file (and path) of image
     21 * - height      - (optional) - image height (default actual height)
     22 * - width       - (optional) - image width (default actual width)
     23 * - basedir     - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT
     24 * - path_prefix - prefix for path output (optional, default empty)
     25 * </pre>
     26 *
     27 * @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image}
    2728 *      (Smarty online manual)
    28  * @author   Monte Ohrt <monte at ohrt dot com>
    29  * @author credits to Duda <duda@big.hu> - wrote first image function
    30  *           in repository, helped with lots of functionality
    31  * @version  1.0
    32  * @param array
    33  * @param Smarty
    34  * @return string
     29 * @author Monte Ohrt <monte at ohrt dot com>
     30 * @author credits to Duda <duda@big.hu>
     31 * @version 1.0
     32 * @param array                    $params   parameters
     33 * @param Smarty_Internal_Template $template template object
     34 * @return string
    3535 * @uses smarty_function_escape_special_chars()
    3636 */
    37 function smarty_function_html_image($params, &$smarty)
     37function smarty_function_html_image($params, $template)
    3838{
    39     require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
    40     
     39    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
     40 
    4141    $alt = '';
    4242    $file = '';
     
    4747    $suffix = '';
    4848    $path_prefix = '';
    49     $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
    50     $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
     49    $basedir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : '';
    5150    foreach($params as $_key => $_val) {
    52         switch($_key) {
     51        switch ($_key) {
    5352            case 'file':
    5453            case 'height':
     
    6160
    6261            case 'alt':
    63                 if(!is_array($_val)) {
     62                if (!is_array($_val)) {
    6463                    $$_key = smarty_function_escape_special_chars($_val);
    6564                } else {
    66                     $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
    67                 }
     65                    throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     66                } 
    6867                break;
    6968
     
    7574
    7675            default:
    77                 if(!is_array($_val)) {
    78                     $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
     76                if (!is_array($_val)) {
     77                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
    7978                } else {
    80                     $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
    81                 }
     79                    throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     80                } 
    8281                break;
    83         }
    84     }
     82        } 
     83    } 
    8584
    8685    if (empty($file)) {
    87         $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
     86        trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
    8887        return;
    89     }
     88    } 
    9089
    91     if (substr($file,0,1) == '/') {
     90    if ($file[0] == '/') {
    9291        $_image_path = $basedir . $file;
    9392    } else {
     
    9594    }
    9695   
    97     if(!isset($params['width']) || !isset($params['height'])) {
    98         if(!$_image_data = @getimagesize($_image_path)) {
    99             if(!file_exists($_image_path)) {
    100                 $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
     96    // strip file protocol
     97    if (stripos($params['file'], 'file://') === 0) {
     98        $params['file'] = substr($params['file'], 7);
     99    }
     100   
     101    $protocol = strpos($params['file'], '://');
     102    if ($protocol !== false) {
     103        $protocol = strtolower(substr($params['file'], 0, $protocol));
     104    }
     105   
     106    if (isset($template->smarty->security_policy)) {
     107        if ($protocol) {
     108            // remote resource (or php stream, …)
     109            if(!$template->smarty->security_policy->isTrustedUri($params['file'])) {
    101110                return;
    102             } else if(!is_readable($_image_path)) {
    103                 $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
    104                 return;
    105             } else {
    106                 $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
     111            }
     112        } else {
     113            // local file
     114            if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) {
    107115                return;
    108116            }
    109117        }
    110         if ($smarty->security &&
    111             ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
    112             (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) &&
    113             (!smarty_core_is_secure($_params, $smarty)) ) {
    114             $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
    115         }       
    116        
    117         if(!isset($params['width'])) {
    118             $width = $_image_data[0];
    119         }
    120         if(!isset($params['height'])) {
    121             $height = $_image_data[1];
     118    }
     119
     120    if (!isset($params['width']) || !isset($params['height'])) {
     121        // FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader!
     122        if (!$_image_data = @getimagesize($_image_path)) {
     123            if (!file_exists($_image_path)) {
     124                trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
     125                return;
     126            } else if (!is_readable($_image_path)) {
     127                trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
     128                return;
     129            } else {
     130                trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
     131                return;
     132            }
    122133        }
    123134
    124     }
     135        if (!isset($params['width'])) {
     136            $width = $_image_data[0];
     137        }
     138        if (!isset($params['height'])) {
     139            $height = $_image_data[1];
     140        }
     141    }
    125142
    126     if(isset($params['dpi'])) {
    127         if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
     143    if (isset($params['dpi'])) {
     144        if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mac')) {
     145            // FIXME: (rodneyrehm) wrong dpi assumption
     146            // don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011.
    128147            $dpi_default = 72;
    129148        } else {
    130149            $dpi_default = 96;
    131         }
    132         $_resize = $dpi_default/$params['dpi'];
     150        } 
     151        $_resize = $dpi_default / $params['dpi'];
    133152        $width = round($width * $_resize);
    134153        $height = round($height * $_resize);
    135     }
     154    } 
    136155
    137     return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.'>' . $suffix;
    138 }
    139 
    140 /* vim: set expandtab: */
     156    return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix;
     157}
    141158
    142159?>
  • trunk/include/smarty/libs/plugins/function.html_options.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
    1010 * Smarty {html_options} function plugin
    11  *
     11 * 
    1212 * Type:     function<br>
    1313 * Name:     html_options<br>
    14  * Input:<br>
    15  *           - name       (optional) - string default "select"
    16  *           - values     (required if no options supplied) - array
    17  *           - options    (required if no values supplied) - associative array
    18  *           - selected   (optional) - string default not set
    19  *           - output     (required if not options supplied) - array
    2014 * Purpose:  Prints the list of <option> tags generated from
    21  *           the passed parameters
    22  * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
     15 *           the passed parameters<br>
     16 * Params:
     17 * <pre>
     18 * - name       (optional) - string default "select"
     19 * - values     (required) - if no options supplied) - array
     20 * - options    (required) - if no values supplied) - associative array
     21 * - selected   (optional) - string default not set
     22 * - output     (required) - if not options supplied) - array
     23 * - id         (optional) - string default not set
     24 * - class      (optional) - string default not set
     25 * </pre>
     26 *
     27 * @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image}
    2328 *      (Smarty online manual)
    24  * @author Monte Ohrt <monte at ohrt dot com>
    25  * @param array
    26  * @param Smarty
    27  * @return string
     29 * @author Monte Ohrt <monte at ohrt dot com>
     30 * @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de>
     31 * @param array                    $params   parameters
     32 * @param Smarty_Internal_Template $template template object
     33 * @return string
    2834 * @uses smarty_function_escape_special_chars()
    2935 */
    30 function smarty_function_html_options($params, &$smarty)
     36function smarty_function_html_options($params, $template)
    3137{
    32     require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
    33    
     38    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
     39
    3440    $name = null;
    3541    $values = null;
    3642    $options = null;
    37     $selected = array();
     43    $selected = null;
    3844    $output = null;
    39    
     45    $id = null;
     46    $class = null;
     47
    4048    $extra = '';
    41    
    42     foreach($params as $_key => $_val) {
    43         switch($_key) {
     49
     50    foreach ($params as $_key => $_val) {
     51        switch ($_key) {
    4452            case 'name':
    45                 $$_key = (string)$_val;
     53            case 'class':
     54            case 'id':
     55                $$_key = (string) $_val;
    4656                break;
    47            
     57
    4858            case 'options':
    49                 $$_key = (array)$_val;
     59                $options = (array) $_val;
    5060                break;
    51                
     61
    5262            case 'values':
    5363            case 'output':
    54                 $$_key = array_values((array)$_val);
     64                $$_key = array_values((array) $_val);
    5565                break;
    5666
    5767            case 'selected':
    58                 $$_key = array_map('strval', array_values((array)$_val));
    59                 break;
    60                
    61             default:
    62                 if(!is_array($_val)) {
    63                     $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
     68                if (is_array($_val)) {
     69                    $selected = array();
     70                    foreach ($_val as $_sel) {
     71                        if (is_object($_sel)) {
     72                            if (method_exists($_sel, "__toString")) {
     73                                $_sel = smarty_function_escape_special_chars((string) $_sel->__toString());
     74                            } else {
     75                                trigger_error("html_options: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE);
     76                                continue;
     77                            }
     78                        } else {
     79                            $_sel = smarty_function_escape_special_chars((string) $_sel);
     80                        }
     81                        $selected[$_sel] = true;
     82                    }
     83                } elseif (is_object($_val)) {
     84                    if (method_exists($_val, "__toString")) {
     85                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
     86                    } else {
     87                        trigger_error("html_options: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
     88                    }
    6489                } else {
    65                     $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     90                    $selected = smarty_function_escape_special_chars((string) $_val);
    6691                }
    6792                break;
    68         }
     93           
     94            case 'strict': break;
     95           
     96            case 'disabled':
     97            case 'readonly':
     98                if (!empty($params['strict'])) {
     99                    if (!is_scalar($_val)) {
     100                        trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
     101                    }
     102                   
     103                    if ($_val === true || $_val === $_key) {
     104                        $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
     105                    }
     106                   
     107                    break;
     108                }
     109                // omit break; to fall through!
     110           
     111            default:
     112                if (!is_array($_val)) {
     113                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
     114                } else {
     115                    trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     116                }
     117                break;
     118        }
    69119    }
    70120
    71     if (!isset($options) && !isset($values))
    72         return ''; /* raise error here? */
     121    if (!isset($options) && !isset($values)) {
     122        /* raise error here? */
     123        return '';
     124    }
    73125
    74126    $_html_result = '';
     127    $_idx = 0;
    75128
    76129    if (isset($options)) {
    77        
    78         foreach ($options as $_key=>$_val)
    79             $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
    80 
     130        foreach ($options as $_key => $_val) {
     131            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
     132        }
    81133    } else {
    82        
    83         foreach ($values as $_i=>$_key) {
     134        foreach ($values as $_i => $_key) {
    84135            $_val = isset($output[$_i]) ? $output[$_i] : '';
    85             $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
    86         }
    87 
     136            $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx);
     137        }
    88138    }
    89139
    90     if(!empty($name)) {
    91         $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
    92     }
     140    if (!empty($name)) {
     141        $_html_class = !empty($class) ? ' class="'.$class.'"' : '';
     142        $_html_id = !empty($id) ? ' id="'.$id.'"' : '';
     143        $_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
     144    }
    93145
    94     return $_html_result;
    95 
    96 }
    97 
    98 function smarty_function_html_options_optoutput($key, $value, $selected) {
    99     if(!is_array($value)) {
    100         $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
    101             smarty_function_escape_special_chars($key) . '"';
    102         if (in_array((string)$key, $selected))
    103             $_html_result .= ' selected="selected"';
    104         $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
    105     } else {
    106         $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
    107     }
    108146    return $_html_result;
    109147}
    110148
    111 function smarty_function_html_options_optgroup($key, $values, $selected) {
     149function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx)
     150{
     151    if (!is_array($value)) {
     152        $_key = smarty_function_escape_special_chars($key);
     153        $_html_result = '<option value="' . $_key . '"';
     154        if (is_array($selected)) {
     155            if (isset($selected[$_key])) {
     156                $_html_result .= ' selected="selected"';
     157            }
     158        } elseif ($_key === $selected) {
     159            $_html_result .= ' selected="selected"';
     160        }
     161        $_html_class = !empty($class) ? ' class="'.$class.' option"' : '';
     162        $_html_id = !empty($id) ? ' id="'.$id.'-'.$idx.'"' : '';
     163        if (is_object($value)) {
     164            if (method_exists($value, "__toString")) {
     165                $value = smarty_function_escape_special_chars((string) $value->__toString());
     166            } else {
     167                trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
     168                return '';
     169            }
     170        } else {
     171            $value = smarty_function_escape_special_chars((string) $value);
     172        }
     173        $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
     174        $idx++;
     175    } else {
     176        $_idx = 0;
     177        $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id.'-'.$idx) : null, $class, $_idx);
     178        $idx++;
     179    }
     180    return $_html_result;
     181}
     182
     183function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx)
     184{
    112185    $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
    113186    foreach ($values as $key => $value) {
    114         $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
    115     }
     187        $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx);
     188    } 
    116189    $optgroup_html .= "</optgroup>\n";
    117190    return $optgroup_html;
    118 }
    119 
    120 /* vim: set expandtab: */
     191}
    121192
    122193?>
  • trunk/include/smarty/libs/plugins/function.html_radios.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
    1010 * Smarty {html_radios} function plugin
    11  *
     11 * 
    1212 * File:       function.html_radios.php<br>
    1313 * Type:       function<br>
     
    1515 * Date:       24.Feb.2003<br>
    1616 * Purpose:    Prints out a list of radio input types<br>
    17  * Input:<br>
    18  *           - name       (optional) - string default "radio"
    19  *           - values     (required) - array
    20  *           - options    (optional) - associative array
    21  *           - checked    (optional) - array default not set
    22  *           - separator  (optional) - ie <br> or &nbsp;
    23  *           - output     (optional) - the output next to each radio button
    24  *           - assign     (optional) - assign the output as an array to this variable
     17 * Params:
     18 * <pre>
     19 * - name       (optional) - string default "radio"
     20 * - values     (required) - array
     21 * - options    (required) - associative array
     22 * - checked    (optional) - array default not set
     23 * - separator  (optional) - ie <br> or &nbsp;
     24 * - output     (optional) - the output next to each radio button
     25 * - assign     (optional) - assign the output as an array to this variable
     26 * - escape     (optional) - escape the content (not value), defaults to true
     27 * </pre>
    2528 * Examples:
    2629 * <pre>
     
    2932 * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
    3033 * </pre>
     34 *
    3135 * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
    3236 *      (Smarty online manual)
    33  * @author     Christopher Kvarme <christopher.kvarme@flashjab.com>
    34  * @author credits to Monte Ohrt <monte at ohrt dot com>
    35  * @version    1.0
    36  * @param array
    37  * @param Smarty
    38  * @return string
     37 * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
     38 * @author credits to Monte Ohrt <monte at ohrt dot com> 
     39 * @version 1.0
     40 * @param array                    $params   parameters
     41 * @param Smarty_Internal_Template $template template object
     42 * @return string 
    3943 * @uses smarty_function_escape_special_chars()
    4044 */
    41 function smarty_function_html_radios($params, &$smarty)
     45function smarty_function_html_radios($params, $template)
    4246{
    43     require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
    44    
     47    require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
     48
    4549    $name = 'radio';
    4650    $values = null;
     
    4852    $selected = null;
    4953    $separator = '';
     54    $escape = true;
    5055    $labels = true;
    5156    $label_ids = false;
     
    5459
    5560    foreach($params as $_key => $_val) {
    56         switch($_key) {
     61        switch ($_key) {
    5762            case 'name':
    5863            case 'separator':
    59                 $$_key = (string)$_val;
     64                $$_key = (string) $_val;
    6065                break;
    6166
    6267            case 'checked':
    6368            case 'selected':
    64                 if(is_array($_val)) {
    65                     $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
     69                if (is_array($_val)) {
     70                    trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
     71                } elseif (is_object($_val)) {
     72                    if (method_exists($_val, "__toString")) {
     73                        $selected = smarty_function_escape_special_chars((string) $_val->__toString());
     74                    } else {
     75                        trigger_error("html_radios: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE);
     76                    }
    6677                } else {
    67                     $selected = (string)$_val;
    68                 }
    69                 break;
    70 
     78                    $selected = (string) $_val;
     79                }
     80                break;
     81
     82            case 'escape':
    7183            case 'labels':
    7284            case 'label_ids':
    73                 $$_key = (bool)$_val;
     85                $$_key = (bool) $_val;
    7486                break;
    7587
    7688            case 'options':
    77                 $$_key = (array)$_val;
     89                $$_key = (array) $_val;
    7890                break;
    7991
    8092            case 'values':
    8193            case 'output':
    82                 $$_key = array_values((array)$_val);
     94                $$_key = array_values((array) $_val);
    8395                break;
    8496
    8597            case 'radios':
    86                 $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
    87                 $options = (array)$_val;
     98                trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
     99                $options = (array) $_val;
    88100                break;
    89101
     
    91103                break;
    92104
     105            case 'strict': break;
     106
     107            case 'disabled':
     108            case 'readonly':
     109                if (!empty($params['strict'])) {
     110                    if (!is_scalar($_val)) {
     111                        trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
     112                    }
     113
     114                    if ($_val === true || $_val === $_key) {
     115                        $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
     116                    }
     117
     118                    break;
     119                }
     120                // omit break; to fall through!
     121
    93122            default:
    94                 if(!is_array($_val)) {
    95                     $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
     123                if (!is_array($_val)) {
     124                    $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
    96125                } else {
    97                     $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
    98                 }
    99                 break;
     126                    trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     127                }
     128                break;
     129        }
     130    }
     131
     132    if (!isset($options) && !isset($values)) {
     133        /* raise error here? */
     134        return '';
     135    }
     136
     137    $_html_result = array();
     138
     139    if (isset($options)) {
     140        foreach ($options as $_key => $_val) {
     141            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
    100142        }
    101     }
    102 
    103     if (!isset($options) && !isset($values))
    104         return ''; /* raise error here? */
    105 
    106     $_html_result = array();
    107 
    108     if (isset($options)) {
    109 
    110         foreach ($options as $_key=>$_val)
    111             $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
    112 
    113     } else {
    114 
    115         foreach ($values as $_i=>$_key) {
     143    } else {
     144        foreach ($values as $_i => $_key) {
    116145            $_val = isset($output[$_i]) ? $output[$_i] : '';
    117             $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
     146            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape);
     147        }
     148    }
     149
     150    if (!empty($params['assign'])) {
     151        $template->assign($params['assign'], $_html_result);
     152    } else {
     153        return implode("\n", $_html_result);
     154    }
     155}
     156
     157function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape)
     158{
     159    $_output = '';
     160   
     161    if (is_object($value)) {
     162        if (method_exists($value, "__toString")) {
     163            $value = (string) $value->__toString();
     164        } else {
     165            trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
     166            return '';
    118167        }
    119 
    120     }
    121 
    122     if(!empty($params['assign'])) {
    123         $smarty->assign($params['assign'], $_html_result);
    124     } else {
    125         return implode("\n",$_html_result);
    126     }
    127 
    128 }
    129 
    130 function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
    131     $_output = '';
     168    } else {
     169        $value = (string) $value;
     170    }
     171   
     172    if (is_object($output)) {
     173        if (method_exists($output, "__toString")) {
     174            $output = (string) $output->__toString();
     175        } else {
     176            trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE);
     177            return '';
     178        }
     179    } else {
     180        $output = (string) $output;
     181    }
     182   
    132183    if ($labels) {
    133       if($label_ids) {
    134           $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
    135           $_output .= '<label for="' . $_id . '">';
    136       } else {
    137           $_output .= '<label>';           
    138       }
    139    }
    140    $_output .= '<input type="radio" name="'
    141         . smarty_function_escape_special_chars($name) . '" value="'
    142         . smarty_function_escape_special_chars($value) . '"';
    143 
    144    if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
    145 
    146     if ((string)$value==$selected) {
     184        if ($label_ids) {
     185            $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value));
     186            $_output .= '<label for="' . $_id . '">';
     187        } else {
     188            $_output .= '<label>';
     189        }
     190    }
     191   
     192    $name = smarty_function_escape_special_chars($name);
     193    $value = smarty_function_escape_special_chars($value);
     194    if ($escape) {
     195        $output = smarty_function_escape_special_chars($output);
     196    }
     197   
     198    $_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"';
     199
     200    if ($labels && $label_ids) {
     201        $_output .= ' id="' . $_id . '"';
     202    }
     203
     204    if ($value === $selected) {
    147205        $_output .= ' checked="checked"';
    148206    }
    149     $_output .= $extra . '>' . $output;
    150     if ($labels) $_output .= '</label>';
    151     $_output .=  $separator;
    152 
     207   
     208    $_output .= $extra . ' />' . $output;
     209    if ($labels) {
     210        $_output .= '</label>';
     211    }
     212   
     213    $_output .= $separator;
    153214    return $_output;
    154 }
     215} 
    155216
    156217?>
  • trunk/include/smarty/libs/plugins/function.html_select_date.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
     8
     9/**
     10 * @ignore
     11 */
     12require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
     13/**
     14 * @ignore
     15 */
     16require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
    717
    818/**
    919 * Smarty {html_select_date} plugin
    10  *
     20 * 
    1121 * Type:     function<br>
    1222 * Name:     html_select_date<br>
    1323 * Purpose:  Prints the dropdowns for date selection.
    14  *
    15  * ChangeLog:<br>
    16  *           - 1.0 initial release
    17  *           - 1.1 added support for +/- N syntax for begin
    18  *                and end year values. (Monte)
    19  *           - 1.2 added support for yyyy-mm-dd syntax for
    20  *                time value. (Jan Rosier)
    21  *           - 1.3 added support for choosing format for
    22  *                month values (Gary Loescher)
    23  *           - 1.3.1 added support for choosing format for
    24  *                day values (Marcus Bointon)
    25  *           - 1.3.2 support negative timestamps, force year
    26  *             dropdown to include given date unless explicitly set (Monte)
    27  *           - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
    28  *             of 0000-00-00 dates (cybot, boots)
    29  * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
     24 *
     25 * ChangeLog:
     26 * <pre>
     27 *            - 1.0 initial release
     28 *            - 1.1 added support for +/- N syntax for begin
     29 *              and end year values. (Monte)
     30 *            - 1.2 added support for yyyy-mm-dd syntax for
     31 *              time value. (Jan Rosier)
     32 *            - 1.3 added support for choosing format for
     33 *              month values (Gary Loescher)
     34 *            - 1.3.1 added support for choosing format for
     35 *              day values (Marcus Bointon)
     36 *            - 1.3.2 support negative timestamps, force year
     37 *              dropdown to include given date unless explicitly set (Monte)
     38 *            - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
     39 *              of 0000-00-00 dates (cybot, boots)
     40 *            - 2.0 complete rewrite for performance, 
     41 *              added attributes month_names, *_id
     42 * </pre>
     43 *
     44 * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date}
    3045 *      (Smarty online manual)
    31  * @version 1.3.4
    32  * @author Andrei Zmievski
    33  * @author Monte Ohrt <monte at ohrt dot com>
    34  * @param array
    35  * @param Smarty
    36  * @return string
     46 * @version 2.0
     47 * @author Andrei Zmievski
     48 * @author Monte Ohrt <monte at ohrt dot com>
     49 * @author Rodney Rehm
     50 * @param array                    $params   parameters
     51 * @param Smarty_Internal_Template $template template object
     52 * @return string
    3753 */
    38 function smarty_function_html_select_date($params, &$smarty)
     54function smarty_function_html_select_date($params, $template)
    3955{
    40     require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
    41     require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
    42     require_once $smarty->_get_plugin_filepath('function','html_options');
     56    // generate timestamps used for month names only
     57    static $_month_timestamps = null;
     58    static $_current_year = null;
     59    if ($_month_timestamps === null) {
     60        $_current_year = date('Y');
     61        $_month_timestamps = array();
     62        for ($i = 1; $i <= 12; $i++) {
     63            $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000);
     64        }
     65    }
     66
    4367    /* Default values. */
    44     $prefix          = "Date_";
    45     $start_year      = strftime("%Y");
    46     $end_year        = $start_year;
    47     $display_days    = true;
    48     $display_months  = true;
    49     $display_years   = true;
    50     $month_format    = "%B";
     68    $prefix = "Date_";
     69    $start_year = null;
     70    $end_year = null;
     71    $display_days = true;
     72    $display_months = true;
     73    $display_years = true;
     74    $month_format = "%B";
    5175    /* Write months as numbers by default  GL */
    5276    $month_value_format = "%m";
    53     $day_format      = "%02d";
     77    $day_format = "%02d";
    5478    /* Write day values using this format MB */
    5579    $day_value_format = "%d";
    56     $year_as_text    = false;
     80    $year_as_text = false;
    5781    /* Display years in reverse order? Ie. 2000,1999,.... */
    58     $reverse_years   = false;
     82    $reverse_years = false;
    5983    /* Should the select boxes be part of an array when returned from PHP?
    6084       e.g. setting it to "birthday", would create "birthday[Day]",
    6185       "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
    62     $field_array     = null;
     86    $field_array = null;
    6387    /* <select size>'s of the different <select> tags.
    6488       If not set, uses default dropdown. */
    65     $day_size        = null;
    66     $month_size      = null;
    67     $year_size       = null;
     89    $day_size = null;
     90    $month_size = null;
     91    $year_size = null;
    6892    /* Unparsed attributes common to *ALL* the <select>/<input> tags.
    6993       An example might be in the template: all_extra ='class ="foo"'. */
    70     $all_extra       = null;
     94    $all_extra = null;
    7195    /* Separate attributes for the tags. */
    72     $day_extra       = null;
    73     $month_extra     = null;
    74     $year_extra      = null;
     96    $day_extra = null;
     97    $month_extra = null;
     98    $year_extra = null;
    7599    /* Order in which to display the fields.
    76100       "D" -> day, "M" -> month, "Y" -> year. */
    77     $field_order     = 'MDY';
     101    $field_order = 'MDY';
    78102    /* String printed between the different fields. */
    79103    $field_separator = "\n";
    80     $time = time();
    81     $all_empty       = null;
    82     $day_empty       = null;
    83     $month_empty     = null;
    84     $year_empty      = null;
    85     $extra_attrs     = '';
    86 
    87     foreach ($params as $_key=>$_value) {
     104    $option_separator = "\n";
     105    $time = null;
     106    // $all_empty = null;
     107    // $day_empty = null;
     108    // $month_empty = null;
     109    // $year_empty = null;
     110    $extra_attrs = '';
     111    $all_id = null;
     112    $day_id = null;
     113    $month_id = null;
     114    $year_id = null;
     115
     116    foreach ($params as $_key => $_value) {
    88117        switch ($_key) {
     118            case 'time':
     119                if (!is_array($_value) && $_value !== null) {
     120                    $time = smarty_make_timestamp($_value);
     121                }
     122                break;
     123               
     124            case 'month_names':
     125                if (is_array($_value) && count($_value) == 12) {
     126                    $$_key = $_value;
     127                } else {
     128                    trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
     129                }
     130                break;
     131               
    89132            case 'prefix':
    90             case 'time':
     133            case 'field_array':
    91134            case 'start_year':
    92135            case 'end_year':
    93             case 'month_format':
    94136            case 'day_format':
    95137            case 'day_value_format':
    96             case 'field_array':
     138            case 'month_format':
     139            case 'month_value_format':
    97140            case 'day_size':
    98141            case 'month_size':
     
    104147            case 'field_order':
    105148            case 'field_separator':
    106             case 'month_value_format':
     149            case 'option_separator':
     150            case 'all_empty':
    107151            case 'month_empty':
    108152            case 'day_empty':
    109153            case 'year_empty':
     154            case 'all_id':
     155            case 'month_id':
     156            case 'day_id':
     157            case 'year_id':
    110158                $$_key = (string)$_value;
    111                 break;
    112 
    113             case 'all_empty':
    114                 $$_key = (string)$_value;
    115                 $day_empty = $month_empty = $year_empty = $all_empty;
    116159                break;
    117160
     
    125168
    126169            default:
    127                 if(!is_array($_value)) {
    128                     $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
     170                if (!is_array($_value)) {
     171                    $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
    129172                } else {
    130                     $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
    131                 }
    132                 break;
    133         }
    134     }
    135 
    136     if (preg_match('!^-\d+$!', $time)) {
    137         // negative timestamp, use date()
    138         $time = date('Y-m-d', $time);
    139     }
    140     // If $time is not in format yyyy-mm-dd
    141     if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
    142         $time = $found[1];
     173                    trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     174                }
     175                break;
     176        }
     177    }
     178   
     179    // Note: date() is faster than strftime()
     180    // Note: explode(date()) is faster than date() date() date()
     181    if (isset($params['time']) && is_array($params['time'])) {
     182        if (isset($params['time'][$prefix . 'Year'])) {
     183            // $_REQUEST[$field_array] given
     184            foreach (array('Y' => 'Year',  'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
     185                $_variableName = '_' . strtolower($_elementName);
     186                $$_variableName = isset($params['time'][$prefix . $_elementName])
     187                    ? $params['time'][$prefix . $_elementName]
     188                    : date($_elementKey);
     189            }
     190            $time = mktime(0, 0, 0, $_month, $_day, $_year);
     191        } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
     192            // $_REQUEST given
     193            foreach (array('Y' => 'Year',  'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
     194                $_variableName = '_' . strtolower($_elementName);
     195                $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
     196                    ? $params['time'][$field_array][$prefix . $_elementName]
     197                    : date($_elementKey);
     198            }
     199            $time = mktime(0, 0, 0, $_month, $_day, $_year);
     200        } else {
     201            // no date found, use NOW
     202            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
     203        }
     204    } elseif ($time === null) {
     205        if (array_key_exists('time', $params)) {
     206            $_year = $_month = $_day = $time = null;
     207        } else {
     208            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
     209        }
    143210    } else {
    144         // use smarty_make_timestamp to get an unix timestamp and
    145         // strftime to make yyyy-mm-dd
    146         $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
    147     }
    148     // Now split this in pieces, which later can be used to set the select
    149     $time = explode("-", $time);
    150 
    151     // make syntax "+N" or "-N" work with start_year and end_year
    152     if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
    153         if ($match[1] == '+') {
    154             $end_year = strftime('%Y') + $match[2];
     211        list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
     212    }
     213
     214    // make syntax "+N" or "-N" work with $start_year and $end_year
     215    // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
     216    foreach (array('start', 'end') as $key) {
     217        $key .= '_year';
     218        $t = $$key;
     219        if ($t === null) {
     220            $$key = (int)$_current_year;
     221        } else if ($t[0] == '+') {
     222            $$key = (int)($_current_year + trim(substr($t, 1)));
     223        } else if ($t[0] == '-') {
     224            $$key = (int)($_current_year - trim(substr($t, 1)));
    155225        } else {
    156             $end_year = strftime('%Y') - $match[2];
    157         }
    158     }
    159     if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
    160         if ($match[1] == '+') {
    161             $start_year = strftime('%Y') + $match[2];
     226            $$key = (int)$$key;
     227        }
     228    }
     229
     230    // flip for ascending or descending
     231    if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
     232        $t = $end_year;
     233        $end_year = $start_year;
     234        $start_year = $t;
     235    }
     236
     237    // generate year <select> or <input>
     238    if ($display_years) {
     239        $_html_years = '';
     240        $_extra = '';
     241        $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
     242        if ($all_extra) {
     243            $_extra .= ' ' . $all_extra;
     244        }
     245        if ($year_extra) {
     246            $_extra .= ' ' . $year_extra;
     247        }
     248       
     249        if ($year_as_text) {
     250            $_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />';
    162251        } else {
    163             $start_year = strftime('%Y') - $match[2];
    164         }
    165     }
    166     if (strlen($time[0]) > 0) {
    167         if ($start_year > $time[0] && !isset($params['start_year'])) {
    168             // force start year to include given date if not explicitly set
    169             $start_year = $time[0];
    170         }
    171         if($end_year < $time[0] && !isset($params['end_year'])) {
    172             // force end year to include given date if not explicitly set
    173             $end_year = $time[0];
    174         }
    175     }
    176 
    177     $field_order = strtoupper($field_order);
    178 
    179     $html_result = $month_result = $day_result = $year_result = "";
    180 
    181     $field_separator_count = -1;
     252            $_html_years = '<select name="' . $_name . '"';
     253            if ($year_id !== null || $all_id !== null) {
     254                $_html_years .= ' id="' . smarty_function_escape_special_chars(
     255                    $year_id !== null ? ( $year_id ? $year_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     256                ) . '"';
     257            }
     258            if ($year_size) {
     259                $_html_years .= ' size="' . $year_size . '"';
     260            }
     261            $_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
     262           
     263            if (isset($year_empty) || isset($all_empty)) {
     264                $_html_years .= '<option value="">' . ( isset($year_empty) ? $year_empty : $all_empty ) . '</option>' . $option_separator;
     265            }
     266           
     267            $op = $start_year > $end_year ? -1 : 1;
     268            for ($i=$start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
     269                $_html_years .= '<option value="' . $i . '"'
     270                    . ($_year == $i ? ' selected="selected"' : '')
     271                    . '>' . $i . '</option>' . $option_separator;
     272            }
     273           
     274            $_html_years .= '</select>';
     275        }
     276    }
     277   
     278    // generate month <select> or <input>
    182279    if ($display_months) {
    183         $field_separator_count++;
    184         $month_names = array();
    185         $month_values = array();
    186         if(isset($month_empty)) {
    187             $month_names[''] = $month_empty;
    188             $month_values[''] = '';
    189         }
     280        $_html_month = '';
     281        $_extra = '';
     282        $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
     283        if ($all_extra) {
     284            $_extra .= ' ' . $all_extra;
     285        }
     286        if ($month_extra) {
     287            $_extra .= ' ' . $month_extra;
     288        }
     289       
     290        $_html_months = '<select name="' . $_name . '"';
     291        if ($month_id !== null || $all_id !== null) {
     292            $_html_months .= ' id="' . smarty_function_escape_special_chars(
     293                $month_id !== null ? ( $month_id ? $month_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     294            ) . '"';
     295        }
     296        if ($month_size) {
     297            $_html_months .= ' size="' . $month_size . '"';
     298        }
     299        $_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
     300       
     301        if (isset($month_empty) || isset($all_empty)) {
     302            $_html_months .= '<option value="">' . ( isset($month_empty) ? $month_empty : $all_empty ) . '</option>' . $option_separator;
     303        }
     304       
    190305        for ($i = 1; $i <= 12; $i++) {
    191             $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
    192             $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
    193         }
    194 
    195         $month_result .= '<select name=';
    196         if (null !== $field_array){
    197             $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
    198         } else {
    199             $month_result .= '"' . $prefix . 'Month"';
    200         }
    201         if (null !== $month_size){
    202             $month_result .= ' size="' . $month_size . '"';
    203         }
    204         if (null !== $month_extra){
    205             $month_result .= ' ' . $month_extra;
    206         }
    207         if (null !== $all_extra){
    208             $month_result .= ' ' . $all_extra;
    209         }
    210         $month_result .= $extra_attrs . '>'."\n";
    211 
    212         $month_result .= smarty_function_html_options(array('output'     => $month_names,
    213                                                             'values'     => $month_values,
    214                                                             'selected'   => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
    215                                                             'print_result' => false),
    216                                                       $smarty);
    217         $month_result .= '</select>';
    218     }
    219 
     306            $_val = sprintf('%02d', $i);
     307            $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i]));
     308            $_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]);
     309            $_html_months .= '<option value="' . $_value . '"'
     310                . ($_val == $_month ? ' selected="selected"' : '')
     311                . '>' . $_text . '</option>' . $option_separator;
     312        }
     313       
     314        $_html_months .= '</select>';
     315    }
     316   
     317    // generate day <select> or <input>
    220318    if ($display_days) {
    221         $field_separator_count++;
    222         $days = array();
    223         if (isset($day_empty)) {
    224             $days[''] = $day_empty;
    225             $day_values[''] = '';
    226         }
     319        $_html_day = '';
     320        $_extra = '';
     321        $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
     322        if ($all_extra) {
     323            $_extra .= ' ' . $all_extra;
     324        }
     325        if ($day_extra) {
     326            $_extra .= ' ' . $day_extra;
     327        }
     328       
     329        $_html_days = '<select name="' . $_name . '"';
     330        if ($day_id !== null || $all_id !== null) {
     331            $_html_days .= ' id="' . smarty_function_escape_special_chars(
     332                $day_id !== null ? ( $day_id ? $day_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     333            ) . '"';
     334        }
     335        if ($day_size) {
     336            $_html_days .= ' size="' . $day_size . '"';
     337        }
     338        $_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
     339       
     340        if (isset($day_empty) || isset($all_empty)) {
     341            $_html_days .= '<option value="">' . ( isset($day_empty) ? $day_empty : $all_empty ) . '</option>' . $option_separator;
     342        }
     343       
    227344        for ($i = 1; $i <= 31; $i++) {
    228             $days[] = sprintf($day_format, $i);
    229             $day_values[] = sprintf($day_value_format, $i);
    230         }
    231 
    232         $day_result .= '<select name=';
    233         if (null !== $field_array){
    234             $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
    235         } else {
    236             $day_result .= '"' . $prefix . 'Day"';
    237         }
    238         if (null !== $day_size){
    239             $day_result .= ' size="' . $day_size . '"';
    240         }
    241         if (null !== $all_extra){
    242             $day_result .= ' ' . $all_extra;
    243         }
    244         if (null !== $day_extra){
    245             $day_result .= ' ' . $day_extra;
    246         }
    247         $day_result .= $extra_attrs . '>'."\n";
    248         $day_result .= smarty_function_html_options(array('output'     => $days,
    249                                                           'values'     => $day_values,
    250                                                           'selected'   => $time[2],
    251                                                           'print_result' => false),
    252                                                     $smarty);
    253         $day_result .= '</select>';
    254     }
    255 
    256     if ($display_years) {
    257         $field_separator_count++;
    258         if (null !== $field_array){
    259             $year_name = $field_array . '[' . $prefix . 'Year]';
    260         } else {
    261             $year_name = $prefix . 'Year';
    262         }
    263         if ($year_as_text) {
    264             $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
    265             if (null !== $all_extra){
    266                 $year_result .= ' ' . $all_extra;
    267             }
    268             if (null !== $year_extra){
    269                 $year_result .= ' ' . $year_extra;
    270             }
    271             $year_result .= '>';
    272         } else {
    273             $years = range((int)$start_year, (int)$end_year);
    274             if ($reverse_years) {
    275                 rsort($years, SORT_NUMERIC);
    276             } else {
    277                 sort($years, SORT_NUMERIC);
    278             }
    279             $yearvals = $years;
    280             if(isset($year_empty)) {
    281                 array_unshift($years, $year_empty);
    282                 array_unshift($yearvals, '');
    283             }
    284             $year_result .= '<select name="' . $year_name . '"';
    285             if (null !== $year_size){
    286                 $year_result .= ' size="' . $year_size . '"';
    287             }
    288             if (null !== $all_extra){
    289                 $year_result .= ' ' . $all_extra;
    290             }
    291             if (null !== $year_extra){
    292                 $year_result .= ' ' . $year_extra;
    293             }
    294             $year_result .= $extra_attrs . '>'."\n";
    295             $year_result .= smarty_function_html_options(array('output' => $years,
    296                                                                'values' => $yearvals,
    297                                                                'selected'   => $time[0],
    298                                                                'print_result' => false),
    299                                                          $smarty);
    300             $year_result .= '</select>';
    301         }
    302     }
    303 
    304     // Loop thru the field_order field
    305     for ($i = 0; $i <= 2; $i++){
    306         $c = substr($field_order, $i, 1);
    307         switch ($c){
     345            $_val = sprintf('%02d', $i);
     346            $_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
     347            $_value = $day_value_format ==  '%02d' ? $_val : sprintf($day_value_format, $i);
     348            $_html_days .= '<option value="' . $_value . '"'
     349                . ($_val == $_day ? ' selected="selected"' : '')
     350                . '>' . $_text . '</option>' . $option_separator;
     351        }
     352       
     353        $_html_days .= '</select>';
     354    }
     355
     356    // order the fields for output
     357    $_html = '';
     358    for ($i=0; $i <= 2; $i++) {
     359        switch ($field_order[$i]) {
     360            case 'Y':
     361            case 'y':
     362                if (isset($_html_years)) {
     363                    if ($_html) {
     364                        $_html .= $field_separator;
     365                    }
     366                    $_html .= $_html_years;
     367                }
     368            break;
     369           
     370            case 'm':
     371            case 'M':
     372                if (isset($_html_months)) {
     373                    if ($_html) {
     374                        $_html .= $field_separator;
     375                    }
     376                    $_html .= $_html_months;
     377                }
     378            break;
     379           
     380            case 'd':
    308381            case 'D':
    309                 $html_result .= $day_result;
    310                 break;
    311 
    312             case 'M':
    313                 $html_result .= $month_result;
    314                 break;
    315 
    316             case 'Y':
    317                 $html_result .= $year_result;
    318                 break;
    319         }
    320         // Add the field seperator
    321         if($i < $field_separator_count) {
    322             $html_result .= $field_separator;
    323         }
    324     }
    325 
    326     return $html_result;
     382                if (isset($_html_days)) {
     383                    if ($_html) {
     384                        $_html .= $field_separator;
     385                    }
     386                    $_html .= $_html_days;
     387                }
     388            break;
     389        }
     390    }
     391    return $_html;
    327392}
    328393
    329 /* vim: set expandtab: */
    330 
    331394?>
  • trunk/include/smarty/libs/plugins/function.html_select_time.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    78
     9/**
     10 * @ignore
     11 */
     12require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php');
     13/**
     14 * @ignore
     15 */
     16require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
    817
    918/**
     
    1322 * Name:     html_select_time<br>
    1423 * Purpose:  Prints the dropdowns for time selection
    15  * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
     24 *
     25 * @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time}
    1626 *          (Smarty online manual)
    1727 * @author Roberto Berto <roberto@berto.net>
    18  * @credits Monte Ohrt <monte AT ohrt DOT com>
    19  * @param array
    20  * @param Smarty
     28 * @author Monte Ohrt <monte AT ohrt DOT com>
     29 * @param array                    $params   parameters
     30 * @param Smarty_Internal_Template $template template object
    2131 * @return string
    2232 * @uses smarty_make_timestamp()
    2333 */
    24 function smarty_function_html_select_time($params, &$smarty)
     34function smarty_function_html_select_time($params, $template)
    2535{
    26     require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
    27     require_once $smarty->_get_plugin_filepath('function','html_options');
    28     /* Default values. */
    29     $prefix             = "Time_";
    30     $time               = time();
    31     $display_hours      = true;
    32     $display_minutes    = true;
    33     $display_seconds    = true;
    34     $display_meridian   = true;
    35     $use_24_hours       = true;
    36     $minute_interval    = 1;
    37     $second_interval    = 1;
    38     /* Should the select boxes be part of an array when returned from PHP?
    39        e.g. setting it to "birthday", would create "birthday[Hour]",
    40        "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
    41        Can be combined with prefix. */
    42     $field_array        = null;
    43     $all_extra          = null;
    44     $hour_extra         = null;
    45     $minute_extra       = null;
    46     $second_extra       = null;
    47     $meridian_extra     = null;
    48 
    49     foreach ($params as $_key=>$_value) {
     36    $prefix = "Time_";
     37    $field_array = null;
     38    $field_separator = "\n";
     39    $option_separator = "\n";
     40    $time = null;
     41
     42    $display_hours = true;
     43    $display_minutes = true;
     44    $display_seconds = true;
     45    $display_meridian = true;
     46
     47    $hour_format = '%02d';
     48    $hour_value_format = '%02d';
     49    $minute_format = '%02d';
     50    $minute_value_format = '%02d';
     51    $second_format = '%02d';
     52    $second_value_format = '%02d';
     53
     54    $hour_size = null;
     55    $minute_size = null;
     56    $second_size = null;
     57    $meridian_size = null;
     58
     59    $all_empty = null;
     60    $hour_empty = null;
     61    $minute_empty = null;
     62    $second_empty = null;
     63    $meridian_empty = null;
     64
     65    $all_id = null;
     66    $hour_id = null;
     67    $minute_id = null;
     68    $second_id = null;
     69    $meridian_id = null;
     70
     71    $use_24_hours = true;
     72    $minute_interval = 1;
     73    $second_interval = 1;
     74
     75    $extra_attrs = '';
     76    $all_extra = null;
     77    $hour_extra = null;
     78    $minute_extra = null;
     79    $second_extra = null;
     80    $meridian_extra = null;
     81
     82    foreach ($params as $_key => $_value) {
    5083        switch ($_key) {
     84            case 'time':
     85                if (!is_array($_value) && $_value !== null) {
     86                    $time = smarty_make_timestamp($_value);
     87                }
     88                break;
     89
    5190            case 'prefix':
    52             case 'time':
    5391            case 'field_array':
     92
     93            case 'field_separator':
     94            case 'option_separator':
     95
    5496            case 'all_extra':
    5597            case 'hour_extra':
     
    5799            case 'second_extra':
    58100            case 'meridian_extra':
     101
     102            case 'all_empty':
     103            case 'hour_empty':
     104            case 'minute_empty':
     105            case 'second_empty':
     106            case 'meridian_empty':
     107
     108            case 'all_id':
     109            case 'hour_id':
     110            case 'minute_id':
     111            case 'second_id':
     112            case 'meridian_id':
     113
     114            case 'hour_format':
     115            case 'hour_value_format':
     116            case 'minute_format':
     117            case 'minute_value_format':
     118            case 'second_format':
     119            case 'second_value_format':
    59120                $$_key = (string)$_value;
    60121                break;
     
    70131            case 'minute_interval':
    71132            case 'second_interval':
     133
     134            case 'hour_size':
     135            case 'minute_size':
     136            case 'second_size':
     137            case 'meridian_size':
    72138                $$_key = (int)$_value;
    73139                break;
    74140
    75141            default:
    76                 $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
    77         }
    78     }
    79 
    80     $time = smarty_make_timestamp($time);
    81 
    82     $html_result = '';
    83 
     142                if (!is_array($_value)) {
     143                    $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
     144                } else {
     145                    trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
     146                }
     147                break;
     148        }
     149    }
     150
     151    if (isset($params['time']) && is_array($params['time'])) {
     152        if (isset($params['time'][$prefix . 'Hour'])) {
     153            // $_REQUEST[$field_array] given
     154            foreach (array('H' => 'Hour',  'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
     155                $_variableName = '_' . strtolower($_elementName);
     156                $$_variableName = isset($params['time'][$prefix . $_elementName])
     157                    ? $params['time'][$prefix . $_elementName]
     158                    : date($_elementKey);
     159            }
     160            $_meridian = isset($params['time'][$prefix . 'Meridian'])
     161                ? (' ' . $params['time'][$prefix . 'Meridian'])
     162                : '';
     163            $time = strtotime( $_hour . ':' . $_minute . ':' . $_second . $_meridian );
     164            list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
     165        } elseif (isset($params['time'][$field_array][$prefix . 'Hour'])) {
     166            // $_REQUEST given
     167            foreach (array('H' => 'Hour',  'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) {
     168                $_variableName = '_' . strtolower($_elementName);
     169                $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
     170                    ? $params['time'][$field_array][$prefix . $_elementName]
     171                    : date($_elementKey);
     172            }
     173            $_meridian = isset($params['time'][$field_array][$prefix . 'Meridian'])
     174                ? (' ' . $params['time'][$field_array][$prefix . 'Meridian'])
     175                : '';
     176            $time = strtotime( $_hour . ':' . $_minute . ':' . $_second . $_meridian );
     177            list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
     178        } else {
     179            // no date found, use NOW
     180            list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
     181        }
     182    } elseif ($time === null) {
     183        if (array_key_exists('time', $params)) {
     184            $_hour = $_minute = $_second = $time = null;
     185        } else {
     186            list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s'));
     187        }
     188    } else {
     189        list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time));
     190    }
     191
     192    // generate hour <select>
    84193    if ($display_hours) {
    85         $hours       = $use_24_hours ? range(0, 23) : range(1, 12);
    86         $hour_fmt = $use_24_hours ? '%H' : '%I';
    87         for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
    88             $hours[$i] = sprintf('%02d', $hours[$i]);
    89         $html_result .= '<select name=';
    90         if (null !== $field_array) {
    91             $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
    92         } else {
    93             $html_result .= '"' . $prefix . 'Hour"';
    94         }
    95         if (null !== $hour_extra){
    96             $html_result .= ' ' . $hour_extra;
    97         }
    98         if (null !== $all_extra){
    99             $html_result .= ' ' . $all_extra;
    100         }
    101         $html_result .= '>'."\n";
    102         $html_result .= smarty_function_html_options(array('output'          => $hours,
    103                                                            'values'          => $hours,
    104                                                            'selected'      => strftime($hour_fmt, $time),
    105                                                            'print_result' => false),
    106                                                      $smarty);
    107         $html_result .= "</select>\n";
    108     }
    109 
     194        $_html_hours = '';
     195        $_extra = '';
     196        $_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour');
     197        if ($all_extra) {
     198            $_extra .= ' ' . $all_extra;
     199        }
     200        if ($hour_extra) {
     201            $_extra .= ' ' . $hour_extra;
     202        }
     203
     204        $_html_hours = '<select name="' . $_name . '"';
     205        if ($hour_id !== null || $all_id !== null) {
     206            $_html_hours .= ' id="' . smarty_function_escape_special_chars(
     207                $hour_id !== null ? ( $hour_id ? $hour_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     208            ) . '"';
     209        }
     210        if ($hour_size) {
     211            $_html_hours .= ' size="' . $hour_size . '"';
     212        }
     213        $_html_hours .= $_extra . $extra_attrs . '>' . $option_separator;
     214
     215        if (isset($hour_empty) || isset($all_empty)) {
     216            $_html_hours .= '<option value="">' . ( isset($hour_empty) ? $hour_empty : $all_empty ) . '</option>' . $option_separator;
     217        }
     218
     219        $start = $use_24_hours ? 0 : 1;
     220        $end = $use_24_hours ? 23 : 12;
     221        for ($i=$start; $i <= $end; $i++) {
     222            $_val = sprintf('%02d', $i);
     223            $_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i);
     224            $_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i);
     225
     226            if (!$use_24_hours) {
     227                $_hour12 = $_hour == 0
     228                    ? 12
     229                    : ($_hour <= 12 ? $_hour : $_hour -12);
     230            }
     231
     232            $selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null;
     233            $_html_hours .= '<option value="' . $_value . '"'
     234                . ($selected ? ' selected="selected"' : '')
     235                . '>' . $_text . '</option>' . $option_separator;
     236        }
     237
     238        $_html_hours .= '</select>';
     239    }
     240
     241    // generate minute <select>
    110242    if ($display_minutes) {
    111         $all_minutes = range(0, 59);
    112         for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
    113             $minutes[] = sprintf('%02d', $all_minutes[$i]);
    114         $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
    115         $html_result .= '<select name=';
    116         if (null !== $field_array) {
    117             $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
    118         } else {
    119             $html_result .= '"' . $prefix . 'Minute"';
    120         }
    121         if (null !== $minute_extra){
    122             $html_result .= ' ' . $minute_extra;
    123         }
    124         if (null !== $all_extra){
    125             $html_result .= ' ' . $all_extra;
    126         }
    127         $html_result .= '>'."\n";
    128        
    129         $html_result .= smarty_function_html_options(array('output'          => $minutes,
    130                                                            'values'          => $minutes,
    131                                                            'selected'      => $selected,
    132                                                            'print_result' => false),
    133                                                      $smarty);
    134         $html_result .= "</select>\n";
    135     }
    136 
     243        $_html_minutes = '';
     244        $_extra = '';
     245        $_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute');
     246        if ($all_extra) {
     247            $_extra .= ' ' . $all_extra;
     248        }
     249        if ($minute_extra) {
     250            $_extra .= ' ' . $minute_extra;
     251        }
     252
     253        $_html_minutes = '<select name="' . $_name . '"';
     254        if ($minute_id !== null || $all_id !== null) {
     255            $_html_minutes .= ' id="' . smarty_function_escape_special_chars(
     256                $minute_id !== null ? ( $minute_id ? $minute_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     257            ) . '"';
     258        }
     259        if ($minute_size) {
     260            $_html_minutes .= ' size="' . $minute_size . '"';
     261        }
     262        $_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator;
     263
     264        if (isset($minute_empty) || isset($all_empty)) {
     265            $_html_minutes .= '<option value="">' . ( isset($minute_empty) ? $minute_empty : $all_empty ) . '</option>' . $option_separator;
     266        }
     267
     268        $selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null;
     269        for ($i=0; $i <= 59; $i += $minute_interval) {
     270            $_val = sprintf('%02d', $i);
     271            $_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i);
     272            $_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i);
     273            $_html_minutes .= '<option value="' . $_value . '"'
     274                . ($selected === $i ? ' selected="selected"' : '')
     275                . '>' . $_text . '</option>' . $option_separator;
     276        }
     277
     278        $_html_minutes .= '</select>';
     279    }
     280
     281    // generate second <select>
    137282    if ($display_seconds) {
    138         $all_seconds = range(0, 59);
    139         for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
    140             $seconds[] = sprintf('%02d', $all_seconds[$i]);
    141         $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
    142         $html_result .= '<select name=';
    143         if (null !== $field_array) {
    144             $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
    145         } else {
    146             $html_result .= '"' . $prefix . 'Second"';
    147         }
    148        
    149         if (null !== $second_extra){
    150             $html_result .= ' ' . $second_extra;
    151         }
    152         if (null !== $all_extra){
    153             $html_result .= ' ' . $all_extra;
    154         }
    155         $html_result .= '>'."\n";
    156        
    157         $html_result .= smarty_function_html_options(array('output'          => $seconds,
    158                                                            'values'          => $seconds,
    159                                                            'selected'      => $selected,
    160                                                            'print_result' => false),
    161                                                      $smarty);
    162         $html_result .= "</select>\n";
    163     }
    164 
     283        $_html_seconds = '';
     284        $_extra = '';
     285        $_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second');
     286        if ($all_extra) {
     287            $_extra .= ' ' . $all_extra;
     288        }
     289        if ($second_extra) {
     290            $_extra .= ' ' . $second_extra;
     291        }
     292
     293        $_html_seconds = '<select name="' . $_name . '"';
     294        if ($second_id !== null || $all_id !== null) {
     295            $_html_seconds .= ' id="' . smarty_function_escape_special_chars(
     296                $second_id !== null ? ( $second_id ? $second_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     297            ) . '"';
     298        }
     299        if ($second_size) {
     300            $_html_seconds .= ' size="' . $second_size . '"';
     301        }
     302        $_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator;
     303
     304        if (isset($second_empty) || isset($all_empty)) {
     305            $_html_seconds .= '<option value="">' . ( isset($second_empty) ? $second_empty : $all_empty ) . '</option>' . $option_separator;
     306        }
     307
     308        $selected = $_second !== null ? ($_second - $_second % $second_interval) : null;
     309        for ($i=0; $i <= 59; $i += $second_interval) {
     310            $_val = sprintf('%02d', $i);
     311            $_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i);
     312            $_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i);
     313            $_html_seconds .= '<option value="' . $_value . '"'
     314                . ($selected === $i ? ' selected="selected"' : '')
     315                . '>' . $_text . '</option>' . $option_separator;
     316        }
     317
     318        $_html_seconds .= '</select>';
     319    }
     320
     321    // generate meridian <select>
    165322    if ($display_meridian && !$use_24_hours) {
    166         $html_result .= '<select name=';
    167         if (null !== $field_array) {
    168             $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
    169         } else {
    170             $html_result .= '"' . $prefix . 'Meridian"';
    171         }
    172        
    173         if (null !== $meridian_extra){
    174             $html_result .= ' ' . $meridian_extra;
    175         }
    176         if (null !== $all_extra){
    177             $html_result .= ' ' . $all_extra;
    178         }
    179         $html_result .= '>'."\n";
    180        
    181         $html_result .= smarty_function_html_options(array('output'          => array('AM', 'PM'),
    182                                                            'values'          => array('am', 'pm'),
    183                                                            'selected'      => strtolower(strftime('%p', $time)),
    184                                                            'print_result' => false),
    185                                                      $smarty);
    186         $html_result .= "</select>\n";
    187     }
    188 
    189     return $html_result;
     323        $_html_meridian = '';
     324        $_extra = '';
     325        $_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian');
     326        if ($all_extra) {
     327            $_extra .= ' ' . $all_extra;
     328        }
     329        if ($meridian_extra) {
     330            $_extra .= ' ' . $meridian_extra;
     331        }
     332
     333        $_html_meridian = '<select name="' . $_name . '"';
     334        if ($meridian_id !== null || $all_id !== null) {
     335            $_html_meridian .= ' id="' . smarty_function_escape_special_chars(
     336                $meridian_id !== null ? ( $meridian_id ? $meridian_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name )
     337            ) . '"';
     338        }
     339        if ($meridian_size) {
     340            $_html_meridian .= ' size="' . $meridian_size . '"';
     341        }
     342        $_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator;
     343
     344        if (isset($meridian_empty) || isset($all_empty)) {
     345            $_html_meridian .= '<option value="">' . ( isset($meridian_empty) ? $meridian_empty : $all_empty ) . '</option>' . $option_separator;
     346        }
     347
     348        $_html_meridian .= '<option value="am"'. ($_hour < 12 ? ' selected="selected"' : '') .'>AM</option>' . $option_separator
     349            . '<option value="pm"'. ($_hour < 12 ? '' : ' selected="selected"') .'>PM</option>' . $option_separator
     350            . '</select>';
     351    }
     352
     353    $_html = '';
     354    foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) {
     355        if (isset($$k)) {
     356            if ($_html) {
     357                $_html .= $field_separator;
     358            }
     359            $_html .= $$k;
     360        }
     361    }
     362
     363    return $_html;
    190364}
    191365
    192 /* vim: set expandtab: */
    193 
    194366?>
  • trunk/include/smarty/libs/plugins/function.html_table.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
     
    1414 * Date:     Feb 17, 2003<br>
    1515 * Purpose:  make an html table from an array of data<br>
    16  * Input:<br>
    17  *         - loop = array to loop through
    18  *         - cols = number of columns, comma separated list of column names
    19  *                  or array of column names
    20  *         - rows = number of rows
    21  *         - table_attr = table attributes
    22  *         - th_attr = table heading attributes (arrays are cycled)
    23  *         - tr_attr = table row attributes (arrays are cycled)
    24  *         - td_attr = table cell attributes (arrays are cycled)
    25  *         - trailpad = value to pad trailing cells with
    26  *         - caption = text for caption element
    27  *         - vdir = vertical direction (default: "down", means top-to-bottom)
    28  *         - hdir = horizontal direction (default: "right", means left-to-right)
    29  *         - inner = inner loop (default "cols": print $loop line by line,
    30  *                   $loop will be printed column by column otherwise)
    31  *
    32  *
     16 * Params:
     17 * <pre>
     18 * - loop       - array to loop through
     19 * - cols       - number of columns, comma separated list of column names
     20 *                or array of column names
     21 * - rows       - number of rows
     22 * - table_attr - table attributes
     23 * - th_attr    - table heading attributes (arrays are cycled)
     24 * - tr_attr    - table row attributes (arrays are cycled)
     25 * - td_attr    - table cell attributes (arrays are cycled)
     26 * - trailpad   - value to pad trailing cells with
     27 * - caption    - text for caption element
     28 * - vdir       - vertical direction (default: "down", means top-to-bottom)
     29 * - hdir       - horizontal direction (default: "right", means left-to-right)
     30 * - inner      - inner loop (default "cols": print $loop line by line,
     31 *                $loop will be printed column by column otherwise)
     32 * </pre>
    3333 * Examples:
    3434 * <pre>
     
    3737 * {table loop=$data cols="first,second,third" tr_attr=$colors}
    3838 * </pre>
    39  * @author   Monte Ohrt <monte at ohrt dot com>
     39 *
     40 * @author Monte Ohrt <monte at ohrt dot com>
    4041 * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
    4142 * @author credit to boots <boots dot smarty at yahoo dot com>
    42  * @version  1.1
    43  * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
     43 * @version 1.1
     44 * @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table}
    4445 *          (Smarty online manual)
    45  * @param array
    46  * @param Smarty
     46 * @param array                    $params   parameters
     47 * @param Smarty_Internal_Template $template template object
    4748 * @return string
    4849 */
    49 function smarty_function_html_table($params, &$smarty)
     50function smarty_function_html_table($params, $template)
    5051{
    5152    $table_attr = 'border="1"';
     
    6061    $inner = 'cols';
    6162    $caption = '';
     63    $loop = null;
    6264
    6365    if (!isset($params['loop'])) {
    64         $smarty->trigger_error("html_table: missing 'loop' parameter");
     66        trigger_error("html_table: missing 'loop' parameter",E_USER_WARNING);
    6567        return;
    6668    }
    6769
    68     foreach ($params as $_key=>$_value) {
     70    foreach ($params as $_key => $_value) {
    6971        switch ($_key) {
    7072            case 'loop':
     
    110112    if (empty($params['rows'])) {
    111113        /* no rows specified */
    112         $rows = ceil($loop_count/$cols_count);
     114        $rows = ceil($loop_count / $cols_count);
    113115    } elseif (empty($params['cols'])) {
    114116        if (!empty($params['rows'])) {
    115117            /* no cols specified, but rows */
    116             $cols_count = ceil($loop_count/$rows);
     118            $cols_count = ceil($loop_count / $rows);
    117119        }
    118120    }
     
    128130        $output .= "<thead><tr>\n";
    129131
    130         for ($r=0; $r<$cols_count; $r++) {
     132        for ($r = 0; $r < $cols_count; $r++) {
    131133            $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
    132134            $output .= $cols[$r];
     
    137139
    138140    $output .= "<tbody>\n";
    139     for ($r=0; $r<$rows; $r++) {
     141    for ($r = 0; $r < $rows; $r++) {
    140142        $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
    141         $rx =  ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
     143        $rx = ($vdir == 'down') ? $r * $cols_count : ($rows-1 - $r) * $cols_count;
    142144
    143         for ($c=0; $c<$cols_count; $c++) {
    144             $x =  ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
    145             if ($inner!='cols') {
     145        for ($c = 0; $c < $cols_count; $c++) {
     146            $x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count-1 - $c;
     147            if ($inner != 'cols') {
    146148                /* shuffle x to loop over rows*/
    147                 $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
     149                $x = floor($x / $cols_count) + ($x % $cols_count) * $rows;
    148150            }
    149151
    150             if ($x<$loop_count) {
     152            if ($x < $loop_count) {
    151153                $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
    152154            } else {
     
    158160    $output .= "</tbody>\n";
    159161    $output .= "</table>\n";
    160    
     162
    161163    return $output;
    162164}
    163165
    164 function smarty_function_html_table_cycle($name, $var, $no) {
    165     if(!is_array($var)) {
     166function smarty_function_html_table_cycle($name, $var, $no)
     167{
     168    if (!is_array($var)) {
    166169        $ret = $var;
    167170    } else {
    168171        $ret = $var[$no % count($var)];
    169172    }
    170    
    171     return ($ret) ? ' '.$ret : '';
     173
     174    return ($ret) ? ' ' . $ret : '';
    172175}
    173176
    174 
    175 /* vim: set expandtab: */
    176 
    177177?>
  • trunk/include/smarty/libs/plugins/function.mailto.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFunction
    67 */
    7 
    88
    99/**
     
    1313 * Name:     mailto<br>
    1414 * Date:     May 21, 2002
    15  * Purpose:  automate mailto address link creation, and optionally
    16  *           encode them.<br>
    17  * Input:<br>
    18  *         - address = e-mail address
    19  *         - text = (optional) text to display, default is address
    20  *         - encode = (optional) can be one of:
    21  *                * none : no encoding (default)
    22  *                * javascript : encode with javascript
    23  *                * javascript_charcode : encode with javascript charcode
    24  *                * hex : encode with hexidecimal (no javascript)
    25  *         - cc = (optional) address(es) to carbon copy
    26  *         - bcc = (optional) address(es) to blind carbon copy
    27  *         - subject = (optional) e-mail subject
    28  *         - newsgroups = (optional) newsgroup(s) to post to
    29  *         - followupto = (optional) address(es) to follow up to
    30  *         - extra = (optional) extra tags for the href link
    31  *
     15 * Purpose:  automate mailto address link creation, and optionally encode them.<br>
     16 * Params:
     17 * <pre>
     18 * - address    - (required) - e-mail address
     19 * - text       - (optional) - text to display, default is address
     20 * - encode     - (optional) - can be one of:
     21 *                             * none : no encoding (default)
     22 *                             * javascript : encode with javascript
     23 *                             * javascript_charcode : encode with javascript charcode
     24 *                             * hex : encode with hexidecimal (no javascript)
     25 * - cc         - (optional) - address(es) to carbon copy
     26 * - bcc        - (optional) - address(es) to blind carbon copy
     27 * - subject    - (optional) - e-mail subject
     28 * - newsgroups - (optional) - newsgroup(s) to post to
     29 * - followupto - (optional) - address(es) to follow up to
     30 * - extra      - (optional) - extra tags for the href link
     31 * </pre>
    3232 * Examples:
    3333 * <pre>
     
    3939 * {mailto address="me@domain.com" extra='class="mailto"'}
    4040 * </pre>
    41  * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
     41 *
     42 * @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto}
    4243 *          (Smarty online manual)
    43  * @version  1.2
    44  * @author   Monte Ohrt <monte at ohrt dot com>
    45  * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
    46  * @param    array
    47  * @param    Smarty
    48  * @return   string
     44 * @version 1.2
     45 * @author Monte Ohrt <monte at ohrt dot com>
     46 * @author credits to Jason Sweat (added cc, bcc and subject functionality)
     47 * @param array                    $params   parameters
     48 * @param Smarty_Internal_Template $template template object
     49 * @return string
    4950 */
    50 function smarty_function_mailto($params, &$smarty)
     51function smarty_function_mailto($params, $template)
    5152{
     53    static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
    5254    $extra = '';
    5355
    5456    if (empty($params['address'])) {
    55         $smarty->trigger_error("mailto: missing 'address' parameter");
     57        trigger_error("mailto: missing 'address' parameter",E_USER_WARNING);
    5658        return;
    5759    } else {
     
    6062
    6163    $text = $address;
    62 
    6364    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
    6465    // so, don't encode it.
    6566    $search = array('%40', '%2C');
    66     $replace  = array('@', ',');
     67    $replace = array('@', ',');
    6768    $mail_parms = array();
    68     foreach ($params as $var=>$value) {
     69    foreach ($params as $var => $value) {
    6970        switch ($var) {
    7071            case 'cc':
     
    7273            case 'followupto':
    7374                if (!empty($value))
    74                     $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
     75                    $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
    7576                break;
    76                
     77
    7778            case 'subject':
    7879            case 'newsgroups':
    79                 $mail_parms[] = $var.'='.rawurlencode($value);
     80                $mail_parms[] = $var . '=' . rawurlencode($value);
    8081                break;
    8182
     
    8889    }
    8990
    90     $mail_parm_vals = '';
    91     for ($i=0; $i<count($mail_parms); $i++) {
    92         $mail_parm_vals .= (0==$i) ? '?' : '&';
    93         $mail_parm_vals .= $mail_parms[$i];
     91    if ($mail_parms) {
     92        $address .= '?' . join('&', $mail_parms);
    9493    }
    95     $address .= $mail_parm_vals;
    96 
     94   
    9795    $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
    98     if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) {
    99         $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
     96    if (!isset($_allowed_encoding[$encode])) {
     97        trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING);
    10098        return;
    10199    }
    102 
    103     if ($encode == 'javascript' ) {
    104         $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
     100    // FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
     101    if ($encode == 'javascript') {
     102        $string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
    105103
    106104        $js_encode = '';
    107         for ($x=0; $x < strlen($string); $x++) {
     105        for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
    108106            $js_encode .= '%' . bin2hex($string[$x]);
    109107        }
    110108
    111         return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>';
     109        return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
     110    } elseif ($encode == 'javascript_charcode') {
     111        $string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
    112112
    113     } elseif ($encode == 'javascript_charcode' ) {
    114         $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
    115 
    116         for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
    117             $ord[] = ord($string[$x]);   
     113        for($x = 0, $y = strlen($string); $x < $y; $x++) {
     114            $ord[] = ord($string[$x]);
    118115        }
    119116
    120         $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n";
    121         $_ret .= "<!--\n";
    122         $_ret .= "{document.write(String.fromCharCode(";
    123         $_ret .= implode(',',$ord);
    124         $_ret .= "))";
    125         $_ret .= "}\n";
    126         $_ret .= "//-->\n";
    127         $_ret .= "</script>\n";
    128        
     117        $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n"
     118            . "{document.write(String.fromCharCode("
     119            . implode(',', $ord)
     120            . "))"
     121            . "}\n"
     122            . "</script>\n";
     123
    129124        return $_ret;
    130        
    131        
    132125    } elseif ($encode == 'hex') {
    133 
    134         preg_match('!^(.*)(\?.*)$!',$address,$match);
    135         if(!empty($match[2])) {
    136             $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
     126        preg_match('!^(.*)(\?.*)$!', $address, $match);
     127        if (!empty($match[2])) {
     128            trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.",E_USER_WARNING);
    137129            return;
    138130        }
    139131        $address_encode = '';
    140         for ($x=0; $x < strlen($address); $x++) {
    141             if(preg_match('!\w!',$address[$x])) {
     132        for ($x = 0, $_length = strlen($address); $x < $_length; $x++) {
     133            if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) {
    142134                $address_encode .= '%' . bin2hex($address[$x]);
    143135            } else {
     
    146138        }
    147139        $text_encode = '';
    148         for ($x=0; $x < strlen($text); $x++) {
    149             $text_encode .= '&#x' . bin2hex($text[$x]).';';
     140        for ($x = 0, $_length = strlen($text); $x < $_length; $x++) {
     141            $text_encode .= '&#x' . bin2hex($text[$x]) . ';';
    150142        }
    151143
    152144        $mailto = "&#109;&#97;&#105;&#108;&#116;&#111;&#58;";
    153         return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
    154 
     145        return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
    155146    } else {
    156147        // no encoding
    157         return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
    158 
     148        return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
    159149    }
    160 
    161150}
    162151
    163 /* vim: set expandtab: */
    164 
    165152?>
  • trunk/include/smarty/libs/plugins/function.math.php

    r3584 r23384  
    22/**
    33 * Smarty plugin
     4 *
     5 * This plugin is only for Smarty2 BC
    46 * @package Smarty
    5  * @subpackage plugins
     7 * @subpackage PluginsFunction
    68 */
    7 
    89
    910/**
     
    1213 * Type:     function<br>
    1314 * Name:     math<br>
    14  * Purpose:  handle math computations in template<br>
    15  * @link http://smarty.php.net/manual/en/language.function.math.php {math}
     15 * Purpose:  handle math computations in template
     16 *
     17 * @link http://www.smarty.net/manual/en/language.function.math.php {math}
    1618 *          (Smarty online manual)
    1719 * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param array
    19  * @param Smarty
    20  * @return string
     20 * @param array                    $params   parameters
     21 * @param Smarty_Internal_Template $template template object
     22 * @return string|null
    2123 */
    22 function smarty_function_math($params, &$smarty)
     24function smarty_function_math($params, $template)
    2325{
     26    static $_allowed_funcs = array(
     27        'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true,
     28        'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true,
     29        'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true ,'tan' => true
     30    );
    2431    // be sure equation parameter is present
    2532    if (empty($params['equation'])) {
    26         $smarty->trigger_error("math: missing equation parameter");
     33        trigger_error("math: missing equation parameter",E_USER_WARNING);
    2734        return;
    2835    }
    2936
    30     // strip out backticks, not necessary for math
    31     $equation = str_replace('`','',$params['equation']);
     37    $equation = $params['equation'];
    3238
    3339    // make sure parenthesis are balanced
    3440    if (substr_count($equation,"(") != substr_count($equation,")")) {
    35         $smarty->trigger_error("math: unbalanced parenthesis");
     41        trigger_error("math: unbalanced parenthesis",E_USER_WARNING);
    3642        return;
    3743    }
    3844
    3945    // match all vars in equation, make sure all are passed
    40     preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match);
    41     $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
    42                            'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
    43    
     46    preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match);
     47
    4448    foreach($match[1] as $curr_var) {
    45         if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
    46             $smarty->trigger_error("math: function call $curr_var not allowed");
     49        if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) {
     50            trigger_error("math: function call $curr_var not allowed",E_USER_WARNING);
    4751            return;
    4852        }
     
    5357            // make sure value is not empty
    5458            if (strlen($val)==0) {
    55                 $smarty->trigger_error("math: parameter $key is empty");
     59                trigger_error("math: parameter $key is empty",E_USER_WARNING);
    5660                return;
    5761            }
    5862            if (!is_numeric($val)) {
    59                 $smarty->trigger_error("math: parameter $key: is not numeric");
     63                trigger_error("math: parameter $key: is not numeric",E_USER_WARNING);
    6064                return;
    6165            }
     
    6367        }
    6468    }
    65 
     69    $smarty_math_result = null;
    6670    eval("\$smarty_math_result = ".$equation.";");
    6771
     
    7074            return $smarty_math_result;
    7175        } else {
    72             $smarty->assign($params['assign'],$smarty_math_result);
     76            $template->assign($params['assign'],$smarty_math_result);
    7377        }
    7478    } else {
     
    7680            printf($params['format'],$smarty_math_result);
    7781        } else {
    78             $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
     82            $template->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
    7983        }
    8084    }
    8185}
    8286
    83 /* vim: set expandtab: */
    84 
    8587?>
  • trunk/include/smarty/libs/plugins/modifier.capitalize.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsModifier
    67 */
    7 
    88
    99/**
    1010 * Smarty capitalize modifier plugin
    11  *
     11 * 
    1212 * Type:     modifier<br>
    1313 * Name:     capitalize<br>
    1414 * Purpose:  capitalize words in the string
    15  * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
    16  *      capitalize (Smarty online manual)
    17  * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param string
    19  * @return string
     15 *
     16 * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }}
     17 *
     18 * @param string  $string    string to capitalize
     19 * @param boolean $uc_digits also capitalize "x123" to "X123"
     20 * @param boolean $lc_rest   capitalize first letters, lowercase all following letters "aAa" to "Aaa"
     21 * @return string capitalized string
     22 * @author Monte Ohrt <monte at ohrt dot com>
     23 * @author Rodney Rehm
    2024 */
    21 function smarty_modifier_capitalize($string, $uc_digits = false)
     25function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
    2226{
    23     smarty_modifier_capitalize_ucfirst(null, $uc_digits);
    24     return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
    25 }
    26 
    27 function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
    28 {
    29     static $_uc_digits = false;
    30    
    31     if(isset($uc_digits)) {
    32         $_uc_digits = $uc_digits;
    33         return;
     27    if (Smarty::$_MBSTRING) {
     28        if ($lc_rest) {
     29            // uppercase (including hyphenated words)
     30            $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET );
     31        } else {
     32            // uppercase word breaks
     33            $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\2'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $string);
     34        }
     35        // check uc_digits case
     36        if (!$uc_digits) {
     37            if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
     38                foreach($matches[1] as $match) {
     39                    $upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0]));
     40                }
     41            }
     42        }
     43        $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\3'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $upper_string);
     44        return $upper_string;
    3445    }
    3546   
    36     if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
    37         return ucfirst($string[0]);
    38     else
    39         return $string[0];
    40 }
    41 
     47    // lowercase first
     48    if ($lc_rest) {
     49        $string = strtolower($string);
     50    }
     51    // uppercase (including hyphenated words)
     52    $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string);
     53    // check uc_digits case
     54    if (!$uc_digits) {
     55        if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
     56            foreach($matches[1] as $match) {
     57                $upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0]));
     58            }
     59        }
     60    }
     61    $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string);
     62    return $upper_string;
     63}
    4264
    4365?>
  • trunk/include/smarty/libs/plugins/modifier.date_format.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsModifier
    67 */
    78
    89/**
    9  * Include the {@link shared.make_timestamp.php} plugin
    10  */
    11 require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
    12 /**
    1310 * Smarty date_format modifier plugin
    14  *
     11 * 
    1512 * Type:     modifier<br>
    1613 * Name:     date_format<br>
    1714 * Purpose:  format datestamps via strftime<br>
    1815 * Input:<br>
    19  *         - string: input date string
    20  *         - format: strftime format for output
    21  *         - default_date: default date if $string is empty
    22  * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
    23  *          date_format (Smarty online manual)
    24  * @author   Monte Ohrt <monte at ohrt dot com>
    25  * @param string
    26  * @param string
    27  * @param string
    28  * @return string|void
     16 *          - string: input date string
     17 *          - format: strftime format for output
     18 *          - default_date: default date if $string is empty
     19 *
     20 * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual)
     21 * @author Monte Ohrt <monte at ohrt dot com>
     22 * @param string $string       input date string
     23 * @param string $format       strftime format for output
     24 * @param string $default_date default date if $string is empty
     25 * @param string $formatter    either 'strftime' or 'auto'
     26 * @return string |void
    2927 * @uses smarty_make_timestamp()
    3028 */
    31 function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
     29function smarty_modifier_date_format($string, $format=null, $default_date='', $formatter='auto')
    3230{
    33     if ($string != '') {
     31    if ($format === null) {
     32        $format = Smarty::$_DATE_FORMAT;
     33    }
     34    /**
     35    * Include the {@link shared.make_timestamp.php} plugin
     36    */
     37    require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
     38    if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') {
    3439        $timestamp = smarty_make_timestamp($string);
    3540    } elseif ($default_date != '') {
     
    3742    } else {
    3843        return;
     44    }
     45    if($formatter=='strftime'||($formatter=='auto'&&strpos($format,'%')!==false)) {
     46        if (DS == '\\') {
     47            $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
     48            $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
     49            if (strpos($format, '%e') !== false) {
     50                $_win_from[] = '%e';
     51                $_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
     52            }
     53            if (strpos($format, '%l') !== false) {
     54                $_win_from[] = '%l';
     55                $_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
     56            }
     57            $format = str_replace($_win_from, $_win_to, $format);
     58        }
     59        return strftime($format, $timestamp);
     60    } else {
     61        return date($format, $timestamp);
    3962    }
    40     if (DIRECTORY_SEPARATOR == '\\') {
    41         $_win_from = array('%D',       '%h', '%n', '%r',          '%R',    '%t', '%T');
    42         $_win_to   = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
    43         if (strpos($format, '%e') !== false) {
    44             $_win_from[] = '%e';
    45             $_win_to[]   = sprintf('%\' 2d', date('j', $timestamp));
    46         }
    47         if (strpos($format, '%l') !== false) {
    48             $_win_from[] = '%l';
    49             $_win_to[]   = sprintf('%\' 2d', date('h', $timestamp));
    50         }
    51         $format = str_replace($_win_from, $_win_to, $format);
    52     }
    53     return strftime($format, $timestamp);
    54 }
    55 
    56 /* vim: set expandtab: */
     63}
    5764
    5865?>
  • trunk/include/smarty/libs/plugins/modifier.debug_print_var.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage Debug
    67 */
    7 
    88
    99/**
    1010 * Smarty debug_print_var modifier plugin
    11  *
     11 * 
    1212 * Type:     modifier<br>
    1313 * Name:     debug_print_var<br>
    1414 * Purpose:  formats variable contents for display in the console
    15  * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
    16  *          debug_print_var (Smarty online manual)
    17  * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param array|object
    19  * @param integer
    20  * @param integer
    21  * @return string
     15 *
     16 * @author Monte Ohrt <monte at ohrt dot com>
     17 * @param array|object $var     variable to be formatted
     18 * @param integer      $depth   maximum recursion depth if $var is an array
     19 * @param integer      $length  maximum string length if $var is a string
     20 * @return string
    2221 */
    23 function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
     22function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40)
    2423{
    25     $_replace = array(
    26         "\n" => '<i>\n</i>',
     24    $_replace = array("\n" => '<i>\n</i>',
    2725        "\r" => '<i>\r</i>',
    2826        "\t" => '<i>\t</i>'
    29     );
     27        );
    3028
    3129    switch (gettype($var)) {
     
    3432            foreach ($var as $curr_key => $curr_val) {
    3533                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
    36                     . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
    37                     . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
    38                     $depth--;
    39             }
     34                 . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
     35                 . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
     36                $depth--;
     37            } 
    4038            break;
     39           
    4140        case 'object' :
    4241            $object_vars = get_object_vars($var);
     
    4443            foreach ($object_vars as $curr_key => $curr_val) {
    4544                $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
    46                     . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
    47                     . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
    48                     $depth--;
    49             }
     45                 . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
     46                 . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
     47                $depth--;
     48            } 
    5049            break;
     50           
    5151        case 'boolean' :
    5252        case 'NULL' :
     
    6060            } else {
    6161                $results = htmlspecialchars((string) $var);
    62             }
     62            } 
    6363            $results = '<i>' . $results . '</i>';
    6464            break;
     65           
    6566        case 'integer' :
    6667        case 'float' :
    6768            $results = htmlspecialchars((string) $var);
    6869            break;
     70           
    6971        case 'string' :
    7072            $results = strtr($var, $_replace);
    71             if (strlen($var) > $length ) {
    72                 $results = substr($var, 0, $length - 3) . '...';
     73            if (Smarty::$_MBSTRING) {
     74                if (mb_strlen($var, Smarty::$_CHARSET) > $length) {
     75                    $results = mb_substr($var, 0, $length - 3, Smarty::$_CHARSET) . '...';
     76                }
     77            } else {
     78                if (isset($var[$length])) {
     79                    $results = substr($var, 0, $length - 3) . '...';
     80                }
    7381            }
     82
    7483            $results = htmlspecialchars('"' . $results . '"');
    7584            break;
     85           
    7686        case 'unknown type' :
    7787        default :
    7888            $results = strtr((string) $var, $_replace);
    79             if (strlen($results) > $length ) {
    80                 $results = substr($results, 0, $length - 3) . '...';
     89            if (Smarty::$_MBSTRING) {
     90                if (mb_strlen($results, Smarty::$_CHARSET) > $length) {
     91                    $results = mb_substr($results, 0, $length - 3, Smarty::$_CHARSET) . '...';
     92                }
     93            } else {
     94                if (strlen($results) > $length) {
     95                    $results = substr($results, 0, $length - 3) . '...';
     96                }
    8197            }
     98             
    8299            $results = htmlspecialchars($results);
    83     }
     100    } 
    84101
    85102    return $results;
    86 }
    87 
    88 /* vim: set expandtab: */
     103}
    89104
    90105?>
  • trunk/include/smarty/libs/plugins/modifier.escape.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsModifier
    67 */
    7 
    88
    99/**
     
    1212 * Type:     modifier<br>
    1313 * Name:     escape<br>
    14  * Purpose:  Escape the string according to escapement type
    15  * @link http://smarty.php.net/manual/en/language.modifier.escape.php
    16  *          escape (Smarty online manual)
    17  * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param string
    19  * @param html|htmlall|url|quotes|hex|hexentity|javascript
    20  * @return string
     14 * Purpose:  escape string for output
     15 *
     16 * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
     17 * @author Monte Ohrt <monte at ohrt dot com>
     18 * @param string  $string        input string
     19 * @param string  $esc_type      escape type
     20 * @param string  $char_set      character set, used for htmlspecialchars() or htmlentities()
     21 * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
     22 * @return string escaped input string
    2123 */
    22 function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1')
     24function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
    2325{
     26    static $_double_encode = null;
     27    if ($_double_encode === null) {
     28        $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
     29    }
     30   
     31    if (!$char_set) {
     32        $char_set = Smarty::$_CHARSET;
     33    }
     34
    2435    switch ($esc_type) {
    2536        case 'html':
    26             return htmlspecialchars($string, ENT_QUOTES, $char_set);
     37            if ($_double_encode) {
     38                // php >=5.3.2 - go native
     39                return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
     40            } else {
     41                if ($double_encode) {
     42                    // php <5.2.3 - only handle double encoding
     43                    return htmlspecialchars($string, ENT_QUOTES, $char_set);
     44                } else {
     45                    // php <5.2.3 - prevent double encoding
     46                    $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
     47                    $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
     48                    $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
     49                    return $string;
     50                }
     51            }
    2752
    2853        case 'htmlall':
    29             return htmlentities($string, ENT_QUOTES, $char_set);
     54            if (Smarty::$_MBSTRING) {
     55                // mb_convert_encoding ignores htmlspecialchars()
     56                if ($_double_encode) {
     57                    // php >=5.3.2 - go native
     58                    $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
     59                } else {
     60                    if ($double_encode) {
     61                        // php <5.2.3 - only handle double encoding
     62                        $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
     63                    } else {
     64                        // php <5.2.3 - prevent double encoding
     65                        $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
     66                        $string = htmlspecialchars($string, ENT_QUOTES, $char_set);
     67                        $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
     68                        return $string;
     69                    }
     70                }
     71               
     72                // htmlentities() won't convert everything, so use mb_convert_encoding
     73                return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
     74            }
     75
     76            // no MBString fallback
     77            if ($_double_encode) {
     78                return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
     79            } else {
     80                if ($double_encode) {
     81                    return htmlentities($string, ENT_QUOTES, $char_set);
     82                } else {
     83                    $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
     84                    $string = htmlentities($string, ENT_QUOTES, $char_set);
     85                    $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
     86                    return $string;
     87                }
     88            }
    3089
    3190        case 'url':
     
    3392
    3493        case 'urlpathinfo':
    35             return str_replace('%2F','/',rawurlencode($string));
    36            
     94            return str_replace('%2F', '/', rawurlencode($string));
     95
    3796        case 'quotes':
    3897            // escape unescaped single quotes
     
    4099
    41100        case 'hex':
    42             // escape every character into hex
     101            // escape every byte into hex
     102            // Note that the UTF-8 encoded character ä will be represented as %c3%a4
    43103            $return = '';
    44             for ($x=0; $x < strlen($string); $x++) {
     104            $_length = strlen($string);
     105            for ($x = 0; $x < $_length; $x++) {
    45106                $return .= '%' . bin2hex($string[$x]);
    46107            }
    47108            return $return;
    48            
     109
    49110        case 'hexentity':
    50111            $return = '';
    51             for ($x=0; $x < strlen($string); $x++) {
     112            if (Smarty::$_MBSTRING) {
     113                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
     114                $return = '';
     115                foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
     116                    $return .= '&#x' . strtoupper(dechex($unicode)) . ';';
     117                }
     118                return $return;
     119            }
     120            // no MBString fallback
     121            $_length = strlen($string);
     122            for ($x = 0; $x < $_length; $x++) {
    52123                $return .= '&#x' . bin2hex($string[$x]) . ';';
    53124            }
     
    56127        case 'decentity':
    57128            $return = '';
    58             for ($x=0; $x < strlen($string); $x++) {
     129            if (Smarty::$_MBSTRING) {
     130                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
     131                $return = '';
     132                foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
     133                    $return .= '&#' . $unicode . ';';
     134                }
     135                return $return;
     136            }
     137            // no MBString fallback
     138            $_length = strlen($string);
     139            for ($x = 0; $x < $_length; $x++) {
    59140                $return .= '&#' . ord($string[$x]) . ';';
    60141            }
     
    63144        case 'javascript':
    64145            // escape quotes and backslashes, newlines, etc.
    65             return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
    66            
     146            return strtr($string, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/'));
     147
    67148        case 'mail':
    68             // safe way to display e-mail address on a web page
    69             return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string);
    70            
     149            if (Smarty::$_MBSTRING) {
     150                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
     151                return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
     152            }
     153            // no MBString fallback
     154            return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string);
     155
    71156        case 'nonstd':
    72            // escape non-standard chars, such as ms document quotes
    73            $_res = '';
    74            for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
    75                $_ord = ord(substr($string, $_i, 1));
    76                // non-standard char, escape it
    77                if($_ord >= 126){
    78                    $_res .= '&#' . $_ord . ';';
    79                }
    80                else {
    81                    $_res .= substr($string, $_i, 1);
    82                }
    83            }
    84            return $_res;
     157            // escape non-standard chars, such as ms document quotes
     158            $return = '';
     159            if (Smarty::$_MBSTRING) {
     160                require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php');
     161                foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) {
     162                    if ($unicode >= 126) {
     163                        $return .= '&#' . $unicode . ';';
     164                    } else {
     165                        $return .= chr($unicode);
     166                    }
     167                }
     168                return $return;
     169            }
     170
     171            $_length = strlen($string);
     172            for ($_i = 0; $_i < $_length; $_i++) {
     173                $_ord = ord(substr($string, $_i, 1));
     174                // non-standard char, escape it
     175                if ($_ord >= 126) {
     176                    $return .= '&#' . $_ord . ';';
     177                } else {
     178                    $return .= substr($string, $_i, 1);
     179                }
     180            }
     181            return $return;
    85182
    86183        default:
     
    89186}
    90187
    91 /* vim: set expandtab: */
    92 
    93188?>
  • trunk/include/smarty/libs/plugins/modifier.regex_replace.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsModifier
    67 */
    7 
    88
    99/**
     
    1313 * Name:     regex_replace<br>
    1414 * Purpose:  regular expression search/replace
     15 *
    1516 * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
    1617 *          regex_replace (Smarty online manual)
    17  * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param string
    19  * @param string|array
    20  * @param string|array
     18 * @author Monte Ohrt <monte at ohrt dot com>
     19 * @param string       $string   input string
     20 * @param string|array $search   regular expression(s) to search for
     21 * @param string|array $replace  string(s) that should be replaced
    2122 * @return string
    2223 */
     
    2425{
    2526    if(is_array($search)) {
    26       foreach($search as $idx => $s)
    27         $search[$idx] = _smarty_regex_replace_check($s);
     27        foreach($search as $idx => $s) {
     28            $search[$idx] = _smarty_regex_replace_check($s);
     29        }
    2830    } else {
    29       $search = _smarty_regex_replace_check($search);
    30     }       
    31 
     31        $search = _smarty_regex_replace_check($search);
     32    }
    3233    return preg_replace($search, $replace, $string);
    3334}
    3435
     36/**
     37 * @param  string $search string(s) that should be replaced
     38 * @return string
     39 * @ignore
     40 */
    3541function _smarty_regex_replace_check($search)
    3642{
    37     if (($pos = strpos($search,"\0")) !== false)
    38       $search = substr($search,0,$pos);
     43    // null-byte injection detection
     44    // anything behind the first null-byte is ignored
     45    if (($pos = strpos($search,"\0")) !== false) {
     46        $search = substr($search,0,$pos);
     47    }
     48    // remove eval-modifier from $search
    3949    if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) {
    40         /* remove eval-modifier from $search */
    4150        $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]);
    4251    }
     
    4453}
    4554
    46 /* vim: set expandtab: */
    47 
    4855?>
  • trunk/include/smarty/libs/plugins/modifier.replace.php

    r3282 r23384  
    33 * Smarty plugin
    44 * @package Smarty
    5  * @subpackage plugins
     5 * @subpackage PluginsModifier
    66 */
    7 
    87
    98/**
    109 * Smarty replace modifier plugin
    11  *
     10 * 
    1211 * Type:     modifier<br>
    1312 * Name:     replace<br>
    1413 * Purpose:  simple search/replace
    15  * @link http://smarty.php.net/manual/en/language.modifier.replace.php
    16  *          replace (Smarty online manual)
    17  * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param string
    19  * @param string
    20  * @param string
    21  * @return string
     14 *
     15 * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual)
     16 * @author Monte Ohrt <monte at ohrt dot com>
     17 * @author Uwe Tews
     18 * @param string $string  input string
     19 * @param string $search  text to search for
     20 * @param string $replace replacement text
     21 * @return string
    2222 */
    2323function smarty_modifier_replace($string, $search, $replace)
    2424{
     25    if (Smarty::$_MBSTRING) {
     26        require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php');
     27        return smarty_mb_str_replace($search, $replace, $string);
     28    }
     29   
    2530    return str_replace($search, $replace, $string);
    26 }
    27 
    28 /* vim: set expandtab: */
     31}
    2932
    3033?>
  • trunk/include/smarty/libs/plugins/modifier.spacify.php

    r3282 r23384  
    33 * Smarty plugin
    44 * @package Smarty
    5  * @subpackage plugins
     5 * @subpackage PluginsModifier
    66 */
    7 
    87
    98/**
    109 * Smarty spacify modifier plugin
    11  *
     10 * 
    1211 * Type:     modifier<br>
    1312 * Name:     spacify<br>
    1413 * Purpose:  add spaces between characters in a string
    15  * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
    16  *         spacify (Smarty online manual)
    17  * @author   Monte Ohrt <monte at ohrt dot com>
    18  * @param string
    19  * @param string
     14 *
     15 * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual)
     16 * @author Monte Ohrt <monte at ohrt dot com>
     17 * @param string $string       input string
     18 * @param string $spacify_char string to insert between characters.
    2019 * @return string
    2120 */
    2221function smarty_modifier_spacify($string, $spacify_char = ' ')
    2322{
    24     return implode($spacify_char,
    25                    preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
    26 }
    27 
    28 /* vim: set expandtab: */
     23    // well… what about charsets besides latin and UTF-8?
     24    return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY));
     25}
    2926
    3027?>
  • trunk/include/smarty/libs/plugins/modifier.truncate.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsModifier
    67 */
    7 
    8 
     8 
    99/**
    1010 * Smarty truncate modifier plugin
    11  *
     11 * 
    1212 * Type:     modifier<br>
    1313 * Name:     truncate<br>
    1414 * Purpose:  Truncate a string to a certain length if necessary,
    15  *           optionally splitting in the middle of a word, and
    16  *           appending the $etc string or inserting $etc into the middle.
    17  * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
    18  *         truncate (Smarty online manual)
    19  * @author   Monte Ohrt <monte at ohrt dot com>
    20  * @param string
    21  * @param integer
    22  * @param string
    23  * @param boolean
    24  * @param boolean
    25  * @return string
     15 *               optionally splitting in the middle of a word, and
     16 *               appending the $etc string or inserting $etc into the middle.
     17 *
     18 * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual)
     19 * @author Monte Ohrt <monte at ohrt dot com>
     20 * @param string  $string      input string
     21 * @param integer $length      length of truncated text
     22 * @param string  $etc         end string
     23 * @param boolean $break_words truncate at word boundary
     24 * @param boolean $middle      truncate in the middle of text
     25 * @return string truncated string
    2626 */
    27 function smarty_modifier_truncate($string, $length = 80, $etc = '...',
    28                                   $break_words = false, $middle = false)
    29 {
     27function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) {
    3028    if ($length == 0)
    3129        return '';
    3230
    33     if (strlen($string) > $length) {
     31    if (Smarty::$_MBSTRING) {
     32        if (mb_strlen($string, Smarty::$_CHARSET) > $length) {
     33            $length -= min($length, mb_strlen($etc, Smarty::$_CHARSET));
     34            if (!$break_words && !$middle) {
     35                $string = preg_replace('/\s+?(\S+)?$/' . Smarty::$_UTF8_MODIFIER, '', mb_substr($string, 0, $length + 1, Smarty::$_CHARSET));
     36            }
     37            if (!$middle) {
     38                return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc;
     39            }
     40            return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . mb_substr($string, - $length / 2, $length, Smarty::$_CHARSET);
     41        }
     42        return $string;
     43    }
     44   
     45    // no MBString fallback
     46    if (isset($string[$length])) {
    3447        $length -= min($length, strlen($etc));
    3548        if (!$break_words && !$middle) {
    36             $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
     49            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
     50        }
     51        if (!$middle) {
     52            return substr($string, 0, $length) . $etc;
    3753        }
    38         if(!$middle) {
    39             return substr($string, 0, $length) . $etc;
    40         } else {
    41             return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
    42         }
    43     } else {
    44         return $string;
     54        return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2);
    4555    }
    46 }
    47 
    48 /* vim: set expandtab: */
     56    return $string;
     57}
    4958
    5059?>
  • trunk/include/smarty/libs/plugins/outputfilter.trimwhitespace.php

    r3282 r23384  
    22/**
    33 * Smarty plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsFilter
    67 */
    78
     
    910 * Smarty trimwhitespace outputfilter plugin
    1011 *
    11  * File:     outputfilter.trimwhitespace.php<br>
    12  * Type:     outputfilter<br>
    13  * Name:     trimwhitespace<br>
    14  * Date:     Jan 25, 2003<br>
    15  * Purpose:  trim leading white space and blank lines from
    16  *           template source after it gets interpreted, cleaning
    17  *           up code and saving bandwidth. Does not affect
    18  *           <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
    19  * Install:  Drop into the plugin directory, call
    20  *           <code>$smarty->load_filter('output','trimwhitespace');</code>
    21  *           from application.
    22  * @author   Monte Ohrt <monte at ohrt dot com>
    23  * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
    24  * @version  1.3
    25  * @param string
    26  * @param Smarty
     12 * Trim unnecessary whitespace from HTML markup.
     13 *
     14 * @author   Rodney Rehm
     15 * @param string                   $source input string
     16 * @param Smarty_Internal_Template $smarty Smarty object
     17 * @return string filtered output
     18 * @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
    2719 */
    28 function smarty_outputfilter_trimwhitespace($source, &$smarty)
     20function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty)
    2921{
    30     // Pull out the script blocks
    31     preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
    32     $_script_blocks = $match[0];
    33     $source = preg_replace("!<script[^>]*?>.*?</script>!is",
    34                            '@@@SMARTY:TRIM:SCRIPT@@@', $source);
     22    $store = array();
     23    $_store = 0;
     24    $_offset = 0;
    3525
    36     // Pull out the pre blocks
    37     preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
    38     $_pre_blocks = $match[0];
    39     $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
    40                            '@@@SMARTY:TRIM:PRE@@@', $source);
    41    
    42     // Pull out the textarea blocks
    43     preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
    44     $_textarea_blocks = $match[0];
    45     $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
    46                            '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
     26    // Unify Line-Breaks to \n
     27    $source = preg_replace("/\015\012|\015|\012/", "\n", $source);
    4728
    48     // remove all leading spaces, tabs and carriage returns NOT
    49     // preceeded by a php close tag.
    50     $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
     29    // capture Internet Explorer Conditional Comments
     30    if (preg_match_all('#<!--\[[^\]]+\]>.*?<!\[[^\]]+\]-->#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
     31        foreach ($matches as $match) {
     32            $store[] = $match[0][0];
     33            $_length = strlen($match[0][0]);
     34            $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
     35            $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
    5136
    52     // replace textarea blocks
    53     smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
     37            $_offset += $_length - strlen($replace);
     38            $_store++;
     39        }
     40    }
    5441
    55     // replace pre blocks
    56     smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
     42    // Strip all HTML-Comments
     43    // yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
     44    $source = preg_replace( '#<!--.*?-->#ms', '', $source );
    5745
    58     // replace script blocks
    59     smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
     46    // capture html elements not to be messed with
     47    $_offset = 0;
     48    if (preg_match_all('#<(script|pre|textarea)[^>]*>.*?</\\1>#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
     49        foreach ($matches as $match) {
     50            $store[] = $match[0][0];
     51            $_length = strlen($match[0][0]);
     52            $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
     53            $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
     54
     55            $_offset += $_length - strlen($replace);
     56            $_store++;
     57        }
     58    }
     59
     60    $expressions = array(
     61        // replace multiple spaces between tags by a single space
     62        // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
     63        '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
     64        // remove spaces between attributes (but not in attribute values!)
     65        '#(([a-z0-9]\s*=\s*(["\'])[^\3]*?\3)|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \4',
     66        // note: for some very weird reason trim() seems to remove spaces inside attributes.
     67        // maybe a \0 byte or something is interfering?
     68        '#^\s+<#Ss' => '<',
     69        '#>\s+$#Ss' => '>',
     70    );
     71
     72    $source = preg_replace( array_keys($expressions), array_values($expressions), $source );
     73    // note: for some very weird reason trim() seems to remove spaces inside attributes.
     74    // maybe a \0 byte or something is interfering?
     75    // $source = trim( $source );
     76
     77    // capture html elements not to be messed with
     78    $_offset = 0;
     79    if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
     80        foreach ($matches as $match) {
     81            $store[] = $match[0][0];
     82            $_length = strlen($match[0][0]);
     83            $replace = array_shift($store);
     84            $source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length);
     85
     86            $_offset += strlen($replace) - $_length;
     87            $_store++;
     88        }
     89    }
    6090
    6191    return $source;
    6292}
    6393
    64 function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
    65     $_len = strlen($search_str);
    66     $_pos = 0;
    67     for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
    68         if (($_pos=strpos($subject, $search_str, $_pos))!==false)
    69             $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
    70         else
    71             break;
    72 
    73 }
    74 
    7594?>
  • trunk/include/smarty/libs/plugins/shared.escape_special_chars.php

    r3282 r23384  
    22/**
    33 * Smarty shared plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsShared
    67 */
    78
    8 
    9 /**
    10  * escape_special_chars common function
    11  *
    12  * Function: smarty_function_escape_special_chars<br>
    13  * Purpose:  used by other smarty functions to escape
    14  *           special chars except for already escaped ones
    15  * @author   Monte Ohrt <monte at ohrt dot com>
    16  * @param string
    17  * @return string
    18  */
    19 function smarty_function_escape_special_chars($string)
    20 {
    21     if(!is_array($string)) {
    22         $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
    23         $string = htmlspecialchars($string);
    24         $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);
    25     }
    26     return $string;
    27 }
    28 
    29 /* vim: set expandtab: */
     9if (version_compare(PHP_VERSION, '5.2.3', '>=')) {
     10    /**
     11     * escape_special_chars common function
     12     *
     13     * Function: smarty_function_escape_special_chars<br>
     14     * Purpose:  used by other smarty functions to escape
     15     *           special chars except for already escaped ones
     16     *
     17     * @author   Monte Ohrt <monte at ohrt dot com>
     18     * @param string $string text that should by escaped
     19     * @return string
     20     */
     21    function smarty_function_escape_special_chars($string)
     22    {
     23        if (!is_array($string)) {
     24            $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false);
     25        }
     26        return $string;
     27    } 
     28} else {         
     29    /**
     30     * escape_special_chars common function
     31     *
     32     * Function: smarty_function_escape_special_chars<br>
     33     * Purpose:  used by other smarty functions to escape
     34     *           special chars except for already escaped ones
     35     *
     36     * @author   Monte Ohrt <monte at ohrt dot com>
     37     * @param string $string text that should by escaped
     38     * @return string
     39     */
     40    function smarty_function_escape_special_chars($string)
     41    {
     42        if (!is_array($string)) {
     43            $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
     44            $string = htmlspecialchars($string);
     45            $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
     46        }
     47        return $string;
     48    }                                                                                                             
     49}
    3050
    3151?>
  • trunk/include/smarty/libs/plugins/shared.make_timestamp.php

    r3282 r23384  
    22/**
    33 * Smarty shared plugin
     4 *
    45 * @package Smarty
    5  * @subpackage plugins
     6 * @subpackage PluginsShared
    67 */
    7 
    88
    99/**
    1010 * Function: smarty_make_timestamp<br>
    11  * Purpose:  used by other smarty functions to make a timestamp
    12  *           from a string.
     11 * Purpose:  used by other smarty functions to make a timestamp from a string.
     12 *
    1313 * @author   Monte Ohrt <monte at ohrt dot com>
    14  * @param string
    15  * @return string
     14 * @param DateTime|int|string $string  date object, timestamp or string that can be converted using strtotime()
     15 * @return int
    1616 */
    1717function smarty_make_timestamp($string)
    1818{
    19     if(empty($string)) {
     19    if (empty($string)) {
    2020        // use "now":
    21         $time = time();
    22 
    23     } elseif (preg_match('/^\d{14}$/', $string)) {
    24         // it is mysql timestamp format of YYYYMMDDHHMMSS?           
    25         $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
     21        return time();
     22    } elseif ($string instanceof DateTime) {
     23        return $string->getTimestamp();
     24    } elseif (strlen($string) == 14 && ctype_digit($string)) {
     25        // it is mysql timestamp format of YYYYMMDDHHMMSS?
     26        return mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2),
    2627                       substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4));
    27        
    2828    } elseif (is_numeric($string)) {
    2929        // it is a numeric string, we handle it as timestamp
    30         $time = (int)$string;
    31        
     30        return (int) $string;
    3231    } else {
    3332        // strtotime should handle it
     
    3534        if ($time == -1 || $time === false) {
    3635            // strtotime() was not able to parse $string, use "now":
    37             $time = time();
     36            return time();
    3837        }
     38        return $time;
    3939    }
    40     return $time;
    41 
    4240}
    4341
    44 /* vim: set expandtab: */
    45 
    4642?>
  • trunk/include/template.class.php

    r23263 r23384  
    5757
    5858    $this->scriptLoader = new ScriptLoader;
    59     $this->smarty = new Smarty;
     59    $this->smarty = new SmartyBC;
    6060    $this->smarty->debugging = $conf['debug_template'];
    6161    $this->smarty->compile_check = $conf['template_compile_check'];
     
    8686    mkgetdir( $compile_dir );
    8787
    88     $this->smarty->compile_dir = $compile_dir;
    89 
    90     $this->smarty->assign_by_ref( 'pwg', new PwgTemplateAdapter() );
     88    $this->smarty->setCompileDir($compile_dir);
     89
     90    $this->smarty->assign( 'pwg', new PwgTemplateAdapter() );
    9191    $this->smarty->register_modifier( 'translate', array('Template', 'mod_translate') );
    9292    $this->smarty->register_modifier( 'explode', array('Template', 'mod_explode') );
     
    106106    }
    107107
    108     $this->smarty->template_dir = array();
     108    $this->smarty->setTemplateDir(array());
    109109    if ( !empty($theme) )
    110110    {
     
    166166  function set_template_dir($dir)
    167167  {
    168     $this->smarty->template_dir[] = $dir;
     168    $this->smarty->addTemplateDir($dir);
    169169
    170170    if (!isset($this->smarty->compile_id))
     
    181181  function get_template_dir()
    182182  {
    183     return $this->smarty->template_dir;
     183    return $this->smarty->getTemplateDir();
    184184  }
    185185
     
    191191      $save_compile_id = $this->smarty->compile_id;
    192192      $this->smarty->compile_id = null;
    193       $this->smarty->clear_compiled_tpl();
     193      $this->smarty->clearCompiledTemplate();
    194194      $this->smarty->compile_id = $save_compile_id;
    195       file_put_contents($this->smarty->compile_dir.'/index.htm', 'Not allowed!');
     195      file_put_contents($this->smarty->getCompileDir().'/index.htm', 'Not allowed!');
    196196  }
    197197
    198198  function get_themeconf($val)
    199199  {
    200     $tc = $this->smarty->get_template_vars('themeconf');
     200    $tc = $this->smarty->getTemplateVars('themeconf');
    201201    return isset($tc[$val]) ? $tc[$val] : '';
    202202  }
     
    341341
    342342  /** see smarty get_template_vars http://www.smarty.net/manual/en/api.get_template_vars.php */
    343   function &get_template_vars($name=null)
    344   {
    345     return $this->smarty->get_template_vars( $name );
     343  function get_template_vars($name=null)
     344  {
     345    return $this->smarty->getTemplateVars( $name );
    346346  }
    347347
     
    370370    }
    371371
    372     $v = $this->smarty->fetch($this->files[$handle], null, null, false);
     372    $v = $this->smarty->fetch($this->files[$handle]);
    373373
    374374    $this->smarty->compile_id = $save_compile_id;
     
    486486        )
    487487        );
    488       require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php');
    489       echo smarty_core_display_debug_console(null, $this->smarty);
     488      Smarty_Internal_Debug::display_debug($this->smarty);
    490489    }
    491490  }
     
    590589    if (!isset($params['id']))
    591590    {
    592       $this->smarty->trigger_error("combine_script: missing 'id' parameter", E_USER_ERROR);
     591      trigger_error("combine_script: missing 'id' parameter", E_USER_ERROR);
    593592    }
    594593    $load = 0;
     
    600599        case 'footer': $load=1; break;
    601600        case 'async': $load=2; break;
    602         default: $this->smarty->trigger_error("combine_script: invalid 'load' parameter", E_USER_ERROR);
     601        default: trigger_error("combine_script: invalid 'load' parameter", E_USER_ERROR);
    603602      }
    604603    }
     
    615614    if (!isset($params['load']))
    616615    {
    617       $this->smarty->trigger_error("get_combined_scripts: missing 'load' parameter", E_USER_ERROR);
     616      trigger_error("get_combined_scripts: missing 'load' parameter", E_USER_ERROR);
    618617    }
    619618    $load = $params['load']=='header' ? 0 : 1;
     
    712711  function func_get_combined_css($params)
    713712  {
    714     return 'echo '.var_export(self::COMBINED_CSS_TAG,true);
     713    return self::COMBINED_CSS_TAG;
    715714  }
    716715
     
    778777  }
    779778
    780   static function prefilter_white_space($source, &$smarty)
     779  static function prefilter_white_space($source, $smarty)
    781780  {
    782781    $ld = $smarty->left_delimiter;
     
    805804   * from templates.
    806805   */
    807   static function prefilter_language($source, &$smarty)
     806  static function prefilter_language($source, $smarty)
    808807  {
    809808    global $lang;
     
    823822  }
    824823
    825   static function prefilter_local_css($source, &$smarty)
     824  static function prefilter_local_css($source, $smarty)
    826825  {
    827826    $css = array();
    828     foreach ($smarty->get_template_vars('themes') as $theme)
     827    foreach ($smarty->getTemplateVars('themes') as $theme)
    829828    {
    830829      $f = PWG_LOCAL_DIR.'css/'.$theme['id'].'-rules.css';
  • trunk/themes/default/template/comment_list.tpl

    r20452 r23384  
    5858
    5959                <span class="commentAuthor">{if $comment.WEBSITE_URL}<a href="{$comment.WEBSITE_URL}" class="external" target="_blank" rel="nofollow">{$comment.AUTHOR}</a>{else}{$comment.AUTHOR}{/if}</span>
    60                         {if $comment.EMAIL}- <a href="mailto:{$comment.EMAIL}">{$comment.EMAIL}</a>{/if}
     60                        {if isset($comment.EMAIL)}- <a href="mailto:{$comment.EMAIL}">{$comment.EMAIL}</a>{/if}
    6161                        - <span class="commentDate">{$comment.DATE}</span>
    6262                {if isset($comment.IN_EDIT)}
  • trunk/themes/default/template/index.tpl

    r23320 r23384  
    9494                </a>{/strip}</li>
    9595{/if}
    96 {foreach from=$PLUGIN_INDEX_BUTTONS item=button}<li>{$button}</li>{/foreach}
     96{if isset($PLUGIN_INDEX_BUTTONS)}{foreach from=$PLUGIN_INDEX_BUTTONS item=button}<li>{$button}</li>{/foreach}{/if}
    9797{if !empty($PLUGIN_INDEX_ACTIONS)}{$PLUGIN_INDEX_ACTIONS}{/if}
    9898        </ul>
  • trunk/themes/default/template/menubar_categories.tpl

    r12671 r23384  
    1515  {else}
    1616    </li>
    17     {'</ul></li>'|@str_repeat:$ref_level-$cat.LEVEL}
     17    {'</ul></li>'|@str_repeat:($ref_level-$cat.LEVEL)}
    1818  {/if}
    1919    <li {if $cat.SELECTED}class="selected"{/if}>
  • trunk/themes/default/template/picture.tpl

    r23320 r23384  
    7070        </a>
    7171{/if}{/strip}
    72 {foreach from=$PLUGIN_PICTURE_BUTTONS item=button}{$button}{/foreach}
     72{if isset($PLUGIN_PICTURE_BUTTONS)}{foreach from=$PLUGIN_PICTURE_BUTTONS item=button}{$button}{/foreach}{/if}
    7373{if isset($PLUGIN_PICTURE_ACTIONS)}{$PLUGIN_PICTURE_ACTIONS}{/if}
    7474{strip}{if isset($favorite)}
Note: See TracChangeset for help on using the changeset viewer.