diff options
author | rvelices <rv-github@modusoptimus.com> | 2013-06-20 03:38:47 +0000 |
---|---|---|
committer | rvelices <rv-github@modusoptimus.com> | 2013-06-20 03:38:47 +0000 |
commit | 6fc07742f8fca9d32db23243d374ea27e8ee4c1e (patch) | |
tree | bc7240c53a1c6bdff6c785153deb6306585c4062 /include/smarty | |
parent | 9843eb362dd7d1b9d762871777ef76fa84e8202a (diff) |
smarty 3 - first pass for tests
git-svn-id: http://piwigo.org/svn/trunk@23384 68402e56-0260-453c-a942-63ccdbb3a9ee
Diffstat (limited to '')
172 files changed, 26414 insertions, 9496 deletions
diff --git a/include/smarty/COPYING.lib b/include/smarty/COPYING.lib index 3b204400c..02bbb60bc 100644 --- a/include/smarty/COPYING.lib +++ b/include/smarty/COPYING.lib @@ -1,458 +1,165 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library.
\ No newline at end of file diff --git a/include/smarty/NEWS b/include/smarty/NEWS deleted file mode 100644 index cbab78f5a..000000000 --- a/include/smarty/NEWS +++ /dev/null @@ -1,1067 +0,0 @@ -Version 2.6.26 (June 18th, 2009) -------------------------------- -- revert super global access changes, and instead rely on - USE_SUPER_GLOBALS for security - -Version 2.6.25 (May 19th, 2009) -------------------------------- -- fix E_NOTICE when sessions are disabled (mohrt) - -Version 2.6.24 (May 16th, 2009) -------------------------------- -- fix problem introduced with super global changes (mohrt) - -Version 2.6.23 (May 13th, 2009) -------------------------------- -- strip backticks from {math} equations (mohrt) -- make PHP super globals read-only from template (mohrt) -- throw error when template exists but not readable (mohrt) - -Version 2.6.22 (Dec 17th, 2008) -------------------------------- - -- back out method chaining, bug in some versions of PCRE causes errors (mohrt) - -Version 2.6.21 (Dec 2nd, 2008) ------------------------------- - -- fix function injection security hole closed (U.Tews) -- fix pass expiration time at cache_handler_fuc call in core.write_cache_file.php (U.Tews) -- Update of compiler.class.php to allow method chaining for PHP4 and PHP5 (U.Tews) - -Version 2.6.20 (Feb 15th, 2008) -------------------------------- - -- fix cache tag bug when multiple cache tags on a page (mankyd, - mohrt) -- fix /e tag checking when using arrays with regex_replace - (mohrt) -- fix that function results can be used with condition like "is even" in - {if} tags (U.Tews) -- fix handling of non-empty <pre>-tags and empty <textarea>- and - <script>-tags (Spuerhund, messju) - -Version 2.6.19 (Feb 11th, 2008) -------------------------------- - -- fix regex_replace allowing \0 in the search string (c960657, - monte) -- add append feature to {capture} (jablko, monte) -- fix when (un)registering filters with the same method name but different class - name (danilo) -- fix calling registered objects' methods with an empty argument list - (marcello, messju) - -Version 2.6.18 (Mar 7th, 2007) ------------------------------- - -- fix html_select_date separator when parts are missing (hayk, - monte) -- fix broken detection of non-cached blocks introduced in 2.6.17 - (messju) - -Version 2.6.17 (Mar 5th, 2007) ------------------------------- - -- fix php handling (monte, boots, danilo) -- fix handling of plugin tags directly followed by an else tag (Fahr, danilo) -- fix handling of $etc in the truncate modifier when $etc is longer - than $length (Sylvinus, messju) -- fix handling of %I with mysql timestamps in the date_format modifier - (danilo, boots) -- update smarty_core_write_file() and smarty_modifier_date_format() to better - recognize Windows (boots, danilo) -- emulate %h, %n, %r, %R, %t in the date_format modifier on Windows - (danilo, boots) - -Version 2.6.16 (Dec 1st, 2006) ------------------------------- - -- fixed replacement bug in trimwhitespace output filter that was introduced - in the last release (Spuerhund, boots) - -Version 2.6.15 (Nov 30th, 2006) -------------------------------- - -- change file writing semantics in smarty_core_write_file() to unlink() only - when rename() fails or a Windows system is detected (c960657, boots) -- update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug - output and apply a Smarty based color scheme (cybot, boots) -- enhance reporting precision of debug_print_var modifier (cybot, boots) -- make html_select_date work consistently with 0000-00-00 00:00:00 and - 0000-00-00 inputs (cybot, boots) -- fix wrong handling of insert's name attribute. (messju) -- fix false replacement of "$t" inside double quotes (checat, messju) -- added support for column headings and caption element to html_table and - updated the output to use thead/tbody elements (boots) -- fixed ordering of replacements in trimwhitespace output filter (Getty, boots) -- update mailto function plugin to work around a firefox/thunderbird - escaping bug (elijahlofgren, boots) -- emulate %l in the date_format modifier on windows (boots) -- fix handling of apostrophes in capitalize modifier (Alec Smecher, boots) - -Version 2.6.14 (May 28th, 2006) -------------------------------- - -- fix compiler bug allowing php tags in secure templates - (boots,monte) -- un-hide hidden xml open tags (boots) -- fix handling of block-methods of registered objects (El Hombre Gris, - messju) - -Version 2.6.13 (March 9th, 2006) --------------------------------- - - - update regex_replace, removing possible use of "e" modifier - -Version 2.6.12 (Jan 18th, 2006) -------------------------------- - - - fix improper use of references in the compiler handling cached - attributes and in compiled code handling block plugins (messju) - - make Smarty::_read_file() work on latest php (messju) - - fixed improper tokenization of certain inline math expressions (boots) - -Version 2.6.11 (Dec 14, 2005) ------------------------------ - - - fixed code generation of non-cacheable blocks to play well with php's - "Alternative syntax for control structures" (kihara, messju) - - fix handling of multiple identical inserts in one display()-call (messju) - - replace {} string access with equivalent substr() to avoid E_STRICT - warnings in PHP 5.1 (boots) - - return valid reference in get_config_vars() when given var is - non-existant (Thomas Schulz, boots) - - plugin html_image: fix incorrect secure_dir error when - file doesn't exist (monte) - - plugin html_image: add path_prefix param (monte) - - add char_set parameter to escape modifier (Loading, monte) - - fix notice in debug security check (Drakla, monte) - - return valid reference in get_template_vars() when given var is - non-existant (monte) - - add escape type "urlpathinfo" to escape modifier (monte) - -Version 2.6.10 (Aug 5, 2005) ----------------------------- - - - allow secure_dir to be a filename, not just - a directory name (monte) - - set debug.tpl as a secure_dir, not the entire - SMARTY_DIR (monte) - - fix proper escaping for literal strings in - Smarty_Compiler::_parse_var_props() (boots, messju) - - remove ambiguity for numeric values passed to smarty_make_timestamp() - (and thus the date_format modifier). numeric values are treated as - timestamps now. (andreas, messju) - - add passthru attribute feature to html_select_date (Sedgar, - monte) - - add "middle" parameter to truncate (monte) - - make form input label ids optional (monte) - - add error message for empty if/elseif statements (eykanal, - monte) - - cast selected value to string for comparison in html_radios - (Exeption, monte) - - updated html_select_date's year_as_text-feature to be xhtml compliant - (Mark West, messju) - - fix handling of selected month html_select_date (Yuri Weseman, messju) - -Version 2.6.9 (Mar 31, 2005) ----------------------------- - - - disallow variable function calls in {if} statements (messju, monte) - - disallow variable function calls in {math} equations (messju, monte) - -Version 2.6.8 (Mar 21, 2005) ----------------------------- - - - remove e-modifier from regex_replace modifier (messju) - - remove cast of object to array in foreach's from-attribute (messju) - - add "null" as a valid token for {if} when security is enabled (messju) - - add javascript_charcode encoding option to mailto function - (monte) - - add ids to html_radios labels (monte, menulis) - - fix handling of strip-tags with non-default delimiters (Mark West, messju) - -Version 2.6.7 (Feb 3, 2005) ---------------------------- - - - fix handling of hashed opening php-tags inside strip-blocks (messju) - - removed border tag from html_image function (monte) - - change escape:url use rawurlencode() instead of urlencode() (messju) - - make $smarty.const.FOO compile to "FOO", and not to "constant('foo')". - this is less code and a little faster execution. note that undefined - constants are now displayed as the constant's name. (messju) - - make block functions and registered objects' block methods use a - local variable for block_content instead of a property of $smarty (messju) - - fix escaping in the generated code that calls smarty_core_load_plugins - (jes5199, messju) - - fix invalid HTML issue with popup (Stefanos Harhalakis, - Monte) - - fixed {popup} to properly handle inarray and function parameters and added - support for mouseoff and followmouse options (boots) - -Version 2.6.6 (Oct 13, 2004) ----------------------------- - - - fixed nocache-handling with nested includes (Lars Jankowfsky, messju) - - moved /libs/core to /libs/internals (boots) - - fixed more parsing problems (messju) - -Version 2.6.5 (Sept 13, 2004) ------------------------------ - - - fixed some parsing problems with object calls introduced - in 2.6.4 (Monte) - - add $smarty->security_settings['ALLOW_CONSTANTS']. note: this - defaults to false which means you have to allow them explicitly - in your secured templates from now on! (messju) - -Version 2.6.4 (Sept 7, 2004) ----------------------------- - - - add $smarty.ldelim and $smarty.rdelim to smarty special var (Monte) - - fall back to old uniqid()-behaviour when tempnam() fails in - core.write_file.php (messju) - - fix capitalize modifier, don't rely on buggy ucwords (Monte) - - make html_select_date work with negative timestamps, also - force year range to include given date unless explicitly - set (Garo, Monte) - - fix bug with {fetch}, passing user/pass in url did not work - (Monte) - - fix occasional wrong error messages on mismatched tags when - {else}, {elseif}, {foreachelse} or {sectionelse} is involved (messju) - - fix handling of methods arguments (messju, Manfred Wischin) - - remove touch() call that made the compiled-template's timestamp the - same as the source-template's one. (messju) - - add assign attribute to html_checkboxes and html_radios - (pcg, Monte) - - remove non-xhtml conformant tag from mailto function - (tacker, Monte) - - handle date_format codes %e, %T and %D for windows (tip, - Monte) - - fix unnecessary call to smarty_core_get_include_path() inside - Smarty::_get_auto_filename() (c960657, messju) - - add error-messages when anything else than an identifier is passed - to foreach's key- or item-attribute (messju) - - fix handling of digits inside tagnames (messju) - - fix escaping of backslashes in Smarty_Compiler::_quote_replace() (messju) - -Version 2.6.3 (June 16, 2004) ------------------------------ - - - added escapement of '</' to '<\/' in escape:javascript - modifier (c960657, Monte) - - added obfuscation of protocol-string in {mailto} when using hex- - encoding (bharat, messju) - - enhanced auto-generated filenames for templates_c and cache (messju) - - add 'nonstd' to escape modifier for escaping non-std chars, - such as ms doc quote (Monte) - - adjusted textformat to not output wrap chars after last para - (Monte) - - use tempnam() instead of unqid() to create better temporary files in - smarty_core_write_file() (xces, messju) - - add 'mail' to escape modifier for safe display of e-mail - addresses (Monte) - - add cycle function attribute "reset" to english docs (Monte) - - enhanced support of numeric constants as variable-expressions (messju) - - add case decentity to smarty_modifier_escape() (Konstantin A. Pelepelin, - messju) - - make smarty_core_write_compiled_include() php5-aware (messju) - - removed unused functionality to load a subset of lines from a file (messju) - - fix is_secure() should only check if a file is_readable, not if - the directory where it is in is readable (sagi, messju) - - fix problem displaying debug console when $default_resource_type - is not "file:" (c960657, Monte) - - fix permission handling with security and config_load (messju) - - removed '.' from the list of default template locations in - _parse_resource_name() (messju) - - fix avoid warning with template_exists() on an absolute paths (messju) - - fix parameters passed to resource's secure()-function (messju) - - fix handling of integer values like width and delay im - smarty_function_popup() (messju) - -Version 2.6.2 (Feb 17, 2004) ----------------------------- - - - fix allow empty years, months and days in html_select_date's - time-attribute (messju) - - fix YES and NO should not be booleanized inside triple-quotes in a - config-file (messju) - - fix accidently slurped line following a triple-quoted value in a - config-file (messju) - - change default for use_sub_dirs to false (messju) - - fix quoting of values in smarty_function_popup() (messju) - - fix handling of hidden sections in Config_File (messju) - - add handling of resources for {config_load} (messju) - - fix bug when using arrays with tr_attr and td_attr in {html_table} (messju) - - add unit testing to cvs core (Monte) - -Version 2.6.1 (Jan 16, 2004) ----------------------------- - - - rename $smarty->tpl_error_reporting to $smarty->error_reporting - (messju) - - fix interpretation of $smarty->security in {html_image} (messju) - - add caching of requested paths to _assemble_plugin_filepath() (messju) - - fix handling of comments inside {php}- and {literal}-blocks (messju) - - fix bug handling triple-quotes in config-files (BRDude, messju) - - change default of request_use_auto_globals to true - $_SERVER is - now preferred over $HTTP_SERVER_VARS (messju) - - re-add support for $SCRIPT_NAME (messju) - - reactivate $smarty->default_modifiers (messju) - - add cookie persistance to debug console (Monte) - - allow single-digit days and months without smarty_make_timestamp() - in html_select_date (messju) - - fix headers sent erroneously with cache_modified_check and fetch() - (wphilips, messju) - - fix config_file path bug (Marc Cabadas, Monte) - - fix 'is even by' and 'is odd by' logic (Monte) - - add day_empty, month_empty, year_empty and all_empty attributes to - html_select_date (messju) - - add table of explanation for {if} qualifiers in docs (boots) - - fix bug when comparing array-keys to "selected" in html_options - and html_checkboxes (messju) - - add better checks for correctly nested tags when compiling (messju) - - remove {$SCRIPT_NAME}. use {$smarty.server.SCRIPT_NAME} instead (messju) - - remove $global_assign. assign global variables explicitly instead (messju) - - fix example for count_characters in docs (boots) - - add section new basic syntax section "Escaping Smarty Parsing" in docs (boots) - - fix error handler call in config_load (boots) - - remove warning in debug_print_var on php-resources (messju) - - move function.assign.php to compiler.assign.php (messju) - - add property $tpl_error_reporting (messju) - - remove property $undefined. "null" is used literally instead (messju) - -Version 2.6.0 (Nov 19, 2003) ----------------------------- - - - move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() (messju) - - remove import of of attributes of {include_php} to php's namespace. - use $params[name] instead (messju) - -Version 2.6.0-RC3 (Nov 13, 2003) --------------------------------- - - - fix handling of $var.key inside [] (messju) - - fix handling of assign inside {insert}-tags (messju) - - fix handling if [...] inside triple-quotes in config-files (messju) - - fix handling of simple-math-operators inside modifiers (Dominik, messju) - - fix handling of trailing-slashes in open_basedir in - smarty_core_create_dir_structure() (packman, messju) - -Version 2.6.0-RC2 (Oct 8, 2003) -------------------------------- - - - apply modifiers only once to section-loop and foreach-from attrs (messju) - - remove use of _smarty_cached_paths-files (messju) - - remove Smarty::_plugin_implementation_exists() - use is_callable() (messju) - - ignore {strip}/{/strip) inside {strip}-blocks (messju) - - fixed removal of leading/trailing newlines in {strip}-blocks (messju) - - fixed proper escaping of " and ' with escape:javascript (messju) - - fixed bug in traversal of $smarty->plugins_dir-array. now the - first matching plugin is taken (messju) - - moved {strip} back into the compiler (messju) - - fixed config_load: handling of section-attribute and use of - multiple config-files in one template (atu, messju) - -Version 2.6.0-RC1 (August 11, 2003) ------------------------------------ - - - fixed status-header for cache_modified_check under cgi-sapi (messju) - - added optional parameter $cache_attrs to register_function() and - register_block(). $cache_attrs is an array containing attribute- - names that should be cached on calls to functions that have - $cacheable set to false. (messju) - - enabled registration of class-methods as callbacks for the register_*- - functions (use: array('classname', 'method_name')) as callback) (messju) - - added filepath caching (Monte) - - added optional assign-attribute to {capture}-tag (messju) - - added $cacheable-parameter to register_compiler_function() (messju) - - added $cacheable-parameter with default=true to register_function() - and register_block() (messju) - - add math speedup to core (Dominik, Monte) - - fix newlines for tags without template output (Monte) - - added config-option "request_use_auto_globals" to make auto-globals be - used as request vars instead of HTTP_*_VARS (messju) - - speed up config_load, simplify compiling (Monte) - - added block-methods for registered objects (Bharat Mediratta, messju) - - ignore one char resource names like c:foo.tpl (Monte) - - added default_resource_type feature (Monte) - - fix bug where config file starts with hidden section (boots, Monte) - - add discrete error checking pertaining to $cache_dir - and $compile_dir, their existance and writability (Monte) - - fixed behaviour of start=... for {counter} (messju) - - fixed assign for {counter} (messju) - - added params vdir, hdir and inner to html_table to allow looping - over the data in various directions (messju) - - allow spaces in literal tags (Paul Lockaby, Monte) - - speed up compiled templates, hardcode plugin filepaths - instead of dynamically calculate at runtime. (Monte) - - abstract many core components from Smarty.class.php, - speeding up core class instantiation (Monte) - - fixed bug in _create_dir_structure() when used with open_basedir- - restriction and relative paths (messju) - - use DIRECTORY_SEPARATOR exclusively, keep DIR_SEP for BC (Monte) - - changed "link" to "href" in html_image. "link" is still working - but deprecated (messju) - - html_image always renders an alt-tag now (default alt="") (messju) - - fixed assign attribute for multiple counters (messju) - - added simple math operators to variables (Monte) - - enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted') - as callback for register_resource() (messju); - - enabled array(&$obj, 'method') as callback for - $default_template_handler_func (messju) - - remove unnecessary close/open tags from compiled templates - (Monte) - - fixed errornous creation of '//' in image_path in html_image (messju) - - fix escapement of special chars for key vals in debug - console (Monte) - - fixed debug timing logic for config_load (Tom Sommer, Monte) - - all in-code doc comments converted to phpDocumentor format (Greg) - - moved strip from smarty core to plugin (Monte) - - moved config_load from smarty core to plugin (Monte) - - added &$repeat-parameter to block-functions (messju) - - enabled hex-constants in function.math.php (messju) - - enabled hex-constants (0x...) as function-attributes, inside if-statements - and as modifier-parameters (messju) - - fixed bug with passing $smarty as reference in Smarty.compiler.class - (messju) - - corrected output with {strip} and PHP tag newlines (Monte) - - added possibility to register function-callbacks as "array(&$obj, 'method)" - this affects register_function(), -block, -compiler_function, -modifier, - -prefilter, -postfilter, -outputfilter-functions() and $cache_handler_func - (messju) - - added <labels> to html_checkboxes and html_radios (Philippe, messju) - - added "labels"-options to turn off labels in html_checkboxes and _radios - (messju) - -Version 2.5.0 (April 11, 2003) ------------------------------- - - - fixed bug with default modifier when passing integer 0 - (Monte) - - change backtic syntax from $`foo` to `$foo` (Monte) - - recognize $foo[][] syntax inside embedded quotes without - backtics (Monte) - - name=123 is passed as an integer (not a string) to plugins now (messju) - - $length is now propagated to sub-values in debug_print_var (messju) - -Version 2.5.0-RC2 (March 26, 2003) ----------------------------------- - - - made clear_cache() ignore compile_id, when clearing cache-groups (this - is when no $tpl_file is supplied) (messju) - - made onmouseout XHTML-compliant in function.popup.php (messju) - - applied local-var-naming-scheme to fetch() (messju) - - renamed $localvars to $_localvars in cache-file-handling-functions, - added _get_auto_id()-function (messju) - - swapped compile_id and cache_id in read_cache_file and write_cache_file - (messju) - - reverted patch for cache-file-handling (messju) - - made html_radios and html_checkboxes accept "selected" instead - of "checked" optionally. (messju) - - made compile_id ignored in clear_cache, made order of - auto_file_name $cache_id.$compile_id again, applied the the new - variable-naming-scheme for cache_file_handing functions (messju) - - removed notice of undefined var in _rm_auto() (messju) - - added warning message when an array is passed as - the "checked" value of html_radios (Monte) - - fixed errormessage in _compile_smarty_ref() (messju) - - updated docs for html_image "name" -> "file" (messju) - - fixed bug with html_options-optgroups (Nichlas Löfdahl, messju) - - cleaned up calls to readdir() (messju) - - fixed bug with passing multiple modifiers to a parameter - (Monte) - - updated docs for html_checkboxes, html_options and html_radios (messju) - - fixed wrong default "name" attribute for html_options (messju) - - html_checkboxes now expect the options as attribute "options" instead - of "checkboxes. html_radios expect "options" instead of "radios". - cleaned up indentiation (messju) - - fixed too greedy str_replace in trimwhitespace outputfilter (messju) - - html_checkboxes and html_radios passthru all unknown paramters now - additionally their output is now XHTML compliant (messju) - - html_options passthru all unknown paramters now (messju) - - fix link functionality of html_image, also make - output XHTML compatible (Hinrich Donner, Monte) - - append "@" to default modifier vars/args - supress possible warnings (Monte) - - fix problem with escaped double quotes (Monte) - - fix html_radios to not return an array (Monte) - - fixed length in modifier.truncate.php (messju) - - fixed handling of '$'-signs in trimwhitespace outputfilter (messju) - - fix bug that makes config files recompile every time - (Nagger, Monte) - - add dpi functionality to html_image, change "name" - parameter to "file" (Thomas Shulz, Monte) - - fix height/width parameter index in html_image (Gerard, - Monte) - - get rid of unsetting name and script attributes - to insert tag (Thomas Schulz, Monte) - - changed argument order of string_format modifier back, - was right in the first place (Monte) - -Version 2.5.0-RC1 (March 5, 2003) ---------------------------------- - - - fixed notice in popup function (Nagger, Monte) - - fix "once" var compiling for include_php (Monte) - - added nl2br modifier to distribution (Monte) - - added html_image to distribution (Monte) - - added cat modifier to distribution (Monte) - - added html_table to distribution (Monte) - - added << >> <> support to if statments (SMK, Monte) - - fix _assign_smarty_interface to not overwrite keys - other than 'request' (Jerome Poudevigne, Monte) - - added html_checkboxes to distribution (Christopher Kvarme, Monte) - - added html_radios to distribution (Christopher Kvarme, Monte) - - fixed string_format modifier args (wrong order) (Paul - Lockaby, Monte) - - use tmp file for file writes, avoid file lock race (Monte) - - support syntax "$`smarty.config.foo`.tpl" for embedded - vars in quotes, and allow full dollar var syntax (Monte) - - add $smarty.config.varname variable for accessing config vars (Paul - Lockaby, Monte) - - silence PHP warnings in function.fetch.php (Eduardo, - Monte) - - added get_config_vars(), same basic functionality as - get_template_vars() (Monte) - - update get_template_vars() to be able to get - individual vars (Monte) - - fix minor logic in _fetch_template_info (Dennis Gearon, - Monte) - - fix cache groups with compile_id set (Monte) - - add support for merging appended vars (messju, Monte) - - allow null as function attribute value - (André Rabold, Monte) - - support $foo->bar[index] syntax (Monte) - - add get_registered_object function (messju, Monte) - - treat unrecognized param attribute syntax as string (Monte) - - support $smarty.const.$foo syntax (messju, Monte) - - remove E_NOTICE warnings from debug.tpl, - escape modifier (Kanstantin, Monte) - - don't count non-ascii chars in count_words modifier - (Kanstantin, Monte) - - clean up param calls to _parse_var and _parse_attrs (Monte) - - define $template_source var, elude possible warning - (Monte) - - fix syntax problem with evaluating PHP constants (Monte) - - add @ and === as valid if statement tokens (Monte) - - enable error messages for config_load errors, - use $this->config_class for loading class name (Monte) - - fix html_options to not escape already escaped entities (Monte) - - send Last-Modified header on cache creation (Monte) - - check strict syntax of function attributes (Monte) - - dropped support for modifers on object parameters, - added support for objects as modifier parameters (Monte) - - fixed bug with decimal numbers in if statements (Monte) - -Version 2.4.2 (Feb 11, 2003) ----------------------------- - - support embedded variables in objects (Monte) - - fix bug with objects with no properties (M Mohr, Monte) - - support full dollar var syntax in quoted text (Monte) - - fixed bug in $smarty.const.FOO introduced in 2.4.1 (M - Mohr, Monte) - -Version 2.4.1 (Feb 6, 2003) ---------------------------- - - - ignore case in IF statements (Rainer Collet, Monte) - - treat undefined constants as null (Ferdinand Beyer, Monte) - - fix problem with inserts and nested fetches - (Rainer Collet, Monte) - - added support for passing params to include_php - (Tim Riley, Monte) - - added support for math operators in if statements (Monte) - - added support for $foo->bar[$x].blah syntax (Monte) - -Version 2.4.0 (Feb 2, 2003) ---------------------------- - - - fix known problems with php tag handling in templates - (recursion, echoing xml tags) (Monte) - - add support for object registration (Monte) - - add debug template to secure_dir, add template_dir - to secure_dir by default (Ferdinand Beyer, Monte) - - added support for assigned object access (Monte) - - fixed bug with directories named '0' (Frank Bauer, Monte) - - add javascript parameter to escape modifier (Monte) - - added calling function line numbers to syntax error - messages in compiler (Monte) - - added support for modifiers to function calls (Monte) - - support return value for custom functions - instead of echoing (but echo still works) (Monte) - - added direct access to constants - via $smarty.const.FOO (Monte) - - added support for passing modifiers - to static values (Monte) - - fix up regex code in compiler, more accurate and - maintainable (Monte) - - added day_value_format to html_select_date (Marcus - Bointon, Monte) - - assigned variables are no longer in global - namespace, saving extract() calls and speeding - up fetch() and display() linearly with no. of - assigned variables (Monte) - - added trimwhitespace output filter to dist. (Monte) - - fix popup function to allow newlines in text (Monte) - - escape html entities in html_options (Monte) - - fixed bug with label for html_options (Monte) - - added config_load API function (Monte) - - added caching to config file loading (Monte) - - added "extra" parameter to mailto function (Monte, - Massimiliano Perantoni) - - added mailto plugin to dist. (Monte) - -Version 2.3.1 (Nov 19, 2002) ----------------------------- - - - added optgroup support to html_options (Monte, Robert - Amos) - - set mtime on compile files so they match source - files (Monte, Peter Bowen) - - added proper support for open_basedir setting - (Monte, Alessandro Astarita) - - added strip variable modifier, updated docs (Monte) - - fixed access to $smarty.x variables as arrays. (Andrei) - - fixed errors with example setup docs (Monte, Matthew - Hagerty) - - added textformat block function (Monte) - -Version 2.3.0 (Aug 7, 2002) ---------------------------- - - - added assign_by_ref() and append_by_ref() functions - (Bob Silva, Monte) - - changed default warning type for plugin errors from - E_USER_WARNING to E_USER_ERROR (Monte) - - added $all_extra, $hour_extra, $minute_extra, - $second_extra and $meridian_extra parameters to - html_select_time function (Rainer Collet, Monte) - - update debug console to print objects (Simon Willison, - Monte) - - fix Config_File class to not error when there are no - sections (Peter Kmet, Monte) - - add default modifier logic (Monte) - - updated popup_init to be xhtml compliant (Tom Oram, Monte) - - fix filename bug with windows (Gary Loescher, Monte) - - add ability to supply expire time in seconds when clearing - cache or compile files (Monte) - - add {debug} plugin to distribution (Monte) - - fixed bug with insert tags, loading from "script" attribute - when caching is enabled (Monte) - - fix bug with debug_tpl file path with Windows (.SMK., Monte) - - fix append() function with string/array problem (Monte) - -Version 2.2.0 (July 11, 2002) ------------------------------ - - - make debug.tpl work with any delimiter (Monte) - - change logic in assign() and append() to test var names - against != '' instead of empty() (Monte) - - fix PHP notice in append() function (Monte) - - allow $plugins_dir to be an array of directories - (Andreas Kossmeier, Monte) - - move debug.tpl to SMARTY_DIR, add to constructor (Monte) - - fixed warning message in function.assign_debug_info (Monte) - - fixed $template_dir, $compile_dir, $cache_dir, $config_dir, - $plugin_dir to respect include_path (Monte) - - fixed warning message with output filter array (Monte) - - add optional 2nd parameter to date_format, used as - the default date if the passed date is empty (Monte) - - gave $reset a default value in cycle plugin (Monte) - - fixed warnings with html_select_date and timestamp - functions (Monte) - - added support for sub directory exlusion format (Monte) - - added support for grouping by cache_id, compile_id - and segments thereof (Monte) - - changed cache and compile files to human readable - format (Monte) - - remove overlib.js file from distribution (Monte) - - fixed bug with 304 Not Modified response sending - content (Monte) - - fixed cycle function to respect delimiter after - initial setting (Monte) - - update $GLOBALS references to work properly with - track_globals settings (Michal Prinke, Monte) - - fixed bug in math function with call to assign - (Grigory V. Kareev, Monte) - - optimized for loops with count() function calls (Monte) - - add month_value_format attribute to html_select_date - plugin (Gary Loescher, Monte) - - made it possible to use simple variables inside [] for - indexing. (Andrei) - - added "once" attribute to {include_php}. (Monte) - -Version 2.1.1 -------------- - - added cycle function. (Monte) - - fixed bug with resource testing, and include_path. (Monte) - - fixed a bug with register_outputfilter function. (Monte) - -Version 2.1.0 -------------- - - - introduced output filters. (Andrei) - - changed the way filters are loaded, added load_filter() - API function and $autoload_filters variable. (Andrei) - - added caching logic for expire times per cache file - (Norbert Rocher, Monte) - - fixed html_select_date when field separator is "/" - (Roberto Berto, Monte) - - added YYYY-MM-DD format support to html_select_date - (Jan Rosier, Monte) - - fixed cache_lifetime logic bug, also made -1 = never - expire (Monte) - - fixed directory separator issue for Windows. (Andrei) - - added ability to use simple variables as array indices or - object properties. (Andrei) - - added ability to unregister pre/postfilters plugins at - runtime. (Andrei) - - added 'htmlall' attribute to escape modifier. (Monte) - - added template_exists() API function. (Andrei) - - fixed a problem with using dynamic values for 'file' - attribute of {include_php} tag. (Andrei) - - added $smarty.template variable. (Andrei) - - fixed several plugins that would not work if the plugin - directory was not the default one. (Andrei) - - implemented support for block functions. (Andrei) - - made it possible to assign variables in pre/postfilter - plugins. (Andrei) - -Version 2.0.1 -------------- - - rename plugin .make_timestamp.php to shared.make_timestamp.php. - (Monte) - - changed crc32() generated values, replace '-' with 'N'. (Monte) - - added support for +/- N syntax in html_select_date year values. - (Monte) - - fixed behavior of inserts with script attribute. (Andrei) - - fixed bug with $smarty.cookies and $smarty.server. (Andrei) - - wordwrap and indent are missing from 2.0 release, now fixed. - (Monte) - - removed show_info_header and show_info_include variables. (Monte) - -Version 2.0.0 -------------- - - added "eval" function plugin for evaluating variables as - templates. (Monte) - - removed $tpl_file_ext class variable, no longer used. (Monte) - - added "hex" and "hexentity" escape types to escape modifier. - (Monte) - - removed dependency on PEAR. (Andrei) - - update popup_init to accept src attribute. (Monte, Duncan Forrest) - - implemented several optimizations, speeding up Smarty - significantly in most cases. (Andrei,Monte) - - implemented plugin architecture. (Andrei) - - added wordwrap and indent modifiers. (Monte) - - added support for 'If-Modified-Since' headers for cached content. - (Monte) - - removed insert_tag_check class variable, no longer needed. (Monte) - - optimized cache fetches by scanning for insert tags only if they - exist. (Monte) - - fixed bugs in overlib. (Monte, Duncan Forrest) - - fixed a problem with compile_id usage. (Andrei) - - fixed problem with using assigned vars with {include_php ...} - filepath. (Monte) - -Version 1.5.2 -------------- - - added Smarty object as fifth argument for template resource functions. - (Monte) - - fixed a bug with incorrectly combined cache and compile id in - clear_cache(). (Andrei) - - fixed bug in smarty_make_timestamp introduced in PHP 4.1.0. (Monte) - - fixed bug with cached insert debug timing. (Monte) - - added 'script' attribute to {insert..} which specifies the script that - the insert function can be found in. (Andrei) - - added default template function handler. (Monte) - -Version 1.5.1 -------------- - - removed error message from the generic _read_file() method, the caller - should take care of that. (Andrei) - - fixed a bug with incorrectly combined cache and compile id. (Andrei) - -Version 1.5.0 -------------- - - added include_php built-in function, documented. (Monte) - - added trusted_dir functionality, documented. (Monte) - - consolidated secure_dir tests to one function. (Monte) - - prepended _smarty_ to variable names in fetch() class function to avoid - namespace conflicts. (Monte) - - introduced $compile_id class variable that can be used to set persistent - compile identifier across multiple display calls, documented. (Andrei) - - fixed bug with concatenated null cache and compile identifiers. (Andrei) - - added $smarty.section.* syntax for accessing section properties, - documented. (Andrei) - - added custom cache handling function ability, documented. (Monte) - - added assign attribute to include, include_php, insert, fetch, math, and - counter functions, documented. (Monte) - - fixed bug with fetch testing for local file when http address. (Monte) - - fixed bug with counter and skipval setting. (Monte) - - made {config_load ...} merge globals from each config file only once per - scope, thus avoiding several problems. (Andrei) - - added {foreach ...} tag that can be used to iterate through - non-sequential and associative arrays, documented. (Andrei) - - speeded up section property access a bit. (Andrei) - - removed $smarty variable from storage used by normal template variables, - to prevent any problems. (Andrei) - - fixed a bug that could cause parse error with quotes inside literal - blocks. (Andrei, Alexander Belonosov) - - added 'field_array' attribute to html_select_time function, documented. - (Andrei, Michael Caplan) - - documented {section} "max" attribute. (Monte) - - fixed notice message in Smarty_Compiler.class.php. (Monte) - - fixed bug with clear_cache introduced in 1.4.6, third parameter should - default to null. (Monte) - - updated Config_File class to support '\' path separator in OS/2. (Monte, - Francesco Cipriani) - - removed secure_ext setting (not used). (Monte) - - made cache reading process more efficient. (Monte) - - fixed bug, is_cached() now supports new 1.4.6 caching behavior. (Monte) - - update FAQ with mailing list Reply-To header FAQ. (Monte) - - supress error messages for fopen(), fix cache to regenerate if cache - file is not available (i.e. cluster race condition). (Monte) - - added index key example to QUICKSTART guide. (Monte) - -Version 1.4.6 -------------- - - fixed bug with {assign ...} when passing an empty value. (Monte) - - add more warning message fixes. (Monte, Tara Johnson) - - documentation updates. (Monte) - - update fetch function to give proper warning when fetching a non-readable - or non-existant file. (Monte) - - fixed problem with newline at the end of included templates (Monte, Andrei) - - added feature to regenerate cache if compile_check is enabled and an - involved template or config file gets modified. (Monte) - - added DEBUG execution times to included files: REQUIRES updated debug.tpl - file! (Monte) - - added support for hidden config variables that cannot be read by - templates. (Andrei) - - added execution time to DEBUG console, total and inserts. (Monte) - - fixed bug where DEBUG console would not appear with cached content. (Monte) - - added support for postfilter functions that are applied to compiled - template right after compilation. (Andrei) - - fixed the name of clear_compile_tpl() API function to clear_compiled_tpl. - (Andrei) - - added fix for removing comments so that the line numbers are reported - correctly in case of errors. (patch from Anders Janson) - - made html_options output xhtml compatible code. (Monte, Arnaud Limbourg) - -Version 1.4.5 -------------- - - update FAQ with index of questions at the top - - update overlib to 3.50, adjust addon code so that the overlib.js - file isn't modified, and not using the mini one. (Monte) - - added many more options to html_select_date. (Alexander Skwar, Andrei) - - added support for generating different compiled templates from the same - source template. (Hans-Peter Oeri, Andrei) - - modified Smarty to pass itself to insert functions as the second - parameter. (Andrei) - - modified Smarty to pass itself to prefilter functions as the second - parameter. (Andrei) - - fixed syntax error when including a non-existant template with security - enabled. (Monte) - - fixed comments handling to allow commenting out template blocks. (Andrei) - - implemented named capture buffers, with results accessible via - $smarty.capture.<name>. (Andrei) - - added ability to index arrays directly by numbers. (Andrei) - - fixed bug with SMARTY_DIR not prepended to Config_File include. (Monte) - -Version 1.4.4 -------------- - - fixed problem with including insecure templates with security enabled. - (Monte) - - numerous documentation updates. (Monte) - - added ENT_QUOTES to escapement of html. (Monte, Sam Beckwith) - - implemented access to request variables via auto-assigned $smarty - template variable. (Andrei) - - fixed a bug with parsing function arguments inside {if} tags if a comma - was present. (Andrei) - - updated debug console with config file vars. (Monte) - - added SMARTY_DIR constant as an alternative to relying on include_path. - (Monte) - - added popup_init and popup functions (requires overlib.js). (Monte) - - updated debug console with config file vars. (Monte) - - added debugging url control. (Monte) - - added 'quotes' type to escape modifier. (Monte, Mike Krus) - - added 'total' and 'iteration' section properties. (Andrei) - - added 'start', 'max', and 'step' section attributes/properties. (Andrei) - - fixed a bug with security checking of functions inside {if} tags. - (Andrei) - - fixed a bug in Config_File that would incorrectly booleanize values that - weren't really booleans. (Andrei) - -Version 1.4.3 -------------- - - added regex_replace modifier, documented. (Monte) - - added debugging console feature and custom function assign_debug_info, - documented. (Monte) - - added 'scope' attribute for {config_load}, 'global' is now deprecated but - is still supported. (Andrei) - - reduced template symbol table pollution by moving config array into the - class itself. (Andrei) - - fixed a bug with passing quoted arguments to modifiers inside {if} - statements. (Andrei, Sam Beckwith) - - added security features for third party template editing, documented - (Monte) - - added assign custom function, documented. (Monte) - - fixed bug with template header using version instead of _version. (Monte) - - fixed a problem with putting $ followed by numbers inside {strip} and - {/strip} tags. (Andrei) - - fixed Config_File class to allow empty config paths (defaults to current - directory). (Andrei) - -Version 1.4.2 -------------- - - move $version to internal variable, remove from docs. (Monte) - - cleaned up compiled templates global scope by moving some variables into - the class itself. (Andrei) - - fixed a bug that would not allow referring to a section in the including - file from the included file. (Andrei) - - configs directory missing from 1.4.1 release, added back in. (Monte) - - added windows include_path setup instructions to FAQ & QUICKSTART. - (Monte) - -Version 1.4.1 -------------- - - fix LOCK_EX logic for all windows platforms (Monte) - - fixed indexing by section properties with the new syntax. (Andrei) - - updated Smarty to use absolute paths when requiring/including Smarty - components. (Andrei, John Lim) - -Version 1.4.0 -------------- - - added {capture}{/capture} function, documented (Monte) - - added {counter} function, documented (Monte) - -Version 1.4.0b2 ---------------- - - fixed issue in Config_File.class with referencing blank sections (Andrei) - - fixed problem with passing variables to included files (Andrei) - - fixed resource path recognition for windows (Monte) - -Version 1.4.0b1 ---------------- - - added "componentized templates" tip into documentation (Monte) - - added {php}{/php} tags for embedding php code into templates (Monte) - - changed default value of $show_info_header to false (Monte) - - implemented '->' syntax for accessing properties of objects passed to the - template. (Andrei) - - allowed custom functions to receive Smarty object as the second - parameter; this can be used to dynamically change template variables, for - example. (Andrei) - - added custom compiler functions support, register_compiler_function() and - unregister_compiler_function() API functions. (Andrei, Ivo Jansch). - - updated GLOBAL_ASSIGN to take SCRIPT_NAME from HTTP_SERVER_VARS - instead of global variable. You can also assign several variables - in one shot with an array. (Monte, Roman Neuhauser) - - added template prefilters, register_prefilter() and - unregister_prefilter() API functions. (Monte) - - added RELEASE_NOTES file to distribution. (Monte) - - moved CREDITS out of manual into its own file. (Monte) - - added register_resource() and unregister_resource() API functions. (Monte) - - changed the syntax of indexing template variables, thus supporting - structures of arbitrary complexity; supplied fix_vars.php script to fix - old syntax. (Andrei) - - added $insert_tag_check to speed up cached pages if {insert ...} is not - used. (Monte) - - added $compiler_class variable to allow specifying a different compiler - class. (Andrei) - - changed Smarty to compile templates at runtime, allowing for arbitrary - template resources. (Monte) - - added fix for LOCK_EX under Windows and changed a couple of file - permissions for security. (Monte, Fernando Nunes) - - allow arbitrary date strings to date_format, html_select_date and - html_select_time (Monte) - -Version 1.3.2 -------------- - - fixed a bug that caused some nested includes to loop infinitely. (Andrei) - - added optional HTML header to output. (Monte) - - significantly improved config_load performance. (Andrei) - - added format attribute to math function. (Monte) - - added html_select_time custom function. (Andrei) - - fixed minor PHP warning when attempting to unset an unset variable - (Monte) - - added count_characters, count_words, count_sentences, count_paragraphs - modifiers (Monte) - -Version 1.3.1pl1 --------------- - - bug fix, recovered missing _syntax_error function (Monte) - -Version 1.3.1 -------------- - - document first, last, index_prev, index_next (Monte) - - added 'first' and 'last' section properties. (Andrei) - - split out compiling code to separate class for faster template execution - time (Monte) - - fixed a couple of minor PHP warnings (Monte) - - added and documented unregister_modifier() and unregister_function() API - calls. (Monte) - - added and documented 'fetch' and 'math' functions. (Monte) - - added ability to index looped variables by section properties, e.g. - $foo.index_prev/bar. (Andrei) - - added index_prev and index_next section properties. (Andrei) - - fixed issue with php executing in literal blocks. (Monte) - -Version 1.3.0 -------------- - - moved license from GPL to LGPL (Monte) - - implemented workaround for PHP "feature" that eats carriage returns - if the PHP tag is at the end of the line. (Andrei) - - removed $allow_php, added $php_handling logic (Monte) - - added file locking to prevent reader/writer problem. (Andrei) - - made Smarty catch unimplemented modifiers and custom functions and output - error messages during compilation instead of failing during run time. - (Andrei) - - removed short-tags at the top of the smarty scripts (Monte) - - added register_function() and register_modifier() API calls to make - registering stuff easier. (Andrei) - - added template results caching capability. (Monte, Andrei) - - added optional 'options' attribute to html_options custom function - that allows passing associative arrays for values/output. (Andrei) - - modifier arguments can now contain '|' and ':' characters inside quoted - strings. (Andrei) - -Version 1.2.2 -------------- - - fixed bug that would not respect nested template directories and would - put all compiled files into top-level one. (Andrei) - - fixed bug using $PHP_VERSION instead of environment var PHP_VERSION. - (Monte) - - a couple small warning fixes. (Monte) - -Version 1.2.1 -------------- - - added $compile_dir, removed $compile_dir_ext, simplified usage. (Monte) - - added tips & tricks chapter to documentation. (Monte) - - misc documentation updates. (Monte) - -Version 1.2.0 -------------- - - updated documentation (Monte) - - added file and line number information to syntax error messages. (Andrei) - - added ability to index template vars by a key. (Andrei) - -Version 1.1.0 -------------- - - misc documentation changes, official stable release - -Version 1.0b ------------- - - fixed the bug that prevented using non-array values for 'loop' attribute. - (Andrei) - - many misc documentation changes & additions (Monte) - -Version 1.0a ------------- - - fixed bug that caused templates to recompile every time (Monte) - -Version 1.0 ------------- - - initial release - -/* vim: set et tw=64 ft=changelog: */ diff --git a/include/smarty/README b/include/smarty/README index 15992d09e..bf03403aa 100644 --- a/include/smarty/README +++ b/include/smarty/README @@ -1,86 +1,574 @@ +Smarty 3.1.13 -NAME: +Author: Monte Ohrt <monte at ohrt dot com > +Author: Uwe Tews - Smarty - the PHP compiling template engine +AN INTRODUCTION TO SMARTY 3 -VERSION: 2.6.26 +NOTICE FOR 3.1 release: -AUTHORS: - - Monte Ohrt <monte at ohrt dot com> - Andrei Zmievski <andrei@php.net> +Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution. -MAILING LISTS: +NOTICE for 3.0.5 release: - We have a few mailing lists. "discussion" for you to share your ideas or ask - questions, "developers" for those interested in the development efforts of Smarty, - and "svn" for those that would like to track the updates made in the svn - repository. +Smarty 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: - send a blank e-mail message to: - smarty-discussion-subscribe@googlecode.com(subscribe to the general discussion list) - smarty-discussion-unsubscribe@googlecode.com (unsubscribe from the general discussion list) - smarty-discussion-digest-subscribe@googlecode.com (subscribe to digest) - smarty-discussion-digest-unsubscribe@googlecode.com (unsubscribe from digest) - smarty-developers-subscribe@googlecode.com (subscribe to the dev list) - smarty-developers-unsubscribe@googlecode.com (unsubscribe from the dev list) - smarty-svn-subscribe@googlecode.com (subscribe to the svn list) - smarty-svn-unsubscribe@googlecode.com (unsubscribe from the svn list) +$smarty->error_reporting = E_ALL & ~E_NOTICE; - You can also browse the mailing list archives at - http://groups.google.com/group/smarty-discussion - http://groups.google.com/group/smarty-developers +NOTICE for 3.0 release: - and the OLD list archives at - http://marc.theaimsgroup.com/?l=smarty&r=1&w=2 +IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release. +We felt it is better to make these now instead of after a 3.0 release, then have to +immediately deprecate APIs in 3.1. Online documentation has been updated +to reflect these changes. Specifically: -SYNOPSIS: +---- API CHANGES RC4 -> 3.0 ---- - require("Smarty.class.php"); +$smarty->register->* +$smarty->unregister->* +$smarty->utility->* +$samrty->cache->* - $smarty = new Smarty; +Have all been changed to local method calls such as: - $smarty->assign("Title","My Homepage"); - $smarty->assign("Names",array("John","Gary","Gregg","James")); +$smarty->clearAllCache() +$smarty->registerFoo() +$smarty->unregisterFoo() +$smarty->testInstall() +etc. - $smarty->display("index.tpl"); +Registration of function, block, compiler, and modifier plugins have been +consolidated under two API calls: +$smarty->registerPlugin(...) +$smarty->unregisterPlugin(...) -DESCRIPTION: +Registration of pre, post, output and variable filters have been +consolidated under two API calls: - What is Smarty? +$smarty->registerFilter(...) +$smarty->unregisterFilter(...) - Smarty is a template engine for PHP. Many other template engines for PHP - provide basic variable substitution and dynamic block functionality. - Smarty takes a step further to be a "smart" template engine, adding - features such as configuration files, template functions, and variable - modifiers, and making all of this functionality as easy as possible to - use for both programmers and template designers. Smarty also converts - the templates into PHP scripts, eliminating the need to parse the - templates on every invocation. This makes Smarty extremely scalable and - manageable for large application needs. +Please refer to the online documentation for all specific changes: - Some of Smarty's features: +http://www.smarty.net/documentation - * it is extremely fast - * no template parsing overhead, only compiles once. - * it is smart about recompiling only the template files that have - changed. - * the template language is remarkably extensible via the plugin - architecture. - * configurable template delimiter tag syntax, so you can use - {}, {{}}, <!--{}-->, or whatever you like. - * built-in caching of template output. - * arbitrary template sources (filesystem, databases, etc.) - * template if/elseif/else/endif constructs are passed to the PHP parser, - so the if syntax can be as simple or as complex as you like. - * unlimited nesting of sections, conditionals, etc. allowed - * it is possible to embed PHP code right in your template files, - although not recommended and doubtfully needed since the engine - is so customizable. - * and many more. +---- -COPYRIGHT: - Copyright (c) 2001-2005 New Digital Group, Inc. All rights reserved. - This software is released under the GNU Lesser General Public License. - Please read the disclaimer at the top of the Smarty.class.php file. +The Smarty 3 API has been refactored to a syntax geared +for consistency and modularity. The Smarty 2 API syntax is still supported, but +will throw a deprecation notice. You can disable the notices, but it is highly +recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run +through an extra rerouting wrapper. + +Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also, +all Smarty properties now have getters and setters. So for example, the property +$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be +retrieved with $smarty->getCacheDir(). + +Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were +just duplicate functions of the now available "get*" methods. + +Here is a rundown of the Smarty 3 API: + +$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null) +$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null) +$smarty->isCached($template, $cache_id = null, $compile_id = null) +$smarty->createData($parent = null) +$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null) +$smarty->enableSecurity() +$smarty->disableSecurity() +$smarty->setTemplateDir($template_dir) +$smarty->addTemplateDir($template_dir) +$smarty->templateExists($resource_name) +$smarty->loadPlugin($plugin_name, $check = true) +$smarty->loadFilter($type, $name) +$smarty->setExceptionHandler($handler) +$smarty->addPluginsDir($plugins_dir) +$smarty->getGlobal($varname = null) +$smarty->getRegisteredObject($name) +$smarty->getDebugTemplate() +$smarty->setDebugTemplate($tpl_name) +$smarty->assign($tpl_var, $value = null, $nocache = false) +$smarty->assignGlobal($varname, $value = null, $nocache = false) +$smarty->assignByRef($tpl_var, &$value, $nocache = false) +$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false) +$smarty->appendByRef($tpl_var, &$value, $merge = false) +$smarty->clearAssign($tpl_var) +$smarty->clearAllAssign() +$smarty->configLoad($config_file, $sections = null) +$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true) +$smarty->getConfigVariable($variable) +$smarty->getStreamVariable($variable) +$smarty->getConfigVars($varname = null) +$smarty->clearConfig($varname = null) +$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true) +$smarty->clearAllCache($exp_time = null, $type = null) +$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) + +$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array()) + +$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + +$smarty->registerFilter($type, $function_name) +$smarty->registerResource($resource_type, $function_names) +$smarty->registerDefaultPluginHandler($function_name) +$smarty->registerDefaultTemplateHandler($function_name) + +$smarty->unregisterPlugin($type, $tag) +$smarty->unregisterObject($object_name) +$smarty->unregisterFilter($type, $function_name) +$smarty->unregisterResource($resource_type) + +$smarty->compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) +$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) +$smarty->testInstall() + +// then all the getters/setters, available for all properties. Here are a few: + +$caching = $smarty->getCaching(); // get $smarty->caching +$smarty->setCaching(true); // set $smarty->caching +$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices +$smarty->setCacheId($id); // set $smarty->cache_id +$debugging = $smarty->getDebugging(); // get $smarty->debugging + + +FILE STRUCTURE + +The Smarty 3 file structure is similar to Smarty 2: + +/libs/ + Smarty.class.php +/libs/sysplugins/ + internal.* +/libs/plugins/ + function.mailto.php + modifier.escape.php + ... + +A lot of Smarty 3 core functionality lies in the sysplugins directory; you do +not need to change any files here. The /libs/plugins/ folder is where Smarty +plugins are located. You can add your own here, or create a separate plugin +directory, just the same as Smarty 2. You will still need to create your own +/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and +/templates_c/ are writable. + +The typical way to use Smarty 3 should also look familiar: + +require('Smarty.class.php'); +$smarty = new Smarty; +$smarty->assign('foo','bar'); +$smarty->display('index.tpl'); + + +However, Smarty 3 works completely different on the inside. Smarty 3 is mostly +backward compatible with Smarty 2, except for the following items: + +*) Smarty 3 is PHP 5 only. It will not work with PHP 4. +*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true. +*) Delimiters surrounded by whitespace are no longer treated as Smarty tags. + Therefore, { foo } will not compile as a tag, you must use {foo}. This change + Makes Javascript/CSS easier to work with, eliminating the need for {literal}. + This can be disabled by setting $smarty->auto_literal = false; +*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated + but still work. You will want to update your calls to Smarty 3 for maximum + efficiency. + + +There are many things that are new to Smarty 3. Here are the notable items: + +LEXER/PARSER +============ + +Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this +means Smarty has some syntax additions that make life easier such as in-template +math, shorter/intuitive function parameter options, infinite function recursion, +more accurate error handling, etc. + + +WHAT IS NEW IN SMARTY TEMPLATE SYNTAX +===================================== + +Smarty 3 allows expressions almost anywhere. Expressions can include PHP +functions as long as they are not disabled by the security policy, object +methods and properties, etc. The {math} plugin is no longer necessary but +is still supported for BC. + +Examples: +{$x+$y} will output the sum of x and y. +{$foo = strlen($bar)} function in assignment +{assign var=foo value= $x+$y} in attributes +{$foo = myfunct( ($x+$y)*3 )} as function parameter +{$foo[$x+3]} as array index + +Smarty tags can be used as values within other tags. +Example: {$foo={counter}+3} + +Smarty tags can also be used inside double quoted strings. +Example: {$foo="this is message {counter}"} + +You can define arrays within templates. +Examples: +{assign var=foo value=[1,2,3]} +{assign var=foo value=['y'=>'yellow','b'=>'blue']} +Arrays can be nested. +{assign var=foo value=[1,[9,8],3]} + +There is a new short syntax supported for assigning variables. +Example: {$foo=$bar+2} + +You can assign a value to a specific array element. If the variable exists but +is not an array, it is converted to an array before the new values are assigned. +Examples: +{$foo['bar']=1} +{$foo['bar']['blar']=1} + +You can append values to an array. If the variable exists but is not an array, +it is converted to an array before the new values are assigned. +Example: {$foo[]=1} + +You can use a PHP-like syntax for accessing array elements, as well as the +original "dot" notation. +Examples: +{$foo[1]} normal access +{$foo['bar']} +{$foo['bar'][1]} +{$foo[$x+$x]} index may contain any expression +{$foo[$bar[1]]} nested index +{$foo[section_name]} smarty section access, not array access! + +The original "dot" notation stays, and with improvements. +Examples: +{$foo.a.b.c} => $foo['a']['b']['c'] +{$foo.a.$b.c} => $foo['a'][$b]['c'] with variable index +{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] with expression as index +{$foo.a.{$b.c}} => $foo['a'][$b['c']] with nested index + +note that { and } are used to address ambiguties when nesting the dot syntax. + +Variable names themselves can be variable and contain expressions. +Examples: +$foo normal variable +$foo_{$bar} variable name containing other variable +$foo_{$x+$y} variable name containing expressions +$foo_{$bar}_buh_{$blar} variable name with multiple segments +{$foo_{$x}} will output the variable $foo_1 if $x has a value of 1. + +Object method chaining is implemented. +Example: {$object->method1($x)->method2($y)} + +{for} tag added for looping (replacement for {section} tag): +{for $x=0, $y=count($foo); $x<$y; $x++} .... {/for} +Any number of statements can be used separated by comma as the first +inital expression at {for}. + +{for $x = $start to $end step $step} ... {/for}is in the SVN now . +You can use also +{for $x = $start to $end} ... {/for} +In this case the step value will be automaticall 1 or -1 depending on the start and end values. +Instead of $start and $end you can use any valid expression. +Inside the loop the following special vars can be accessed: +$x@iteration = number of iteration +$x@total = total number of iterations +$x@first = true on first iteration +$x@last = true on last iteration + + +The Smarty 2 {section} syntax is still supported. + +New shorter {foreach} syntax to loop over an array. +Example: {foreach $myarray as $var}...{/foreach} + +Within the foreach loop, properties are access via: + +$var@key foreach $var array key +$var@iteration foreach current iteration count (1,2,3...) +$var@index foreach current index count (0,1,2...) +$var@total foreach $var array total +$var@first true on first iteration +$var@last true on last iteration + +The Smarty 2 {foreach} tag syntax is still supported. + +NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo. +If you want to access an array element with index foo, you must use quotes +such as {$bar['foo']}, or use the dot syntax {$bar.foo}. + +while block tag is now implemented: +{while $foo}...{/while} +{while $x lt 10}...{/while} + +Direct access to PHP functions: +Just as you can use PHP functions as modifiers directly, you can now access +PHP functions directly, provided they are permitted by security settings: +{time()} + +There is a new {function}...{/function} block tag to implement a template function. +This enables reuse of code sequences like a plugin function. It can call itself recursively. +Template function must be called with the new {call name=foo...} tag. + +Example: + +Template file: +{function name=menu level=0} + <ul class="level{$level}"> + {foreach $data as $entry} + {if is_array($entry)} + <li>{$entry@key}</li> + {call name=menu data=$entry level=$level+1} + {else} + <li>{$entry}</li> + {/if} + {/foreach} + </ul> +{/function} + +{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' => + ['item3-3-1','item3-3-2']],'item4']} + +{call name=menu data=$menu} + + +Generated output: + * item1 + * item2 + * item3 + o item3-1 + o item3-2 + o item3-3 + + item3-3-1 + + item3-3-2 + * item4 + +The function tag itself must have the "name" attribute. This name is the tag +name when calling the function. The function tag may have any number of +additional attributes. These will be default settings for local variables. + +New {nocache} block function: +{nocache}...{/nocache} will declare a section of the template to be non-cached +when template caching is enabled. + +New nocache attribute: +You can declare variable/function output as non-cached with the nocache attribute. +Examples: + +{$foo nocache=true} +{$foo nocache} /* same */ + +{foo bar="baz" nocache=true} +{foo bar="baz" nocache} /* same */ + +{time() nocache=true} +{time() nocache} /* same */ + +Or you can also assign the variable in your script as nocache: +$smarty->assign('foo',$something,true); // third param is nocache setting +{$foo} /* non-cached */ + +$smarty.current_dir returns the directory name of the current template. + +You can use strings directly as templates with the "string" resource type. +Examples: +$smarty->display('string:This is my template, {$foo}!'); // php +{include file="string:This is my template, {$foo}!"} // template + + + +VARIABLE SCOPE / VARIABLE STORAGE +================================= + +In Smarty 2, all assigned variables were stored within the Smarty object. +Therefore, all variables assigned in PHP were accessible by all subsequent +fetch and display template calls. + +In Smarty 3, we have the choice to assign variables to the main Smarty object, +to user-created data objects, and to user-created template objects. +These objects can be chained. The object at the end of a chain can access all +variables belonging to that template and all variables within the parent objects. +The Smarty object can only be the root of a chain, but a chain can be isolated +from the Smarty object. + +All known Smarty assignment interfaces will work on the data and template objects. + +Besides the above mentioned objects, there is also a special storage area for +global variables. + +A Smarty data object can be created as follows: +$data = $smarty->createData(); // create root data object +$data->assign('foo','bar'); // assign variables as usual +$data->config_load('my.conf'); // load config file + +$data= $smarty->createData($smarty); // create data object having a parent link to +the Smarty object + +$data2= $smarty->createData($data); // create data object having a parent link to +the $data data object + +A template object can be created by using the createTemplate method. It has the +same parameter assignments as the fetch() or display() method. +Function definition: +function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null) + +The first parameter can be a template name, a smarty object or a data object. + +Examples: +$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent +$tpl->assign('foo','bar'); // directly assign variables +$tpl->config_load('my.conf'); // load config file + +$tpl = $smarty->createTemplate('mytpl.tpl',$smarty); // create template having a parent link to the Smarty object +$tpl = $smarty->createTemplate('mytpl.tpl',$data); // create template having a parent link to the $data object + +The standard fetch() and display() methods will implicitly create a template object. +If the $parent parameter is not specified in these method calls, the template object +is will link back to the Smarty object as it's parent. + +If a template is called by an {include...} tag from another template, the +subtemplate links back to the calling template as it's parent. + +All variables assigned locally or from a parent template are accessible. If the +template creates or modifies a variable by using the {assign var=foo...} or +{$foo=...} tags, these new values are only known locally (local scope). When the +template exits, none of the new variables or modifications can be seen in the +parent template(s). This is same behavior as in Smarty 2. + +With Smarty 3, we can assign variables with a scope attribute which allows the +availablility of these new variables or modifications globally (ie in the parent +templates.) + +Possible scopes are local, parent, root and global. +Examples: +{assign var=foo value='bar'} // no scope is specified, the default 'local' +{$foo='bar'} // same, local scope +{assign var=foo value='bar' scope='local'} // same, local scope + +{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object +{$foo='bar' scope='parent'} // (normally the calling template) + +{assign var=foo value='bar' scope='root'} // Values will be exported up to the root object, so they can +{$foo='bar' scope='root'} // be seen from all templates using the same root. + +{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage, +{$foo='bar' scope='global'} // they are available to any and all templates. + + +The scope attribute can also be attached to the {include...} tag. In this case, +the specified scope will be the default scope for all assignments within the +included template. + + +PLUGINS +======= + +Smarty3 are following the same coding rules as in Smarty2. +The only difference is that the template object is passed as additional third parameter. + +smarty_plugintype_name (array $params, object $smarty, object $template) + +The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty2 internals. + + +TEMPLATE INHERITANCE: +===================== + +With template inheritance you can define blocks, which are areas that can be +overriden by child templates, so your templates could look like this: + +parent.tpl: +<html> + <head> + <title>{block name='title'}My site name{/block}</title> + </head> + <body> + <h1>{block name='page-title'}Default page title{/block}</h1> + <div id="content"> + {block name='content'} + Default content + {/block} + </div> + </body> +</html> + +child.tpl: +{extends file='parent.tpl'} +{block name='title'} +Child title +{/block} + +grandchild.tpl: +{extends file='child.tpl'} +{block name='title'}Home - {$smarty.block.parent}{/block} +{block name='page-title'}My home{/block} +{block name='content'} + {foreach $images as $img} + <img src="{$img.url}" alt="{$img.description}" /> + {/foreach} +{/block} + +We redefined all the blocks here, however in the title block we used {$smarty.block.parent}, +which tells Smarty to insert the default content from the parent template in its place. +The content block was overriden to display the image files, and page-title has also be +overriden to display a completely different title. + +If we render grandchild.tpl we will get this: +<html> + <head> + <title>Home - Child title</title> + </head> + <body> + <h1>My home</h1> + <div id="content"> + <img src="/example.jpg" alt="image" /> + <img src="/example2.jpg" alt="image" /> + <img src="/example3.jpg" alt="image" /> + </div> + </body> +</html> + +NOTE: In the child templates everything outside the {extends} or {block} tag sections +is ignored. + +The inheritance tree can be as big as you want (meaning you can extend a file that +extends another one that extends another one and so on..), but be aware that all files +have to be checked for modifications at runtime so the more inheritance the more overhead you add. + +Instead of defining the parent/child relationships with the {extends} tag in the child template you +can use the resource as follow: + +$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl'); + +Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content +is appended or prepended to the child block content. + +{block name='title' append} My title {/block} + + +PHP STREAMS: +============ + +(see online documentation) + +VARIBLE FILTERS: +================ + +(see online documentation) + + +STATIC CLASS ACCESS AND NAMESPACE SUPPORT +========================================= + +You can register a class with optional namespace for the use in the template like: + +$smarty->register->templateClass('foo','name\name2\myclass'); + +In the template you can use it like this: +{foo::method()} etc. + + +======================= + +Please look through it and send any questions/suggestions/etc to the forums. + +http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168 + +Monte and Uwe diff --git a/include/smarty/SMARTY_2_BC_NOTES.txt b/include/smarty/SMARTY_2_BC_NOTES.txt new file mode 100644 index 000000000..79a2cb1b6 --- /dev/null +++ b/include/smarty/SMARTY_2_BC_NOTES.txt @@ -0,0 +1,109 @@ += Known incompatibilities with Smarty 2 = + +== Syntax == + +Smarty 3 API has a new syntax. Much of the Smarty 2 syntax is supported +by a wrapper but deprecated. See the README that comes with Smarty 3 for more +information. + +The {$array|@mod} syntax has always been a bit confusing, where an "@" is required +to apply a modifier to an array instead of the individual elements. Normally you +always want the modifier to apply to the variable regardless of its type. In Smarty 3, +{$array|mod} and {$array|@mod} behave identical. It is safe to drop the "@" and the +modifier will still apply to the array. If you really want the modifier to apply to +each array element, you must loop the array in-template, or use a custom modifier that +supports array iteration. Most smarty functions already escape values where necessary +such as {html_options} + +== PHP Version == +Smarty 3 is PHP 5 only. It will not work with PHP 4. + +== {php} Tag == +The {php} tag is disabled by default. The use of {php} tags is +deprecated. It can be enabled with $smarty->allow_php_tag=true. + +But if you scatter PHP code which belongs together into several +{php} tags it may not work any longer. + +== Delimiters and whitespace == +Delimiters surrounded by whitespace are no longer treated as Smarty tags. +Therefore, { foo } will not compile as a tag, you must use {foo}. This change +Makes Javascript/CSS easier to work with, eliminating the need for {literal}. +This can be disabled by setting $smarty->auto_literal = false; + +== Unquoted Strings == +Smarty 2 was a bit more forgiving (and ambiguous) when it comes to unquoted strings +in parameters. Smarty3 is more restrictive. You can still pass strings without quotes +so long as they contain no special characters. (anything outside of A-Za-z0-9_) + +For example filename strings must be quoted +<source lang="smarty"> +{include file='path/foo.tpl'} +</source> + +== Extending the Smarty class == +Smarty 3 makes use of the __construct method for initialization. If you are extending +the Smarty class, its constructor is not called implicitly if the your child class defines +its own constructor. In order to run Smarty's constructor, a call to parent::__construct() +within your child constructor is required. + +<source lang="php"> +class MySmarty extends Smarty { + function __construct() { + parent::__construct(); + + // your initialization code goes here + + } +} +</source> + +== Autoloader == +Smarty 3 does register its own autoloader with spl_autoload_register. If your code has +an existing __autoload function then this function must be explicitly registered on +the __autoload stack. See http://us3.php.net/manual/en/function.spl-autoload-register.php +for further details. + +== Plugin Filenames == +Smarty 3 optionally supports the PHP spl_autoloader. The autoloader requires filenames +to be lower case. Because of this, Smarty plugin file names must also be lowercase. +In Smarty 2, mixed case file names did work. + +== Scope of Special Smarty Variables == +In Smarty 2 the special Smarty variables $smarty.section... and $smarty.foreach... +had global scope. If you had loops with the same name in subtemplates you could accidentally +overwrite values of parent template. + +In Smarty 3 these special Smarty variable have only local scope in the template which +is defining the loop. If you need their value in a subtemplate you have to pass them +as parameter. +<source lang="smarty"> +{include file='path/foo.tpl' index=$smarty.section.foo.index} +</source> + +== SMARTY_RESOURCE_CHAR_SET == +Smarty 3 sets the constant SMARTY_RESOURCE_CHAR_SET to utf-8 as default template charset. +This is now used also on modifiers like escape as default charset. If your templates use +other charsets make sure that you define the constant accordingly. Otherwise you may not +get any output. + +== newline at {if} tags == +A \n was added to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source. +If one of the {if} tags is at the line end you will now get a newline in the HTML output. + +== trigger_error() == +The API function trigger_error() has been removed because it did just map to PHP trigger_error. +However it's still included in the Smarty2 API wrapper. + +== Smarty constants == +The constants +SMARTY_PHP_PASSTHRU +SMARTY_PHP_QUOTE +SMARTY_PHP_REMOVE +SMARTY_PHP_ALLOW +have been replaced with class constants +Smarty::PHP_PASSTHRU +Smarty::PHP_QUOTE +Smarty::PHP_REMOVE +Smarty::PHP_ALLOW + diff --git a/include/smarty/SMARTY_3.0_BC_NOTES.txt b/include/smarty/SMARTY_3.0_BC_NOTES.txt new file mode 100644 index 000000000..fd8b540c2 --- /dev/null +++ b/include/smarty/SMARTY_3.0_BC_NOTES.txt @@ -0,0 +1,24 @@ +== Smarty2 backward compatibility == +All Smarty2 specific API functions and deprecated functionallity has been moved +to the SmartyBC class. + +== {php} Tag == +The {php} tag is no longer available in the standard Smarty calls. +The use of {php} tags is deprecated and only available in the SmartyBC class. + +== {include_php} Tag == +The {include_php} tag is no longer available in the standard Smarty calls. +The use of {include_php} tags is deprecated and only available in the SmartyBC class. + +== php template resource == +The support of the php template resource is removed. + +== $cache_dir, $compile_dir, $config_dir, $template_dir access == +The mentioned properties can't be accessed directly any longer. You must use +corresponding getter/setters like addConfigDir(), setConfigDir(), getConfigDir() + +== obsolete Smarty class properties == +The following no longer used properties are removed: +$allow_php_tag +$allow_php_template +$deprecation_notices
\ No newline at end of file diff --git a/include/smarty/SMARTY_3.1_NOTES.txt b/include/smarty/SMARTY_3.1_NOTES.txt new file mode 100644 index 000000000..e56e56f67 --- /dev/null +++ b/include/smarty/SMARTY_3.1_NOTES.txt @@ -0,0 +1,306 @@ +Smarty 3.1 Notes +================ + +Smarty 3.1 is a departure from 2.0 compatibility. Most notably, all +backward compatibility has been moved to a separate class file named +SmartyBC.class.php. If you require compatibility with 2.0, you will +need to use this class. + +Some differences from 3.0 are also present. 3.1 begins the journey of +requiring setters/getters for property access. So far this is only +implemented on the five directory properties: template_dir, +plugins_dir, configs_dir, compile_dir and cache_dir. These properties +are now protected, it is required to use the setters/getters instead. +That said, direct property access will still work, however slightly +slower since they will now fall through __set() and __get() and in +turn passed through the setter/getter methods. 3.2 will exhibit a full +list of setter/getter methods for all (currently) public properties, +so code-completion in your IDE will work as expected. + +There is absolutely no PHP allowed in templates any more. All +deprecated features of Smarty 2.0 are gone. Again, use the SmartyBC +class if you need any backward compatibility. + +Internal Changes + + Full UTF-8 Compatibility + +The plugins shipped with Smarty 3.1 have been rewritten to fully +support UTF-8 strings if Multibyte String is available. Without +MBString UTF-8 cannot be handled properly. For those rare cases where +templates themselves have to juggle encodings, the new modifiers +to_charset and from_charset may come in handy. + + Plugin API and Performance + +All Plugins (modifiers, functions, blocks, resources, +default_template_handlers, etc) are now receiving the +Smarty_Internal_Template instance, where they were supplied with the +Smarty instance in Smarty 3.0. *. As The Smarty_Internal_Template +mimics the behavior of Smarty, this API simplification should not +require any changes to custom plugins. + +The plugins shipped with Smarty 3.1 have been rewritten for better +performance. Most notably {html_select_date} and {html_select_time} +have been improved vastly. Performance aside, plugins have also been +reviewed and generalized in their API. {html_select_date} and +{html_select_time} now share almost all available options. + +The escape modifier now knows the $double_encode option, which will +prevent entities from being encoded again. + +The capitalize modifier now know the $lc_rest option, which makes sure +all letters following a captial letter are lower-cased. + +The count_sentences modifier now accepts (.?!) as +legitimate endings of a sentence - previously only (.) was +accepted + +The new unescape modifier is there to reverse the effects of the +escape modifier. This applies to the escape formats html, htmlall and +entity. + + default_template_handler_func + +The invocation of $smarty->$default_template_handler_func had to be +altered. Instead of a Smarty_Internal_Template, the fifth argument is +now provided with the Smarty instance. New footprint: + + +/** + * Default Template Handler + * + * called when Smarty's file: resource is unable to load a requested file + * + * @param string $type resource type (e.g. "file", "string", "eval", "resource") + * @param string $name resource name (e.g. "foo/bar.tpl") + * @param string &$content template's content + * @param integer &$modified template's modification time + * @param Smarty $smarty Smarty instance + * @return string|boolean path to file or boolean true if $content and $modified + * have been filled, boolean false if no default template + * could be loaded + */ +function default_template_handler_func($type, $name, &$content, &$modified, Smarty $smarty) { + if (false) { + // return corrected filepath + return "/tmp/some/foobar.tpl"; + } elseif (false) { + // return a template directly + $content = "the template source"; + $modified = time(); + return true; + } else { + // tell smarty that we failed + return false; + } +} + + Stuff done to the compiler + +Many performance improvements have happened internally. One notable +improvement is that all compiled templates are now handled as PHP +functions. This speeds up repeated templates tremendously, as each one +calls an (in-memory) PHP function instead of performing another file +include/scan. + +New Features + + Template syntax + + {block}..{/block} + +The {block} tag has a new hide option flag. It does suppress the block +content if no corresponding child block exists. +EXAMPLE: +parent.tpl +{block name=body hide} child content "{$smarty.block.child}" was +inserted {block} +In the above example the whole block will be suppressed if no child +block "body" is existing. + + {setfilter}..{/setfilter} + +The new {setfilter} block tag allows the definition of filters which +run on variable output. +SYNTAX: +{setfilter filter1|filter2|filter3....} +Smarty3 will lookup up matching filters in the following search order: +1. varibale filter plugin in plugins_dir. +2. a valid modifier. A modifier specification will also accept +additional parameter like filter2:'foo' +3. a PHP function +{/setfilter} will turn previous filter setting off again. +{setfilter} tags can be nested. +EXAMPLE: +{setfilter filter1} + {$foo} + {setfilter filter2} + {$bar} + {/setfilter} + {$buh} +{/setfilter} +{$blar} +In the above example filter1 will run on the output of $foo, filter2 +on $bar, filter1 again on $buh and no filter on $blar. +NOTES: +- {$foo nofilter} will suppress the filters +- These filters will run in addition to filters defined by +registerFilter('variable',...), autoLoadFilter('variable',...) and +defined default modifier. +- {setfilter} will effect only the current template, not included +subtemplates. + + Resource API + +Smarty 3.1 features a new approach to resource management. The +Smarty_Resource API allows simple, yet powerful integration of custom +resources for templates and configuration files. It offers simple +functions for loading data from a custom resource (e.g. database) as +well as define new template types adhering to the special +non-compiling (e,g, plain php) and non-compile-caching (e.g. eval: +resource type) resources. + +See demo/plugins/resource.mysql.php for an example custom database +resource. + +Note that old-fashioned registration of callbacks for resource +management has been deprecated but is still possible with SmartyBC. + + CacheResource API + +In line with the Resource API, the CacheResource API offers a more +comfortable handling of output-cache data. With the +Smarty_CacheResource_Custom accessing databases is made simple. With +the introduction of Smarty_CacheResource_KeyValueStore the +implementation of resources like memcache or APC became a no-brainer; +simple hash-based storage systems are now supporting hierarchical +output-caches. + +See demo/plugins/cacheresource.mysql.php for an example custom +database CacheResource. +See demo/plugins/cacheresource.memcache.php for an example custom +memcache CacheResource using the KeyValueStore helper. + +Note that old-fashioned registration of $cache_handler is not possible +anymore. As the functionality had not been ported to Smarty 3.0.x +properly, it has been dropped from 3.1 completely. + +Locking facilities have been implemented to avoid concurrent cache +generation. Enable cache locking by setting +$smarty->cache_locking = true; + + Relative Paths in Templates (File-Resource) + +As of Smarty 3.1 {include file="../foo.tpl"} and {include +file="./foo.tpl"} will resolve relative to the template they're in. +Relative paths are available with {include file="..."} and +{extends file="..."}. As $smarty->fetch('../foo.tpl') and +$smarty->fetch('./foo.tpl') cannot be relative to a template, an +exception is thrown. + + Adressing a specific $template_dir + +Smarty 3.1 introduces the $template_dir index notation. +$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"} +require the template bar.tpl to be loaded from $template_dir['foo']; +Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to +define indexes along with the actual directories. + + Mixing Resources in extends-Resource + +Taking the php extends: template resource one step further, it is now +possible to mix resources within an extends: call like +$smarty->fetch("extends:file:foo.tpl|db:bar.tpl"); + +To make eval: and string: resources available to the inheritance +chain, eval:base64:TPL_STRING and eval:urlencode:TPL_STRING have been +introduced. Supplying the base64 or urlencode flags will trigger +decoding the TPL_STRING in with either base64_decode() or urldecode(). + + extends-Resource in template inheritance + +Template based inheritance may now inherit from php's extends: +resource like {extends file="extends:foo.tpl|db:bar.tpl"}. + + New Smarty property escape_html + +$smarty->escape_html = true will autoescape all template variable +output by calling htmlspecialchars({$output}, ENT_QUOTES, +SMARTY_RESOURCE_CHAR_SET). +NOTE: +This is a compile time option. If you change the setting you must make +sure that the templates get recompiled. + + New option at Smarty property compile_check + +The automatic recompilation of modified templates can now be +controlled by the following settings: +$smarty->compile_check = COMPILECHECK_OFF (false) - template files +will not be checked +$smarty->compile_check = COMPILECHECK_ON (true) - template files will +always be checked +$smarty->compile_check = COMPILECHECK_CACHEMISS - template files will +be checked if caching is enabled and there is no existing cache file +or it has expired + + Automatic recompilation on Smarty version change + +Templates will now be automatically recompiled on Smarty version +changes to avoide incompatibillities in the compiled code. Compiled +template checked against the current setting of the SMARTY_VERSION +constant. + + default_config_handler_func() + +Analogous to the default_template_handler_func() +default_config_handler_func() has been introduced. + + default_plugin_handler_func() + +An optional default_plugin_handler_func() can be defined which gets called +by the compiler on tags which can't be resolved internally or by plugins. +The default_plugin_handler() can map tags to plugins on the fly. + +New getters/setters + +The following setters/getters will be part of the official +documentation, and will be strongly recommended. Direct property +access will still work for the foreseeable future... it will be +transparently routed through the setters/getters, and consequently a +bit slower. + +array|string getTemplateDir( [string $index] ) +replaces $smarty->template_dir; and $smarty->template_dir[$index]; +Smarty setTemplateDir( array|string $path ) +replaces $smarty->template_dir = "foo"; and $smarty->template_dir = +array("foo", "bar"); +Smarty addTemplateDir( array|string $path, [string $index]) +replaces $smarty->template_dir[] = "bar"; and +$smarty->template_dir[$index] = "bar"; + +array|string getConfigDir( [string $index] ) +replaces $smarty->config_dir; and $smarty->config_dir[$index]; +Smarty setConfigDir( array|string $path ) +replaces $smarty->config_dir = "foo"; and $smarty->config_dir = +array("foo", "bar"); +Smarty addConfigDir( array|string $path, [string $index]) +replaces $smarty->config_dir[] = "bar"; and +$smarty->config_dir[$index] = "bar"; + +array getPluginsDir() +replaces $smarty->plugins_dir; +Smarty setPluginsDir( array|string $path ) +replaces $smarty->plugins_dir = "foo"; +Smarty addPluginsDir( array|string $path ) +replaces $smarty->plugins_dir[] = "bar"; + +string getCompileDir() +replaces $smarty->compile_dir; +Smarty setCompileDir( string $path ) +replaces $smarty->compile_dir = "foo"; + +string getCacheDir() +replaces $smarty->cache_dir; +Smarty setCacheDir( string $path ) +replaces $smarty->cache_dir; diff --git a/include/smarty/change_log.txt b/include/smarty/change_log.txt new file mode 100644 index 000000000..69642e276 --- /dev/null +++ b/include/smarty/change_log.txt @@ -0,0 +1,2153 @@ +===== Smarty-3.1.13 ===== +13.01.2013 +- enhancement allow to disable exception message escaping by SmartyException::$escape = false; (Issue #130) + +09.01.2013 +- bugfix compilation did fail when a prefilter did modify an {extends} tag (Forum Topic 23966) +- bugfix template inheritance could fail if nested {block} tags in childs did contain {$smarty.block.child} (Issue #127) +- bugfix template inheritance could fail if {block} tags in childs did have similar name as used plugins (Issue #128) +- added abstract method declaration doCompile() in Smarty_Internal_TemplateCompilerBase (Forum Topic 23969) + +06.01.2013 +- Allow '://' URL syntax in template names of stream resources (Issue #129) + +27.11.2012 +- bugfix wrong variable usage in smarty_internal_utility.php (Issue #125) + +26.11.2012 +- bugfix global variable assigned within template function are not seen after template function exit (Forum Topic 23800) + +24.11.2012 +- made SmartyBC loadable via composer (Issue #124) + +20.11.2012 +- bugfix assignGlobal() called from plugins did not work (Forum Topic 23771) + +13.11.2012 +- adding attribute "strict" to html_options, html_checkboxes, html_radios to only print disabled/readonly attributes if their values are true or "disabled"/"readonly" (Issue #120) + +01.11.2012 +- bugfix muteExcpetedErrors() would screw up for non-readable paths (Issue #118) + +===== Smarty-3.1.12 ===== +14.09.2012 +- bugfix template inheritance failed to compile with delimiters {/ and /} (Forum Topic 23008) + +11.09.2012 +- bugfix escape Smarty exception messages to avoid possible script execution + +10.09.2012 +- bugfix tag option flags and shorttag attributes did not work when rdel started with '=' (Forum Topic 22979) + +31.08.2012 +- bugfix resolving relative paths broke in some circumstances (Issue #114) + +22.08.2012 +- bugfix test MBString availability through mb_split, as it could've been compiled without regex support (--enable-mbregex). + Either we get MBstring's full package, or we pretend it's not there at all. + +21.08.2012 +- bugfix $auto_literal = false did not work with { block} tags in child templates + (problem was reintroduced after fix in 3.1.7)(Forum Topic 20581) + +17.08.2012 +- bugfix compiled code of nocache sections could contain wrong escaping (Forum Topic 22810) + +15.08.2012 +- bugfix template inheritance did produce wrong code if subtemplates with {block} was + included several times (from smarty-developers forum) + +14.08.2012 +- bugfix PHP5.2 compatibility compromised by SplFileInfo::getBasename() (Issue 110) + +01.08.2012 +- bugfix avoid PHP error on $smarty->configLoad(...) with invalid section specification (Forum Topic 22608) + +30.07.2012 +-bugfix {assign} in a nocache section should not overwrite existing variable values + during compilation (issue 109) + +28.07.2012 +- bugfix array access of config variables did not work (Forum Topic 22527) + +19.07.2012 +- bugfix the default plugin handler did create wrong compiled code for static class methods + from external script files (issue 108) + +===== Smarty-3.1.11 ===== +30.06.2012 +- bugfix {block.. hide} did not work as nested child (Forum Topic 22216) + +25.06.2012 +- bugfix the default plugin handler did not allow static class methods for modifier (issue 85) + +24.06.2012 +- bugfix escape modifier support for PHP < 5.2.3 (Forum Topic 21176) + +11.06.2012 +- bugfix the patch for Topic 21856 did break tabs between tag attributes (Forum Topic 22124) + +===== Smarty-3.1.10 ===== +09.06.2012 +- bugfix the compiler did ignore registered compiler plugins for closing tags (Forum Topic 22094) +- bugfix the patch for Topic 21856 did break multiline tags (Forum Topic 22124) + +===== Smarty-3.1.9 ===== +07.06.2012 +- bugfix fetch() and display() with relative paths (Issue 104) +- bugfix treat "0000-00-00" as 0 in modifier.date_format (Issue 103) + +24.05.2012 +- bugfix Smarty_Internal_Write_File::writeFile() could cause race-conditions on linux systems (Issue 101) +- bugfix attribute parameter names of plugins may now contain also "-" and ":" (Forum Topic 21856) +- bugfix add compile_id to cache key of of source (Issue 97) + +22.05.2012 +- bugfix recursive {include} within {section} did fail (Smarty developer group) + +12.05.2012 +- bugfix {html_options} did not properly escape values (Issue 98) + +03.05.2012 +- bugfix make HTTP protocall version variable (issue 96) + +02.05.2012 +- bugfix {nocache}{block}{plugin}... did produce wrong compiled code when caching is disabled (Forum Topic 21572, issue 95) + +12.04.2012 +- bugfix Smarty did eat the linebreak after the <?xml...?> closing tag (Issue 93) +- bugfix concurrent cache updates could create a warning (Forum Topic 21403) + +08.04.2012 +- bugfix "\\" was not escaped correctly when generating nocache code (Forum Topic 21364) + +30.03.2012 +- bugfix template inheritance did not throw exception when a parent template was deleted (issue 90) + +27.03.2012 +- bugfix prefilter did run multiple times on inline subtemplates compiled into several main templates (Forum Topic 21325) +- bugfix implement Smarty2's behaviour of variables assigned by reference in SmartyBC. {assign} will affect all references. + (issue 88) + +21.03.2012 +- bugfix compileAllTemplates() and compileAllConfig() did not return the number of compiled files (Forum Topic 21286) + +13.03.2012 +- correction of yesterdays bugfix (Forum Topic 21175 and 21182) + +12.03.2012 +- bugfix a double quoted string of "$foo" did not compile into PHP "$foo" (Forum Topic 21175) +- bugfix template inheritance did set $merge_compiled_includes globally true + +03.03.2012 +- optimization of compiling speed when same modifier was used several times + +02.03.2012 +- enhancement the default plugin handler can now also resolve undefined modifier (Smarty::PLUGIN_MODIFIER) + (Issue 85) + +===== Smarty-3.1.8 ===== +19.02.2012 +- bugfix {include} could result in a fatal error if used in appended or prepended nested {block} tags + (reported by mh and Issue 83) +- enhancement added Smarty special variable $smarty.template_object to return the current template object (Forum Topic 20289) + + +07.02.2012 +- bugfix increase entropy of internal function names in compiled and cached template files (Forum Topic 20996) +- enhancement cacheable parameter added to default plugin handler, same functionality as in registerPlugin (request by calguy1000) + +06.02.2012 +- improvement stream_resolve_include_path() added to Smarty_Internal_Get_Include_Path (Forum Topic 20980) +- bugfix fetch('extends:foo.tpl') always yielded $source->exists == true (Forum Topic 20980) +- added modifier unescape:"url", fix (Forum Topic 20980) +- improvement replaced some calls of preg_replace with str_replace (Issue 73) + +30.01.2012 +- bugfix Smarty_Security internal $_resource_dir cache wasn't properly propagated + +27.01.2012 +- bugfix Smarty did not a template name of "0" (Forum Topic 20895) + +20.01.2012 +- bugfix typo in Smarty_Internal_Get_IncludePath did cause runtime overhead (Issue 74) +- improvment remove unneeded assigments (Issue 75 and 76) +- fixed typo in template parser +- bugfix output filter must not run before writing cache when template does contain nocache code (Issue 71) + +02.01.2012 +- bugfix {block foo nocache} did not load plugins within child {block} in nocache mode (Forum Topic 20753) + +29.12.2011 +- bugfix enable more entropy in Smarty_Internal_Write_File for "more uniqueness" and Cygwin compatibility (Forum Topic 20724) +- bugfix embedded quotes in single quoted strings did not compile correctly in {nocache} sections (Forum Topic 20730) + +28.12.2011 +- bugfix Smarty's internal header code must be excluded from postfilters (issue 71) + +22.12.2011 +- bugfix the new lexer of 17.12.2011 did fail if mbstring.func_overload != 0 (issue 70) (Forum Topic 20680) +- bugfix template inheritace did fail if mbstring.func_overload != 0 (issue 70) (Forum Topic 20680) + +20.12.2011 +- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return + content after {$smarty.block.child} (Forum Topic 20564) + +===== Smarty-3.1.7 ===== +18.12.2011 +- bugfix strings ending with " in multiline strings of config files failed to compile (issue #67) +- added chaining to Smarty_Internal_Templatebase +- changed unloadFilter() to not return a boolean in favor of chaining and API conformity +- bugfix unregisterObject() raised notice when object to unregister did not exist +- changed internals to use Smarty::$_MBSTRING ($_CHARSET, $_DATE_FORMAT) for better unit testing +- added Smarty::$_UTF8_MODIFIER for proper PCRE charset handling (Forum Topic 20452) +- added Smarty_Security::isTrustedUri() and Smarty_Security::$trusted_uri to validate + remote resource calls through {fetch} and {html_image} (Forum Topic 20627) + +17.12.2011 +- improvement of compiling speed by new handling of plain text blocks in the lexer/parser (issue #68) + +16.12.2011 +- bugfix the source exits flag and timestamp was not setup when template was in php include path (issue #69) + +9.12.2011 +- bugfix {capture} tags around recursive {include} calls did throw exception (Forum Topic 20549) +- bugfix $auto_literal = false did not work with { block} tags in child templates (Forum Topic 20581) +- bugfix template inheritance: do not include code of {include} in overloaded {block} into compiled + parent template (Issue #66} +- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return expected + result (Forum Topic 20564) + +===== Smarty-3.1.6 ===== +30.11.2011 +- bugfix is_cache() for individual cached subtemplates with $smarty->caching = CACHING_OFF did produce + an exception (Forum Topic 20531) + +29.11.2011 +- bugfix added exception if the default plugin handler did return a not static callback (Forum Topic 20512) + +25.11.2011 +- bugfix {html_select_date} and {html_slecet_time} did not default to current time if "time" was not specified + since r4432 (issue 60) + +24.11.2011 +- bugfix a subtemplate later used as main template did use old variable values + +21.11.2011 +- bugfix cache file could include unneeded modifier plugins under certain condition + +18.11.2011 +- bugfix declare all directory properties private to map direct access to getter/setter also on extended Smarty class + +16.11.2011 +- bugfix Smarty_Resource::load() did not always return a proper resource handler (Forum Topic 20414) +- added escape argument to html_checkboxes and html_radios (Forum Topic 20425) + +===== Smarty-3.1.5 ===== +14.11.2011 +- bugfix allow space between function name and open bracket (forum topic 20375) + +09.11.2011 +- bugfix different behaviour of uniqid() on cygwin. See https://bugs.php.net/bug.php?id=34908 + (forum topic 20343) + +01.11.2011 +- bugfix {if} and {while} tags without condition did not throw a SmartyCompilerException (Issue #57) +- bugfix multiline strings in config files could fail on longer strings (reopened Issue #55) + +22.10.2011 +- bugfix smarty_mb_from_unicode() would not decode unicode-points properly +- bugfix use catch Exception instead UnexpectedValueException in + clearCompiledTemplate to be PHP 5.2 compatible + +21.10.2011 +- bugfix apostrophe in plugins_dir path name failed (forum topic 20199) +- improvement sha1() for array keys longer than 150 characters +- add Smarty::$allow_ambiguous_resources to activate unique resource handling (Forum Topic 20128) + +20.10.2011 +- @silenced unlink() in Smarty_Internal_Write_File since debuggers go haywire without it. +- bugfix Smarty::clearCompiledTemplate() threw an Exception if $cache_id was not present in $compile_dir when $use_sub_dirs = true. +- bugfix {html_select_date} and {html_select_time} did not properly handle empty time arguments (Forum Topic 20190) +- improvement removed unnecessary sha1() + +19.10.2011 +- revert PHP4 constructor message +- fixed PHP4 constructor message + +===== Smarty-3.1.4 ===== +19.10.2011 +- added exception when using PHP4 style constructor + +16.10.2011 +- bugfix testInstall() did not propery check cache_dir and compile_dir + +15.10.2011 +- bugfix Smarty_Resource and Smarty_CacheResource runtime caching (Forum Post 75264) + +14.10.2011 +- bugfix unique_resource did not properly apply to compiled resources (Forum Topic 20128) +- add locking to custom resources (Forum Post 75252) +- add Smarty_Internal_Template::clearCache() to accompany isCached() fetch() etc. + +13.10.2011 +- add caching for config files in Smarty_Resource +- bugfix disable of caching after isCached() call did not work (Forum Topic 20131) +- add concept unique_resource to combat potentially ambiguous template_resource values when custom resource handlers are used (Forum Topic 20128) +- bugfix multiline strings in config files could fail on longer strings (Issue #55) + +11.10.2011 +- add runtime checks for not matching {capture}/{/capture} calls (Forum Topic 20120) + +10.10.2011 +- bugfix variable name typo in {html_options} and {html_checkboxes} (Issue #54) +- bugfix <?xml> tag did create wrong output when caching enabled and the tag was in included subtemplate +- bugfix Smarty_CacheResource_mysql example was missing strtotime() calls + +===== Smarty-3.1.3 ===== +07.10.2011 +- improvement removed html comments from {mailto} (Forum Topic 20092) +- bugfix testInstall() would not show path to internal plugins_dir (Forum Post 74627) +- improvement testInstall() now showing resolved paths and checking the include_path if necessary +- bugfix html_options plugin did not handle object values properly (Issue #49, Forum Topic 20049) +- improvement html_checkboxes and html_radios to accept null- and object values, and label_ids attribute +- improvement removed some unnecessary count()s +- bugfix parent pointer was not set when fetch() for other template was called on template object + +06.10.2011 +- bugfix switch lexer internals depending on mbstring.func_overload +- bugfix start_year and end_year of {html_select_date} did not use current year as offset base (Issue #53) + +05.10.2011 +- bugfix of problem introduced with r4342 by replacing strlen() with isset() +- add environment configuration issue with mbstring.func_overload Smarty cannot compensate for (Issue #45) +- bugfix nofilter tag option did not disable default modifier +- bugfix html_options plugin did not handle null- and object values properly (Issue #49, Forum Topic 20049) + +04.10.2011 +- bugfix assign() in plugins called in subtemplates did change value also in parent template +- bugfix of problem introduced with r4342 on math plugin +- bugfix output filter should not run on individually cached subtemplates +- add unloadFilter() method +- bugfix has_nocache_code flag was not reset before compilation + +===== Smarty-3.1.2 ===== +03.10.2011 +- improvement add internal $joined_template_dir property instead computing it on the fly several times + +01.10.2011 +- improvement replaced most in_array() calls by more efficient isset() on array_flip()ed haystacks +- improvement replaced some strlen($foo) > 3 calls by isset($foo[3]) +- improvement Smarty_Internal_Utility::clearCompiledTemplate() removed redundant strlen()s + +29.09.2011 +- improvement of Smarty_Internal_Config::loadConfigVars() dropped the in_array for index look up + +28.09.2011 +- bugfix on template functions called nocache calling other template functions + +27.09.2011 +- bugfix possible warning "attempt to modify property of non-object" in {section} (issue #34) +- added chaining to Smarty_Internal_Data so $smarty->assign('a',1)->assign('b',2); is possible now +- bugfix remove race condition when a custom resource did change timestamp during compilation +- bugfix variable property did not work on objects variable in template +- bugfix smarty_make_timestamp() failed to process DateTime objects properly +- bugfix wrong resource could be used on compile check of custom resource + +26.09.2011 +- bugfix repeated calls to same subtemplate did not make use of cached template object + +24.09.2011 +- removed internal muteExpectedErrors() calls in favor of having the implementor call this once from his application +- optimized muteExpectedErrors() to pass errors to the latest registered error handler, if appliccable +- added compile_dir and cache_dir to list of muted directories +- improvment better error message for undefined templates at {include} + +23.09.2011 +- remove unused properties +- optimization use real function instead anonymous function for preg_replace_callback +- bugfix a relative {include} in child template blocks failed +- bugfix direct setting of $template_dir, $config_dir, $plugins_dir in __construct() of an + extended Smarty class created problems +- bugfix error muting was not implemented for cache locking + +===== Smarty 3.1.1 ===== +22.09.2011 +- bugfix {foreachelse} does fail if {section} was nested inside {foreach} +- bugfix debug.tpl did not display correctly when it was compiled with escape_html = true + +21.09.2011 +- bugfix look for mixed case plugin file names as in 3.0 if not found try all lowercase +- added $error_muting to suppress error messages even for badly implemented error_handlers +- optimized autoloader +- reverted ./ and ../ handling in fetch() and display() - they're allowed again + +20.09.2011 +- bugfix removed debug echo output while compiling template inheritance +- bugfix relative paths in $template_dir broke relative path resolving in {include "../foo.tpl"} +- bugfix {include} did not work inside nested {block} tags +- bugfix {assign} with scope root and global did not work in all cases + +19.09.2011 +- bugfix regression in Smarty_CacheReource_KeyValueStore introduced by r4261 +- bugfix output filter shall not run on included subtemplates + +18.09.2011 +- bugfix template caching did not care about file.tpl in different template_dir +- bugfix {include $file} was broken when merge_compiled_incluges = true +- bugfix {include} was broken when merge_compiled_incluges = true and same indluded template + was used in different main templates in one compilation run +- bugfix for Smarty2 style compiler plugins on unnamed attribute passing like {tag $foo $bar} +- bugfix debug.tpl did not display correctly when it was compiled with escape_html = true + +17.09.2011 +- bugfix lock_id for file resource would create invalid filepath +- bugfix resource caching did not care about file.tpl in different template_dir + +===== Smarty 3.1.0 ===== +15/09/2011 +- optimization of {foreach}; call internal _count() method only when "total" or "last" {foreach} properties are used + +11/09/2011 +- added unregisterObject() method + +06/09/2011 +- bugfix isset() did not work in templates on config variables + +03/09/2011 +- bugfix createTemplate() must default to cache_id and compile_id of Smarty object +- bugfix Smarty_CacheResource_KeyValueStore must include $source->uid in cache filepath to keep templates with same + name but different folders seperated +- added cacheresource.apc.php example in demo folder + +02/09/2011 +- bugfix cache lock file must use absolute filepath + +01/09/2011 +- update of cache locking + +30/08/2011 +- added locking mechanism to CacheResource API (implemented with File and KeyValueStores) + +28/08/2011 +- bugfix clearCompileTemplate() did not work for specific template subfolder or resource + +27/08/2011 +- bugfix {$foo|bar+1} did create syntax error + +26/08/2011 +- bugfix when generating nocache code which contains double \ +- bugfix handle race condition if cache file was deleted between filemtime and include + +17/08/2011 +- bugfix CacheResource_Custom bad internal fetch() call + +15/08/2011 +- bugfix CacheResource would load content twice for KeyValueStore and Custom handlers + +06/08/2011 +- bugfix {include} with scope attribute could execute in wrong scope +- optimization of compile_check processing + +03/08/2011 +- allow comment tags to comment {block} tags out in child templates + +26/07/2011 +- bugfix experimental getTags() method did not work + +24/07/2011 +- sure opened output buffers are closed on exception +- bugfix {foreach} did not work on IteratorAggregate + +22/07/2011 +- clear internal caches on clearAllCache(), clearCache(), clearCompiledTemplate() + +21/07/2011 +- bugfix value changes of variable values assigned to Smarty object could not be seen on repeated $smarty->fetch() calls + +17/07/2011 +- bugfix {$smarty.block.child} did drop a notice at undefined child + +15/07/2011 +- bugfix individual cache_lifetime of {include} did not work correctly inside {block} tags +- added caches for Smarty_Template_Source and Smarty_Template_Compiled to reduce I/O for multiple cache_id rendering + +14/07/2011 +- made Smarty::loadPlugin() respect the include_path if required + +13/07/2011 +- optimized internal file write functionality +- bugfix PHP did eat line break on nocache sections +- fixed typo of Smarty_Security properties $allowed_modifiers and $disabled_modifiers + +06/07/2011 +- bugfix variable modifier must run befor gereral filtering/escaping + +04/07/2011 +- bugfix use (?P<name>) syntax at preg_match as some pcre libraries failed on (?<name>) +- some performance improvement when using generic getter/setter on template objects + +30/06/2011 +- bugfix generic getter/setter of Smarty properties used on template objects did throw exception +- removed is_dir and is_readable checks from directory setters for better performance + +28/06/2011 +- added back support of php template resource as undocumented feature +- bugfix automatic recompilation on version change could drop undefined index notice on old 3.0 cache and compiled files +- update of README_3_1_DEV.txt and moved into the distribution folder +- improvement show first characters of eval and string templates instead sha1 Uid in debug window + +===== Smarty 3.1-RC1 ===== +25/06/2011 +- revert change of 17/06/2011. $_smarty varibale removed. call loadPlugin() from inside plugin code if required +- code cleanup, remove no longer used properties and methods +- update of PHPdoc comments + +23/06/2011 +- bugfix {html_select_date} would not respect current time zone + +19/06/2011 +- added $errors argument to testInstall() functions to suppress output. +- added plugin-file checks to testInstall() + +18/06/2011 +- bugfix mixed use of same subtemplate inline and not inline in same script could cause a warning during compilation + +17/06/2011 +- bugfix/change use $_smarty->loadPlugin() when loading nested depending plugins via loadPlugin +- bugfix {include ... inline} within {block}...{/block} did fail + +16/06/2011 +- bugfix do not overwrite '$smarty' template variable when {include ... scope=parent} is called +- bugfix complete empty inline subtemplates did fail + +15/06/2011 +- bugfix template variables where not accessable within inline subtemplates + +12/06/2011 +- bugfix removed unneeded merging of template variable when fetching includled subtemplates + +10/06/2011 +- made protected properties $template_dir, $plugins_dir, $cache_dir, $compile_dir, $config_dir accessible via magic methods + +09/06/2011 +- fix smarty security_policy issue in plugins {html_image} and {fetch} + +05/06/2011 +- update of SMARTY_VERSION +- bugfix made getTags() working again + +04/06/2011 +- allow extends resource in file attribute of {extends} tag + +03/06/2011 +- added {setfilter} tag to set filters for variable output +- added escape_html property to control autoescaping of variable output + +27/05/2011 +- added allowed/disabled tags and modifiers in security for sandboxing + +23/05/2011 +- added base64: and urlencode: arguments to eval and string resource types + +22/05/2011 +- made time-attribute of {html_select_date} and {html_select_time} accept arrays as defined by attributes prefix and field_array + +13/05/2011 +- remove setOption / getOption calls from SamrtyBC class + +02/05/2011 +- removed experimental setOption() getOption() methods +- output returned content also on opening tag calls of block plugins +- rewrite of default plugin handler +- compile code of variable filters for better performance + +20/04/2011 +- allow {php} {include_php} tags and PHP_ALLOW handling only with the SmartyBC class +- removed support of php template resource + +20/04/2011 +- added extendsall resource example +- optimization of template variable access +- optimization of subtemplate handling {include} +- optimization of template class + +01/04/2011 +- bugfix quote handling in capitalize modifier + +28/03/2011 +- bugfix stripslashes() requried when using PCRE e-modifier + +04/03/2011 +- upgrade to new PHP_LexerGenerator version 0.4.0 for better performance + +27/02/2011 +- ignore .svn folders when clearing cache and compiled files +- string resources do not need a modify check + +26/02/2011 +- replaced smarty_internal_wrapper by SmartyBC class +- load utility functions as static methods instead through __call() +- bugfix in extends resource when subresources are used +- optimization of modify checks + +25/02/2011 +- use $smarty->error_unassigned to control NOTICE handling on unassigned variables + +21/02/2011 +- added new new compile_check mode COMPILECHECK_CACHEMISS +- corrected new cloning behaviour of createTemplate() +- do no longer store the compiler object as property in the compile_tag classes to avoid possible memory leaks + during compilation + +19/02/2011 +- optimizations on merge_compiled_includes handling +- a couple of optimizations and bugfixes related to new resource structure + +17/02/2011 +- changed ./ and ../ behaviour + +14/02/2011 +- added {block ... hide} option to supress block if no child is defined + +13/02/2011 +- update handling of recursive subtemplate calls +- bugfix replace $smarty->triggerError() by exception in smarty_internal_resource_extends.php + +12/02/2011 +- new class Smarty_Internal_TemplateBase with shared methods of Smarty and Template objects +- optimizations of template processing +- made register... methods permanet +- code for default_plugin_handler +- add automatic recompilation at version change + +04/02/2011 +- change in Smarty_CacheResource_Custom +- bugfix cache_lifetime did not compile correctly at {include} after last update +- moved isCached processing into CacheResource class +- bugfix new CacheResource API did not work with disabled compile_check + +03/02/2011 +- handle template content as function to improve speed on multiple calls of same subtemplate and isCached()/display() calls +- bugfixes and improvents in the new resource API +- optimizations of template class code + +25/01/2011 +- optimized function html_select_time + +22/01/2011 +- added Smarty::$use_include_path configuration directive for Resource API + +21/01/2011 +- optimized function html_select_date + +19/01/2011 +- optimized outputfilter trimwhitespace + +18/01/2011 +- bugfix Config to use Smarty_Resource to fetch sources +- optimized Smarty_Security's isTrustedDir() and isTrustedPHPDir() + +17/01/2011 +- bugfix HTTP headers for CGI SAPIs + +16/01/2011 +- optimized internals of Smarty_Resource and Smarty_CacheResource + +14/01/2011 +- added modifiercompiler escape to improve performance of escaping html, htmlall, url, urlpathinfo, quotes, javascript +- added support to choose template_dir to load from: [index]filename.tpl + +12/01/2011 +- added unencode modifier to revert results of encode modifier +- added to_charset and from_charset modifier for character encoding + +11/01/2011 +- added SMARTY_MBSTRING to generalize MBString detection +- added argument $lc_rest to modifier.capitalize to lower-case anything but the first character of a word +- changed strip modifier to consider unicode white-space, too +- changed wordwrap modifier to accept UTF-8 strings +- changed count_sentences modifier to consider unicode characters and treat sequences delimited by ? and ! as sentences, too +- added argument $double_encode to modifier.escape (applies to html and htmlall only) +- changed escape modifier to be UTF-8 compliant +- changed textformat block to be UTF-8 compliant +- optimized performance of mailto function +- fixed spacify modifier so characters are not prepended and appended, made it unicode compatible +- fixed truncate modifier to properly use mb_string if possible +- removed UTF-8 frenzy from count_characters modifier +- fixed count_words modifier to treat "hello-world" as a single word like str_count_words() does +- removed UTF-8 frenzy from upper modifier +- removed UTF-8 frenzy from lower modifier + +01/01/2011 +- optimize smarty_modified_escape for hex, hexentity, decentity. + +28/12/2010 +- changed $tpl_vars, $config_vars and $parent to belong to Smarty_Internal_Data +- added Smarty::registerCacheResource() for dynamic cache resource object registration + +27/12/2010 +- added Smarty_CacheResource API and refactored existing cache resources accordingly +- added Smarty_CacheResource_Custom and Smarty_CacheResource_Mysql + +26/12/2010 +- added Smarty_Resource API and refactored existing resources accordingly +- added Smarty_Resource_Custom and Smarty_Resource_Mysql +- bugfix Smarty::createTemplate() to return properly cloned template instances + +24/12/2010 +- optimize smarty_function_escape_special_chars() for PHP >= 5.2.3 + +===== SVN 3.0 trunk ===== +14/05/2011 +- bugfix error handling at stream resources + +13/05/2011 +- bugfix condition starting with "-" did fail at {if} and {while} tags + +22/04/2011 +- bugfix allow only fixed string as file attribute at {extends} tag + +01/04/2011 +- bugfix do not run filters and default modifier when displaying the debug template +- bugfix of embedded double quotes within multi line strings (""") + +29/03/2011 +- bugfix on error message in smarty_internal_compile_block.php +- bugfix mb handling in strip modifier +- bugfix for Smarty2 style registered compiler function on unnamed attribute passing like {tag $foo $bar} + +17/03/2011 +- bugfix on default {function} parameters when {function} was used in nocache sections +- bugfix on compiler object destruction. compiler_object property was by mistake unset. + +09/03/2011 +-bugfix a variable filter should run before modifers on an output tag (see change of 23/07/2010) + +08/03/2011 +- bugfix loading config file without section should load only defaults + +03/03/2011 +- bugfix "smarty" template variable was not recreated when cached templated had expired +- bugfix internal rendered_content must be cleared after subtemplate was included + +01/03/2011 +- bugfix replace modifier did not work in 3.0.7 on systems without multibyte support +- bugfix {$smarty.template} could return in 3.0.7 parent template name instead of + child name when it needed to compile + +25/02/2011 +- bugfix for Smarty2 style compiler plugins on unnamed attribute passing like {tag $foo $bar} + +24/02/2011 +- bugfix $smarty->clearCache('some.tpl') did by mistake cache the template object + +18/02/2011 +- bugfix removed possible race condition when isCached() was called for an individually cached subtemplate +- bugfix force default debug.tpl to be loaded by the file resource + +17/02/2011 +-improvement not to delete files starting with '.' from cache and template_c folders on clearCompiledTemplate() and clearCache() + +16/02/2011 +-fixed typo in exception message of Smarty_Internal_Template +-improvement allow leading spaces on } tag closing if auto_literal is enabled + +13/02/2011 +- bufix replace $smarty->triggerError() by exception +- removed obsolete {popup_init..} plugin from demo templates +- bugfix replace $smarty->triggerError() by exception in smarty_internal_resource_extends.php + +===== Smarty 3.0.7 ===== +09/02/2011 +- patched vulnerability when using {$smarty.template} + +01/02/2011 +- removed assert() from config and template parser + +31/01/2011 +- bugfix the lexer/parser did fail on special characters like VT + +16/01/2011 +-bugfix of ArrayAccess object handling in internal _count() method +-bugfix of Iterator object handling in internal _count() method + +14/01/2011 +-bugfix removed memory leak while processing compileAllTemplates + +12/01/2011 +- bugfix in {if} and {while} tag compiler when using assignments as condition and nocache mode + +10/01/2011 +- bugfix when using {$smarty.block.child} and name of {block} was in double quoted string +- bugfix updateParentVariables() was called twice when leaving {include} processing + +- bugfix mb_str_replace in replace and escape modifiers work with utf8 + +31/12/2010 +- bugfix dynamic configuration of $debugging_crtl did not work +- bugfix default value of $config_read_hidden changed to false +- bugfix format of attribute array on compiler plugins +- bugfix getTemplateVars() could return value from wrong scope + +28/12/2010 +- bugfix multiple {append} tags failed to compile. + +22/12/2010 +- update do not clone the Smarty object an internal createTemplate() calls to increase performance + +21/12/2010 +- update html_options to support class and id attrs + +17/12/2010 +- bugfix added missing support of $cache_attrs for registered plugins + +15/12/2010 +- bugfix assignment as condition in {while} did drop an E_NOTICE + +14/12/2010 +- bugfix when passing an array as default parameter at {function} tag + +13/12/2010 +- bugfix {$smarty.template} in child template did not return right content +- bugfix Smarty3 did not search the PHP include_path for template files + +===== Smarty 3.0.6 ===== + +12/12/2010 +- bugfix fixed typo regarding yesterdays change to allow streamWrapper + +11/12/2010 +- bugfix nested block tags in template inheritance child templates did not work correctly +- bugfix {$smarty.current_dir} in child template did not point to dir of child template +- bugfix changed code when writing temporary compiled files to allow stream_wrapper + +06/12/2010 +- bugfix getTemplateVars() should return 'null' instead dropping E_NOTICE on an unassigned variable + +05/12/2010 +- bugfix missing declaration of $smarty in Smarty class +- bugfix empty($foo) in {if} did drop a notice when $foo was not assigned + +01/12/2010 +- improvement of {debug} tag output + +27/11/2010 +-change run output filter before cache file is written. (same as in Smarty2) + +24/11/2011 +-bugfix on parser at !$foo|modifier +-change parser logic when assignments used as condition in {if] and {while} to allow assign to array element + +23/11/2011 +-bugfix allow integer as attribute name in plugin calls +-change trimm whitespace from error message, removed long list of expected tokens + +22/11/2010 +- bugfix on template inheritance when an {extends} tag was inserted by a prefilter +- added error message for illegal variable file attributes at {extends...} tags + +===== Smarty 3.0.5 ===== + + +19/11/2010 +- bugfix on block plugins with modifiers + +18/11/2010 +- change on handling of unassigned template variable -- default will drop E_NOTICE +- bugfix on Smarty2 wrapper load_filter() did not work + +17/11/2010 +- bugfix on {call} with variable function name +- bugfix on {block} if name did contain '-' +- bugfix in function.fetch.php , referece to undefined $smarty + +16/11/2010 +- bugfix whitespace in front of "<?php" in smarty_internal_compile_private_block_plugin.php +- bugfix {$smarty.now} did compile incorrectly +- bugfix on reset(),end(),next(),prev(),current() within templates +- bugfix on default parameter for {function} + +15/11/2010 +- bugfix when using {$smarty.session} as object +- bugfix scoping problem on $smarty object passed to filters +- bugfix captured content could not be accessed globally +- bugfix Smarty2 wrapper functions could not be call from within plugins + +===== Smarty 3.0.4 ===== + +14/11/2010 +- bugfix isset() did not allow multiple parameter +- improvment of some error messages +- bugfix html_image did use removed property $request_use_auto_globals +- small performace patch in Smarty class + +13/11/2010 +- bugfix overloading problem when $smarty->fetch()/display() have been used in plugins + (introduced with 3.0.2) +- code cleanup + +===== Smarty 3.0.3 ===== + +13/11/2010 +- bugfix on {debug} +- reverted location of loadPlugin() to Smarty class +- fixed comments in plugins +- fixed internal_config (removed unwanted code line) +- improvement remove last linebreak from {function} definition + +===== Smarty 3.0.2 ===== + +12/11/2010 +- reactivated $error_reporting property handling +- fixed typo in compile_continue +- fixed security in {fetch} plugin +- changed back plugin parameters to two. second is template object + with transparent access to Smarty object +- fixed {config_load} scoping form compile time to run time + +===== Smarty 3.0.0 ===== + + + +11/11/2010 +- major update including some API changes + +10/11/2010 +- observe compile_id also for config files + +09/11/2010 +-bugfix on complex expressions as start value for {for} tag +request_use_auto_globals +04/11/2010 +- bugfix do not allow access of dynamic and private object members of assigned objects when + security is enabled. + +01/11/2010 +- bugfix related to E_NOTICE change. {if empty($foo)} did fail when $foo contained a string + +28/10/2010 +- bugfix on compiling modifiers within $smarty special vars like {$smarty.post.{$foo|lower}} + +27/10/2010 +- bugfix default parameter values did not work for template functions included with {include} + +25/10/2010 +- bugfix for E_NOTICE change, array elements did not work as modifier parameter + +20/10/2010 +- bugfix for the E_NOTICE change + +19/10/2010 +- change Smarty does no longer mask out E_NOTICE by default during template processing + +13/10/2010 +- bugfix removed ambiguity between ternary and stream variable in template syntax +- bugfix use caching properties of template instead of smarty object when compiling child {block} +- bugfix {*block}...{/block*} did throw an exception in template inheritance +- bugfix on template inheritance using nested eval or string resource in {extends} tags +- bugfix on output buffer handling in isCached() method + +===== RC4 ===== + +01/10/2010 +- added {break} and {continue} tags for flow control of {foreach},{section},{for} and {while} loops +- change of 'string' resource. It's no longer evaluated and compiled files are now stored +- new 'eval' resource which evaluates a template without saving the compiled file +- change in isCached() method to allow multiple calls for the same template + +25/09/2010 +- bugfix on some compiling modifiers + +24/09/2010 +- bugfix merge_compiled_includes flag was not restored correctly in {block} tag + +22/09/2010 +- bugfix on default modifier + +18/09/2010 +- bugfix untility compileAllConfig() did not create sha1 code for compiled template file names if template_dir was defined with no trailing DS +- bugfix on templateExists() for extends resource + +17/09/2010 +- bugfix {$smarty.template} and {$smarty.current_dir} did not compile correctly within {block} tags +- bugfix corrected error message on missing template files in extends resource +- bugfix untility compileAllTemplates() did not create sha1 code for compiled template file names if template_dir was defined with no trailing DS + +16/09/2010 +- bugfix when a doublequoted modifier parameter did contain Smarty tags and ':' + +15/09/2010 +- bugfix resolving conflict between '<%'/'%>' as custom Smarty delimiter and ASP tags +- use ucfirst for resource name on internal resource class names + +12/09/2010 +- bugfix for change of 08/09/2010 (final {block} tags in subtemplates did not produce correct results) + +10/09/2010 +- bugfix for change of 08/09/2010 (final {block} tags in subtemplates did not produce correct results) + +08/09/2010 +- allow multiple template inheritance branches starting in subtemplates + +07/09/2010 +- bugfix {counter} and {cycle} plugin assigned result to smarty variable not in local(template) scope +- bugfix templates containing just {strip} {/strip} tags did produce an error + + +23/08/2010 +- fixed E_STRICT errors for uninitialized variables + +22/08/2010 +- added attribute cache_id to {include} tag + +13/08/2010 +- remove exception_handler property from Smarty class +- added Smarty's own exceptions SmartyException and SmartyCompilerException + +09/08/2010 +- bugfix on modifier with doublequoted strings as parameter containing embedded tags + +06/08/2010 +- bugfix when cascading some modifier like |strip|strip_tags modifier + +05/08/2010 +- added plugin type modifiercompiler to produce compiled modifier code +- changed standard modifier plugins to the compiling versions whenever possible +- bugfix in nocache sections {include} must not cache the subtemplate + +02/08/2010 +- bugfix strip did not work correctly in conjunction with comment lines + +31/07/2010 +- bugfix on nocache attribute at {assign} and {append} + +30/07/2010 +- bugfix passing scope attributes in doublequoted strings did not work at {include} {assign} and {append} + +25/07/2010 +- another bugfix of change from 23/07/2010 when compiling modifer + +24/07/2010 +- bugfix of change from 23/07/2010 when compiling modifer + +23/07/2010 +- changed execution order. A variable filter does now run before modifiers on output of variables +- bugfix use always { and } as delimiter for debug.tpl + + +22/07/2010 +- bugfix in templateExists() method + +20/07/2010 +- fixed handling of { strip } tag with whitespaces + +15/07/2010 +- bufix {$smarty.template} does include now the relative path, not just filename + +===== RC3 ===== + + + + +15/07/2010 +- make the date_format modifier work also on objects of the DateTime class +- implementation of parsetrees in the parser to close security holes and remove unwanted empty line in HTML output + +08/07/2010 +- bugfix on assigning multidimensional arrays within templates +- corrected bugfix for truncate modifier + +07/07/2010 +- bugfix the truncate modifier needs to check if the string is utf-8 encoded or not +- bugfix support of script files relative to trusted_dir + +06/07/2010 +- create exception on recursive {extends} calls +- fixed reported line number at "unexpected closing tag " exception +- bugfix on escape:'mail' modifier +- drop exception if 'item' variable is equal 'from' variable in {foreach} tag + +01/07/2010 +- removed call_user_func_array calls for optimization of compiled code when using registered modifiers and plugins + +25/06/2010 +- bugfix escaping " when block tags are used within doublequoted strings + +24/06/2010 +- replace internal get_time() calls with standard PHP5 microtime(true) calls in Smarty_Internal_Utility +- added $smarty->register->templateClass() and $smarty->unregister->templateClass() methods for supporting static classes with namespace + + +22/06/2010 +- allow spaces between typecast and value in template syntax +- bugfix get correct count of traversables in {foreach} tag + +21/06/2010 +- removed use of PHP shortags SMARTY_PHP_PASSTHRU mode +- improved speed of cache->clear() when a compile_id was specified and use_sub_dirs is true + +20/06/2010 +- replace internal get_time() calls with standard PHP5 microtime(true) calls +- closed security hole when php.ini asp_tags = on + +18/06/2010 +- added __toString method to the Smarty_Variable class + + +14/06/2010 +- make handling of Smarty comments followed by newline BC to Smarty2 + + +===== RC2 ===== + + + +13/06/2010 +- bugfix Smarty3 did not handle hexadecimals like 0x0F as numerical value +- bugifx Smarty3 did not accept numerical constants like .1 or 2. (without a leading or trailing digit) + +11/06/2010 +- bugfix the lexer did fail on larger {literal} ... {/literal} sections + +03/06/2010 +- bugfix on calling template functions like Smarty tags + +01/06/2010 +- bugfix on template functions used with template inheritance +- removed /* vim: set expandtab: */ comments +- bugfix of auto literal problem introduce with fix of 31/05/2010 + +31/05/2010 +- bugfix the parser did not allow some smarty variables with special name like $for, $if, $else and others. + +27/05/2010 +- bugfix on object chaining using variable properties +- make scope of {counter} and {cycle} tags again global as in Smarty2 + +26/05/2010 +- bugfix removed decrepated register_resource call in smarty_internal_template.php + +25/05/2010 +- rewrite of template function handling to improve speed +- bugfix on file dependency when merge_compiled_includes = true + + +16/05/2010 +- bugfix when passing parameter with numeric name like {foo 1='bar' 2='blar'} + +14/05/2010 +- bugfix compile new config files if compile_check and force_compile = false +- added variable static classes names to template syntax + +11/05/2010 +- bugfix make sure that the cache resource is loaded in all conditions when template methods getCached... are called externally +- reverted the change 0f 30/04/2010. With the exception of forward references template functions can be again called by a standard tag. + +10/05/2010 +- bugfix on {foreach} and {for} optimizations of 27/04/2010 + +09/05/2010 +- update of template and config file parser because of minor parser generator bugs + +07/05/2010 +- bugfix on {insert} + +06/05/2010 +- bugfix when merging compiled templates and objects are passed as parameter of the {include} tag + +05/05/2010 +- bugfix on {insert} to cache parameter +- implementation of $smarty->default_modifiers as in Smarty2 +- bugfix on getTemplateVars method + +01/05/2010 +- bugfix on handling of variable method names at object chaning + +30/04/2010 +- bugfix when comparing timestamps in sysplugins/smarty_internal_config.php +- work around of a substr_compare bug in older PHP5 versions +- bugfix on template inheritance for tag names starting with "block" +- bugfix on {function} tag with name attribute in doublequoted strings +- fix to make calling of template functions unambiguously by madatory usage of the {call} tag + +===== RC1 ===== + +27/04/2010 +- change default of $debugging_ctrl to 'NONE' +- optimization of compiled code of {foreach} and {for} loops +- change of compiler for config variables + +27/04/2010 +- bugfix in $smarty->cache->clear() method. (do not cache template object) + + +17/04/2010 +- security fix in {math} plugin + + +12/04/2010 +- bugfix in smarty_internal_templatecompilerbase (overloaded property) +- removed parser restrictions in using true,false and null as ID + +07/04/2010 +- bugfix typo in smarty_internal_templatecompilerbase + +31/03/2010 +- compile locking by touching old compiled files to avoid concurrent compilations + +29/03/2010 +- bugfix allow array definitions as modifier parameter +- bugfix observe compile_check property when loading config files +- added the template object as third filter parameter + +25/03/2010 +- change of utility->compileAllTemplates() log messages +- bugfix on nocache code in {function} tags +- new method utility->compileAllConfig() to compile all config files + +24/03/2010 +- bugfix on register->modifier() error messages + +23/03/2010 +- bugfix on template inheritance when calling multiple child/parent relations +- bugfix on caching mode SMARTY_CACHING_LIFETIME_SAVED and cache_lifetime = 0 + +22/03/2010 +- bugfix make directory separator operating system independend in compileAllTemplates() + +21/03/2010 +- removed unused code in compileAllTemplates() + +19/03/2010 +- bugfix for multiple {/block} tags on same line + +17/03/2010 +- bugfix make $smarty->cache->clear() function independent from caching status + +16/03/2010 +- bugfix on assign attribute at registered template objects +- make handling of modifiers on expression BC to Smarty2 + +15/03/2010 +- bugfix on block plugin calls + +11/03/2010 +- changed parsing of <?php and ?> back to Smarty2 behaviour + +08/03/2010 +- bugfix on uninitialized properties in smarty_internal_template +- bugfix on $smarty->disableSecurity() + +04/03/2010 +- bugfix allow uppercase chars in registered resource names +- bugfix on accessing chained objects of static classes + +01/03/2010 +- bugfix on nocache code in {block} tags if child template was included by {include} + +27/02/2010 +- allow block tags inside double quoted string + +26/02/2010 +- cache modified check implemented +- support of access to a class constant from an object (since PHP 5.3) + +24/02/2010 +- bugfix on expressions in doublequoted string enclosed in backticks +- added security property $static_classes for static class security + +18/02/2010 +- bugfix on parsing Smarty tags inside <?xml ... ?> +- bugfix on truncate modifier + +17/02/2010 +- removed restriction that modifiers did require surrounding parenthesis in some cases +- added {$smarty.block.child} special variable for template inheritance + +16/02/2010 +- bugfix on <?xml ... ?> tags for all php_handling modes +- bugfix on parameter of variablefilter.htmlspecialchars.php plugin + +14/02/2010 +- added missing _plugins property in smarty.class.php +- bugfix $smarty.const... inside doublequoted strings and backticks was compiled into wrong PHP code + +12/02/2010 +- bugfix on nested {block} tags +- changed Smarty special variable $smarty.parent to $smarty.block.parent +- added support of nested {bock} tags + +10/02/2010 +- avoid possible notice on $smarty->cache->clear(...), $smarty->clear_cache(....) +- allow Smarty tags inside <? ... ?> tags in SMARTY_PHP_QUOTE and SMARTY_PHP_PASSTHRU mode +- bugfix at new "for" syntax like {for $x=1 to 10 step 2} + +09/02/2010 +- added $smarty->_tag_stack for tracing block tag hierarchy + +08/02/2010 +- bugfix use template fullpath at §smarty->cache->clear(...), $smarty->clear_cache(....) +- bugfix of cache filename on extended templates when force_compile=true + +07/02/2010 +- bugfix on changes of 05/02/2010 +- preserve line endings type form template source +- API changes (see README file) + +05/02/2010 +- bugfix on modifier and block plugins with same name + +02/02/2010 +- retaining newlines at registered functions and function plugins + +01/25/2010 +- bugfix cache resource was not loaded when caching was globally off but enabled at a template object +- added test that $_SERVER['SCRIPT_NAME'] does exist in Smarty.class.php + +01/22/2010 +- new method $smarty->createData([$parent]) for creating a data object (required for bugfixes below) +- bugfix config_load() method now works also on a data object +- bugfix get_config_vars() method now works also on a data and template objects +- bugfix clear_config() method now works also on a data and template objects + +01/19/2010 +- bugfix on plugins if same plugin was called from a nocache section first and later from a cached section + + +###beta 7### + + +01/17/2010 +- bugfix on $smarty.const... in double quoted strings + +01/16/2010 +- internal change of config file lexer/parser on handling of section names +- bugfix on registered objects (format parameter of register_object was not handled correctly) + +01/14/2010 +- bugfix on backslash within single quoted strings +- bugfix allow absolute filepath for config files +- bugfix on special Smarty variable $smarty.cookies +- revert handling of newline on no output tags like {if...} +- allow special characters in config file section names for Smarty2 BC + +01/13/2010 +- bugfix on {if} tags + +01/12/2010 +- changed back modifer handling in parser. Some restrictions still apply: + if modifiers are used in side {if...} expression or in mathematical expressions + parentheses must be used. +- bugfix the {function..} tag did not accept the name attribute in double quotes +- closed possible security hole at <?php ... ?> tags +- bugfix of config file parser on large config files + + +###beta 6#### + +01/11/2010 +- added \n to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source +- added missing support of insert plugins +- added optional nocache attribute to {block} tags in parent template +- updated <?php...?> handling supporting now heredocs and newdocs. (thanks to Thue Jnaus Kristensen) + +01/09/2010 +- bugfix on nocache {block} tags in parent templates + +01/08/2010 +- bugfix on variable filters. filter/nofilter attributes did not work on output statements + +01/07/2010 +- bugfix on file dependency at template inheritance +- bugfix on nocache code at template inheritance + +01/06/2010 +- fixed typo in smarty_internal_resource_registered +- bugfix for custom delimiter at extends resource and {extends} tag + +01/05/2010 +- bugfix sha1() calculations at extends resource and some general improvments on sha1() handling + + +01/03/2010 +- internal change on building cache files + +01/02/2010 +- update cached_timestamp at the template object after cache file is written to avoid possible side effects +- use internally always SMARTY_CACHING_LIFETIME_* constants + +01/01/2010 +- bugfix for obtaining plugins which must be included (related to change of 12/30/2009) +- bugfix for {php} tag (trow an exception if allow_php_tag = false) + +12/31/2009 +- optimization of generated code for doublequoted strings containing variables +- rewrite of {function} tag handling + - can now be declared in an external subtemplate + - can contain nocache sections (nocache_hash handling) + - can be called in noccache sections (nocache_hash handling) + - new {call..} tag to call template functions with a variable name {call name=$foo} +- fixed nocache_hash handling in merged compiled templates + +12/30/2009 +- bugfix for plugins defined in the script as smarty_function_foo + +12/29/2009 +- use sha1() for filepath encoding +- updates on nocache_hash handling +- internal change on merging some data +- fixed cache filename for custom resources + +12/28/2009 +- update for security fixes +- make modifier plugins always trusted +- fixed bug loading modifiers in child template at template inheritance + +12/27/2009 +--- this is a major update with a couple of internal changes --- +- new config file lexer/parser (thanks to Thue Jnaus Kristensen) +- template lexer/parser fixes for PHP and {literal} handing (thanks to Thue Jnaus Kristensen) +- fix on registered plugins with different type but same name +- rewrite of plugin handling (optimized execution speed) +- closed a security hole regarding PHP code injection into cache files +- fixed bug in clear cache handling +- Renamed a couple of internal classes +- code cleanup for merging compiled templates +- couple of runtime optimizations (still not all done) +- update of getCachedTimestamp() +- fixed bug on modifier plugins at nocache output + +12/19/2009 +- bugfix on comment lines in config files + +12/17/2009 +- bugfix of parent/global variable update at included/merged subtemplates +- encode final template filepath into filename of compiled and cached files +- fixed {strip} handling in auto literals + +12/16/2009 +- update of changelog +- added {include file='foo.tpl' inline} inline option to merge compiled code of subtemplate into the calling template + +12/14/2009 +- fixed sideefect of last modification (objects in array index did not work anymore) + +12/13/2009 +- allow boolean negation ("!") as operator on variables outside {if} tag + +12/12/2009 +- bugfix on single quotes inside {function} tag +- fix short append/prepend attributes in {block} tags + +12/11/2009 +- bugfix on clear_compiled_tpl (avoid possible warning) + +12/10/2009 +- bugfix on {function} tags and template inheritance + +12/05/2009 +- fixed problem when a cached file was fetched several times +- removed unneeded lexer code + +12/04/2009 +- added max attribute to for loop +- added security mode allow_super_globals + +12/03/2009 +- template inheritance: child templates can now call functions defined by the {function} tag in the parent template +- added {for $foo = 1 to 5 step 2} syntax +- bugfix for {$foo.$x.$y.$z} + +12/01/2009 +- fixed parsing of names of special formated tags like if,elseif,while,for,foreach +- removed direct access to constants in templates because of some syntax problems +- removed cache resource plugin for mysql from the distribution +- replaced most hard errors (exceptions) by softerrors(trigger_error) in plugins +- use $template_class property for template class name when compiling {include},{eval} and {extends} tags + +11/30/2009 +- map 'true' to SMARTY_CACHING_LIFETIME_CURRENT for the $smarty->caching parameter +- allow {function} tags within {block} tags + +11/28/2009 +- ignore compile_id at debug template +- added direct access to constants in templates +- some lexer/parser optimizations + +11/27/2009 +- added cache resource MYSQL plugin + +11/26/2009 +- bugfix on nested doublequoted strings +- correct line number on unknown tag error message +- changed {include} compiled code +- fix on checking dynamic varibales with error_unassigned = true + +11/25/2009 +- allow the following writing for boolean: true, TRUE, True, false, FALSE, False +- {strip} tag functionality rewritten + +11/24/2009 +- bugfix for $smarty->config_overwrite = false + +11/23/2009 +- suppress warnings on unlink caused by race conditions +- correct line number on unknown tag error message + +------- beta 5 +11/23/2009 +- fixed configfile parser for text starting with a numeric char +- the default_template_handler_func may now return a filepath to a template source + +11/20/2009 +- bugfix for empty config files +- convert timestamps of registered resources to integer + +11/19/2009 +- compiled templates are no longer touched with the filemtime of template source + +11/18/2009 +- allow integer as attribute name in plugin calls + +------- beta 4 +11/18/2009 +- observe umask settings when setting file permissions +- avoide unneeded cache file creation for subtemplates which did occur in some situations +- make $smarty->_current_file available during compilation for Smarty2 BC + +11/17/2009 +- sanitize compile_id and cache_id (replace illegal chars with _) +- use _dir_perms and _file_perms properties at file creation +- new constant SMARTY_RESOURCE_DATE_FORMAT (default '%b %e, %Y') which is used as default format in modifier date_format +- added {foreach $array as $key=>$value} syntax +- renamed extend tag and resource to extends: {extends file='foo.tol'} , $smarty->display('extends:foo.tpl|bar.tpl); +- bugfix cycle plugin + +11/15/2009 +- lexer/parser optimizations on quoted strings + +11/14/2009 +- bugfix on merging compiled templates when source files got removed or renamed. +- bugfix modifiers on registered object tags +- fixed locaion where outputfilters are running +- fixed config file definitions at EOF +- fix on merging compiled templates with nocache sections in nocache includes +- parser could run into a PHP error on wrong file attribute + +11/12/2009 +- fixed variable filenames in {include_php} and {insert} +- added scope to Smarty variables in the {block} tag compiler +- fix on nocache code in child {block} tags + +11/11/2009 +- fixed {foreachelse}, {forelse}, {sectionelse} compiled code at nocache variables +- removed checking for reserved variables +- changed debugging handling + +11/10/2009 +- fixed preg_qoute on delimiters + +11/09/2009 +- lexer/parser bugfix +- new SMARTY_SPL_AUTOLOAD constant to control the autoloader option +- bugfix for {function} block tags in included templates + +11/08/2009 +- fixed alphanumeric array index +- bugfix on complex double quoted strings + +11/05/2009 +- config_load method can now be called on data and template objects + +11/04/2009 +- added typecasting support for template variables +- bugfix on complex indexed special Smarty variables + +11/03/2009 +- fixed parser error on objects with special smarty vars +- fixed file dependency for {incude} inside {block} tag +- fixed not compiling on non existing compiled templates when compile_check = false +- renamed function names of autoloaded Smarty methods to Smarty_Method_.... +- new security_class property (default is Smarty_Security) + +11/02/2009 +- added neq,lte,gte,mod as aliases to if conditions +- throw exception on illegal Smarty() constructor calls + +10/31/2009 +- change of filenames in sysplugins folder for internal spl_autoload function +- lexer/parser changed for increased compilation speed + +10/27/2009 +- fixed missing quotes in include_php.php + +10/27/2009 +- fixed typo in method.register_resource +- pass {} through as literal + +10/26/2009 +- merge only compiled subtemplates into the compiled code of the main template + +10/24/2009 +- fixed nocache vars at internal block tags +- fixed merging of recursive includes + +10/23/2009 +- fixed nocache var problem + +10/22/2009 +- fix trimwhitespace outputfilter parameter + +10/21/2009 +- added {$foo++}{$foo--} syntax +- buxfix changed PHP "if (..):" to "if (..){" because of possible bad code when concenating PHP tags +- autoload Smarty internal classes +- fixed file dependency for config files +- some code optimizations +- fixed function definitions on some autoloaded methods +- fixed nocache variable inside if condition of {if} tag + +10/20/2009 +- check at compile time for variable filter to improve rendering speed if no filter is used +- fixed bug at combination of {elseif} tag and {...} in double quoted strings of static class parameter + +10/19/2009 +- fixed compiled template merging on variable double quoted strings as name +- fixed bug in caching mode 2 and cache_lifetime -1 +- fixed modifier support on block tags + +10/17/2009 +- remove ?>\n<?php and ?><?php sequences from compiled template + +10/15/2009 +- buxfix on assigning array elements inside templates +- parser bugfix on array access + +10/15/2009 +- allow bit operator '&' inside {if} tag +- implementation of ternary operator + +10/13/2009 +- do not recompile evaluated templates if reused just with other data +- recompile config files when config properties did change +- some lexer/parser otimizations + +10/11/2009 +- allow {block} tags inside included templates +- bugfix for resource plugins in Smarty2 format +- some optimizations of internal.template.php + +10/11/2009 +- fixed bug when template with same name is used with different data objects +- fixed bug with double quoted name attribute at {insert} tag +- reenabled assign_by_ref and append_by_ref methods + +10/07/2009 +- removed block nesting checks for {capture} + +10/05/2009 +- added support of "isinstance" to {if} tag + +10/03/2009 +- internal changes to improve performance +- fix registering of filters for classes + +10/01/2009 +- removed default timezone setting +- reactivated PHP resource for simple PHP templates. Must set allow_php_templates = true to enable +- {PHP} tag can be enabled by allow_php_tag = true + +09/30/2009 +- fixed handling template_exits method for all resource types +- bugfix for other cache resources than file +- the methods assign_by_ref is now wrapped to assign, append_by_ref to append +- allow arrays of variables pass in display, fetch and createTemplate calls + $data = array('foo'=>'bar','foo2'=>'blar'); + $smarty->display('my.tpl',$data); + +09/29/2009 +- changed {php} tag handling +- removed support of Smarty::instance() +- removed support of PHP resource type +- improved execution speed of {foreach} tags +- fixed bug in {section} tag + +09/23/2009 +- improvements and bugfix on {include} tag handling +NOTICE: existing compiled template and cache files must be deleted + +09/19/2009 +- replace internal "eval()" calls by "include" during rendering process +- speed improvment for templates which have included subtemplates + the compiled code of included templates is merged into the compiled code of the parent template +- added logical operator "xor" for {if} tag +- changed parameter ordering for Smarty2 BC + fetch($template, $cache_id = null, $compile_id = null, $parent = null) + display($template, $cache_id = null, $compile_id = null, $parent = null) + createTemplate($template, $cache_id = null, $compile_id = null, $parent = null) +- property resource_char_set is now replaced by constant SMARTY_RESOURCE_CHAR_SET +- fixed handling of classes in registered blocks +- speed improvement of lexer on text sections + +09/01/2009 +- dropped nl2br as plugin +- added '<>' as comparission operator in {if} tags +- cached caching_lifetime property to cache_liftime for backward compatibility with Smarty2. + {include} optional attribute is also now cache_lifetime +- fixed trigger_error method (moved into Smarty class) +- version is now Beta!!! + + +08/30/2009 +- some speed optimizations on loading internal plugins + + +08/29/2009 +- implemented caching of registered Resources +- new property 'auto_literal'. if true(default) '{ ' and ' }' interpreted as literal, not as Smarty delimiter + + +08/28/2009 +- Fix on line breaks inside {if} tags + +08/26/2009 +- implemented registered resources as in Smarty2. NOTE: caching does not work yet +- new property 'force_cache'. if true it forces the creation of a new cache file +- fixed modifiers on arrays +- some speed optimization on loading internal classes + + +08/24/2009 +- fixed typo in lexer definition for '!==' operator +- bugfix - the ouput of plugins was not cached +- added global variable SCRIPT_NAME + +08/21/2009 +- fixed problems whitespace in conjuction with custom delimiters +- Smarty tags can now be used as value anywhere + +08/18/2009 +- definition of template class name moded in internal.templatebase.php +- whitespace parser changes + +08/12/2009 +- fixed parser problems + +08/11/2009 +- fixed parser problems with custom delimiter + +08/10/2009 +- update of mb support in plugins + + +08/09/2009 +- fixed problems with doublequoted strings at name attribute of {block} tag +- bugfix at scope attribute of {append} tag + +08/08/2009 +- removed all internal calls of Smarty::instance() +- fixed code in double quoted strings + +08/05/2009 +- bugfix mb_string support +- bugfix of \n.\t etc in double quoted strings + +07/29/2009 +- added syntax for variable config vars like #$foo# + +07/28/2009 +- fixed parsing of $smarty.session vars containing objects + +07/22/2009 +- fix of "$" handling in double quoted strings + +07/21/2009 +- fix that {$smarty.current_dir} return correct value within {block} tags. + +07/20/2009 +- drop error message on unmatched {block} {/block} pairs + +07/01/2009 +- fixed smarty_function_html_options call in plugin function.html_select_date.php (missing ,) + +06/24/2009 +- fixed smarty_function_html_options call in plugin function.html_select_date.php + +06/22/2009 +- fix on \n and spaces inside smarty tags +- removed request_use_auto_globals propert as it is no longer needed because Smarty 3 will always run under PHP 5 + + +06/18/2009 +- fixed compilation of block plugins when caching enabled +- added $smarty.current_dir which returns the current working directory + +06/14/2009 +- fixed array access on super globals +- allow smarty tags within xml tags + +06/13/2009 +- bugfix at extend resource: create unique files for compiled template and cache for each combination of template files +- update extend resource to handle appen and prepend block attributes +- instantiate classes of plugins instead of calling them static + +06/03/2009 +- fixed repeat at block plugins + +05/25/2009 +- fixed problem with caching of compiler plugins + +05/14/2009 +- fixed directory separator handling + +05/09/2009 +- syntax change for stream variables +- fixed bug when using absolute template filepath and caching + +05/08/2009 +- fixed bug of {nocache} tag in included templates + +05/06/2009 +- allow that plugins_dir folder names can end without directory separator + +05/05/2009 +- fixed E_STRICT incompabilities +- {function} tag bug fix +- security policy definitions have been moved from plugins folder to file Security.class.php in libs folder +- added allow_super_global configuration to security + +04/30/2009 +- functions defined with the {function} tag now always have global scope + +04/29/2009 +- fixed problem with directory setter methods +- allow that cache_dir can end without directory separator + +04/28/2009 +- the {function} tag can no longer overwrite standard smarty tags +- inherit functions defined by the {fuction} tag into subtemplates +- added {while <statement>} sytax to while tag + +04/26/2009 +- added trusted stream checking to security +- internal changes at file dependency check for caching + +04/24/2009 +- changed name of {template} tag to {function} +- added new {template} tag + +04/23/2009 +- fixed access of special smarty variables from included template + +04/22/2009 +- unified template stream syntax with standard Smarty resource syntax $smarty->display('mystream:mytemplate') + +04/21/2009 +- change of new style syntax for forach. Now: {foreach $array as $var} like in PHP + +04/20/2009 +- fixed "$foo.bar ..." variable replacement in double quoted strings +- fixed error in {include} tag with variable file attribute + +04/18/2009 +- added stream resources ($smarty->display('mystream://mytemplate')) +- added stream variables {$mystream:myvar} + +04/14/2009 +- fixed compile_id handling on {include} tags +- fixed append/prepend attributes in {block} tag +- added {if 'expression' is in 'array'} syntax +- use crc32 as hash for compiled config files. + +04/13/2009 +- fixed scope problem with parent variables when appending variables within templates. +- fixed code for {block} without childs (possible sources for notice errors removed) + +04/12/2009 +- added append and prepend attribute to {block} tag + +04/11/2009 +- fixed variables in 'file' attribute of {extend} tag +- fixed problems in modifiers (if mb string functions not present) + +04/10/2009 +- check if mb string functions available otherwise fallback to normal string functions +- added global variable scope SMARTY_GLOBAL_SCOPE +- enable 'variable' filter by default +- fixed {$smarty.block.parent.foo} +- implementation of a 'variable' filter as replacement for default modifier + +04/09/2009 +- fixed execution of filters defined by classes +- compile the always the content of {block} tags to make shure that the filters are running over it +- syntax corrections on variable object property +- syntax corrections on array access in dot syntax + +04/08/2009 +- allow variable object property + +04/07/2009 +- changed variable scopes to SMARTY_LOCAL_SCOPE, SMARTY_PARENT_SCOPE, SMARTY_ROOT_SCOPE to avoid possible conflicts with user constants +- Smarty variable global attribute replaced with scope attribute + +04/06/2009 +- variable scopes LOCAL_SCOPE, PARENT_SCOPE, ROOT_SCOPE +- more getter/setter methods + +04/05/2009 +- replaced new array looping syntax {for $foo in $array} with {foreach $foo in $array} to avoid confusion +- added append array for short form of assign {$foo[]='bar'} and allow assignments to nested arrays {$foo['bla']['blue']='bar'} + +04/04/2009 +- make output of template default handlers cachable and save compiled source +- some fixes on yesterdays update + +04/03/2006 +- added registerDefaultTemplateHandler method and functionallity +- added registerDefaultPluginHandler method and functionallity +- added {append} tag to extend Smarty array variabled + +04/02/2009 +- added setter/getter methods +- added $foo@first and $foo@last properties at {for} tag +- added $set_timezone (true/false) property to setup optionally the default time zone + +03/31/2009 +- bugfix smarty.class and internal.security_handler +- added compile_check configuration +- added setter/getter methods + +03/30/2009 +- added all major setter/getter methods + +03/28/2009 +- {block} tags can be nested now +- md5 hash function replace with crc32 for speed optimization +- file order for exted resource inverted +- clear_compiled_tpl and clear_cache_all will not touch .svn folder any longer + +03/27/2009 +- added extend resource + +03/26/2009 +- fixed parser not to create error on `word` in double quoted strings +- allow PHP array(...) +- implemented $smarty.block.name.parent to access parent block content +- fixed smarty.class + + +03/23/2009 +- fixed {foreachelse} and {forelse} tags + +03/22/2009 +- fixed possible sources for notice errors +- rearrange SVN into distribution and development folders + +03/21/2009 +- fixed exceptions in function plugins +- fixed notice error in Smarty.class.php +- allow chained objects to span multiple lines +- fixed error in modifers + +03/20/2009 +- moved /plugins folder into /libs folder +- added noprint modifier +- autoappend a directory separator if the xxxxx_dir definition have no trailing one + +03/19/2009 +- allow array definition as modifer parameter +- changed modifier to use multi byte string funktions. + +03/17/2009 +- bugfix + +03/15/2009 +- added {include_php} tag for BC +- removed @ error suppression +- bugfix fetch did always repeat output of first call when calling same template several times +- PHPunit tests extended + +03/13/2009 +- changed block syntax to be Smarty like {block:titel} -> {block name=titel} +- compiling of {block} and {extend} tags rewriten for better performance +- added special Smarty variable block ($smarty.block.foo} returns the parent definition of block foo +- optimization of {block} tag compiled code. +- fixed problem with escaped double quotes in double quoted strings + +03/12/2009 +- added support of template inheritance by {extend } and {block } tags. +- bugfix comments within literals +- added scope attribuie to {include} tag + +03/10/2009 +- couple of bugfixes and improvements +- PHPunit tests extended + +03/09/2009 +- added support for global template vars. {assign_global...} $smarty->assign_global(...) +- added direct_access_security +- PHPunit tests extended +- added missing {if} tag conditions like "is div by" etc. + +03/08/2009 +- splitted up the Compiler class to make it easier to use a coustom compiler +- made default plugins_dir relative to Smarty root and not current working directory +- some changes to make the lexer parser better configurable +- implemented {section} tag for Smarty2 BC + +03/07/2009 +- fixed problem with comment tags +- fixed problem with #xxxx in double quoted string +- new {while} tag implemented +- made lexer and paser class configurable as $smarty property +- Smarty method get_template_vars implemented +- Smarty method get_registered_object implemented +- Smarty method trigger_error implemented +- PHPunit tests extended + +03/06/2009 +- final changes on config variable handling +- parser change - unquoted strings will by be converted into single quoted strings +- PHPunit tests extended +- some code cleanup +- fixed problem on catenate strings with expression +- update of count_words modifier +- bugfix on comment tags + + +03/05/2009 +- bugfix on <?xml...> tag with caching enabled +- changes on exception handling (by Monte) + +03/04/2009 +- added support for config variables +- bugfix on <?xml...> tag + +03/02/2009 +- fixed unqouted strings within modifier parameter +- bugfix parsing of mofifier parameter + +03/01/2009 +- modifier chaining works now as in Smarty2 + +02/28/2009 +- changed handling of unqouted strings + +02/26/2009 +- bugfix +- changed $smarty.capture.foo to be global for Smarty2 BC. + +02/24/2009 +- bugfix {php} {/php} tags for backward compatibility +- bugfix for expressions on arrays +- fixed usage of "null" value +- added $smarty.foreach.foo.first and $smarty.foreach.foo.last + +02/06/2009 +- bugfix for request variables without index for example $smarty.get +- experimental solution for variable functions in static class + +02/05/2009 +- update of popup plugin +- added config variables to template parser (load config functions still missing) +- parser bugfix for empty quoted strings + +02/03/2009 +- allow array of objects as static class variabales. +- use htmlentities at source output at template errors. + +02/02/2009 +- changed search order on modifiers to look at plugins folder first +- parser bug fix for modifier on array elements $foo.bar|modifier +- parser bug fix on single quoted srings +- internal: splitted up compiler plugin files + +02/01/2009 +- allow method chaining on static classes +- special Smarty variables $smarty.... implemented +- added {PHP} {/PHP} tags for backward compatibility + +01/31/2009 +- added {math} plugin for Smarty2 BC +- added template_exists method +- changed Smarty3 method enable_security() to enableSecurity() to follow camelCase standards + +01/30/2009 +- bugfix in single quoted strings +- changed syntax for variable property access from $foo:property to $foo@property because of ambiguous syntax at modifiers + +01/29/2009 +- syntax for array definition changed from (1,2,3) to [1,2,3] to remove ambiguous syntax +- allow {for $foo in [1,2,3]} syntax +- bugfix in double quoted strings +- allow <?xml...?> tags in template even if short_tags are enabled + +01/28/2009 +- fixed '!==' if condition. + +01/28/2009 +- added support of {strip} {/strip} tag. + +01/27/2009 +- bug fix on backticks in double quoted strings at objects + +01/25/2009 +- Smarty2 modfiers added to SVN + +01/25/2009 +- bugfix allow arrays at object properties in Smarty syntax +- the template object is now passed as additional parameter at plugin calls +- clear_compiled_tpl method completed + +01/20/2009 +- access to class constants implemented ( class::CONSTANT ) +- access to static class variables implemented ( class::$variable ) +- call of static class methods implemented ( class::method() ) + +01/16/2009 +- reallow leading _ in variable names {$_var} +- allow array of objects {$array.index->method()} syntax +- finished work on clear_cache and clear_cache_all methods + +01/11/2009 +- added support of {literal} tag +- added support of {ldelim} and {rdelim} tags +- make code compatible to run with E_STRICT error setting + +01/08/2009 +- moved clear_assign and clear_all_assign to internal.templatebase.php +- added assign_by_ref, append and append_by_ref methods + +01/02/2009 +- added load_filter method +- fished work on filter handling +- optimization of plugin loading + +12/30/2008 +- added compiler support of registered object +- added backtick support in doubled quoted strings for backward compatibility +- some minor bug fixes and improvments + +12/23/2008 +- fixed problem of not working "not" operator in if-expressions +- added handling of compiler function plugins +- finished work on (un)register_compiler_function method +- finished work on (un)register_modifier method +- plugin handling from plugins folder changed for modifier plugins + deleted - internal.modifier.php +- added modifier chaining to parser + +12/17/2008 +- finished (un)register_function method +- finished (un)register_block method +- added security checking for PHP functions in PHP templates +- plugin handling from plugins folder rewritten + new - internal.plugin_handler.php + deleted - internal.block.php + deleted - internal.function.php +- removed plugin checking from security handler + +12/16/2008 + +- new start of this change_log file diff --git a/include/smarty/libs/Config_File.class.php b/include/smarty/libs/Config_File.class.php deleted file mode 100644 index 5787ad15f..000000000 --- a/include/smarty/libs/Config_File.class.php +++ /dev/null @@ -1,393 +0,0 @@ -<?php - -/** - * Config_File class. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * For questions, help, comments, discussion, etc., please join the - * Smarty mailing list. Send a blank e-mail to - * smarty-discussion-subscribe@googlegroups.com - * - * @link http://www.smarty.net/ - * @version 2.6.26 - * @copyright Copyright: 2001-2005 New Digital Group, Inc. - * @author Andrei Zmievski <andrei@php.net> - * @access public - * @package Smarty - */ - -/* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */ - -/** - * Config file reading class - * @package Smarty - */ -class Config_File { - /**#@+ - * Options - * @var boolean - */ - /** - * Controls whether variables with the same name overwrite each other. - */ - var $overwrite = true; - - /** - * Controls whether config values of on/true/yes and off/false/no get - * converted to boolean values automatically. - */ - var $booleanize = true; - - /** - * Controls whether hidden config sections/vars are read from the file. - */ - var $read_hidden = true; - - /** - * Controls whether or not to fix mac or dos formatted newlines. - * If set to true, \r or \r\n will be changed to \n. - */ - var $fix_newlines = true; - /**#@-*/ - - /** @access private */ - var $_config_path = ""; - var $_config_data = array(); - /**#@-*/ - - /** - * Constructs a new config file class. - * - * @param string $config_path (optional) path to the config files - */ - function Config_File($config_path = NULL) - { - if (isset($config_path)) - $this->set_path($config_path); - } - - - /** - * Set the path where configuration files can be found. - * - * @param string $config_path path to the config files - */ - function set_path($config_path) - { - if (!empty($config_path)) { - if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { - $this->_trigger_error_msg("Bad config file path '$config_path'"); - return; - } - if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { - $config_path .= DIRECTORY_SEPARATOR; - } - - $this->_config_path = $config_path; - } - } - - - /** - * Retrieves config info based on the file, section, and variable name. - * - * @param string $file_name config file to get info for - * @param string $section_name (optional) section to get info for - * @param string $var_name (optional) variable to get info for - * @return string|array a value or array of values - */ - function get($file_name, $section_name = NULL, $var_name = NULL) - { - if (empty($file_name)) { - $this->_trigger_error_msg('Empty config file name'); - return; - } else { - $file_name = $this->_config_path . $file_name; - if (!isset($this->_config_data[$file_name])) - $this->load_file($file_name, false); - } - - if (!empty($var_name)) { - if (empty($section_name)) { - return $this->_config_data[$file_name]["vars"][$var_name]; - } else { - if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) - return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; - else - return array(); - } - } else { - if (empty($section_name)) { - return (array)$this->_config_data[$file_name]["vars"]; - } else { - if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) - return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; - else - return array(); - } - } - } - - - /** - * Retrieves config info based on the key. - * - * @param $file_name string config key (filename/section/var) - * @return string|array same as get() - * @uses get() retrieves information from config file and returns it - */ - function &get_key($config_key) - { - list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); - $result = &$this->get($file_name, $section_name, $var_name); - return $result; - } - - /** - * Get all loaded config file names. - * - * @return array an array of loaded config file names - */ - function get_file_names() - { - return array_keys($this->_config_data); - } - - - /** - * Get all section names from a loaded file. - * - * @param string $file_name config file to get section names from - * @return array an array of section names from the specified file - */ - function get_section_names($file_name) - { - $file_name = $this->_config_path . $file_name; - if (!isset($this->_config_data[$file_name])) { - $this->_trigger_error_msg("Unknown config file '$file_name'"); - return; - } - - return array_keys($this->_config_data[$file_name]["sections"]); - } - - - /** - * Get all global or section variable names. - * - * @param string $file_name config file to get info for - * @param string $section_name (optional) section to get info for - * @return array an array of variables names from the specified file/section - */ - function get_var_names($file_name, $section = NULL) - { - if (empty($file_name)) { - $this->_trigger_error_msg('Empty config file name'); - return; - } else if (!isset($this->_config_data[$file_name])) { - $this->_trigger_error_msg("Unknown config file '$file_name'"); - return; - } - - if (empty($section)) - return array_keys($this->_config_data[$file_name]["vars"]); - else - return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); - } - - - /** - * Clear loaded config data for a certain file or all files. - * - * @param string $file_name file to clear config data for - */ - function clear($file_name = NULL) - { - if ($file_name === NULL) - $this->_config_data = array(); - else if (isset($this->_config_data[$file_name])) - $this->_config_data[$file_name] = array(); - } - - - /** - * Load a configuration file manually. - * - * @param string $file_name file name to load - * @param boolean $prepend_path whether current config path should be - * prepended to the filename - */ - function load_file($file_name, $prepend_path = true) - { - if ($prepend_path && $this->_config_path != "") - $config_file = $this->_config_path . $file_name; - else - $config_file = $file_name; - - ini_set('track_errors', true); - $fp = @fopen($config_file, "r"); - if (!is_resource($fp)) { - $this->_trigger_error_msg("Could not open config file '$config_file'"); - return false; - } - - $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; - fclose($fp); - - $this->_config_data[$config_file] = $this->parse_contents($contents); - return true; - } - - /** - * Store the contents of a file manually. - * - * @param string $config_file file name of the related contents - * @param string $contents the file-contents to parse - */ - function set_file_contents($config_file, $contents) - { - $this->_config_data[$config_file] = $this->parse_contents($contents); - return true; - } - - /** - * parse the source of a configuration file manually. - * - * @param string $contents the file-contents to parse - */ - function parse_contents($contents) - { - if($this->fix_newlines) { - // fix mac/dos formatted newlines - $contents = preg_replace('!\r\n?!', "\n", $contents); - } - - $config_data = array(); - $config_data['sections'] = array(); - $config_data['vars'] = array(); - - /* reference to fill with data */ - $vars =& $config_data['vars']; - - /* parse file line by line */ - preg_match_all('!^.*\r?\n?!m', $contents, $match); - $lines = $match[0]; - for ($i=0, $count=count($lines); $i<$count; $i++) { - $line = $lines[$i]; - if (empty($line)) continue; - - if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { - /* section found */ - if (substr($match[1], 0, 1) == '.') { - /* hidden section */ - if ($this->read_hidden) { - $section_name = substr($match[1], 1); - } else { - /* break reference to $vars to ignore hidden section */ - unset($vars); - $vars = array(); - continue; - } - } else { - $section_name = $match[1]; - } - if (!isset($config_data['sections'][$section_name])) - $config_data['sections'][$section_name] = array('vars' => array()); - $vars =& $config_data['sections'][$section_name]['vars']; - continue; - } - - if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { - /* variable found */ - $var_name = rtrim($match[1]); - if (strpos($match[2], '"""') === 0) { - /* handle multiline-value */ - $lines[$i] = substr($match[2], 3); - $var_value = ''; - while ($i<$count) { - if (($pos = strpos($lines[$i], '"""')) === false) { - $var_value .= $lines[$i++]; - } else { - /* end of multiline-value */ - $var_value .= substr($lines[$i], 0, $pos); - break; - } - } - $booleanize = false; - - } else { - /* handle simple value */ - $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); - $booleanize = $this->booleanize; - - } - $this->_set_config_var($vars, $var_name, $var_value, $booleanize); - } - /* else unparsable line / means it is a comment / means ignore it */ - } - return $config_data; - } - - /**#@+ @access private */ - /** - * @param array &$container - * @param string $var_name - * @param mixed $var_value - * @param boolean $booleanize determines whether $var_value is converted to - * to true/false - */ - function _set_config_var(&$container, $var_name, $var_value, $booleanize) - { - if (substr($var_name, 0, 1) == '.') { - if (!$this->read_hidden) - return; - else - $var_name = substr($var_name, 1); - } - - if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { - $this->_trigger_error_msg("Bad variable name '$var_name'"); - return; - } - - if ($booleanize) { - if (preg_match("/^(on|true|yes)$/i", $var_value)) - $var_value = true; - else if (preg_match("/^(off|false|no)$/i", $var_value)) - $var_value = false; - } - - if (!isset($container[$var_name]) || $this->overwrite) - $container[$var_name] = $var_value; - else { - settype($container[$var_name], 'array'); - $container[$var_name][] = $var_value; - } - } - - /** - * @uses trigger_error() creates a PHP warning/error - * @param string $error_msg - * @param integer $error_type one of - */ - function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) - { - trigger_error("Config_File error: $error_msg", $error_type); - } - /**#@-*/ -} - -?> diff --git a/include/smarty/libs/Smarty.class.php b/include/smarty/libs/Smarty.class.php index 2aaecbd93..40532fc2a 100644 --- a/include/smarty/libs/Smarty.class.php +++ b/include/smarty/libs/Smarty.class.php @@ -1,8 +1,8 @@ <?php - /** * Project: Smarty: the PHP compiling template engine * File: Smarty.class.php + * SVN: $Id: Smarty.class.php 4694 2013-01-13 21:13:14Z uwe.tews@googlemail.com $ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,1944 +23,1506 @@ * smarty-discussion-subscribe@googlegroups.com * * @link http://www.smarty.net/ - * @copyright 2001-2005 New Digital Group, Inc. + * @copyright 2008 New Digital Group, Inc. * @author Monte Ohrt <monte at ohrt dot com> - * @author Andrei Zmievski <andrei@php.net> + * @author Uwe Tews + * @author Rodney Rehm * @package Smarty - * @version 2.6.26 + * @version 3.1.13 */ -/* $Id: Smarty.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */ - /** - * DIR_SEP isn't used anymore, but third party apps might + * define shorthand directory separator constant */ -if(!defined('DIR_SEP')) { - define('DIR_SEP', DIRECTORY_SEPARATOR); +if (!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); } /** * set SMARTY_DIR to absolute path to Smarty library files. - * if not defined, include_path will be used. Sets SMARTY_DIR only if user - * application has not already defined it. + * Sets SMARTY_DIR only if user application has not already defined it. */ - if (!defined('SMARTY_DIR')) { - define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); + define('SMARTY_DIR', dirname(__FILE__) . DS); +} + +/** + * set SMARTY_SYSPLUGINS_DIR to absolute path to Smarty internal plugins. + * Sets SMARTY_SYSPLUGINS_DIR only if user application has not already defined it. + */ +if (!defined('SMARTY_SYSPLUGINS_DIR')) { + define('SMARTY_SYSPLUGINS_DIR', SMARTY_DIR . 'sysplugins' . DS); +} +if (!defined('SMARTY_PLUGINS_DIR')) { + define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); +} +if (!defined('SMARTY_MBSTRING')) { + define('SMARTY_MBSTRING', function_exists('mb_split')); +} +if (!defined('SMARTY_RESOURCE_CHAR_SET')) { + // UTF-8 can only be done properly when mbstring is available! + /** + * @deprecated in favor of Smarty::$_CHARSET + */ + define('SMARTY_RESOURCE_CHAR_SET', SMARTY_MBSTRING ? 'UTF-8' : 'ISO-8859-1'); +} +if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { + /** + * @deprecated in favor of Smarty::$_DATE_FORMAT + */ + define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y'); } -if (!defined('SMARTY_CORE_DIR')) { - define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); +/** + * register the class autoloader + */ +if (!defined('SMARTY_SPL_AUTOLOAD')) { + define('SMARTY_SPL_AUTOLOAD', 0); +} + +if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR . SMARTY_SYSPLUGINS_DIR) !== false) { + $registeredAutoLoadFunctions = spl_autoload_functions(); + if (!isset($registeredAutoLoadFunctions['spl_autoload'])) { + spl_autoload_register(); + } +} else { + spl_autoload_register('smartyAutoload'); } -define('SMARTY_PHP_PASSTHRU', 0); -define('SMARTY_PHP_QUOTE', 1); -define('SMARTY_PHP_REMOVE', 2); -define('SMARTY_PHP_ALLOW', 3); +/** + * Load always needed external class files + */ +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php'; +include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php'; /** + * This is the main Smarty class * @package Smarty */ -class Smarty -{ +class Smarty extends Smarty_Internal_TemplateBase { + /**#@+ - * Smarty Configuration Section + * constant definitions */ /** - * The name of the directory where templates are located. - * - * @var string + * smarty version */ - var $template_dir = 'templates'; + const SMARTY_VERSION = 'Smarty-3.1.13'; /** - * The directory where compiled templates are located. - * - * @var string + * define variable scopes */ - var $compile_dir = 'templates_c'; - + const SCOPE_LOCAL = 0; + const SCOPE_PARENT = 1; + const SCOPE_ROOT = 2; + const SCOPE_GLOBAL = 3; /** - * The directory where config files are located. - * - * @var string + * define caching modes + */ + const CACHING_OFF = 0; + const CACHING_LIFETIME_CURRENT = 1; + const CACHING_LIFETIME_SAVED = 2; + /** + * define compile check modes + */ + const COMPILECHECK_OFF = 0; + const COMPILECHECK_ON = 1; + const COMPILECHECK_CACHEMISS = 2; + /** + * modes for handling of "<?php ... ?>" tags in templates. */ - var $config_dir = 'configs'; + const PHP_PASSTHRU = 0; //-> print tags as plain text + const PHP_QUOTE = 1; //-> escape tags as entities + const PHP_REMOVE = 2; //-> escape tags as entities + const PHP_ALLOW = 3; //-> escape tags as entities + /** + * filter types + */ + const FILTER_POST = 'post'; + const FILTER_PRE = 'pre'; + const FILTER_OUTPUT = 'output'; + const FILTER_VARIABLE = 'variable'; + /** + * plugin types + */ + const PLUGIN_FUNCTION = 'function'; + const PLUGIN_BLOCK = 'block'; + const PLUGIN_COMPILER = 'compiler'; + const PLUGIN_MODIFIER = 'modifier'; + const PLUGIN_MODIFIERCOMPILER = 'modifiercompiler'; + + /**#@-*/ /** - * An array of directories searched for plugins. - * - * @var array + * assigned global tpl vars */ - var $plugins_dir = array('plugins'); + public static $global_tpl_vars = array(); /** - * If debugging is enabled, a debug console window will display - * when the page loads (make sure your browser allows unrequested - * popup windows) - * - * @var boolean + * error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors() + */ + public static $_previous_error_handler = null; + /** + * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors() + */ + public static $_muted_directories = array(); + /** + * Flag denoting if Multibyte String functions are available + */ + public static $_MBSTRING = SMARTY_MBSTRING; + /** + * The character set to adhere to (e.g. "UTF-8") + */ + public static $_CHARSET = SMARTY_RESOURCE_CHAR_SET; + /** + * The date format to be used internally + * (accepts date() and strftime()) + */ + public static $_DATE_FORMAT = SMARTY_RESOURCE_DATE_FORMAT; + /** + * Flag denoting if PCRE should run in UTF-8 mode */ - var $debugging = false; + public static $_UTF8_MODIFIER = 'u'; /** - * When set, smarty does uses this value as error_reporting-level. - * - * @var integer + * Flag denoting if operating system is windows + */ + public static $_IS_WINDOWS = false; + + /**#@+ + * variables */ - var $error_reporting = null; /** - * This is the path to the debug console template. If not set, - * the default one will be used. - * + * auto literal on delimiters with whitspace + * @var boolean + */ + public $auto_literal = true; + /** + * display error on not assigned variables + * @var boolean + */ + public $error_unassigned = false; + /** + * look up relative filepaths in include_path + * @var boolean + */ + public $use_include_path = false; + /** + * template directory + * @var array + */ + private $template_dir = array(); + /** + * joined template directory string used in cache keys * @var string */ - var $debug_tpl = ''; - + public $joined_template_dir = null; /** - * This determines if debugging is enable-able from the browser. - * <ul> - * <li>NONE => no debugging control allowed</li> - * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> - * </ul> - * @link http://www.foo.dom/index.php?SMARTY_DEBUG + * joined config directory string used in cache keys * @var string */ - var $debugging_ctrl = 'NONE'; - + public $joined_config_dir = null; /** - * This tells Smarty whether to check for recompiling or not. Recompiling - * does not need to happen unless a template or config file is changed. - * Typically you enable this during development, and disable for - * production. - * + * default template handler + * @var callable + */ + public $default_template_handler_func = null; + /** + * default config handler + * @var callable + */ + public $default_config_handler_func = null; + /** + * default plugin handler + * @var callable + */ + public $default_plugin_handler_func = null; + /** + * compile directory + * @var string + */ + private $compile_dir = null; + /** + * plugins directory + * @var array + */ + private $plugins_dir = array(); + /** + * cache directory + * @var string + */ + private $cache_dir = null; + /** + * config directory + * @var array + */ + private $config_dir = array(); + /** + * force template compiling? * @var boolean */ - var $compile_check = true; - + public $force_compile = false; /** - * This forces templates to compile every time. Useful for development - * or debugging. - * + * check template for modifications? * @var boolean */ - var $force_compile = false; - + public $compile_check = true; /** - * This enables template caching. - * <ul> - * <li>0 = no caching</li> - * <li>1 = use class cache_lifetime value</li> - * <li>2 = use cache_lifetime in cache file</li> - * </ul> - * @var integer + * use sub dirs for compiled/cached files? + * @var boolean */ - var $caching = 0; - + public $use_sub_dirs = false; /** - * The name of the directory for cache files. - * - * @var string + * allow ambiguous resources (that are made unique by the resource handler) + * @var boolean */ - var $cache_dir = 'cache'; - + public $allow_ambiguous_resources = false; /** - * This is the number of seconds cached content will persist. - * <ul> - * <li>0 = always regenerate cache</li> - * <li>-1 = never expires</li> - * </ul> - * - * @var integer + * caching enabled + * @var boolean */ - var $cache_lifetime = 3600; - + public $caching = false; /** - * Only used when $caching is enabled. If true, then If-Modified-Since headers - * are respected with cached content, and appropriate HTTP headers are sent. - * This way repeated hits to a cached page do not send the entire page to the - * client every time. - * + * merge compiled includes * @var boolean */ - var $cache_modified_check = false; - + public $merge_compiled_includes = false; /** - * This determines how Smarty handles "<?php ... ?>" tags in templates. - * possible values: - * <ul> - * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li> - * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li> - * <li>SMARTY_PHP_REMOVE -> remove php tags</li> - * <li>SMARTY_PHP_ALLOW -> execute php tags</li> - * </ul> - * + * cache lifetime in seconds * @var integer */ - var $php_handling = SMARTY_PHP_PASSTHRU; - + public $cache_lifetime = 3600; /** - * This enables template security. When enabled, many things are restricted - * in the templates that normally would go unchecked. This is useful when - * untrusted parties are editing templates and you want a reasonable level - * of security. (no direct execution of PHP in templates for example) - * + * force cache file creation * @var boolean */ - var $security = false; - + public $force_cache = false; /** - * This is the list of template directories that are considered secure. This - * is used only if {@link $security} is enabled. One directory per array - * element. {@link $template_dir} is in this list implicitly. + * Set this if you want different sets of cache files for the same + * templates. * - * @var array + * @var string */ - var $secure_dir = array(); - + public $cache_id = null; /** - * These are the security settings for Smarty. They are used only when - * {@link $security} is enabled. + * Set this if you want different sets of compiled files for the same + * templates. * - * @var array + * @var string */ - var $security_settings = array( - 'PHP_HANDLING' => false, - 'IF_FUNCS' => array('array', 'list', - 'isset', 'empty', - 'count', 'sizeof', - 'in_array', 'is_array', - 'true', 'false', 'null'), - 'INCLUDE_ANY' => false, - 'PHP_TAGS' => false, - 'MODIFIER_FUNCS' => array('count'), - 'ALLOW_CONSTANTS' => false, - 'ALLOW_SUPER_GLOBALS' => true - ); - - /** - * This is an array of directories where trusted php scripts reside. - * {@link $security} is disabled during their inclusion/execution. - * - * @var array + public $compile_id = null; + /** + * template left-delimiter + * @var string */ - var $trusted_dir = array(); - + public $left_delimiter = "{"; /** - * The left delimiter used for the template tags. - * + * template right-delimiter * @var string */ - var $left_delimiter = '{'; - + public $right_delimiter = "}"; + /**#@+ + * security + */ /** - * The right delimiter used for the template tags. + * class name + * + * This should be instance of Smarty_Security. * * @var string + * @see Smarty_Security */ - var $right_delimiter = '}'; - + public $security_class = 'Smarty_Security'; /** - * The order in which request variables are registered, similar to - * variables_order in php.ini E = Environment, G = GET, P = POST, - * C = Cookies, S = Server + * implementation of security class * - * @var string + * @var Smarty_Security */ - var $request_vars_order = 'EGPCS'; - + public $security_policy = null; /** - * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) - * are uses as request-vars or $_*[]-vars. note: if - * request_use_auto_globals is true, then $request_vars_order has - * no effect, but the php-ini-value "gpc_order" + * controls handling of PHP-blocks * - * @var boolean + * @var integer */ - var $request_use_auto_globals = true; - + public $php_handling = self::PHP_PASSTHRU; /** - * Set this if you want different sets of compiled files for the same - * templates. This is useful for things like different languages. - * Instead of creating separate sets of templates per language, you - * set different compile_ids like 'en' and 'de'. + * controls if the php template file resource is allowed * - * @var string + * @var bool */ - var $compile_id = null; - + public $allow_php_templates = false; /** - * This tells Smarty whether or not to use sub dirs in the cache/ and - * templates_c/ directories. sub directories better organized, but - * may not work well with PHP safe mode enabled. + * Should compiled-templates be prevented from being called directly? * - * @var boolean + * {@internal + * Currently used by Smarty_Internal_Template only. + * }} * + * @var boolean */ - var $use_sub_dirs = false; - + public $direct_access_security = true; + /**#@-*/ /** - * This is a list of the modifiers to apply to all template variables. - * Put each modifier in a separate array element in the order you want - * them applied. example: <code>array('escape:"htmlall"');</code> + * debug mode * - * @var array + * Setting this to true enables the debug-console. + * + * @var boolean */ - var $default_modifiers = array(); - + public $debugging = false; /** - * This is the resource type to be used when not specified - * at the beginning of the resource path. examples: - * $smarty->display('file:index.tpl'); - * $smarty->display('db:index.tpl'); - * $smarty->display('index.tpl'); // will use default resource type - * {include file="file:index.tpl"} - * {include file="db:index.tpl"} - * {include file="index.tpl"} {* will use default resource type *} - * - * @var array + * This determines if debugging is enable-able from the browser. + * <ul> + * <li>NONE => no debugging control allowed</li> + * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> + * </ul> + * @var string */ - var $default_resource_type = 'file'; - + public $debugging_ctrl = 'NONE'; /** - * The function used for cache file handling. If not set, built-in caching is used. + * Name of debugging URL-param. * - * @var null|string function name + * Only used when $debugging_ctrl is set to 'URL'. + * The name of the URL-parameter that activates debugging. + * + * @var type */ - var $cache_handler_func = null; - + public $smarty_debug_id = 'SMARTY_DEBUG'; /** - * This indicates which filters are automatically loaded into Smarty. - * - * @var array array of filter names + * Path of debug template. + * @var string + */ + public $debug_tpl = null; + /** + * When set, smarty uses this value as error_reporting-level. + * @var int */ - var $autoload_filters = array(); + public $error_reporting = null; + /** + * Internal flag for getTags() + * @var boolean + */ + public $get_used_tags = false; /**#@+ + * config var settings + */ + + /** + * Controls whether variables with the same name overwrite each other. * @var boolean */ + public $config_overwrite = true; /** - * This tells if config file vars of the same name overwrite each other or not. - * if disabled, same name variables are accumulated in an array. + * Controls whether config values of on/true/yes and off/false/no get converted to boolean. + * @var boolean */ - var $config_overwrite = true; - + public $config_booleanize = true; /** - * This tells whether or not to automatically booleanize config file variables. - * If enabled, then the strings "on", "true", and "yes" are treated as boolean - * true, and "off", "false" and "no" are treated as boolean false. + * Controls whether hidden config sections/vars are read from the file. + * @var boolean */ - var $config_booleanize = true; + public $config_read_hidden = false; - /** - * This tells whether hidden sections [.foobar] are readable from the - * tempalates or not. Normally you would never allow this since that is - * the point behind hidden sections: the application can access them, but - * the templates cannot. + /**#@-*/ + + /**#@+ + * resource locking */ - var $config_read_hidden = false; /** - * This tells whether or not automatically fix newlines in config files. - * It basically converts \r (mac) or \r\n (dos) to \n + * locking concurrent compiles + * @var boolean + */ + public $compile_locking = true; + /** + * Controls whether cache resources should emply locking mechanism + * @var boolean + */ + public $cache_locking = false; + /** + * seconds to wait for acquiring a lock before ignoring the write lock + * @var float */ - var $config_fix_newlines = true; + public $locking_timeout = 10; + /**#@-*/ /** - * If a template cannot be found, this PHP function will be executed. - * Useful for creating templates on-the-fly or other special action. - * - * @var string function name + * global template functions + * @var array */ - var $default_template_handler_func = ''; - + public $template_functions = array(); /** - * The file that contains the compiler class. This can a full - * pathname, or relative to the php_include path. + * resource type used if none given * + * Must be an valid key of $registered_resources. * @var string */ - var $compiler_file = 'Smarty_Compiler.class.php'; - + public $default_resource_type = 'file'; /** - * The class used for compiling templates. + * caching type + * + * Must be an element of $cache_resource_types. * * @var string */ - var $compiler_class = 'Smarty_Compiler'; - + public $caching_type = 'file'; /** - * The class used to load config vars. - * + * internal config properties + * @var array + */ + public $properties = array(); + /** + * config type * @var string */ - var $config_class = 'Config_File'; - -/**#@+ - * END Smarty Configuration Section - * There should be no need to touch anything below this line. - * @access private - */ + public $default_config_type = 'file'; /** - * where assigned template vars are kept - * + * cached template objects * @var array */ - var $_tpl_vars = array(); - + public $template_objects = array(); /** - * stores run-time $smarty.* vars - * - * @var null|array + * check If-Modified-Since headers + * @var boolean */ - var $_smarty_vars = null; - + public $cache_modified_check = false; /** - * keeps track of sections - * + * registered plugins * @var array */ - var $_sections = array(); - + public $registered_plugins = array(); /** - * keeps track of foreach blocks - * + * plugin search order * @var array */ - var $_foreach = array(); - + public $plugin_search_order = array('function', 'block', 'compiler', 'class'); /** - * keeps track of tag hierarchy - * + * registered objects * @var array */ - var $_tag_stack = array(); - + public $registered_objects = array(); /** - * configuration object - * - * @var Config_file + * registered classes + * @var array */ - var $_conf_obj = null; - + public $registered_classes = array(); /** - * loaded configuration settings - * + * registered filters * @var array */ - var $_config = array(array('vars' => array(), 'files' => array())); - + public $registered_filters = array(); /** - * md5 checksum of the string 'Smarty' - * - * @var string + * registered resources + * @var array */ - var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; - + public $registered_resources = array(); /** - * Smarty version number - * - * @var string + * resource handler cache + * @var array */ - var $_version = '2.6.26'; - + public $_resource_handlers = array(); /** - * current template inclusion depth - * - * @var integer + * registered cache resources + * @var array */ - var $_inclusion_depth = 0; - + public $registered_cache_resources = array(); /** - * for different compiled templates - * - * @var string + * cache resource handler cache + * @var array */ - var $_compile_id = null; - + public $_cacheresource_handlers = array(); /** - * text in URL to enable debug mode - * - * @var string + * autoload filter + * @var array */ - var $_smarty_debug_id = 'SMARTY_DEBUG'; - + public $autoload_filters = array(); /** - * debugging information for debug console - * + * default modifier * @var array */ - var $_smarty_debug_info = array(); - + public $default_modifiers = array(); /** - * info that makes up a cache file - * + * autoescape variable output + * @var boolean + */ + public $escape_html = false; + /** + * global internal smarty vars * @var array */ - var $_cache_info = array(); - + public static $_smarty_vars = array(); + /** + * start time for execution time calculation + * @var int + */ + public $start_time = 0; /** * default file permissions - * - * @var integer + * @var int */ - var $_file_perms = 0644; - + public $_file_perms = 0644; /** * default dir permissions - * - * @var integer + * @var int */ - var $_dir_perms = 0771; - + public $_dir_perms = 0771; /** - * registered objects - * + * block tag hierarchy * @var array */ - var $_reg_objects = array(); - + public $_tag_stack = array(); /** - * table keeping track of plugins - * - * @var array + * self pointer to Smarty object + * @var Smarty */ - var $_plugins = array( - 'modifier' => array(), - 'function' => array(), - 'block' => array(), - 'compiler' => array(), - 'prefilter' => array(), - 'postfilter' => array(), - 'outputfilter' => array(), - 'resource' => array(), - 'insert' => array()); - - + public $smarty; /** - * cache serials - * - * @var array + * required by the compiler for BC + * @var string */ - var $_cache_serials = array(); - + public $_current_file = null; /** - * name of optional cache include file - * - * @var string + * internal flag to enable parser debugging + * @var bool */ - var $_cache_include = null; - + public $_parserdebug = false; /** - * indicate if the current code is used in a compiled - * include + * Saved parameter of merged templates during compilation * - * @var string + * @var array */ - var $_cache_including = false; - + public $merged_templates_func = array(); /**#@-*/ - /** - * The class constructor. - */ - function Smarty() - { - $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] - : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); - } /** - * assigns values to template variables + * Initialize new Smarty object * - * @param array|string $tpl_var the template variable name(s) - * @param mixed $value the value to assign */ - function assign($tpl_var, $value = null) + public function __construct() { - if (is_array($tpl_var)){ - foreach ($tpl_var as $key => $val) { - if ($key != '') { - $this->_tpl_vars[$key] = $val; - } - } - } else { - if ($tpl_var != '') - $this->_tpl_vars[$tpl_var] = $value; + // selfpointer needed by some other class methods + $this->smarty = $this; + if (is_callable('mb_internal_encoding')) { + mb_internal_encoding(Smarty::$_CHARSET); + } + $this->start_time = microtime(true); + // set default dirs + $this->setTemplateDir('.' . DS . 'templates' . DS) + ->setCompileDir('.' . DS . 'templates_c' . DS) + ->setPluginsDir(SMARTY_PLUGINS_DIR) + ->setCacheDir('.' . DS . 'cache' . DS) + ->setConfigDir('.' . DS . 'configs' . DS); + + $this->debug_tpl = 'file:' . dirname(__FILE__) . '/debug.tpl'; + if (isset($_SERVER['SCRIPT_NAME'])) { + $this->assignGlobal('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']); } } - /** - * assigns values to template variables by reference - * - * @param string $tpl_var the template variable name - * @param mixed $value the referenced value to assign - */ - function assign_by_ref($tpl_var, &$value) - { - if ($tpl_var != '') - $this->_tpl_vars[$tpl_var] = &$value; - } /** - * appends values to template variables - * - * @param array|string $tpl_var the template variable name(s) - * @param mixed $value the value to append + * Class destructor */ - function append($tpl_var, $value=null, $merge=false) + public function __destruct() { - if (is_array($tpl_var)) { - // $tpl_var is an array, ignore $value - foreach ($tpl_var as $_key => $_val) { - if ($_key != '') { - if(!@is_array($this->_tpl_vars[$_key])) { - settype($this->_tpl_vars[$_key],'array'); - } - if($merge && is_array($_val)) { - foreach($_val as $_mkey => $_mval) { - $this->_tpl_vars[$_key][$_mkey] = $_mval; - } - } else { - $this->_tpl_vars[$_key][] = $_val; - } - } - } - } else { - if ($tpl_var != '' && isset($value)) { - if(!@is_array($this->_tpl_vars[$tpl_var])) { - settype($this->_tpl_vars[$tpl_var],'array'); - } - if($merge && is_array($value)) { - foreach($value as $_mkey => $_mval) { - $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; - } - } else { - $this->_tpl_vars[$tpl_var][] = $value; - } - } - } + // intentionally left blank } /** - * appends values to template variables by reference - * - * @param string $tpl_var the template variable name - * @param mixed $value the referenced value to append + * <<magic>> set selfpointer on cloned object */ - function append_by_ref($tpl_var, &$value, $merge=false) + public function __clone() { - if ($tpl_var != '' && isset($value)) { - if(!@is_array($this->_tpl_vars[$tpl_var])) { - settype($this->_tpl_vars[$tpl_var],'array'); - } - if ($merge && is_array($value)) { - foreach($value as $_key => $_val) { - $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; - } - } else { - $this->_tpl_vars[$tpl_var][] = &$value; - } - } + $this->smarty = $this; } /** - * clear the given assigned template variable. + * <<magic>> Generic getter. * - * @param string $tpl_var the template variable to clear - */ - function clear_assign($tpl_var) - { - if (is_array($tpl_var)) - foreach ($tpl_var as $curr_var) - unset($this->_tpl_vars[$curr_var]); - else - unset($this->_tpl_vars[$tpl_var]); - } - - - /** - * Registers custom function to be used in templates + * Calls the appropriate getter function. + * Issues an E_USER_NOTICE if no valid getter is found. * - * @param string $function the name of the template function - * @param string $function_impl the name of the PHP function to register + * @param string $name property name + * @return mixed */ - function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + public function __get($name) { - $this->_plugins['function'][$function] = - array($function_impl, null, null, false, $cacheable, $cache_attrs); + $allowed = array( + 'template_dir' => 'getTemplateDir', + 'config_dir' => 'getConfigDir', + 'plugins_dir' => 'getPluginsDir', + 'compile_dir' => 'getCompileDir', + 'cache_dir' => 'getCacheDir', + ); + if (isset($allowed[$name])) { + return $this->{$allowed[$name]}(); + } else { + trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE); + } } /** - * Unregisters custom function + * <<magic>> Generic setter. * - * @param string $function name of template function - */ - function unregister_function($function) - { - unset($this->_plugins['function'][$function]); - } - - /** - * Registers object to be used in templates + * Calls the appropriate setter function. + * Issues an E_USER_NOTICE if no valid setter is found. * - * @param string $object name of template object - * @param object &$object_impl the referenced PHP object to register - * @param null|array $allowed list of allowed methods (empty = all) - * @param boolean $smarty_args smarty argument format, else traditional - * @param null|array $block_functs list of methods that are block format + * @param string $name property name + * @param mixed $value parameter passed to setter */ - function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + public function __set($name, $value) { - settype($allowed, 'array'); - settype($smarty_args, 'boolean'); - $this->_reg_objects[$object] = - array(&$object_impl, $allowed, $smarty_args, $block_methods); + $allowed = array( + 'template_dir' => 'setTemplateDir', + 'config_dir' => 'setConfigDir', + 'plugins_dir' => 'setPluginsDir', + 'compile_dir' => 'setCompileDir', + 'cache_dir' => 'setCacheDir', + ); + + if (isset($allowed[$name])) { + $this->{$allowed[$name]}($value); + } else { + trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); + } } /** - * Unregisters object + * Check if a template resource exists * - * @param string $object name of template object + * @param string $resource_name template name + * @return boolean status */ - function unregister_object($object) + public function templateExists($resource_name) { - unset($this->_reg_objects[$object]); + // create template object + $save = $this->template_objects; + $tpl = new $this->template_class($resource_name, $this); + // check if it does exists + $result = $tpl->source->exists; + $this->template_objects = $save; + return $result; } - /** - * Registers block function to be used in templates + * Returns a single or all global variables * - * @param string $block name of template block - * @param string $block_impl PHP function to register + * @param object $smarty + * @param string $varname variable name or null + * @return string variable value or or array of variables */ - function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + public function getGlobal($varname = null) { - $this->_plugins['block'][$block] = - array($block_impl, null, null, false, $cacheable, $cache_attrs); + if (isset($varname)) { + if (isset(self::$global_tpl_vars[$varname])) { + return self::$global_tpl_vars[$varname]->value; + } else { + return ''; + } + } else { + $_result = array(); + foreach (self::$global_tpl_vars AS $key => $var) { + $_result[$key] = $var->value; + } + return $_result; + } } /** - * Unregisters block function + * Empty cache folder * - * @param string $block name of template function + * @param integer $exp_time expiration time + * @param string $type resource type + * @return integer number of cache files deleted */ - function unregister_block($block) + function clearAllCache($exp_time = null, $type = null) { - unset($this->_plugins['block'][$block]); + // load cache resource and call clearAll + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + return $_cache_resource->clearAll($this, $exp_time); } /** - * Registers compiler function + * Empty cache for a specific template * - * @param string $function name of template function - * @param string $function_impl name of PHP function to register + * @param string $template_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @param string $type resource type + * @return integer number of cache files deleted */ - function register_compiler_function($function, $function_impl, $cacheable=true) + public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) { - $this->_plugins['compiler'][$function] = - array($function_impl, null, null, false, $cacheable); + // load cache resource and call clear + $_cache_resource = Smarty_CacheResource::load($this, $type); + Smarty_CacheResource::invalidLoadedCache($this); + return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); } /** - * Unregisters compiler function + * Loads security class and enables security * - * @param string $function name of template function + * @param string|Smarty_Security $security_class if a string is used, it must be class-name + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when an invalid class name is provided */ - function unregister_compiler_function($function) + public function enableSecurity($security_class = null) { - unset($this->_plugins['compiler'][$function]); + if ($security_class instanceof Smarty_Security) { + $this->security_policy = $security_class; + return $this; + } elseif (is_object($security_class)) { + throw new SmartyException("Class '" . get_class($security_class) . "' must extend Smarty_Security."); + } + if ($security_class == null) { + $security_class = $this->security_class; + } + if (!class_exists($security_class)) { + throw new SmartyException("Security class '$security_class' is not defined"); + } elseif ($security_class !== 'Smarty_Security' && !is_subclass_of($security_class, 'Smarty_Security')) { + throw new SmartyException("Class '$security_class' must extend Smarty_Security."); + } else { + $this->security_policy = new $security_class($this); + } + + return $this; } /** - * Registers modifier to be used in templates - * - * @param string $modifier name of template modifier - * @param string $modifier_impl name of PHP function to register + * Disable security + * @return Smarty current Smarty instance for chaining */ - function register_modifier($modifier, $modifier_impl) + public function disableSecurity() { - $this->_plugins['modifier'][$modifier] = - array($modifier_impl, null, null, false); + $this->security_policy = null; + + return $this; } /** - * Unregisters modifier + * Set template directory * - * @param string $modifier name of template modifier + * @param string|array $template_dir directory(s) of template sources + * @return Smarty current Smarty instance for chaining */ - function unregister_modifier($modifier) + public function setTemplateDir($template_dir) { - unset($this->_plugins['modifier'][$modifier]); + $this->template_dir = array(); + foreach ((array) $template_dir as $k => $v) { + $this->template_dir[$k] = rtrim($v, '/\\') . DS; + } + + $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); + return $this; } /** - * Registers a resource to fetch a template + * Add template directory(s) * - * @param string $type name of resource - * @param array $functions array of functions to handle resource + * @param string|array $template_dir directory(s) of template sources + * @param string $key of the array element to assign the template dir to + * @return Smarty current Smarty instance for chaining + * @throws SmartyException when the given template directory is not valid */ - function register_resource($type, $functions) + public function addTemplateDir($template_dir, $key=null) { - if (count($functions)==4) { - $this->_plugins['resource'][$type] = - array($functions, false); - - } elseif (count($functions)==5) { - $this->_plugins['resource'][$type] = - array(array(array(&$functions[0], $functions[1]) - ,array(&$functions[0], $functions[2]) - ,array(&$functions[0], $functions[3]) - ,array(&$functions[0], $functions[4])) - ,false); - + // make sure we're dealing with an array + $this->template_dir = (array) $this->template_dir; + + if (is_array($template_dir)) { + foreach ($template_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->template_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->template_dir[$k] = rtrim($v, '/\\') . DS; + } + } + } elseif ($key !== null) { + // override directory at specified index + $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS; } else { - $this->trigger_error("malformed function-list for '$type' in register_resource"); - + // append new directory + $this->template_dir[] = rtrim($template_dir, '/\\') . DS; } + $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); + return $this; } /** - * Unregisters a resource + * Get template directories * - * @param string $type name of resource + * @param mixed index of directory to get, null to get all + * @return array|string list of template directories, or directory of $index */ - function unregister_resource($type) + public function getTemplateDir($index=null) { - unset($this->_plugins['resource'][$type]); - } + if ($index !== null) { + return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; + } - /** - * Registers a prefilter function to apply - * to a template before compiling - * - * @param callback $function - */ - function register_prefilter($function) - { - $this->_plugins['prefilter'][$this->_get_filter_name($function)] - = array($function, null, null, false); + return (array)$this->template_dir; } /** - * Unregisters a prefilter function + * Set config directory * - * @param callback $function + * @param string|array $template_dir directory(s) of configuration sources + * @return Smarty current Smarty instance for chaining */ - function unregister_prefilter($function) + public function setConfigDir($config_dir) { - unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]); - } + $this->config_dir = array(); + foreach ((array) $config_dir as $k => $v) { + $this->config_dir[$k] = rtrim($v, '/\\') . DS; + } - /** - * Registers a postfilter function to apply - * to a compiled template after compilation - * - * @param callback $function - */ - function register_postfilter($function) - { - $this->_plugins['postfilter'][$this->_get_filter_name($function)] - = array($function, null, null, false); + $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); + return $this; } /** - * Unregisters a postfilter function + * Add config directory(s) * - * @param callback $function + * @param string|array $config_dir directory(s) of config sources + * @param string key of the array element to assign the config dir to + * @return Smarty current Smarty instance for chaining */ - function unregister_postfilter($function) + public function addConfigDir($config_dir, $key=null) { - unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]); - } + // make sure we're dealing with an array + $this->config_dir = (array) $this->config_dir; + + if (is_array($config_dir)) { + foreach ($config_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->config_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->config_dir[$k] = rtrim($v, '/\\') . DS; + } + } + } elseif( $key !== null ) { + // override directory at specified index + $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS; + } else { + // append new directory + $this->config_dir[] = rtrim($config_dir, '/\\') . DS; + } - /** - * Registers an output filter function to apply - * to a template output - * - * @param callback $function - */ - function register_outputfilter($function) - { - $this->_plugins['outputfilter'][$this->_get_filter_name($function)] - = array($function, null, null, false); + $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); + return $this; } /** - * Unregisters an outputfilter function + * Get config directory * - * @param callback $function + * @param mixed index of directory to get, null to get all + * @return array|string configuration directory */ - function unregister_outputfilter($function) + public function getConfigDir($index=null) { - unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]); + if ($index !== null) { + return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null; + } + + return (array)$this->config_dir; } /** - * load a filter of specified type and name + * Set plugins directory * - * @param string $type filter type - * @param string $name filter name + * @param string|array $plugins_dir directory(s) of plugins + * @return Smarty current Smarty instance for chaining */ - function load_filter($type, $name) + public function setPluginsDir($plugins_dir) { - switch ($type) { - case 'output': - $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - break; - - case 'pre': - case 'post': - if (!isset($this->_plugins[$type . 'filter'][$name])) - $this->_plugins[$type . 'filter'][$name] = false; - break; + $this->plugins_dir = array(); + foreach ((array)$plugins_dir as $k => $v) { + $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; } + + return $this; } /** - * clear cached content for the given template and cache id + * Adds directory of plugin files * - * @param string $tpl_file name of template file - * @param string $cache_id name of cache_id - * @param string $compile_id name of compile_id - * @param string $exp_time expiration time - * @return boolean + * @param object $smarty + * @param string $ |array $ plugins folder + * @return Smarty current Smarty instance for chaining */ - function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + public function addPluginsDir($plugins_dir) { - - if (!isset($compile_id)) - $compile_id = $this->compile_id; - - if (!isset($tpl_file)) - $compile_id = null; - - $_auto_id = $this->_get_auto_id($cache_id, $compile_id); - - if (!empty($this->cache_handler_func)) { - return call_user_func_array($this->cache_handler_func, - array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); + // make sure we're dealing with an array + $this->plugins_dir = (array) $this->plugins_dir; + + if (is_array($plugins_dir)) { + foreach ($plugins_dir as $k => $v) { + if (is_int($k)) { + // indexes are not merged but appended + $this->plugins_dir[] = rtrim($v, '/\\') . DS; + } else { + // string indexes are overridden + $this->plugins_dir[$k] = rtrim($v, '/\\') . DS; + } + } } else { - $_params = array('auto_base' => $this->cache_dir, - 'auto_source' => $tpl_file, - 'auto_id' => $_auto_id, - 'exp_time' => $exp_time); - require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); - return smarty_core_rm_auto($_params, $this); + // append new directory + $this->plugins_dir[] = rtrim($plugins_dir, '/\\') . DS; } + $this->plugins_dir = array_unique($this->plugins_dir); + return $this; } - /** - * clear the entire contents of cache (all templates) + * Get plugin directories * - * @param string $exp_time expire time - * @return boolean results of {@link smarty_core_rm_auto()} + * @return array list of plugin directories */ - function clear_all_cache($exp_time = null) + public function getPluginsDir() { - return $this->clear_cache(null, null, null, $exp_time); + return (array)$this->plugins_dir; } - /** - * test to see if valid cache exists for this template + * Set compile directory * - * @param string $tpl_file name of template file - * @param string $cache_id - * @param string $compile_id - * @return string|false results of {@link _read_cache_file()} + * @param string $compile_dir directory to store compiled templates in + * @return Smarty current Smarty instance for chaining */ - function is_cached($tpl_file, $cache_id = null, $compile_id = null) + public function setCompileDir($compile_dir) { - if (!$this->caching) - return false; - - if (!isset($compile_id)) - $compile_id = $this->compile_id; - - $_params = array( - 'tpl_file' => $tpl_file, - 'cache_id' => $cache_id, - 'compile_id' => $compile_id - ); - require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); - return smarty_core_read_cache_file($_params, $this); + $this->compile_dir = rtrim($compile_dir, '/\\') . DS; + if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { + Smarty::$_muted_directories[$this->compile_dir] = null; + } + return $this; } - /** - * clear all the assigned template variables. + * Get compiled directory * + * @return string path to compiled templates */ - function clear_all_assign() + public function getCompileDir() { - $this->_tpl_vars = array(); + return $this->compile_dir; } /** - * clears compiled version of specified template resource, - * or all compiled template files if one is not specified. - * This function is for advanced use only, not normally needed. + * Set cache directory * - * @param string $tpl_file - * @param string $compile_id - * @param string $exp_time - * @return boolean results of {@link smarty_core_rm_auto()} + * @param string $cache_dir directory to store cached templates in + * @return Smarty current Smarty instance for chaining */ - function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + public function setCacheDir($cache_dir) { - if (!isset($compile_id)) { - $compile_id = $this->compile_id; + $this->cache_dir = rtrim($cache_dir, '/\\') . DS; + if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { + Smarty::$_muted_directories[$this->cache_dir] = null; } - $_params = array('auto_base' => $this->compile_dir, - 'auto_source' => $tpl_file, - 'auto_id' => $compile_id, - 'exp_time' => $exp_time, - 'extensions' => array('.inc', '.php')); - require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); - return smarty_core_rm_auto($_params, $this); + return $this; } /** - * Checks whether requested template exists. + * Get cache directory * - * @param string $tpl_file - * @return boolean + * @return string path of cache directory */ - function template_exists($tpl_file) + public function getCacheDir() { - $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); - return $this->_fetch_resource_info($_params); + return $this->cache_dir; } /** - * Returns an array containing template variables + * Set default modifiers * - * @param string $name - * @param string $type - * @return array + * @param array|string $modifiers modifier or list of modifiers to set + * @return Smarty current Smarty instance for chaining */ - function &get_template_vars($name=null) + public function setDefaultModifiers($modifiers) { - if(!isset($name)) { - return $this->_tpl_vars; - } elseif(isset($this->_tpl_vars[$name])) { - return $this->_tpl_vars[$name]; - } else { - // var non-existant, return valid reference - $_tmp = null; - return $_tmp; - } + $this->default_modifiers = (array) $modifiers; + return $this; } /** - * Returns an array containing config variables + * Add default modifiers * - * @param string $name - * @param string $type - * @return array + * @param array|string $modifiers modifier or list of modifiers to add + * @return Smarty current Smarty instance for chaining */ - function &get_config_vars($name=null) + public function addDefaultModifiers($modifiers) { - if(!isset($name) && is_array($this->_config[0])) { - return $this->_config[0]['vars']; - } else if(isset($this->_config[0]['vars'][$name])) { - return $this->_config[0]['vars'][$name]; + if (is_array($modifiers)) { + $this->default_modifiers = array_merge($this->default_modifiers, $modifiers); } else { - // var non-existant, return valid reference - $_tmp = null; - return $_tmp; + $this->default_modifiers[] = $modifiers; } + + return $this; } /** - * trigger Smarty error + * Get default modifiers * - * @param string $error_msg - * @param integer $error_type + * @return array list of default modifiers */ - function trigger_error($error_msg, $error_type = E_USER_WARNING) + public function getDefaultModifiers() { - trigger_error("Smarty error: $error_msg", $error_type); + return $this->default_modifiers; } /** - * executes & displays the template results + * Set autoload filters * - * @param string $resource_name - * @param string $cache_id - * @param string $compile_id + * @param array $filters filters to load automatically + * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * @return Smarty current Smarty instance for chaining */ - function display($resource_name, $cache_id = null, $compile_id = null) + public function setAutoloadFilters($filters, $type=null) { - $this->fetch($resource_name, $cache_id, $compile_id, true); + if ($type !== null) { + $this->autoload_filters[$type] = (array) $filters; + } else { + $this->autoload_filters = (array) $filters; + } + + return $this; } /** - * executes & returns or displays the template results + * Add autoload filters * - * @param string $resource_name - * @param string $cache_id - * @param string $compile_id - * @param boolean $display + * @param array $filters filters to load automatically + * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * @return Smarty current Smarty instance for chaining */ - function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) + public function addAutoloadFilters($filters, $type=null) { - static $_cache_info = array(); - - $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) - ? $this->error_reporting : error_reporting() & ~E_NOTICE); - - if (!$this->debugging && $this->debugging_ctrl == 'URL') { - $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; - if (@strstr($_query_string, $this->_smarty_debug_id)) { - if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { - // enable debugging for this browser session - @setcookie('SMARTY_DEBUG', true); - $this->debugging = true; - } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { - // disable debugging for this browser session - @setcookie('SMARTY_DEBUG', false); - $this->debugging = false; - } else { - // enable debugging for this page - $this->debugging = true; - } + if ($type !== null) { + if (!empty($this->autoload_filters[$type])) { + $this->autoload_filters[$type] = array_merge($this->autoload_filters[$type], (array) $filters); } else { - $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); + $this->autoload_filters[$type] = (array) $filters; } - } - - if ($this->debugging) { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $_debug_start_time = smarty_core_get_microtime($_params, $this); - $this->_smarty_debug_info[] = array('type' => 'template', - 'filename' => $resource_name, - 'depth' => 0); - $_included_tpls_idx = count($this->_smarty_debug_info) - 1; - } - - if (!isset($compile_id)) { - $compile_id = $this->compile_id; - } - - $this->_compile_id = $compile_id; - $this->_inclusion_depth = 0; - - if ($this->caching) { - // save old cache_info, initialize cache_info - array_push($_cache_info, $this->_cache_info); - $this->_cache_info = array(); - $_params = array( - 'tpl_file' => $resource_name, - 'cache_id' => $cache_id, - 'compile_id' => $compile_id, - 'results' => null - ); - require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); - if (smarty_core_read_cache_file($_params, $this)) { - $_smarty_results = $_params['results']; - if (!empty($this->_cache_info['insert_tags'])) { - $_params = array('plugins' => $this->_cache_info['insert_tags']); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - $_params = array('results' => $_smarty_results); - require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); - $_smarty_results = smarty_core_process_cached_inserts($_params, $this); - } - if (!empty($this->_cache_info['cache_serials'])) { - $_params = array('results' => $_smarty_results); - require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); - $_smarty_results = smarty_core_process_compiled_include($_params, $this); - } - - - if ($display) { - if ($this->debugging) - { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; - require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); - $_smarty_results .= smarty_core_display_debug_console($_params, $this); - } - if ($this->cache_modified_check) { - $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; - $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); - $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; - if (@count($this->_cache_info['insert_tags']) == 0 - && !$this->_cache_serials - && $_gmt_mtime == $_last_modified_date) { - if (php_sapi_name()=='cgi') - header('Status: 304 Not Modified'); - else - header('HTTP/1.1 304 Not Modified'); - - } else { - header('Last-Modified: '.$_gmt_mtime); - echo $_smarty_results; - } - } else { - echo $_smarty_results; - } - error_reporting($_smarty_old_error_level); - // restore initial cache_info - $this->_cache_info = array_pop($_cache_info); - return true; + } else { + foreach ((array) $filters as $key => $value) { + if (!empty($this->autoload_filters[$key])) { + $this->autoload_filters[$key] = array_merge($this->autoload_filters[$key], (array) $value); } else { - error_reporting($_smarty_old_error_level); - // restore initial cache_info - $this->_cache_info = array_pop($_cache_info); - return $_smarty_results; - } - } else { - $this->_cache_info['template'][$resource_name] = true; - if ($this->cache_modified_check && $display) { - header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); - } - } - } - - // load filters that are marked as autoload - if (count($this->autoload_filters)) { - foreach ($this->autoload_filters as $_filter_type => $_filters) { - foreach ($_filters as $_filter) { - $this->load_filter($_filter_type, $_filter); + $this->autoload_filters[$key] = (array) $value; } } } - $_smarty_compile_path = $this->_get_compile_path($resource_name); - - // if we just need to display the results, don't perform output - // buffering - for speed - $_cache_including = $this->_cache_including; - $this->_cache_including = false; - if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { - if ($this->_is_compiled($resource_name, $_smarty_compile_path) - || $this->_compile_resource($resource_name, $_smarty_compile_path)) - { - include($_smarty_compile_path); - } - } else { - ob_start(); - if ($this->_is_compiled($resource_name, $_smarty_compile_path) - || $this->_compile_resource($resource_name, $_smarty_compile_path)) - { - include($_smarty_compile_path); - } - $_smarty_results = ob_get_contents(); - ob_end_clean(); - - foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { - $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); - } - } - - if ($this->caching) { - $_params = array('tpl_file' => $resource_name, - 'cache_id' => $cache_id, - 'compile_id' => $compile_id, - 'results' => $_smarty_results); - require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); - smarty_core_write_cache_file($_params, $this); - require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); - $_smarty_results = smarty_core_process_cached_inserts($_params, $this); - - if ($this->_cache_serials) { - // strip nocache-tags from output - $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' - ,'' - ,$_smarty_results); - } - // restore initial cache_info - $this->_cache_info = array_pop($_cache_info); - } - $this->_cache_including = $_cache_including; - - if ($display) { - if (isset($_smarty_results)) { echo $_smarty_results; } - if ($this->debugging) { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); - require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); - echo smarty_core_display_debug_console($_params, $this); - } - error_reporting($_smarty_old_error_level); - return; - } else { - if ($this->debugging) { - // capture time for debugging info - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime(array(), $this) - $_debug_start_time); - } - error_reporting($_smarty_old_error_level); - if (isset($_smarty_results)) { return $_smarty_results; } - } + return $this; } /** - * load configuration values + * Get autoload filters * - * @param string $file - * @param string $section - * @param string $scope + * @param string $type type of filter to get autoloads for. Defaults to all autoload filters + * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified */ - function config_load($file, $section = null, $scope = 'global') + public function getAutoloadFilters($type=null) { - require_once($this->_get_plugin_filepath('function', 'config_load')); - smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); - } - - /** - * return a reference to a registered object - * - * @param string $name - * @return object - */ - function &get_registered_object($name) { - if (!isset($this->_reg_objects[$name])) - $this->_trigger_fatal_error("'$name' is not a registered object"); - - if (!is_object($this->_reg_objects[$name][0])) - $this->_trigger_fatal_error("registered '$name' is not an object"); + if ($type !== null) { + return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); + } - return $this->_reg_objects[$name][0]; + return $this->autoload_filters; } /** - * clear configuration values + * return name of debugging template * - * @param string $var + * @return string */ - function clear_config($var = null) + public function getDebugTemplate() { - if(!isset($var)) { - // clear all values - $this->_config = array(array('vars' => array(), - 'files' => array())); - } else { - unset($this->_config[0]['vars'][$var]); - } + return $this->debug_tpl; } /** - * get filepath of requested plugin + * set the debug template * - * @param string $type - * @param string $name - * @return string|false + * @param string $tpl_name + * @return Smarty current Smarty instance for chaining + * @throws SmartyException if file is not readable */ - function _get_plugin_filepath($type, $name) + public function setDebugTemplate($tpl_name) { - $_params = array('type' => $type, 'name' => $name); - require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); - return smarty_core_assemble_plugin_filepath($_params, $this); - } - - /** - * test if resource needs compiling - * - * @param string $resource_name - * @param string $compile_path - * @return boolean - */ - function _is_compiled($resource_name, $compile_path) - { - if (!$this->force_compile && file_exists($compile_path)) { - if (!$this->compile_check) { - // no need to check compiled file - return true; - } else { - // get file source and timestamp - $_params = array('resource_name' => $resource_name, 'get_source'=>false); - if (!$this->_fetch_resource_info($_params)) { - return false; - } - if ($_params['resource_timestamp'] <= filemtime($compile_path)) { - // template not expired, no recompile - return true; - } else { - // compile template - return false; - } - } - } else { - // compiled template does not exist, or forced compile - return false; + if (!is_readable($tpl_name)) { + throw new SmartyException("Unknown file '{$tpl_name}'"); } + $this->debug_tpl = $tpl_name; + + return $this; } - /** - * compile the template + /** + * creates a template object * - * @param string $resource_name - * @param string $compile_path - * @return boolean + * @param string $template the resource handle of the template file + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param object $parent next higher level of Smarty variables + * @param boolean $do_clone flag is Smarty object shall be cloned + * @return object template object */ - function _compile_resource($resource_name, $compile_path) + public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) { - - $_params = array('resource_name' => $resource_name); - if (!$this->_fetch_resource_info($_params)) { - return false; + if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) { + $parent = $cache_id; + $cache_id = null; } - - $_source_content = $_params['source_content']; - $_cache_include = substr($compile_path, 0, -4).'.inc'; - - if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { - // if a _cache_serial was set, we also have to write an include-file: - if ($this->_cache_include_info) { - require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); - smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); - } - - $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); - require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); - smarty_core_write_compiled_resource($_params, $this); - - return true; + if (!empty($parent) && is_array($parent)) { + $data = $parent; + $parent = null; } else { - return false; + $data = null; } - - } - - /** - * compile the given source - * - * @param string $resource_name - * @param string $source_content - * @param string $compiled_content - * @return boolean - */ - function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) - { - if (file_exists(SMARTY_DIR . $this->compiler_file)) { - require_once(SMARTY_DIR . $this->compiler_file); + // default to cache_id and compile_id of Smarty object + $cache_id = $cache_id === null ? $this->cache_id : $cache_id; + $compile_id = $compile_id === null ? $this->compile_id : $compile_id; + // already in template cache? + if ($this->allow_ambiguous_resources) { + $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id; } else { - // use include_path - require_once($this->compiler_file); - } - - - $smarty_compiler = new $this->compiler_class; - - $smarty_compiler->template_dir = $this->template_dir; - $smarty_compiler->compile_dir = $this->compile_dir; - $smarty_compiler->plugins_dir = $this->plugins_dir; - $smarty_compiler->config_dir = $this->config_dir; - $smarty_compiler->force_compile = $this->force_compile; - $smarty_compiler->caching = $this->caching; - $smarty_compiler->php_handling = $this->php_handling; - $smarty_compiler->left_delimiter = $this->left_delimiter; - $smarty_compiler->right_delimiter = $this->right_delimiter; - $smarty_compiler->_version = $this->_version; - $smarty_compiler->security = $this->security; - $smarty_compiler->secure_dir = $this->secure_dir; - $smarty_compiler->security_settings = $this->security_settings; - $smarty_compiler->trusted_dir = $this->trusted_dir; - $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; - $smarty_compiler->_reg_objects = &$this->_reg_objects; - $smarty_compiler->_plugins = &$this->_plugins; - $smarty_compiler->_tpl_vars = &$this->_tpl_vars; - $smarty_compiler->default_modifiers = $this->default_modifiers; - $smarty_compiler->compile_id = $this->_compile_id; - $smarty_compiler->_config = $this->_config; - $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; - - if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { - $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; + $_templateId = $this->joined_template_dir . '#' . $template . $cache_id . $compile_id; } - $smarty_compiler->_cache_include = $cache_include_path; - - - $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); - - if ($smarty_compiler->_cache_serial) { - $this->_cache_include_info = array( - 'cache_serial'=>$smarty_compiler->_cache_serial - ,'plugins_code'=>$smarty_compiler->_plugins_code - ,'include_file_path' => $cache_include_path); - - } else { - $this->_cache_include_info = null; - + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); } - - return $_results; - } - - /** - * Get the compile path for this resource - * - * @param string $resource_name - * @return string results of {@link _get_auto_filename()} - */ - function _get_compile_path($resource_name) - { - return $this->_get_auto_filename($this->compile_dir, $resource_name, - $this->_compile_id) . '.php'; - } - - /** - * fetch the template info. Gets timestamp, and source - * if get_source is true - * - * sets $source_content to the source of the template, and - * $resource_timestamp to its time stamp - * @param string $resource_name - * @param string $source_content - * @param integer $resource_timestamp - * @param boolean $get_source - * @param boolean $quiet - * @return boolean - */ - - function _fetch_resource_info(&$params) - { - if(!isset($params['get_source'])) { $params['get_source'] = true; } - if(!isset($params['quiet'])) { $params['quiet'] = false; } - - $_return = false; - $_params = array('resource_name' => $params['resource_name']) ; - if (isset($params['resource_base_path'])) - $_params['resource_base_path'] = $params['resource_base_path']; - else - $_params['resource_base_path'] = $this->template_dir; - - if ($this->_parse_resource_name($_params)) { - $_resource_type = $_params['resource_type']; - $_resource_name = $_params['resource_name']; - switch ($_resource_type) { - case 'file': - if ($params['get_source']) { - $params['source_content'] = $this->_read_file($_resource_name); - } - $params['resource_timestamp'] = filemtime($_resource_name); - $_return = is_file($_resource_name) && is_readable($_resource_name); - break; - - default: - // call resource functions to fetch the template source and timestamp - if ($params['get_source']) { - $_source_return = isset($this->_plugins['resource'][$_resource_type]) && - call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], - array($_resource_name, &$params['source_content'], &$this)); - } else { - $_source_return = true; - } - - $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && - call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], - array($_resource_name, &$params['resource_timestamp'], &$this)); - - $_return = $_source_return && $_timestamp_return; - break; + if ($do_clone) { + if (isset($this->template_objects[$_templateId])) { + // return cached template object + $tpl = clone $this->template_objects[$_templateId]; + $tpl->smarty = clone $tpl->smarty; + $tpl->parent = $parent; + $tpl->tpl_vars = array(); + $tpl->config_vars = array(); + } else { + $tpl = new $this->template_class($template, clone $this, $parent, $cache_id, $compile_id); } - } - - if (!$_return) { - // see if we can get a template with the default template handler - if (!empty($this->default_template_handler_func)) { - if (!is_callable($this->default_template_handler_func)) { - $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); - } else { - $_return = call_user_func_array( - $this->default_template_handler_func, - array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); - } + } else { + if (isset($this->template_objects[$_templateId])) { + // return cached template object + $tpl = $this->template_objects[$_templateId]; + $tpl->parent = $parent; + $tpl->tpl_vars = array(); + $tpl->config_vars = array(); + } else { + $tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id); } } - - if (!$_return) { - if (!$params['quiet']) { - $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); - } - } else if ($_return && $this->security) { - require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); - if (!smarty_core_is_secure($_params, $this)) { - if (!$params['quiet']) - $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); - $params['source_content'] = null; - $params['resource_timestamp'] = null; - return false; + // fill data if present + if (!empty($data) && is_array($data)) { + // set up variable values + foreach ($data as $_key => $_val) { + $tpl->tpl_vars[$_key] = new Smarty_variable($_val); } } - return $_return; + return $tpl; } /** - * parse out the type and name from the resource + * Takes unknown classes and loads plugin files for them + * class name format: Smarty_PluginType_PluginName + * plugin filename format: plugintype.pluginname.php * - * @param string $resource_base_path - * @param string $resource_name - * @param string $resource_type - * @param string $resource_name - * @return boolean + * @param string $plugin_name class plugin name to load + * @param bool $check check if already loaded + * @return string |boolean filepath of loaded file or false */ - - function _parse_resource_name(&$params) + public function loadPlugin($plugin_name, $check = true) { - - // split tpl_path by the first colon - $_resource_name_parts = explode(':', $params['resource_name'], 2); - - if (count($_resource_name_parts) == 1) { - // no resource type given - $params['resource_type'] = $this->default_resource_type; - $params['resource_name'] = $_resource_name_parts[0]; - } else { - if(strlen($_resource_name_parts[0]) == 1) { - // 1 char is not resource type, but part of filepath - $params['resource_type'] = $this->default_resource_type; - $params['resource_name'] = $params['resource_name']; + // if function or class exists, exit silently (already loaded) + if ($check && (is_callable($plugin_name) || class_exists($plugin_name, false))) { + return true; + } + // Plugin name is expected to be: Smarty_[Type]_[Name] + $_name_parts = explode('_', $plugin_name, 3); + // class name must have three parts to be valid plugin + // count($_name_parts) < 3 === !isset($_name_parts[2]) + if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') { + throw new SmartyException("plugin {$plugin_name} is not a valid name format"); + return false; + } + // if type is "internal", get plugin from sysplugins + if (strtolower($_name_parts[1]) == 'internal') { + $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php'; + if (file_exists($file)) { + require_once($file); + return $file; } else { - $params['resource_type'] = $_resource_name_parts[0]; - $params['resource_name'] = $_resource_name_parts[1]; + return false; } } + // plugin filename is expected to be: [type].[name].php + $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; - if ($params['resource_type'] == 'file') { - if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { - // relative pathname to $params['resource_base_path'] - // use the first directory where the file is found - foreach ((array)$params['resource_base_path'] as $_curr_path) { - $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; - if (file_exists($_fullpath) && is_file($_fullpath)) { - $params['resource_name'] = $_fullpath; - return true; + $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); + + // loop through plugin dirs and find the plugin + foreach($this->getPluginsDir() as $_plugin_dir) { + $names = array( + $_plugin_dir . $_plugin_filename, + $_plugin_dir . strtolower($_plugin_filename), + ); + foreach ($names as $file) { + if (file_exists($file)) { + require_once($file); + return $file; + } + if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $file = stream_resolve_include_path($file); + } else { + $file = Smarty_Internal_Get_Include_Path::getIncludePath($file); } - // didn't find the file, try include_path - $_params = array('file_path' => $_fullpath); - require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); - if(smarty_core_get_include_path($_params, $this)) { - $params['resource_name'] = $_params['new_file_path']; - return true; + + if ($file !== false) { + require_once($file); + return $file; } } - return false; - } else { - /* absolute path */ - return file_exists($params['resource_name']); } - } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { - $_params = array('type' => $params['resource_type']); - require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); - smarty_core_load_resource_plugin($_params, $this); } - - return true; + // no plugin loaded + return false; } - /** - * Handle modifiers + * Compile all template files * - * @param string|null $modifier_name - * @param array|null $map_array - * @return string result of modifiers + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * @return integer number of template files recompiled */ - function _run_mod_handler() + public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) { - $_args = func_get_args(); - list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); - list($_func_name, $_tpl_file, $_tpl_line) = - $this->_plugins['modifier'][$_modifier_name]; - - $_var = $_args[0]; - foreach ($_var as $_key => $_val) { - $_args[0] = $_val; - $_var[$_key] = call_user_func_array($_func_name, $_args); - } - return $_var; + return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this); } /** - * Remove starting and ending quotes from the string + * Compile all config files * - * @param string $string - * @return string + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * @return integer number of template files recompiled */ - function _dequote($string) + public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) { - if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && - substr($string, -1) == substr($string, 0, 1)) - return substr($string, 1, -1); - else - return $string; + return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this); } - /** - * read in a file + * Delete compiled template file * - * @param string $filename - * @return string + * @param string $resource_name template name + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @return integer number of template files deleted */ - function _read_file($filename) + public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) { - if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) { - $contents = ''; - while (!feof($fd)) { - $contents .= fread($fd, 8192); - } - fclose($fd); - return $contents; - } else { - return false; - } + return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this); } - /** - * get a concrete filename for automagically created content - * - * @param string $auto_base - * @param string $auto_source - * @param string $auto_id - * @return string - * @staticvar string|null - * @staticvar string|null - */ - function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) - { - $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; - $_return = $auto_base . DIRECTORY_SEPARATOR; - - if(isset($auto_id)) { - // make auto_id safe for directory names - $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); - // split into separate directories - $_return .= $auto_id . $_compile_dir_sep; - } - - if(isset($auto_source)) { - // make source name safe for filename - $_filename = urlencode(basename($auto_source)); - $_crc32 = sprintf('%08X', crc32($auto_source)); - // prepend %% to avoid name conflicts with - // with $params['auto_id'] names - $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . - substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; - $_return .= '%%' . $_crc32 . '%%' . $_filename; - } - - return $_return; - } /** - * unlink a file, possibly using expiration time + * Return array of tag/attributes of all tags used by an template * - * @param string $resource - * @param integer $exp_time + * @param object $templae template object + * @return array of tag/attributes */ - function _unlink($resource, $exp_time = null) + public function getTags(Smarty_Internal_Template $template) { - if(isset($exp_time)) { - if(time() - @filemtime($resource) >= $exp_time) { - return @unlink($resource); - } - } else { - return @unlink($resource); - } - } - - /** - * returns an auto_id for auto-file-functions - * - * @param string $cache_id - * @param string $compile_id - * @return string|null - */ - function _get_auto_id($cache_id=null, $compile_id=null) { - if (isset($cache_id)) - return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; - elseif(isset($compile_id)) - return $compile_id; - else - return null; + return Smarty_Internal_Utility::getTags($template); } /** - * trigger Smarty plugin error + * Run installation test * - * @param string $error_msg - * @param string $tpl_file - * @param integer $tpl_line - * @param string $file - * @param integer $line - * @param integer $error_type - */ - function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, - $file = null, $line = null, $error_type = E_USER_ERROR) - { - if(isset($file) && isset($line)) { - $info = ' ('.basename($file).", line $line)"; - } else { - $info = ''; - } - if (isset($tpl_line) && isset($tpl_file)) { - $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); - } else { - $this->trigger_error($error_msg . $info, $error_type); - } - } - - - /** - * callback function for preg_replace, to call a non-cacheable block - * @return string + * @param array $errors Array to write errors into, rather than outputting them + * @return boolean true if setup is fine, false if something is wrong */ - function _process_compiled_include_callback($match) { - $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; - ob_start(); - $_func($this); - $_ret = ob_get_contents(); - ob_end_clean(); - return $_ret; + public function testInstall(&$errors=null) + { + return Smarty_Internal_Utility::testInstall($this, $errors); } - /** - * called for included templates + * Error Handler to mute expected messages * - * @param string $_smarty_include_tpl_file - * @param string $_smarty_include_vars + * @link http://php.net/set_error_handler + * @param integer $errno Error level + * @return boolean */ - - // $_smarty_include_tpl_file, $_smarty_include_vars - - function _smarty_include($params) + public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) { - if ($this->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $debug_start_time = smarty_core_get_microtime($_params, $this); - $this->_smarty_debug_info[] = array('type' => 'template', - 'filename' => $params['smarty_include_tpl_file'], - 'depth' => ++$this->_inclusion_depth); - $included_tpls_idx = count($this->_smarty_debug_info) - 1; - } - - $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); - - // config vars are treated as local, so push a copy of the - // current ones onto the front of the stack - array_unshift($this->_config, $this->_config[0]); - - $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); - - - if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) - || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) - { - include($_smarty_compile_path); - } - - // pop the local vars off the front of the stack - array_shift($this->_config); - - $this->_inclusion_depth--; - - if ($this->debugging) { - // capture time for debugging info - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; + $_is_muted_directory = false; + + // add the SMARTY_DIR to the list of muted directories + if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { + $smarty_dir = realpath(SMARTY_DIR); + if ($smarty_dir !== false) { + Smarty::$_muted_directories[SMARTY_DIR] = array( + 'file' => $smarty_dir, + 'length' => strlen($smarty_dir), + ); + } } - if ($this->caching) { - $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; + // walk the muted directories and test against $errfile + foreach (Smarty::$_muted_directories as $key => &$dir) { + if (!$dir) { + // resolve directory and length for speedy comparisons + $file = realpath($key); + if ($file === false) { + // this directory does not exist, remove and skip it + unset(Smarty::$_muted_directories[$key]); + continue; + } + $dir = array( + 'file' => $file, + 'length' => strlen($file), + ); + } + if (!strncmp($errfile, $dir['file'], $dir['length'])) { + $_is_muted_directory = true; + break; + } } - } - - - /** - * get or set an array of cached attributes for function that is - * not cacheable - * @return array - */ - function &_smarty_cache_attrs($cache_serial, $count) { - $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; - - if ($this->_cache_including) { - /* return next set of cache_attrs */ - $_return = current($_cache_attrs); - next($_cache_attrs); - return $_return; - - } else { - /* add a reference to a new set of cache_attrs */ - $_cache_attrs[] = array(); - return $_cache_attrs[count($_cache_attrs)-1]; + // pass to next error handler if this error did not occur inside SMARTY_DIR + // or the error was within smarty but masked to be ignored + if (!$_is_muted_directory || ($errno && $errno & error_reporting())) { + if (Smarty::$_previous_error_handler) { + return call_user_func(Smarty::$_previous_error_handler, $errno, $errstr, $errfile, $errline, $errcontext); + } else { + return false; + } } - } - /** - * wrapper for include() retaining $this - * @return mixed + * Enable error handler to mute expected messages + * + * @return void */ - function _include($filename, $once=false, $params=null) + public static function muteExpectedErrors() { - if ($once) { - return include_once($filename); - } else { - return include($filename); + /* + error muting is done because some people implemented custom error_handlers using + http://php.net/set_error_handler and for some reason did not understand the following paragraph: + + It is important to remember that the standard PHP error handler is completely bypassed for the + error types specified by error_types unless the callback function returns FALSE. + error_reporting() settings will have no effect and your error handler will be called regardless - + however you are still able to read the current value of error_reporting and act appropriately. + Of particular note is that this value will be 0 if the statement that caused the error was + prepended by the @ error-control operator. + + Smarty deliberately uses @filemtime() over file_exists() and filemtime() in some places. Reasons include + - @filemtime() is almost twice as fast as using an additional file_exists() + - between file_exists() and filemtime() a possible race condition is opened, + which does not exist using the simple @filemtime() approach. + */ + $error_handler = array('Smarty', 'mutingErrorHandler'); + $previous = set_error_handler($error_handler); + + // avoid dead loops + if ($previous !== $error_handler) { + Smarty::$_previous_error_handler = $previous; } } - /** - * wrapper for eval() retaining $this - * @return mixed + * Disable error handler muting expected messages + * + * @return void */ - function _eval($code, $params=null) + public static function unmuteExpectedErrors() { - return eval($code); + restore_error_handler(); } +} - /** - * Extracts the filter name from the given callback - * - * @param callback $function - * @return string - */ - function _get_filter_name($function) - { - if (is_array($function)) { - $_class_name = (is_object($function[0]) ? - get_class($function[0]) : $function[0]); - return $_class_name . '_' . $function[1]; - } - else { - return $function; - } - } +// Check if we're running on windows +Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; - /**#@-*/ +// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 +if (Smarty::$_CHARSET !== 'UTF-8') { + Smarty::$_UTF8_MODIFIER = ''; +} +/** + * Smarty exception class + * @package Smarty + */ +class SmartyException extends Exception { + public static $escape = true; + public function __construct($message) { + $this->message = self::$escape ? htmlentities($message) : $message; + } } -/* vim: set expandtab: */ +/** + * Smarty compiler exception class + * @package Smarty + */ +class SmartyCompilerException extends SmartyException { +} + +/** + * Autoloader + */ +function smartyAutoload($class) +{ + $_class = strtolower($class); + $_classes = array( + 'smarty_config_source' => true, + 'smarty_config_compiled' => true, + 'smarty_security' => true, + 'smarty_cacheresource' => true, + 'smarty_cacheresource_custom' => true, + 'smarty_cacheresource_keyvaluestore' => true, + 'smarty_resource' => true, + 'smarty_resource_custom' => true, + 'smarty_resource_uncompiled' => true, + 'smarty_resource_recompiled' => true, + ); + + if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { + include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + } +} ?> diff --git a/include/smarty/libs/SmartyBC.class.php b/include/smarty/libs/SmartyBC.class.php new file mode 100644 index 000000000..f8f0a138f --- /dev/null +++ b/include/smarty/libs/SmartyBC.class.php @@ -0,0 +1,460 @@ +<?php
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: SmartyBC.class.php
+ * SVN: $Id: $
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-discussion-subscribe@googlegroups.com
+ *
+ * @link http://www.smarty.net/
+ * @copyright 2008 New Digital Group, Inc.
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ * @package Smarty
+ */
+/**
+ * @ignore
+ */
+require(dirname(__FILE__) . '/Smarty.class.php');
+
+/**
+ * Smarty Backward Compatability Wrapper Class
+ *
+ * @package Smarty
+ */
+class SmartyBC extends Smarty {
+
+ /**
+ * Smarty 2 BC
+ * @var string
+ */
+ public $_version = self::SMARTY_VERSION;
+
+ /**
+ * Initialize new SmartyBC object
+ *
+ * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false )
+ */
+ public function __construct(array $options=array())
+ {
+ parent::__construct($options);
+ // register {php} tag
+ $this->registerPlugin('block', 'php', 'smarty_php_tag');
+ }
+
+ /**
+ * wrapper for assign_by_ref
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed &$value the referenced value to assign
+ */
+ public function assign_by_ref($tpl_var, &$value)
+ {
+ $this->assignByRef($tpl_var, $value);
+ }
+
+ /**
+ * wrapper for append_by_ref
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed &$value the referenced value to append
+ * @param boolean $merge flag if array elements shall be merged
+ */
+ public function append_by_ref($tpl_var, &$value, $merge = false)
+ {
+ $this->appendByRef($tpl_var, $value, $merge);
+ }
+
+ /**
+ * clear the given assigned template variable.
+ *
+ * @param string $tpl_var the template variable to clear
+ */
+ public function clear_assign($tpl_var)
+ {
+ $this->clearAssign($tpl_var);
+ }
+
+ /**
+ * Registers custom function to be used in templates
+ *
+ * @param string $function the name of the template function
+ * @param string $function_impl the name of the PHP function to register
+ * @param bool $cacheable
+ * @param mixed $cache_attrs
+ */
+ public function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+ {
+ $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
+ }
+
+ /**
+ * Unregisters custom function
+ *
+ * @param string $function name of template function
+ */
+ public function unregister_function($function)
+ {
+ $this->unregisterPlugin('function', $function);
+ }
+
+ /**
+ * Registers object to be used in templates
+ *
+ * @param string $object name of template object
+ * @param object $object_impl the referenced PHP object to register
+ * @param array $allowed list of allowed methods (empty = all)
+ * @param boolean $smarty_args smarty argument format, else traditional
+ * @param array $block_functs list of methods that are block format
+ */
+ public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+ {
+ settype($allowed, 'array');
+ settype($smarty_args, 'boolean');
+ $this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
+ }
+
+ /**
+ * Unregisters object
+ *
+ * @param string $object name of template object
+ */
+ public function unregister_object($object)
+ {
+ $this->unregisterObject($object);
+ }
+
+ /**
+ * Registers block function to be used in templates
+ *
+ * @param string $block name of template block
+ * @param string $block_impl PHP function to register
+ * @param bool $cacheable
+ * @param mixed $cache_attrs
+ */
+ public function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+ {
+ $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
+ }
+
+ /**
+ * Unregisters block function
+ *
+ * @param string $block name of template function
+ */
+ public function unregister_block($block)
+ {
+ $this->unregisterPlugin('block', $block);
+ }
+
+ /**
+ * Registers compiler function
+ *
+ * @param string $function name of template function
+ * @param string $function_impl name of PHP function to register
+ * @param bool $cacheable
+ */
+ public function register_compiler_function($function, $function_impl, $cacheable=true)
+ {
+ $this->registerPlugin('compiler', $function, $function_impl, $cacheable);
+ }
+
+ /**
+ * Unregisters compiler function
+ *
+ * @param string $function name of template function
+ */
+ public function unregister_compiler_function($function)
+ {
+ $this->unregisterPlugin('compiler', $function);
+ }
+
+ /**
+ * Registers modifier to be used in templates
+ *
+ * @param string $modifier name of template modifier
+ * @param string $modifier_impl name of PHP function to register
+ */
+ public function register_modifier($modifier, $modifier_impl)
+ {
+ $this->registerPlugin('modifier', $modifier, $modifier_impl);
+ }
+
+ /**
+ * Unregisters modifier
+ *
+ * @param string $modifier name of template modifier
+ */
+ public function unregister_modifier($modifier)
+ {
+ $this->unregisterPlugin('modifier', $modifier);
+ }
+
+ /**
+ * Registers a resource to fetch a template
+ *
+ * @param string $type name of resource
+ * @param array $functions array of functions to handle resource
+ */
+ public function register_resource($type, $functions)
+ {
+ $this->registerResource($type, $functions);
+ }
+
+ /**
+ * Unregisters a resource
+ *
+ * @param string $type name of resource
+ */
+ public function unregister_resource($type)
+ {
+ $this->unregisterResource($type);
+ }
+
+ /**
+ * Registers a prefilter function to apply
+ * to a template before compiling
+ *
+ * @param callable $function
+ */
+ public function register_prefilter($function)
+ {
+ $this->registerFilter('pre', $function);
+ }
+
+ /**
+ * Unregisters a prefilter function
+ *
+ * @param callable $function
+ */
+ public function unregister_prefilter($function)
+ {
+ $this->unregisterFilter('pre', $function);
+ }
+
+ /**
+ * Registers a postfilter function to apply
+ * to a compiled template after compilation
+ *
+ * @param callable $function
+ */
+ public function register_postfilter($function)
+ {
+ $this->registerFilter('post', $function);
+ }
+
+ /**
+ * Unregisters a postfilter function
+ *
+ * @param callable $function
+ */
+ public function unregister_postfilter($function)
+ {
+ $this->unregisterFilter('post', $function);
+ }
+
+ /**
+ * Registers an output filter function to apply
+ * to a template output
+ *
+ * @param callable $function
+ */
+ public function register_outputfilter($function)
+ {
+ $this->registerFilter('output', $function);
+ }
+
+ /**
+ * Unregisters an outputfilter function
+ *
+ * @param callable $function
+ */
+ public function unregister_outputfilter($function)
+ {
+ $this->unregisterFilter('output', $function);
+ }
+
+ /**
+ * load a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ */
+ public function load_filter($type, $name)
+ {
+ $this->loadFilter($type, $name);
+ }
+
+ /**
+ * clear cached content for the given template and cache id
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id name of cache_id
+ * @param string $compile_id name of compile_id
+ * @param string $exp_time expiration time
+ * @return boolean
+ */
+ public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+ {
+ return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
+ }
+
+ /**
+ * clear the entire contents of cache (all templates)
+ *
+ * @param string $exp_time expire time
+ * @return boolean
+ */
+ public function clear_all_cache($exp_time = null)
+ {
+ return $this->clearCache(null, null, null, $exp_time);
+ }
+
+ /**
+ * test to see if valid cache exists for this template
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @return boolean
+ */
+ public function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+ {
+ return $this->isCached($tpl_file, $cache_id, $compile_id);
+ }
+
+ /**
+ * clear all the assigned template variables.
+ */
+ public function clear_all_assign()
+ {
+ $this->clearAllAssign();
+ }
+
+ /**
+ * clears compiled version of specified template resource,
+ * or all compiled template files if one is not specified.
+ * This function is for advanced use only, not normally needed.
+ *
+ * @param string $tpl_file
+ * @param string $compile_id
+ * @param string $exp_time
+ * @return boolean results of {@link smarty_core_rm_auto()}
+ */
+ public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+ {
+ return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
+ }
+
+ /**
+ * Checks whether requested template exists.
+ *
+ * @param string $tpl_file
+ * @return boolean
+ */
+ public function template_exists($tpl_file)
+ {
+ return $this->templateExists($tpl_file);
+ }
+
+ /**
+ * Returns an array containing template variables
+ *
+ * @param string $name
+ * @return array
+ */
+ public function get_template_vars($name=null)
+ {
+ return $this->getTemplateVars($name);
+ }
+
+ /**
+ * Returns an array containing config variables
+ *
+ * @param string $name
+ * @return array
+ */
+ public function get_config_vars($name=null)
+ {
+ return $this->getConfigVars($name);
+ }
+
+ /**
+ * load configuration values
+ *
+ * @param string $file
+ * @param string $section
+ * @param string $scope
+ */
+ public function config_load($file, $section = null, $scope = 'global')
+ {
+ $this->ConfigLoad($file, $section, $scope);
+ }
+
+ /**
+ * return a reference to a registered object
+ *
+ * @param string $name
+ * @return object
+ */
+ public function get_registered_object($name)
+ {
+ return $this->getRegisteredObject($name);
+ }
+
+ /**
+ * clear configuration values
+ *
+ * @param string $var
+ */
+ public function clear_config($var = null)
+ {
+ $this->clearConfig($var);
+ }
+
+ /**
+ * trigger Smarty error
+ *
+ * @param string $error_msg
+ * @param integer $error_type
+ */
+ public function trigger_error($error_msg, $error_type = E_USER_WARNING)
+ {
+ trigger_error("Smarty error: $error_msg", $error_type);
+ }
+
+}
+
+/**
+ * Smarty {php}{/php} block function
+ *
+ * @param array $params parameter list
+ * @param string $content contents of the block
+ * @param object $template template object
+ * @param boolean &$repeat repeat flag
+ * @return string content re-formatted
+ */
+function smarty_php_tag($params, $content, $template, &$repeat)
+{
+ eval($content);
+ return '';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/Smarty_Compiler.class.php b/include/smarty/libs/Smarty_Compiler.class.php deleted file mode 100644 index 62a467bea..000000000 --- a/include/smarty/libs/Smarty_Compiler.class.php +++ /dev/null @@ -1,2365 +0,0 @@ -<?php - -/** - * Project: Smarty: the PHP compiling template engine - * File: Smarty_Compiler.class.php - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * @link http://smarty.php.net/ - * @author Monte Ohrt <monte at ohrt dot com> - * @author Andrei Zmievski <andrei@php.net> - * @version 2.6.26 - * @copyright 2001-2005 New Digital Group, Inc. - * @package Smarty - */ - -/* $Id: Smarty_Compiler.class.php 3163 2009-06-17 14:39:24Z monte.ohrt $ */ - -/** - * Template compiling class - * @package Smarty - */ -class Smarty_Compiler extends Smarty { - - // internal vars - /**#@+ - * @access private - */ - var $_folded_blocks = array(); // keeps folded template blocks - var $_current_file = null; // the current template being compiled - var $_current_line_no = 1; // line number for error messages - var $_capture_stack = array(); // keeps track of nested capture buffers - var $_plugin_info = array(); // keeps track of plugins to load - var $_init_smarty_vars = false; - var $_permitted_tokens = array('true','false','yes','no','on','off','null'); - var $_db_qstr_regexp = null; // regexps are setup in the constructor - var $_si_qstr_regexp = null; - var $_qstr_regexp = null; - var $_func_regexp = null; - var $_reg_obj_regexp = null; - var $_var_bracket_regexp = null; - var $_num_const_regexp = null; - var $_dvar_guts_regexp = null; - var $_dvar_regexp = null; - var $_cvar_regexp = null; - var $_svar_regexp = null; - var $_avar_regexp = null; - var $_mod_regexp = null; - var $_var_regexp = null; - var $_parenth_param_regexp = null; - var $_func_call_regexp = null; - var $_obj_ext_regexp = null; - var $_obj_start_regexp = null; - var $_obj_params_regexp = null; - var $_obj_call_regexp = null; - var $_cacheable_state = 0; - var $_cache_attrs_count = 0; - var $_nocache_count = 0; - var $_cache_serial = null; - var $_cache_include = null; - - var $_strip_depth = 0; - var $_additional_newline = "\n"; - - /**#@-*/ - /** - * The class constructor. - */ - function Smarty_Compiler() - { - // matches double quoted strings: - // "foobar" - // "foo\"bar" - $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; - - // matches single quoted strings: - // 'foobar' - // 'foo\'bar' - $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - - // matches single or double quoted strings - $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; - - // matches bracket portion of vars - // [0] - // [foo] - // [$bar] - $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; - - // matches numerical constants - // 30 - // -12 - // 13.22 - $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; - - // matches $ vars (not objects): - // $foo - // $foo.bar - // $foo.bar.foobar - // $foo[0] - // $foo[$bar] - // $foo[5][blah] - // $foo[5].bar[$foobar][4] - $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; - $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; - $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp - . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; - $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; - - // matches config vars: - // #foo# - // #foobar123_foo# - $this->_cvar_regexp = '\#\w+\#'; - - // matches section vars: - // %foo.bar% - $this->_svar_regexp = '\%\w+\.\w+\%'; - - // matches all valid variables (no quotes, no modifiers) - $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' - . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; - - // matches valid variable syntax: - // $foo - // $foo - // #foo# - // #foo# - // "text" - // "text" - $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; - - // matches valid object call (one level of object nesting allowed in parameters): - // $foo->bar - // $foo->bar() - // $foo->bar("text") - // $foo->bar($foo, $bar, "text") - // $foo->bar($foo, "foo") - // $foo->bar->foo() - // $foo->bar->foo->bar() - // $foo->bar($foo->bar) - // $foo->bar($foo->bar()) - // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) - $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; - $this->_obj_restricted_param_regexp = '(?:' - . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' - . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; - $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' - . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; - $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp - . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; - $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; - $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; - - // matches valid modifier syntax: - // |foo - // |@foo - // |foo:"bar" - // |foo:$bar - // |foo:"bar":$foobar - // |foo|bar - // |foo:$foo->bar - $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' - . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; - - // matches valid function name: - // foo123 - // _foo_bar - $this->_func_regexp = '[a-zA-Z_]\w*'; - - // matches valid registered object: - // foo->bar - $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; - - // matches valid parameter values: - // true - // $foo - // $foo|bar - // #foo# - // #foo#|bar - // "text" - // "text"|bar - // $foo->bar - $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' - . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; - - // matches valid parenthesised function parameters: - // - // "text" - // $foo, $bar, "text" - // $foo|bar, "foo"|bar, $foo->bar($foo)|bar - $this->_parenth_param_regexp = '(?:\((?:\w+|' - . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' - . $this->_param_regexp . ')))*)?\))'; - - // matches valid function call: - // foo() - // foo_bar($foo) - // _foo_bar($foo,"bar") - // foo123($foo,$foo->bar(),"foo") - $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' - . $this->_parenth_param_regexp . '))'; - } - - /** - * compile a resource - * - * sets $compiled_content to the compiled source - * @param string $resource_name - * @param string $source_content - * @param string $compiled_content - * @return true - */ - function _compile_file($resource_name, $source_content, &$compiled_content) - { - - if ($this->security) { - // do not allow php syntax to be executed unless specified - if ($this->php_handling == SMARTY_PHP_ALLOW && - !$this->security_settings['PHP_HANDLING']) { - $this->php_handling = SMARTY_PHP_PASSTHRU; - } - } - - $this->_load_filters(); - - $this->_current_file = $resource_name; - $this->_current_line_no = 1; - $ldq = preg_quote($this->left_delimiter, '~'); - $rdq = preg_quote($this->right_delimiter, '~'); - - // run template source through prefilter functions - if (count($this->_plugins['prefilter']) > 0) { - foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { - if ($prefilter === false) continue; - if ($prefilter[3] || is_callable($prefilter[0])) { - $source_content = call_user_func_array($prefilter[0], - array($source_content, &$this)); - $this->_plugins['prefilter'][$filter_name][3] = true; - } else { - $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); - } - } - } - - /* fetch all special blocks */ - $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; - - preg_match_all($search, $source_content, $match, PREG_SET_ORDER); - $this->_folded_blocks = $match; - reset($this->_folded_blocks); - - /* replace special blocks by "{php}" */ - $source_content = preg_replace($search.'e', "'" - . $this->_quote_replace($this->left_delimiter) . 'php' - . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" - . $this->_quote_replace($this->right_delimiter) - . "'" - , $source_content); - - /* Gather all template tags. */ - preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); - $template_tags = $_match[1]; - /* Split content by template tags to obtain non-template content. */ - $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); - - /* loop through text blocks */ - for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { - /* match anything resembling php tags */ - if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { - /* replace tags with placeholders to prevent recursive replacements */ - $sp_match[1] = array_unique($sp_match[1]); - usort($sp_match[1], '_smarty_sort_length'); - for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { - $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); - } - /* process each one */ - for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { - if ($this->php_handling == SMARTY_PHP_PASSTHRU) { - /* echo php contents */ - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]); - } else if ($this->php_handling == SMARTY_PHP_QUOTE) { - /* quote php tags */ - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); - } else if ($this->php_handling == SMARTY_PHP_REMOVE) { - /* remove php tags */ - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); - } else { - /* SMARTY_PHP_ALLOW, but echo non php starting tags */ - $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]); - $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); - } - } - } - } - - /* Compile the template tags into PHP code. */ - $compiled_tags = array(); - for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { - $this->_current_line_no += substr_count($text_blocks[$i], "\n"); - $compiled_tags[] = $this->_compile_tag($template_tags[$i]); - $this->_current_line_no += substr_count($template_tags[$i], "\n"); - } - if (count($this->_tag_stack)>0) { - list($_open_tag, $_line_no) = end($this->_tag_stack); - $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); - return; - } - - /* Reformat $text_blocks between 'strip' and '/strip' tags, - removing spaces, tabs and newlines. */ - $strip = false; - for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { - if ($compiled_tags[$i] == '{strip}') { - $compiled_tags[$i] = ''; - $strip = true; - /* remove leading whitespaces */ - $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); - } - if ($strip) { - /* strip all $text_blocks before the next '/strip' */ - for ($j = $i + 1; $j < $for_max; $j++) { - /* remove leading and trailing whitespaces of each line */ - $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', ' ', $text_blocks[$j]); - if ($compiled_tags[$j] == '{/strip}') { - /* remove trailing whitespaces from the last text_block */ - $text_blocks[$j] = rtrim($text_blocks[$j]); - } - $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>"; - if ($compiled_tags[$j] == '{/strip}') { - $compiled_tags[$j] = "\n"; /* slurped by php, but necessary - if a newline is following the closing strip-tag */ - $strip = false; - $i = $j; - break; - } - } - } - } - $compiled_content = ''; - - $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; - - /* Interleave the compiled contents and text blocks to get the final result. */ - for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { - if ($compiled_tags[$i] == '') { - // tag result empty, remove first newline from following text block - $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); - } - // replace legit PHP tags with placeholder - $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]); - $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]); - - $compiled_content .= $text_blocks[$i] . $compiled_tags[$i]; - } - $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]); - - // escape php tags created by interleaving - $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content); - $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content); - - // recover legit tags - $compiled_content = str_replace($tag_guard, '<?', $compiled_content); - - // remove \n from the end of the file, if any - if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) { - $compiled_content = substr($compiled_content, 0, -1); - } - - if (!empty($this->_cache_serial)) { - $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; - } - - // run compiled template through postfilter functions - if (count($this->_plugins['postfilter']) > 0) { - foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { - if ($postfilter === false) continue; - if ($postfilter[3] || is_callable($postfilter[0])) { - $compiled_content = call_user_func_array($postfilter[0], - array($compiled_content, &$this)); - $this->_plugins['postfilter'][$filter_name][3] = true; - } else { - $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); - } - } - } - - // put header at the top of the compiled template - $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; - $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; - - /* Emit code to load needed plugins. */ - $this->_plugins_code = ''; - if (count($this->_plugin_info)) { - $_plugins_params = "array('plugins' => array("; - foreach ($this->_plugin_info as $plugin_type => $plugins) { - foreach ($plugins as $plugin_name => $plugin_info) { - $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; - $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; - } - } - $_plugins_params .= '))'; - $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n"; - $template_header .= $plugins_code; - $this->_plugin_info = array(); - $this->_plugins_code = $plugins_code; - } - - if ($this->_init_smarty_vars) { - $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n"; - $this->_init_smarty_vars = false; - } - - $compiled_content = $template_header . $compiled_content; - return true; - } - - /** - * Compile a template tag - * - * @param string $template_tag - * @return string - */ - function _compile_tag($template_tag) - { - /* Matched comment. */ - if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') - return ''; - - /* Split tag into two three parts: command, command modifiers and the arguments. */ - if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp - . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) - (?:\s+(.*))?$ - ~xs', $template_tag, $match)) { - $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); - } - - $tag_command = $match[1]; - $tag_modifier = isset($match[2]) ? $match[2] : null; - $tag_args = isset($match[3]) ? $match[3] : null; - - if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { - /* tag name is a variable or object */ - $_return = $this->_parse_var_props($tag_command . $tag_modifier); - return "<?php echo $_return; ?>" . $this->_additional_newline; - } - - /* If the tag name is a registered object, we process it. */ - if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { - return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); - } - - switch ($tag_command) { - case 'include': - return $this->_compile_include_tag($tag_args); - - case 'include_php': - return $this->_compile_include_php_tag($tag_args); - - case 'if': - $this->_push_tag('if'); - return $this->_compile_if_tag($tag_args); - - case 'else': - list($_open_tag) = end($this->_tag_stack); - if ($_open_tag != 'if' && $_open_tag != 'elseif') - $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); - else - $this->_push_tag('else'); - return '<?php else: ?>'; - - case 'elseif': - list($_open_tag) = end($this->_tag_stack); - if ($_open_tag != 'if' && $_open_tag != 'elseif') - $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); - if ($_open_tag == 'if') - $this->_push_tag('elseif'); - return $this->_compile_if_tag($tag_args, true); - - case '/if': - $this->_pop_tag('if'); - return '<?php endif; ?>'; - - case 'capture': - return $this->_compile_capture_tag(true, $tag_args); - - case '/capture': - return $this->_compile_capture_tag(false); - - case 'ldelim': - return $this->left_delimiter; - - case 'rdelim': - return $this->right_delimiter; - - case 'section': - $this->_push_tag('section'); - return $this->_compile_section_start($tag_args); - - case 'sectionelse': - $this->_push_tag('sectionelse'); - return "<?php endfor; else: ?>"; - break; - - case '/section': - $_open_tag = $this->_pop_tag('section'); - if ($_open_tag == 'sectionelse') - return "<?php endif; ?>"; - else - return "<?php endfor; endif; ?>"; - - case 'foreach': - $this->_push_tag('foreach'); - return $this->_compile_foreach_start($tag_args); - break; - - case 'foreachelse': - $this->_push_tag('foreachelse'); - return "<?php endforeach; else: ?>"; - - case '/foreach': - $_open_tag = $this->_pop_tag('foreach'); - if ($_open_tag == 'foreachelse') - return "<?php endif; unset(\$_from); ?>"; - else - return "<?php endforeach; endif; unset(\$_from); ?>"; - break; - - case 'strip': - case '/strip': - if (substr($tag_command, 0, 1)=='/') { - $this->_pop_tag('strip'); - if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ - $this->_additional_newline = "\n"; - return '{' . $tag_command . '}'; - } - } else { - $this->_push_tag('strip'); - if ($this->_strip_depth++==0) { /* outermost opening {strip} */ - $this->_additional_newline = ""; - return '{' . $tag_command . '}'; - } - } - return ''; - - case 'php': - /* handle folded tags replaced by {php} */ - list(, $block) = each($this->_folded_blocks); - $this->_current_line_no += substr_count($block[0], "\n"); - /* the number of matched elements in the regexp in _compile_file() - determins the type of folded tag that was found */ - switch (count($block)) { - case 2: /* comment */ - return ''; - - case 3: /* literal */ - return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; - - case 4: /* php */ - if ($this->security && !$this->security_settings['PHP_TAGS']) { - $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); - return; - } - return '<?php ' . $block[3] .' ?>'; - } - break; - - case 'insert': - return $this->_compile_insert_tag($tag_args); - - default: - if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { - return $output; - } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { - return $output; - } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { - return $output; - } else { - $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); - } - - } - } - - - /** - * compile the custom compiler tag - * - * sets $output to the compiled custom compiler tag - * @param string $tag_command - * @param string $tag_args - * @param string $output - * @return boolean - */ - function _compile_compiler_tag($tag_command, $tag_args, &$output) - { - $found = false; - $have_function = true; - - /* - * First we check if the compiler function has already been registered - * or loaded from a plugin file. - */ - if (isset($this->_plugins['compiler'][$tag_command])) { - $found = true; - $plugin_func = $this->_plugins['compiler'][$tag_command][0]; - if (!is_callable($plugin_func)) { - $message = "compiler function '$tag_command' is not implemented"; - $have_function = false; - } - } - /* - * Otherwise we need to load plugin file and look for the function - * inside it. - */ - else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { - $found = true; - - include_once $plugin_file; - - $plugin_func = 'smarty_compiler_' . $tag_command; - if (!is_callable($plugin_func)) { - $message = "plugin function $plugin_func() not found in $plugin_file\n"; - $have_function = false; - } else { - $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); - } - } - - /* - * True return value means that we either found a plugin or a - * dynamically registered function. False means that we didn't and the - * compiler should now emit code to load custom function plugin for this - * tag. - */ - if ($found) { - if ($have_function) { - $output = call_user_func_array($plugin_func, array($tag_args, &$this)); - if($output != '') { - $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command) - . $output - . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; - } - } else { - $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); - } - return true; - } else { - return false; - } - } - - - /** - * compile block function tag - * - * sets $output to compiled block function tag - * @param string $tag_command - * @param string $tag_args - * @param string $tag_modifier - * @param string $output - * @return boolean - */ - function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) - { - if (substr($tag_command, 0, 1) == '/') { - $start_tag = false; - $tag_command = substr($tag_command, 1); - } else - $start_tag = true; - - $found = false; - $have_function = true; - - /* - * First we check if the block function has already been registered - * or loaded from a plugin file. - */ - if (isset($this->_plugins['block'][$tag_command])) { - $found = true; - $plugin_func = $this->_plugins['block'][$tag_command][0]; - if (!is_callable($plugin_func)) { - $message = "block function '$tag_command' is not implemented"; - $have_function = false; - } - } - /* - * Otherwise we need to load plugin file and look for the function - * inside it. - */ - else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { - $found = true; - - include_once $plugin_file; - - $plugin_func = 'smarty_block_' . $tag_command; - if (!function_exists($plugin_func)) { - $message = "plugin function $plugin_func() not found in $plugin_file\n"; - $have_function = false; - } else { - $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); - - } - } - - if (!$found) { - return false; - } else if (!$have_function) { - $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); - return true; - } - - /* - * Even though we've located the plugin function, compilation - * happens only once, so the plugin will still need to be loaded - * at runtime for future requests. - */ - $this->_add_plugin('block', $tag_command); - - if ($start_tag) - $this->_push_tag($tag_command); - else - $this->_pop_tag($tag_command); - - if ($start_tag) { - $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command); - $attrs = $this->_parse_attrs($tag_args); - $_cache_attrs=''; - $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); - $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; - $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; - $output .= 'while ($_block_repeat) { ob_start(); ?>'; - } else { - $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); '; - $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; - if ($tag_modifier != '') { - $this->_parse_modifiers($_out_tag_text, $tag_modifier); - } - $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; - $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; - } - - return true; - } - - - /** - * compile custom function tag - * - * @param string $tag_command - * @param string $tag_args - * @param string $tag_modifier - * @return string - */ - function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) - { - $found = false; - $have_function = true; - - /* - * First we check if the custom function has already been registered - * or loaded from a plugin file. - */ - if (isset($this->_plugins['function'][$tag_command])) { - $found = true; - $plugin_func = $this->_plugins['function'][$tag_command][0]; - if (!is_callable($plugin_func)) { - $message = "custom function '$tag_command' is not implemented"; - $have_function = false; - } - } - /* - * Otherwise we need to load plugin file and look for the function - * inside it. - */ - else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { - $found = true; - - include_once $plugin_file; - - $plugin_func = 'smarty_function_' . $tag_command; - if (!function_exists($plugin_func)) { - $message = "plugin function $plugin_func() not found in $plugin_file\n"; - $have_function = false; - } else { - $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); - - } - } - - if (!$found) { - return false; - } else if (!$have_function) { - $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); - return true; - } - - /* declare plugin to be loaded on display of the template that - we compile right now */ - $this->_add_plugin('function', $tag_command); - - $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); - $attrs = $this->_parse_attrs($tag_args); - $_cache_attrs = ''; - $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); - - $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; - if($tag_modifier != '') { - $this->_parse_modifiers($output, $tag_modifier); - } - - if($output != '') { - $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';' - . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; - } - - return true; - } - - /** - * compile a registered object tag - * - * @param string $tag_command - * @param array $attrs - * @param string $tag_modifier - * @return string - */ - function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) - { - if (substr($tag_command, 0, 1) == '/') { - $start_tag = false; - $tag_command = substr($tag_command, 1); - } else { - $start_tag = true; - } - - list($object, $obj_comp) = explode('->', $tag_command); - - $arg_list = array(); - if(count($attrs)) { - $_assign_var = false; - foreach ($attrs as $arg_name => $arg_value) { - if($arg_name == 'assign') { - $_assign_var = $arg_value; - unset($attrs['assign']); - continue; - } - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - } - - if($this->_reg_objects[$object][2]) { - // smarty object argument format - $args = "array(".implode(',', (array)$arg_list)."), \$this"; - } else { - // traditional argument format - $args = implode(',', array_values($attrs)); - if (empty($args)) { - $args = ''; - } - } - - $prefix = ''; - $postfix = ''; - $newline = ''; - if(!is_object($this->_reg_objects[$object][0])) { - $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); - } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { - $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); - } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { - // method - if(in_array($obj_comp, $this->_reg_objects[$object][3])) { - // block method - if ($start_tag) { - $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; - $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; - $prefix .= "while (\$_block_repeat) { ob_start();"; - $return = null; - $postfix = ''; - } else { - $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; - $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; - $postfix = "} array_pop(\$this->_tag_stack);"; - } - } else { - // non-block method - $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; - } - } else { - // property - $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; - } - - if($return != null) { - if($tag_modifier != '') { - $this->_parse_modifiers($return, $tag_modifier); - } - - if(!empty($_assign_var)) { - $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; - } else { - $output = 'echo ' . $return . ';'; - $newline = $this->_additional_newline; - } - } else { - $output = ''; - } - - return '<?php ' . $prefix . $output . $postfix . "?>" . $newline; - } - - /** - * Compile {insert ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_insert_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $name = $this->_dequote($attrs['name']); - - if (empty($name)) { - return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); - } - - if (!preg_match('~^\w+$~', $name)) { - return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); - } - - if (!empty($attrs['script'])) { - $delayed_loading = true; - } else { - $delayed_loading = false; - } - - foreach ($attrs as $arg_name => $arg_value) { - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - $this->_add_plugin('insert', $name, $delayed_loading); - - $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; - - return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline; - } - - /** - * Compile {include ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_include_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $arg_list = array(); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); - } - - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'file') { - $include_file = $arg_value; - continue; - } else if ($arg_name == 'assign') { - $assign_var = $arg_value; - continue; - } - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - $output = '<?php '; - - if (isset($assign_var)) { - $output .= "ob_start();\n"; - } - - $output .= - "\$_smarty_tpl_vars = \$this->_tpl_vars;\n"; - - - $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; - $output .= "\$this->_smarty_include($_params);\n" . - "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . - "unset(\$_smarty_tpl_vars);\n"; - - if (isset($assign_var)) { - $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; - } - - $output .= ' ?>'; - - return $output; - - } - - /** - * Compile {include ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_include_php_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); - } - - $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); - $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; - - $arg_list = array(); - foreach($attrs as $arg_name => $arg_value) { - if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { - if(is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - } - - $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; - - return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline; - } - - - /** - * Compile {section ...} tag - * - * @param string $tag_args - * @return string - */ - function _compile_section_start($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $arg_list = array(); - - $output = '<?php '; - $section_name = $attrs['name']; - if (empty($section_name)) { - $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); - } - - $output .= "unset(\$this->_sections[$section_name]);\n"; - $section_props = "\$this->_sections[$section_name]"; - - foreach ($attrs as $attr_name => $attr_value) { - switch ($attr_name) { - case 'loop': - $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; - break; - - case 'show': - if (is_bool($attr_value)) - $show_attr_value = $attr_value ? 'true' : 'false'; - else - $show_attr_value = "(bool)$attr_value"; - $output .= "{$section_props}['show'] = $show_attr_value;\n"; - break; - - case 'name': - $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; - break; - - case 'max': - case 'start': - $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; - break; - - case 'step': - $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; - break; - - default: - $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); - break; - } - } - - if (!isset($attrs['show'])) - $output .= "{$section_props}['show'] = true;\n"; - - if (!isset($attrs['loop'])) - $output .= "{$section_props}['loop'] = 1;\n"; - - if (!isset($attrs['max'])) - $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; - else - $output .= "if ({$section_props}['max'] < 0)\n" . - " {$section_props}['max'] = {$section_props}['loop'];\n"; - - if (!isset($attrs['step'])) - $output .= "{$section_props}['step'] = 1;\n"; - - if (!isset($attrs['start'])) - $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; - else { - $output .= "if ({$section_props}['start'] < 0)\n" . - " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . - "else\n" . - " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; - } - - $output .= "if ({$section_props}['show']) {\n"; - if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { - $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; - } else { - $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; - } - $output .= " if ({$section_props}['total'] == 0)\n" . - " {$section_props}['show'] = false;\n" . - "} else\n" . - " {$section_props}['total'] = 0;\n"; - - $output .= "if ({$section_props}['show']):\n"; - $output .= " - for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; - {$section_props}['iteration'] <= {$section_props}['total']; - {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; - $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; - $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; - $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; - $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; - $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; - - $output .= "?>"; - - return $output; - } - - - /** - * Compile {foreach ...} tag. - * - * @param string $tag_args - * @return string - */ - function _compile_foreach_start($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $arg_list = array(); - - if (empty($attrs['from'])) { - return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); - } - $from = $attrs['from']; - - if (empty($attrs['item'])) { - return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); - } - $item = $this->_dequote($attrs['item']); - if (!preg_match('~^\w+$~', $item)) { - return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); - } - - if (isset($attrs['key'])) { - $key = $this->_dequote($attrs['key']); - if (!preg_match('~^\w+$~', $key)) { - return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); - } - $key_part = "\$this->_tpl_vars['$key'] => "; - } else { - $key = null; - $key_part = ''; - } - - if (isset($attrs['name'])) { - $name = $attrs['name']; - } else { - $name = null; - } - - $output = '<?php '; - $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }"; - if (isset($name)) { - $foreach_props = "\$this->_foreach[$name]"; - $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; - $output .= "if ({$foreach_props}['total'] > 0):\n"; - $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; - $output .= " {$foreach_props}['iteration']++;\n"; - } else { - $output .= "if (count(\$_from)):\n"; - $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; - } - $output .= '?>'; - - return $output; - } - - - /** - * Compile {capture} .. {/capture} tags - * - * @param boolean $start true if this is the {capture} tag - * @param string $tag_args - * @return string - */ - - function _compile_capture_tag($start, $tag_args = '') - { - $attrs = $this->_parse_attrs($tag_args); - - if ($start) { - $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'"; - $assign = isset($attrs['assign']) ? $attrs['assign'] : null; - $append = isset($attrs['append']) ? $attrs['append'] : null; - - $output = "<?php ob_start(); ?>"; - $this->_capture_stack[] = array($buffer, $assign, $append); - } else { - list($buffer, $assign, $append) = array_pop($this->_capture_stack); - $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); "; - if (isset($assign)) { - $output .= " \$this->assign($assign, ob_get_contents());"; - } - if (isset($append)) { - $output .= " \$this->append($append, ob_get_contents());"; - } - $output .= "ob_end_clean(); ?>"; - } - - return $output; - } - - /** - * Compile {if ...} tag - * - * @param string $tag_args - * @param boolean $elseif if true, uses elseif instead of if - * @return string - */ - function _compile_if_tag($tag_args, $elseif = false) - { - - /* Tokenize args for 'if' tag. */ - preg_match_all('~(?> - ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call - ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string - \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token - \b\w+\b | # valid word token - \S+ # anything else - )~x', $tag_args, $match); - - $tokens = $match[0]; - - if(empty($tokens)) { - $_error_msg = $elseif ? "'elseif'" : "'if'"; - $_error_msg .= ' statement requires arguments'; - $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); - } - - - // make sure we have balanced parenthesis - $token_count = array_count_values($tokens); - if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { - $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); - } - - $is_arg_stack = array(); - - for ($i = 0; $i < count($tokens); $i++) { - - $token = &$tokens[$i]; - - switch (strtolower($token)) { - case '!': - case '%': - case '!==': - case '==': - case '===': - case '>': - case '<': - case '!=': - case '<>': - case '<<': - case '>>': - case '<=': - case '>=': - case '&&': - case '||': - case '|': - case '^': - case '&': - case '~': - case ')': - case ',': - case '+': - case '-': - case '*': - case '/': - case '@': - break; - - case 'eq': - $token = '=='; - break; - - case 'ne': - case 'neq': - $token = '!='; - break; - - case 'lt': - $token = '<'; - break; - - case 'le': - case 'lte': - $token = '<='; - break; - - case 'gt': - $token = '>'; - break; - - case 'ge': - case 'gte': - $token = '>='; - break; - - case 'and': - $token = '&&'; - break; - - case 'or': - $token = '||'; - break; - - case 'not': - $token = '!'; - break; - - case 'mod': - $token = '%'; - break; - - case '(': - array_push($is_arg_stack, $i); - break; - - case 'is': - /* If last token was a ')', we operate on the parenthesized - expression. The start of the expression is on the stack. - Otherwise, we operate on the last encountered token. */ - if ($tokens[$i-1] == ')') { - $is_arg_start = array_pop($is_arg_stack); - if ($is_arg_start != 0) { - if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) { - $is_arg_start--; - } - } - } else - $is_arg_start = $i-1; - /* Construct the argument for 'is' expression, so it knows - what to operate on. */ - $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); - - /* Pass all tokens from next one until the end to the - 'is' expression parsing function. The function will - return modified tokens, where the first one is the result - of the 'is' expression and the rest are the tokens it - didn't touch. */ - $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); - - /* Replace the old tokens with the new ones. */ - array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); - - /* Adjust argument start so that it won't change from the - current position for the next iteration. */ - $i = $is_arg_start; - break; - - default: - if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { - // function call - if($this->security && - !in_array($token, $this->security_settings['IF_FUNCS'])) { - $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); - } - } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { - // variable function call - $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); - } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { - // object or variable - $token = $this->_parse_var_props($token); - } elseif(is_numeric($token)) { - // number, skip it - } else { - $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); - } - break; - } - } - - if ($elseif) - return '<?php elseif ('.implode(' ', $tokens).'): ?>'; - else - return '<?php if ('.implode(' ', $tokens).'): ?>'; - } - - - function _compile_arg_list($type, $name, $attrs, &$cache_code) { - $arg_list = array(); - - if (isset($type) && isset($name) - && isset($this->_plugins[$type]) - && isset($this->_plugins[$type][$name]) - && empty($this->_plugins[$type][$name][4]) - && is_array($this->_plugins[$type][$name][5]) - ) { - /* we have a list of parameters that should be cached */ - $_cache_attrs = $this->_plugins[$type][$name][5]; - $_count = $this->_cache_attrs_count++; - $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; - - } else { - /* no parameters are cached */ - $_cache_attrs = null; - } - - foreach ($attrs as $arg_name => $arg_value) { - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - if (is_null($arg_value)) - $arg_value = 'null'; - if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { - $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; - } else { - $arg_list[] = "'$arg_name' => $arg_value"; - } - } - return $arg_list; - } - - /** - * Parse is expression - * - * @param string $is_arg - * @param array $tokens - * @return array - */ - function _parse_is_expr($is_arg, $tokens) - { - $expr_end = 0; - $negate_expr = false; - - if (($first_token = array_shift($tokens)) == 'not') { - $negate_expr = true; - $expr_type = array_shift($tokens); - } else - $expr_type = $first_token; - - switch ($expr_type) { - case 'even': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; - } else - $expr = "!(1 & $is_arg)"; - break; - - case 'odd': - if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; - } else - $expr = "(1 & $is_arg)"; - break; - - case 'div': - if (@$tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; - } else { - $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); - } - break; - - default: - $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); - break; - } - - if ($negate_expr) { - $expr = "!($expr)"; - } - - array_splice($tokens, 0, $expr_end, $expr); - - return $tokens; - } - - - /** - * Parse attribute string - * - * @param string $tag_args - * @return array - */ - function _parse_attrs($tag_args) - { - - /* Tokenize tag attributes. */ - preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) - )+ | - [=] - ~x', $tag_args, $match); - $tokens = $match[0]; - - $attrs = array(); - /* Parse state: - 0 - expecting attribute name - 1 - expecting '=' - 2 - expecting attribute value (not '=') */ - $state = 0; - - foreach ($tokens as $token) { - switch ($state) { - case 0: - /* If the token is a valid identifier, we set attribute name - and go to state 1. */ - if (preg_match('~^\w+$~', $token)) { - $attr_name = $token; - $state = 1; - } else - $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); - break; - - case 1: - /* If the token is '=', then we go to state 2. */ - if ($token == '=') { - $state = 2; - } else - $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); - break; - - case 2: - /* If token is not '=', we set the attribute value and go to - state 0. */ - if ($token != '=') { - /* We booleanize the token if it's a non-quoted possible - boolean value. */ - if (preg_match('~^(on|yes|true)$~', $token)) { - $token = 'true'; - } else if (preg_match('~^(off|no|false)$~', $token)) { - $token = 'false'; - } else if ($token == 'null') { - $token = 'null'; - } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { - /* treat integer literally */ - } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { - /* treat as a string, double-quote it escaping quotes */ - $token = '"'.addslashes($token).'"'; - } - - $attrs[$attr_name] = $token; - $state = 0; - } else - $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); - break; - } - $last_token = $token; - } - - if($state != 0) { - if($state == 1) { - $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); - } else { - $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); - } - } - - $this->_parse_vars_props($attrs); - - return $attrs; - } - - /** - * compile multiple variables and section properties tokens into - * PHP code - * - * @param array $tokens - */ - function _parse_vars_props(&$tokens) - { - foreach($tokens as $key => $val) { - $tokens[$key] = $this->_parse_var_props($val); - } - } - - /** - * compile single variable and section properties token into - * PHP code - * - * @param string $val - * @param string $tag_attrs - * @return string - */ - function _parse_var_props($val) - { - $val = trim($val); - - if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { - // $ variable or object - $return = $this->_parse_var($match[1]); - $modifiers = $match[2]; - if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { - $_default_mod_string = implode('|',(array)$this->default_modifiers); - $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; - } - $this->_parse_modifiers($return, $modifiers); - return $return; - } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // double quoted text - preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); - $return = $this->_expand_quoted_text($match[1]); - if($match[2] != '') { - $this->_parse_modifiers($return, $match[2]); - } - return $return; - } - elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // numerical constant - preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); - if($match[2] != '') { - $this->_parse_modifiers($match[1], $match[2]); - return $match[1]; - } - } - elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // single quoted text - preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); - if($match[2] != '') { - $this->_parse_modifiers($match[1], $match[2]); - return $match[1]; - } - } - elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // config var - return $this->_parse_conf_var($val); - } - elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { - // section var - return $this->_parse_section_prop($val); - } - elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { - // literal string - return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); - } - return $val; - } - - /** - * expand quoted text with embedded variables - * - * @param string $var_expr - * @return string - */ - function _expand_quoted_text($var_expr) - { - // if contains unescaped $, expand it - if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) { - $_match = $_match[0]; - $_replace = array(); - foreach($_match as $_var) { - $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."'; - } - $var_expr = strtr($var_expr, $_replace); - $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr); - } else { - $_return = $var_expr; - } - // replace double quoted literal string with single quotes - $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return); - return $_return; - } - - /** - * parse variable expression into PHP code - * - * @param string $var_expr - * @param string $output - * @return string - */ - function _parse_var($var_expr) - { - $_has_math = false; - $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); - - if(count($_math_vars) > 1) { - $_first_var = ""; - $_complete_var = ""; - $_output = ""; - // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) - foreach($_math_vars as $_k => $_math_var) { - $_math_var = $_math_vars[$_k]; - - if(!empty($_math_var) || is_numeric($_math_var)) { - // hit a math operator, so process the stuff which came before it - if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { - $_has_math = true; - if(!empty($_complete_var) || is_numeric($_complete_var)) { - $_output .= $this->_parse_var($_complete_var); - } - - // just output the math operator to php - $_output .= $_math_var; - - if(empty($_first_var)) - $_first_var = $_complete_var; - - $_complete_var = ""; - } else { - $_complete_var .= $_math_var; - } - } - } - if($_has_math) { - if(!empty($_complete_var) || is_numeric($_complete_var)) - $_output .= $this->_parse_var($_complete_var); - - // get the modifiers working (only the last var from math + modifier is left) - $var_expr = $_complete_var; - } - } - - // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) - if(is_numeric(substr($var_expr, 0, 1))) - $_var_ref = $var_expr; - else - $_var_ref = substr($var_expr, 1); - - if(!$_has_math) { - - // get [foo] and .foo and ->foo and (...) pieces - preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); - - $_indexes = $match[0]; - $_var_name = array_shift($_indexes); - - /* Handle $smarty.* variable references as a special case. */ - if ($_var_name == 'smarty') { - /* - * If the reference could be compiled, use the compiled output; - * otherwise, fall back on the $smarty variable generated at - * run-time. - */ - if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { - $_output = $smarty_ref; - } else { - $_var_name = substr(array_shift($_indexes), 1); - $_output = "\$this->_smarty_vars['$_var_name']"; - } - } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { - // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers - if(count($_indexes) > 0) - { - $_var_name .= implode("", $_indexes); - $_indexes = array(); - } - $_output = $_var_name; - } else { - $_output = "\$this->_tpl_vars['$_var_name']"; - } - - foreach ($_indexes as $_index) { - if (substr($_index, 0, 1) == '[') { - $_index = substr($_index, 1, -1); - if (is_numeric($_index)) { - $_output .= "[$_index]"; - } elseif (substr($_index, 0, 1) == '$') { - if (strpos($_index, '.') !== false) { - $_output .= '[' . $this->_parse_var($_index) . ']'; - } else { - $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; - } - } else { - $_var_parts = explode('.', $_index); - $_var_section = $_var_parts[0]; - $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; - $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; - } - } else if (substr($_index, 0, 1) == '.') { - if (substr($_index, 1, 1) == '$') - $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; - else - $_output .= "['" . substr($_index, 1) . "']"; - } else if (substr($_index,0,2) == '->') { - if(substr($_index,2,2) == '__') { - $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } elseif($this->security && substr($_index, 2, 1) == '_') { - $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } elseif (substr($_index, 2, 1) == '$') { - if ($this->security) { - $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } else { - $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; - } - } else { - $_output .= $_index; - } - } elseif (substr($_index, 0, 1) == '(') { - $_index = $this->_parse_parenth_args($_index); - $_output .= $_index; - } else { - $_output .= $_index; - } - } - } - - return $_output; - } - - /** - * parse arguments in function call parenthesis - * - * @param string $parenth_args - * @return string - */ - function _parse_parenth_args($parenth_args) - { - preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); - $orig_vals = $match = $match[0]; - $this->_parse_vars_props($match); - $replace = array(); - for ($i = 0, $count = count($match); $i < $count; $i++) { - $replace[$orig_vals[$i]] = $match[$i]; - } - return strtr($parenth_args, $replace); - } - - /** - * parse configuration variable expression into PHP code - * - * @param string $conf_var_expr - */ - function _parse_conf_var($conf_var_expr) - { - $parts = explode('|', $conf_var_expr, 2); - $var_ref = $parts[0]; - $modifiers = isset($parts[1]) ? $parts[1] : ''; - - $var_name = substr($var_ref, 1, -1); - - $output = "\$this->_config[0]['vars']['$var_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - /** - * parse section property expression into PHP code - * - * @param string $section_prop_expr - * @return string - */ - function _parse_section_prop($section_prop_expr) - { - $parts = explode('|', $section_prop_expr, 2); - $var_ref = $parts[0]; - $modifiers = isset($parts[1]) ? $parts[1] : ''; - - preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); - $section_name = $match[1]; - $prop_name = $match[2]; - - $output = "\$this->_sections['$section_name']['$prop_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - - /** - * parse modifier chain into PHP code - * - * sets $output to parsed modified chain - * @param string $output - * @param string $modifier_string - */ - function _parse_modifiers(&$output, $modifier_string) - { - preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); - list(, $_modifiers, $modifier_arg_strings) = $_match; - - for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { - $_modifier_name = $_modifiers[$_i]; - - if($_modifier_name == 'smarty') { - // skip smarty modifier - continue; - } - - preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); - $_modifier_args = $_match[1]; - - if (substr($_modifier_name, 0, 1) == '@') { - $_map_array = false; - $_modifier_name = substr($_modifier_name, 1); - } else { - $_map_array = true; - } - - if (empty($this->_plugins['modifier'][$_modifier_name]) - && !$this->_get_plugin_filepath('modifier', $_modifier_name) - && function_exists($_modifier_name)) { - if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { - $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); - } else { - $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); - } - } - $this->_add_plugin('modifier', $_modifier_name); - - $this->_parse_vars_props($_modifier_args); - - if($_modifier_name == 'default') { - // supress notifications of default modifier vars and args - if(substr($output, 0, 1) == '$') { - $output = '@' . $output; - } - if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { - $_modifier_args[0] = '@' . $_modifier_args[0]; - } - } - if (count($_modifier_args) > 0) - $_modifier_args = ', '.implode(', ', $_modifier_args); - else - $_modifier_args = ''; - - if ($_map_array) { - $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; - - } else { - - $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; - - } - } - } - - - /** - * add plugin - * - * @param string $type - * @param string $name - * @param boolean? $delayed_loading - */ - function _add_plugin($type, $name, $delayed_loading = null) - { - if (!isset($this->_plugin_info[$type])) { - $this->_plugin_info[$type] = array(); - } - if (!isset($this->_plugin_info[$type][$name])) { - $this->_plugin_info[$type][$name] = array($this->_current_file, - $this->_current_line_no, - $delayed_loading); - } - } - - - /** - * Compiles references of type $smarty.foo - * - * @param string $indexes - * @return string - */ - function _compile_smarty_ref(&$indexes) - { - /* Extract the reference name. */ - $_ref = substr($indexes[0], 1); - foreach($indexes as $_index_no=>$_index) { - if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { - $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); - } - } - - switch ($_ref) { - case 'now': - $compiled_ref = 'time()'; - $_max_index = 1; - break; - - case 'foreach': - array_shift($indexes); - $_var = $this->_parse_var_props(substr($indexes[0], 1)); - $_propname = substr($indexes[1], 1); - $_max_index = 1; - switch ($_propname) { - case 'index': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; - break; - - case 'first': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; - break; - - case 'last': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; - break; - - case 'show': - array_shift($indexes); - $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; - break; - - default: - unset($_max_index); - $compiled_ref = "\$this->_foreach[$_var]"; - } - break; - - case 'section': - array_shift($indexes); - $_var = $this->_parse_var_props(substr($indexes[0], 1)); - $compiled_ref = "\$this->_sections[$_var]"; - break; - - case 'get': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - $compiled_ref = "\$_GET"; - break; - - case 'post': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - $compiled_ref = "\$_POST"; - break; - - case 'cookies': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - $compiled_ref = "\$_COOKIE"; - break; - - case 'env': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - $compiled_ref = "\$_ENV"; - break; - - case 'server': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - $compiled_ref = "\$_SERVER"; - break; - - case 'session': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - $compiled_ref = "\$_SESSION"; - break; - - /* - * These cases are handled either at run-time or elsewhere in the - * compiler. - */ - case 'request': - if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) { - $this->_syntax_error("(secure mode) super global access not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - if ($this->request_use_auto_globals) { - $compiled_ref = "\$_REQUEST"; - break; - } else { - $this->_init_smarty_vars = true; - } - return null; - - case 'capture': - return null; - - case 'template': - $compiled_ref = "'$this->_current_file'"; - $_max_index = 1; - break; - - case 'version': - $compiled_ref = "'$this->_version'"; - $_max_index = 1; - break; - - case 'const': - if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { - $this->_syntax_error("(secure mode) constants not permitted", - E_USER_WARNING, __FILE__, __LINE__); - return; - } - array_shift($indexes); - if (preg_match('!^\.\w+$!', $indexes[0])) { - $compiled_ref = '@' . substr($indexes[0], 1); - } else { - $_val = $this->_parse_var_props(substr($indexes[0], 1)); - $compiled_ref = '@constant(' . $_val . ')'; - } - $_max_index = 1; - break; - - case 'config': - $compiled_ref = "\$this->_config[0]['vars']"; - $_max_index = 3; - break; - - case 'ldelim': - $compiled_ref = "'$this->left_delimiter'"; - break; - - case 'rdelim': - $compiled_ref = "'$this->right_delimiter'"; - break; - - default: - $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); - break; - } - - if (isset($_max_index) && count($indexes) > $_max_index) { - $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); - } - - array_shift($indexes); - return $compiled_ref; - } - - /** - * compiles call to plugin of type $type with name $name - * returns a string containing the function-name or method call - * without the paramter-list that would have follow to make the - * call valid php-syntax - * - * @param string $type - * @param string $name - * @return string - */ - function _compile_plugin_call($type, $name) { - if (isset($this->_plugins[$type][$name])) { - /* plugin loaded */ - if (is_array($this->_plugins[$type][$name][0])) { - return ((is_object($this->_plugins[$type][$name][0][0])) ? - "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ - : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ - ). $this->_plugins[$type][$name][0][1]; - - } else { - /* function callback */ - return $this->_plugins[$type][$name][0]; - - } - } else { - /* plugin not loaded -> auto-loadable-plugin */ - return 'smarty_'.$type.'_'.$name; - - } - } - - /** - * load pre- and post-filters - */ - function _load_filters() - { - if (count($this->_plugins['prefilter']) > 0) { - foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { - if ($prefilter === false) { - unset($this->_plugins['prefilter'][$filter_name]); - $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - } - } - } - if (count($this->_plugins['postfilter']) > 0) { - foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { - if ($postfilter === false) { - unset($this->_plugins['postfilter'][$filter_name]); - $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); - require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); - smarty_core_load_plugins($_params, $this); - } - } - } - } - - - /** - * Quote subpattern references - * - * @param string $string - * @return string - */ - function _quote_replace($string) - { - return strtr($string, array('\\' => '\\\\', '$' => '\\$')); - } - - /** - * display Smarty syntax error - * - * @param string $error_msg - * @param integer $error_type - * @param string $file - * @param integer $line - */ - function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) - { - $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); - } - - - /** - * check if the compilation changes from cacheable to - * non-cacheable state with the beginning of the current - * plugin. return php-code to reflect the transition. - * @return string - */ - function _push_cacheable_state($type, $name) { - $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; - if ($_cacheable - || 0<$this->_cacheable_state++) return ''; - if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); - $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:' - . $this->_cache_serial . '#' . $this->_nocache_count - . '}\'; endif;'; - return $_ret; - } - - - /** - * check if the compilation changes from non-cacheable to - * cacheable state with the end of the current plugin return - * php-code to reflect the transition. - * @return string - */ - function _pop_cacheable_state($type, $name) { - $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; - if ($_cacheable - || --$this->_cacheable_state>0) return ''; - return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:' - . $this->_cache_serial . '#' . ($this->_nocache_count++) - . '}\'; endif;'; - } - - - /** - * push opening tag-name, file-name and line-number on the tag-stack - * @param string the opening tag's name - */ - function _push_tag($open_tag) - { - array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); - } - - /** - * pop closing tag-name - * raise an error if this stack-top doesn't match with the closing tag - * @param string the closing tag's name - * @return string the opening tag's name - */ - function _pop_tag($close_tag) - { - $message = ''; - if (count($this->_tag_stack)>0) { - list($_open_tag, $_line_no) = array_pop($this->_tag_stack); - if ($close_tag == $_open_tag) { - return $_open_tag; - } - if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { - return $this->_pop_tag($close_tag); - } - if ($close_tag == 'section' && $_open_tag == 'sectionelse') { - $this->_pop_tag($close_tag); - return $_open_tag; - } - if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { - $this->_pop_tag($close_tag); - return $_open_tag; - } - if ($_open_tag == 'else' || $_open_tag == 'elseif') { - $_open_tag = 'if'; - } elseif ($_open_tag == 'sectionelse') { - $_open_tag = 'section'; - } elseif ($_open_tag == 'foreachelse') { - $_open_tag = 'foreach'; - } - $message = " expected {/$_open_tag} (opened line $_line_no)."; - } - $this->_syntax_error("mismatched tag {/$close_tag}.$message", - E_USER_ERROR, __FILE__, __LINE__); - } - -} - -/** - * compare to values by their string length - * - * @access private - * @param string $a - * @param string $b - * @return 0|-1|1 - */ -function _smarty_sort_length($a, $b) -{ - if($a == $b) - return 0; - - if(strlen($a) == strlen($b)) - return ($a > $b) ? -1 : 1; - - return (strlen($a) > strlen($b)) ? -1 : 1; -} - - -/* vim: set et: */ - -?> diff --git a/include/smarty/libs/debug.tpl b/include/smarty/libs/debug.tpl index c05ef5d0b..12eef0ffd 100644 --- a/include/smarty/libs/debug.tpl +++ b/include/smarty/libs/debug.tpl @@ -1,14 +1,10 @@ -{* Smarty *} -{* debug.tpl, last updated version 2.1.0 *} -{assign_debug_info} -{capture assign=debug_output} +{capture name='_smarty_debug' assign=debug_output} <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Smarty Debug Console</title> -{literal} <style type="text/css"> -/* <![CDATA[ */ +{literal} body, h1, h2, td, th, p { font-family: sans-serif; font-weight: normal; @@ -85,73 +81,53 @@ td { #table_config_vars th { color: maroon; } -/* ]]> */ -</style> {/literal} +</style> </head> <body> -<h1>Smarty Debug Console</h1> +<h1>Smarty Debug Console - {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}</h1> +{if !empty($template_data)} <h2>included templates & config files (load time in seconds)</h2> <div> -{section name=templates loop=$_debug_tpls} - {section name=indent loop=$_debug_tpls[templates].depth} {/section} - <font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}> - {$_debug_tpls[templates].filename|escape:html}</font> - {if isset($_debug_tpls[templates].exec_time)} - <span class="exectime"> - ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}) - {if %templates.index% eq 0}(total){/if} - </span> - {/if} - <br /> -{sectionelse} - <p>no templates included</p> -{/section} +{foreach $template_data as $template} + <font color=brown>{$template.name}</font> + <span class="exectime"> + (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}) + </span> + <br> +{/foreach} </div> +{/if} <h2>assigned template variables</h2> <table id="table_assigned_vars"> - {section name=vars loop=$_debug_keys} - <tr class="{cycle values="odd,even"}"> - <th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th> - <td>{$_debug_vals[vars]|@debug_print_var}</td></tr> - {sectionelse} - <tr><td><p>no template variables assigned</p></td></tr> - {/section} + {foreach $assigned_vars as $vars} + <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}"> + <th>${$vars@key|escape:'html'}</th> + <td>{$vars|debug_print_var nofilter}</td></tr> + {/foreach} </table> <h2>assigned config file variables (outer template scope)</h2> <table id="table_config_vars"> - {section name=config_vars loop=$_debug_config_keys} - <tr class="{cycle values="odd,even"}"> - <th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th> - <td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr> - {sectionelse} - <tr><td><p>no config vars assigned</p></td></tr> - {/section} + {foreach $config_vars as $vars} + <tr class="{if $vars@iteration % 2 eq 0}odd{else}even{/if}"> + <th>{$vars@key|escape:'html'}</th> + <td>{$vars|debug_print_var nofilter}</td></tr> + {/foreach} + </table> </body> </html> {/capture} -{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} - {$debug_output} -{else} <script type="text/javascript"> -// <![CDATA[ - if ( self.name == '' ) {ldelim} - var title = 'Console'; - {rdelim} - else {ldelim} - var title = 'Console_' + self.name; - {rdelim} - _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes"); - _smarty_console.document.write('{$debug_output|escape:'javascript'}'); +{$id = $template_name|default:''|md5} + _smarty_console = window.open("","console{$id}","width=680,height=600,resizable,scrollbars=yes"); + _smarty_console.document.write("{$debug_output|escape:'javascript' nofilter}"); _smarty_console.document.close(); -// ]]> </script> -{/if}
\ No newline at end of file diff --git a/include/smarty/libs/internals/core.assemble_plugin_filepath.php b/include/smarty/libs/internals/core.assemble_plugin_filepath.php deleted file mode 100644 index 690d3ddbc..000000000 --- a/include/smarty/libs/internals/core.assemble_plugin_filepath.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * assemble filepath of requested plugin - * - * @param string $type - * @param string $name - * @return string|false - */ -function smarty_core_assemble_plugin_filepath($params, &$smarty) -{ - static $_filepaths_cache = array(); - - $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php'; - if (isset($_filepaths_cache[$_plugin_filename])) { - return $_filepaths_cache[$_plugin_filename]; - } - $_return = false; - - foreach ((array)$smarty->plugins_dir as $_plugin_dir) { - - $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; - - // see if path is relative - if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) { - $_relative_paths[] = $_plugin_dir; - // relative path, see if it is in the SMARTY_DIR - if (@is_readable(SMARTY_DIR . $_plugin_filepath)) { - $_return = SMARTY_DIR . $_plugin_filepath; - break; - } - } - // try relative to cwd (or absolute) - if (@is_readable($_plugin_filepath)) { - $_return = $_plugin_filepath; - break; - } - } - - if($_return === false) { - // still not found, try PHP include_path - if(isset($_relative_paths)) { - foreach ((array)$_relative_paths as $_plugin_dir) { - - $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; - - $_params = array('file_path' => $_plugin_filepath); - require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); - if(smarty_core_get_include_path($_params, $smarty)) { - $_return = $_params['new_file_path']; - break; - } - } - } - } - $_filepaths_cache[$_plugin_filename] = $_return; - return $_return; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.assign_smarty_interface.php b/include/smarty/libs/internals/core.assign_smarty_interface.php deleted file mode 100644 index 7e65a73ec..000000000 --- a/include/smarty/libs/internals/core.assign_smarty_interface.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Smarty assign_smarty_interface core plugin - * - * Type: core<br> - * Name: assign_smarty_interface<br> - * Purpose: assign the $smarty interface variable - * @param array Format: null - * @param Smarty - */ -function smarty_core_assign_smarty_interface($params, &$smarty) -{ - if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) { - return; - } - - $_globals_map = array('g' => 'HTTP_GET_VARS', - 'p' => 'HTTP_POST_VARS', - 'c' => 'HTTP_COOKIE_VARS', - 's' => 'HTTP_SERVER_VARS', - 'e' => 'HTTP_ENV_VARS'); - - $_smarty_vars_request = array(); - - foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) { - if (isset($_globals_map[$_c])) { - $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]); - } - } - $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']); - - $smarty->_smarty_vars['request'] = $_smarty_vars_request; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.create_dir_structure.php b/include/smarty/libs/internals/core.create_dir_structure.php deleted file mode 100644 index 3eecc4972..000000000 --- a/include/smarty/libs/internals/core.create_dir_structure.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * create full directory structure - * - * @param string $dir - */ - -// $dir - -function smarty_core_create_dir_structure($params, &$smarty) -{ - if (!file_exists($params['dir'])) { - $_open_basedir_ini = ini_get('open_basedir'); - - if (DIRECTORY_SEPARATOR=='/') { - /* unix-style paths */ - $_dir = $params['dir']; - $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY); - $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/'; - if($_use_open_basedir = !empty($_open_basedir_ini)) { - $_open_basedirs = explode(':', $_open_basedir_ini); - } - - } else { - /* other-style paths */ - $_dir = str_replace('\\','/', $params['dir']); - $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY); - if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) { - /* leading "//" for network volume, or "[letter]:/" for full path */ - $_new_dir = $_root_dir[1]; - /* remove drive-letter from _dir_parts */ - if (isset($_root_dir[3])) array_shift($_dir_parts); - - } else { - $_new_dir = str_replace('\\', '/', getcwd()).'/'; - - } - - if($_use_open_basedir = !empty($_open_basedir_ini)) { - $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini)); - } - - } - - /* all paths use "/" only from here */ - foreach ($_dir_parts as $_dir_part) { - $_new_dir .= $_dir_part; - - if ($_use_open_basedir) { - // do not attempt to test or make directories outside of open_basedir - $_make_new_dir = false; - foreach ($_open_basedirs as $_open_basedir) { - if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) { - $_make_new_dir = true; - break; - } - } - } else { - $_make_new_dir = true; - } - - if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) { - $smarty->trigger_error("problem creating directory '" . $_new_dir . "'"); - return false; - } - $_new_dir .= '/'; - } - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.display_debug_console.php b/include/smarty/libs/internals/core.display_debug_console.php deleted file mode 100644 index 1a80f3909..000000000 --- a/include/smarty/libs/internals/core.display_debug_console.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Smarty debug_console function plugin - * - * Type: core<br> - * Name: display_debug_console<br> - * Purpose: display the javascript debug console window - * @param array Format: null - * @param Smarty - */ -function smarty_core_display_debug_console($params, &$smarty) -{ - // we must force compile the debug template in case the environment - // changed between separate applications. - - if(empty($smarty->debug_tpl)) { - // set path to debug template from SMARTY_DIR - $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; - if($smarty->security && is_file($smarty->debug_tpl)) { - $smarty->secure_dir[] = realpath($smarty->debug_tpl); - } - $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; - } - - $_ldelim_orig = $smarty->left_delimiter; - $_rdelim_orig = $smarty->right_delimiter; - - $smarty->left_delimiter = '{'; - $smarty->right_delimiter = '}'; - - $_compile_id_orig = $smarty->_compile_id; - $smarty->_compile_id = null; - - $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl); - if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path)) - { - ob_start(); - $smarty->_include($_compile_path); - $_results = ob_get_contents(); - ob_end_clean(); - } else { - $_results = ''; - } - - $smarty->_compile_id = $_compile_id_orig; - - $smarty->left_delimiter = $_ldelim_orig; - $smarty->right_delimiter = $_rdelim_orig; - - return $_results; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.get_include_path.php b/include/smarty/libs/internals/core.get_include_path.php deleted file mode 100644 index 43432412b..000000000 --- a/include/smarty/libs/internals/core.get_include_path.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Get path to file from include_path - * - * @param string $file_path - * @param string $new_file_path - * @return boolean - * @staticvar array|null - */ - -// $file_path, &$new_file_path - -function smarty_core_get_include_path(&$params, &$smarty) -{ - static $_path_array = null; - - if(!isset($_path_array)) { - $_ini_include_path = ini_get('include_path'); - - if(strstr($_ini_include_path,';')) { - // windows pathnames - $_path_array = explode(';',$_ini_include_path); - } else { - $_path_array = explode(':',$_ini_include_path); - } - } - foreach ($_path_array as $_include_path) { - if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) { - $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path']; - return true; - } - } - return false; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.get_microtime.php b/include/smarty/libs/internals/core.get_microtime.php deleted file mode 100644 index f1a28e042..000000000 --- a/include/smarty/libs/internals/core.get_microtime.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Get seconds and microseconds - * @return double - */ -function smarty_core_get_microtime($params, &$smarty) -{ - $mtime = microtime(); - $mtime = explode(" ", $mtime); - $mtime = (double)($mtime[1]) + (double)($mtime[0]); - return ($mtime); -} - - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.get_php_resource.php b/include/smarty/libs/internals/core.get_php_resource.php deleted file mode 100644 index 786d4e78e..000000000 --- a/include/smarty/libs/internals/core.get_php_resource.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Retrieves PHP script resource - * - * sets $php_resource to the returned resource - * @param string $resource - * @param string $resource_type - * @param $php_resource - * @return boolean - */ - -function smarty_core_get_php_resource(&$params, &$smarty) -{ - - $params['resource_base_path'] = $smarty->trusted_dir; - $smarty->_parse_resource_name($params, $smarty); - - /* - * Find out if the resource exists. - */ - - if ($params['resource_type'] == 'file') { - $_readable = false; - if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) { - $_readable = true; - } else { - // test for file in include_path - $_params = array('file_path' => $params['resource_name']); - require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); - if(smarty_core_get_include_path($_params, $smarty)) { - $_include_path = $_params['new_file_path']; - $_readable = true; - } - } - } else if ($params['resource_type'] != 'file') { - $_template_source = null; - $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0]) - && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0], - array($params['resource_name'], &$_template_source, &$smarty)); - } - - /* - * Set the error function, depending on which class calls us. - */ - if (method_exists($smarty, '_syntax_error')) { - $_error_funcc = '_syntax_error'; - } else { - $_error_funcc = 'trigger_error'; - } - - if ($_readable) { - if ($smarty->security) { - require_once(SMARTY_CORE_DIR . 'core.is_trusted.php'); - if (!smarty_core_is_trusted($params, $smarty)) { - $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted'); - return false; - } - } - } else { - $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable'); - return false; - } - - if ($params['resource_type'] == 'file') { - $params['php_resource'] = $params['resource_name']; - } else { - $params['php_resource'] = $_template_source; - } - return true; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.is_secure.php b/include/smarty/libs/internals/core.is_secure.php deleted file mode 100644 index d54abd432..000000000 --- a/include/smarty/libs/internals/core.is_secure.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * determines if a resource is secure or not. - * - * @param string $resource_type - * @param string $resource_name - * @return boolean - */ - -// $resource_type, $resource_name - -function smarty_core_is_secure($params, &$smarty) -{ - if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) { - return true; - } - - if ($params['resource_type'] == 'file') { - $_rp = realpath($params['resource_name']); - if (isset($params['resource_base_path'])) { - foreach ((array)$params['resource_base_path'] as $curr_dir) { - if ( ($_cd = realpath($curr_dir)) !== false && - strncmp($_rp, $_cd, strlen($_cd)) == 0 && - substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { - return true; - } - } - } - if (!empty($smarty->secure_dir)) { - foreach ((array)$smarty->secure_dir as $curr_dir) { - if ( ($_cd = realpath($curr_dir)) !== false) { - if($_cd == $_rp) { - return true; - } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && - substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { - return true; - } - } - } - } - } else { - // resource is not on local file system - return call_user_func_array( - $smarty->_plugins['resource'][$params['resource_type']][0][2], - array($params['resource_name'], &$smarty)); - } - - return false; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.is_trusted.php b/include/smarty/libs/internals/core.is_trusted.php deleted file mode 100644 index 429973158..000000000 --- a/include/smarty/libs/internals/core.is_trusted.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * determines if a resource is trusted or not - * - * @param string $resource_type - * @param string $resource_name - * @return boolean - */ - - // $resource_type, $resource_name - -function smarty_core_is_trusted($params, &$smarty) -{ - $_smarty_trusted = false; - if ($params['resource_type'] == 'file') { - if (!empty($smarty->trusted_dir)) { - $_rp = realpath($params['resource_name']); - foreach ((array)$smarty->trusted_dir as $curr_dir) { - if (!empty($curr_dir) && is_readable ($curr_dir)) { - $_cd = realpath($curr_dir); - if (strncmp($_rp, $_cd, strlen($_cd)) == 0 - && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { - $_smarty_trusted = true; - break; - } - } - } - } - - } else { - // resource is not on local file system - $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3], - array($params['resource_name'], $smarty)); - } - - return $_smarty_trusted; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.load_plugins.php b/include/smarty/libs/internals/core.load_plugins.php deleted file mode 100644 index 6db1dc51d..000000000 --- a/include/smarty/libs/internals/core.load_plugins.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Load requested plugins - * - * @param array $plugins - */ - -// $plugins - -function smarty_core_load_plugins($params, &$smarty) -{ - - foreach ($params['plugins'] as $_plugin_info) { - list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info; - $_plugin = &$smarty->_plugins[$_type][$_name]; - - /* - * We do not load plugin more than once for each instance of Smarty. - * The following code checks for that. The plugin can also be - * registered dynamically at runtime, in which case template file - * and line number will be unknown, so we fill them in. - * - * The final element of the info array is a flag that indicates - * whether the dynamically registered plugin function has been - * checked for existence yet or not. - */ - if (isset($_plugin)) { - if (empty($_plugin[3])) { - if (!is_callable($_plugin[0])) { - $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__); - } else { - $_plugin[1] = $_tpl_file; - $_plugin[2] = $_tpl_line; - $_plugin[3] = true; - if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */ - } - } - continue; - } else if ($_type == 'insert') { - /* - * For backwards compatibility, we check for insert functions in - * the symbol table before trying to load them as a plugin. - */ - $_plugin_func = 'insert_' . $_name; - if (function_exists($_plugin_func)) { - $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false); - continue; - } - } - - $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name); - - if (! $_found = ($_plugin_file != false)) { - $_message = "could not load plugin file '$_type.$_name.php'\n"; - } - - /* - * If plugin file is found, it -must- provide the properly named - * plugin function. In case it doesn't, simply output the error and - * do not fall back on any other method. - */ - if ($_found) { - include_once $_plugin_file; - - $_plugin_func = 'smarty_' . $_type . '_' . $_name; - if (!function_exists($_plugin_func)) { - $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__); - continue; - } - } - /* - * In case of insert plugins, their code may be loaded later via - * 'script' attribute. - */ - else if ($_type == 'insert' && $_delayed_loading) { - $_plugin_func = 'smarty_' . $_type . '_' . $_name; - $_found = true; - } - - /* - * Plugin specific processing and error checking. - */ - if (!$_found) { - if ($_type == 'modifier') { - /* - * In case modifier falls back on using PHP functions - * directly, we only allow those specified in the security - * context. - */ - if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) { - $_message = "(secure mode) modifier '$_name' is not allowed"; - } else { - if (!function_exists($_name)) { - $_message = "modifier '$_name' is not implemented"; - } else { - $_plugin_func = $_name; - $_found = true; - } - } - } else if ($_type == 'function') { - /* - * This is a catch-all situation. - */ - $_message = "unknown tag - '$_name'"; - } - } - - if ($_found) { - $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true); - } else { - // output error - $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__); - } - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.load_resource_plugin.php b/include/smarty/libs/internals/core.load_resource_plugin.php deleted file mode 100644 index a7d37d1af..000000000 --- a/include/smarty/libs/internals/core.load_resource_plugin.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * load a resource plugin - * - * @param string $type - */ - -// $type - -function smarty_core_load_resource_plugin($params, &$smarty) -{ - /* - * Resource plugins are not quite like the other ones, so they are - * handled differently. The first element of plugin info is the array of - * functions provided by the plugin, the second one indicates whether - * all of them exist or not. - */ - - $_plugin = &$smarty->_plugins['resource'][$params['type']]; - if (isset($_plugin)) { - if (!$_plugin[1] && count($_plugin[0])) { - $_plugin[1] = true; - foreach ($_plugin[0] as $_plugin_func) { - if (!is_callable($_plugin_func)) { - $_plugin[1] = false; - break; - } - } - } - - if (!$_plugin[1]) { - $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__); - } - - return; - } - - $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']); - $_found = ($_plugin_file != false); - - if ($_found) { /* - * If the plugin file is found, it -must- provide the properly named - * plugin functions. - */ - include_once($_plugin_file); - - /* - * Locate functions that we require the plugin to provide. - */ - $_resource_ops = array('source', 'timestamp', 'secure', 'trusted'); - $_resource_funcs = array(); - foreach ($_resource_ops as $_op) { - $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op; - if (!function_exists($_plugin_func)) { - $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__); - return; - } else { - $_resource_funcs[] = $_plugin_func; - } - } - - $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true); - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.process_cached_inserts.php b/include/smarty/libs/internals/core.process_cached_inserts.php deleted file mode 100644 index 1d78edd93..000000000 --- a/include/smarty/libs/internals/core.process_cached_inserts.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Replace cached inserts with the actual results - * - * @param string $results - * @return string - */ -function smarty_core_process_cached_inserts($params, &$smarty) -{ - preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis', - $params['results'], $match); - list($cached_inserts, $insert_args) = $match; - - for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) { - if ($smarty->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $debug_start_time = smarty_core_get_microtime($_params, $smarty); - } - - $args = unserialize($insert_args[$i]); - $name = $args['name']; - - if (isset($args['script'])) { - $_params = array('resource_name' => $smarty->_dequote($args['script'])); - require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); - if(!smarty_core_get_php_resource($_params, $smarty)) { - return false; - } - $resource_type = $_params['resource_type']; - $php_resource = $_params['php_resource']; - - - if ($resource_type == 'file') { - $smarty->_include($php_resource, true); - } else { - $smarty->_eval($php_resource); - } - } - - $function_name = $smarty->_plugins['insert'][$name][0]; - if (empty($args['assign'])) { - $replace = $function_name($args, $smarty); - } else { - $smarty->assign($args['assign'], $function_name($args, $smarty)); - $replace = ''; - } - - $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); - if ($smarty->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $smarty->_smarty_debug_info[] = array('type' => 'insert', - 'filename' => 'insert_'.$name, - 'depth' => $smarty->_inclusion_depth, - 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time); - } - } - - return $params['results']; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.process_compiled_include.php b/include/smarty/libs/internals/core.process_compiled_include.php deleted file mode 100644 index 904d59745..000000000 --- a/include/smarty/libs/internals/core.process_compiled_include.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Replace nocache-tags by results of the corresponding non-cacheable - * functions and return it - * - * @param string $compiled_tpl - * @param string $cached_source - * @return string - */ - -function smarty_core_process_compiled_include($params, &$smarty) -{ - $_cache_including = $smarty->_cache_including; - $smarty->_cache_including = true; - - $_return = $params['results']; - - foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { - $smarty->_include($_include_file_path, true); - } - - foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { - $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', - array(&$smarty, '_process_compiled_include_callback'), - $_return); - } - $smarty->_cache_including = $_cache_including; - return $_return; -} - -?> diff --git a/include/smarty/libs/internals/core.read_cache_file.php b/include/smarty/libs/internals/core.read_cache_file.php deleted file mode 100644 index c60e113a7..000000000 --- a/include/smarty/libs/internals/core.read_cache_file.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * read a cache file, determine if it needs to be - * regenerated or not - * - * @param string $tpl_file - * @param string $cache_id - * @param string $compile_id - * @param string $results - * @return boolean - */ - -// $tpl_file, $cache_id, $compile_id, &$results - -function smarty_core_read_cache_file(&$params, &$smarty) -{ - static $content_cache = array(); - - if ($smarty->force_compile) { - // force compile enabled, always regenerate - return false; - } - - if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) { - list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']]; - return true; - } - - if (!empty($smarty->cache_handler_func)) { - // use cache_handler function - call_user_func_array($smarty->cache_handler_func, - array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); - } else { - // use local cache file - $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); - $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); - $params['results'] = $smarty->_read_file($_cache_file); - } - - if (empty($params['results'])) { - // nothing to parse (error?), regenerate cache - return false; - } - - $_contents = $params['results']; - $_info_start = strpos($_contents, "\n") + 1; - $_info_len = (int)substr($_contents, 0, $_info_start - 1); - $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len)); - $params['results'] = substr($_contents, $_info_start + $_info_len); - - if ($smarty->caching == 2 && isset ($_cache_info['expires'])){ - // caching by expiration time - if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) { - // cache expired, regenerate - return false; - } - } else { - // caching by lifetime - if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) { - // cache expired, regenerate - return false; - } - } - - if ($smarty->compile_check) { - $_params = array('get_source' => false, 'quiet'=>true); - foreach (array_keys($_cache_info['template']) as $_template_dep) { - $_params['resource_name'] = $_template_dep; - if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { - // template file has changed, regenerate cache - return false; - } - } - - if (isset($_cache_info['config'])) { - $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true); - foreach (array_keys($_cache_info['config']) as $_config_dep) { - $_params['resource_name'] = $_config_dep; - if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) { - // config file has changed, regenerate cache - return false; - } - } - } - } - - $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); - - $smarty->_cache_info = $_cache_info; - return true; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.rm_auto.php b/include/smarty/libs/internals/core.rm_auto.php deleted file mode 100644 index b251f6491..000000000 --- a/include/smarty/libs/internals/core.rm_auto.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * delete an automagically created file by name and id - * - * @param string $auto_base - * @param string $auto_source - * @param string $auto_id - * @param integer $exp_time - * @return boolean - */ - -// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null - -function smarty_core_rm_auto($params, &$smarty) -{ - if (!@is_dir($params['auto_base'])) - return false; - - if(!isset($params['auto_id']) && !isset($params['auto_source'])) { - $_params = array( - 'dirname' => $params['auto_base'], - 'level' => 0, - 'exp_time' => $params['exp_time'] - ); - require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); - $_res = smarty_core_rmdir($_params, $smarty); - } else { - $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); - - if(isset($params['auto_source'])) { - if (isset($params['extensions'])) { - $_res = false; - foreach ((array)$params['extensions'] as $_extension) - $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']); - } else { - $_res = $smarty->_unlink($_tname, $params['exp_time']); - } - } elseif ($smarty->use_sub_dirs) { - $_params = array( - 'dirname' => $_tname, - 'level' => 1, - 'exp_time' => $params['exp_time'] - ); - require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); - $_res = smarty_core_rmdir($_params, $smarty); - } else { - // remove matching file names - $_handle = opendir($params['auto_base']); - $_res = true; - while (false !== ($_filename = readdir($_handle))) { - if($_filename == '.' || $_filename == '..') { - continue; - } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) { - $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']); - } - } - } - } - - return $_res; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.rmdir.php b/include/smarty/libs/internals/core.rmdir.php deleted file mode 100644 index 2166c44d2..000000000 --- a/include/smarty/libs/internals/core.rmdir.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * delete a dir recursively (level=0 -> keep root) - * WARNING: no tests, it will try to remove what you tell it! - * - * @param string $dirname - * @param integer $level - * @param integer $exp_time - * @return boolean - */ - -// $dirname, $level = 1, $exp_time = null - -function smarty_core_rmdir($params, &$smarty) -{ - if(!isset($params['level'])) { $params['level'] = 1; } - if(!isset($params['exp_time'])) { $params['exp_time'] = null; } - - if($_handle = @opendir($params['dirname'])) { - - while (false !== ($_entry = readdir($_handle))) { - if ($_entry != '.' && $_entry != '..') { - if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) { - $_params = array( - 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry, - 'level' => $params['level'] + 1, - 'exp_time' => $params['exp_time'] - ); - smarty_core_rmdir($_params, $smarty); - } - else { - $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']); - } - } - } - closedir($_handle); - } - - if ($params['level']) { - return @rmdir($params['dirname']); - } - return (bool)$_handle; - -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.run_insert_handler.php b/include/smarty/libs/internals/core.run_insert_handler.php deleted file mode 100644 index 71c384508..000000000 --- a/include/smarty/libs/internals/core.run_insert_handler.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Handle insert tags - * - * @param array $args - * @return string - */ -function smarty_core_run_insert_handler($params, &$smarty) -{ - - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - if ($smarty->debugging) { - $_params = array(); - $_debug_start_time = smarty_core_get_microtime($_params, $smarty); - } - - if ($smarty->caching) { - $_arg_string = serialize($params['args']); - $_name = $params['args']['name']; - if (!isset($smarty->_cache_info['insert_tags'][$_name])) { - $smarty->_cache_info['insert_tags'][$_name] = array('insert', - $_name, - $smarty->_plugins['insert'][$_name][1], - $smarty->_plugins['insert'][$_name][2], - !empty($params['args']['script']) ? true : false); - } - return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5; - } else { - if (isset($params['args']['script'])) { - $_params = array('resource_name' => $smarty->_dequote($params['args']['script'])); - require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); - if(!smarty_core_get_php_resource($_params, $smarty)) { - return false; - } - - if ($_params['resource_type'] == 'file') { - $smarty->_include($_params['php_resource'], true); - } else { - $smarty->_eval($_params['php_resource']); - } - unset($params['args']['script']); - } - - $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0]; - $_content = $_funcname($params['args'], $smarty); - if ($smarty->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $smarty->_smarty_debug_info[] = array('type' => 'insert', - 'filename' => 'insert_'.$params['args']['name'], - 'depth' => $smarty->_inclusion_depth, - 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); - } - - if (!empty($params['args']["assign"])) { - $smarty->assign($params['args']["assign"], $_content); - } else { - return $_content; - } - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.smarty_include_php.php b/include/smarty/libs/internals/core.smarty_include_php.php deleted file mode 100644 index 30c6e7654..000000000 --- a/include/smarty/libs/internals/core.smarty_include_php.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * called for included php files within templates - * - * @param string $smarty_file - * @param string $smarty_assign variable to assign the included template's - * output into - * @param boolean $smarty_once uses include_once if this is true - * @param array $smarty_include_vars associative array of vars from - * {include file="blah" var=$var} - */ - -// $file, $assign, $once, $_smarty_include_vars - -function smarty_core_smarty_include_php($params, &$smarty) -{ - $_params = array('resource_name' => $params['smarty_file']); - require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); - smarty_core_get_php_resource($_params, $smarty); - $_smarty_resource_type = $_params['resource_type']; - $_smarty_php_resource = $_params['php_resource']; - - if (!empty($params['smarty_assign'])) { - ob_start(); - if ($_smarty_resource_type == 'file') { - $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); - } else { - $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); - } - $smarty->assign($params['smarty_assign'], ob_get_contents()); - ob_end_clean(); - } else { - if ($_smarty_resource_type == 'file') { - $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']); - } else { - $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']); - } - } -} - - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.write_cache_file.php b/include/smarty/libs/internals/core.write_cache_file.php deleted file mode 100644 index fa3cdd746..000000000 --- a/include/smarty/libs/internals/core.write_cache_file.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Prepend the cache information to the cache file - * and write it - * - * @param string $tpl_file - * @param string $cache_id - * @param string $compile_id - * @param string $results - * @return true|null - */ - - // $tpl_file, $cache_id, $compile_id, $results - -function smarty_core_write_cache_file($params, &$smarty) -{ - - // put timestamp in cache header - $smarty->_cache_info['timestamp'] = time(); - if ($smarty->cache_lifetime > -1){ - // expiration set - $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime; - } else { - // cache will never expire - $smarty->_cache_info['expires'] = -1; - } - - // collapse nocache.../nocache-tags - if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { - // remove everything between every pair of outermost noache.../nocache-tags - // and replace it by a single nocache-tag - // this new nocache-tag will be replaced by dynamic contents in - // smarty_core_process_compiled_includes() on a cache-read - - $match_count = count($match[0]); - $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); - - $level = 0; - $j = 0; - for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { - if ($results[$i] == $match[0][$j]) { - // nocache tag - if ($match[1][$j]) { // closing tag - $level--; - unset($results[$i]); - } else { // opening tag - if ($level++ > 0) unset($results[$i]); - } - $j++; - } elseif ($level > 0) { - unset($results[$i]); - } - } - $params['results'] = implode('', $results); - } - $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; - - // prepend the cache header info into cache file - $_cache_info = serialize($smarty->_cache_info); - $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; - - if (!empty($smarty->cache_handler_func)) { - // use cache_handler function - call_user_func_array($smarty->cache_handler_func, - array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires'])); - } else { - // use local cache file - - if(!@is_writable($smarty->cache_dir)) { - // cache_dir not writable, see if it exists - if(!@is_dir($smarty->cache_dir)) { - $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); - return false; - } - $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR); - return false; - } - - $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); - $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); - $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); - require_once(SMARTY_CORE_DIR . 'core.write_file.php'); - smarty_core_write_file($_params, $smarty); - return true; - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.write_compiled_include.php b/include/smarty/libs/internals/core.write_compiled_include.php deleted file mode 100644 index c14adb5f4..000000000 --- a/include/smarty/libs/internals/core.write_compiled_include.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Extract non-cacheable parts out of compiled template and write it - * - * @param string $compile_path - * @param string $template_compiled - * @return boolean - */ - -function smarty_core_write_compiled_include($params, &$smarty) -{ - $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;'; - $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;'; - - preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', - $params['compiled_content'], $_match_source, PREG_SET_ORDER); - - // no nocache-parts found: done - if (count($_match_source)==0) return; - - // convert the matched php-code to functions - $_include_compiled = "<?php /* Smarty version ".$smarty->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; - $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n"; - - $_compile_path = $params['include_file_path']; - - $smarty->_cache_serials[$_compile_path] = $params['cache_serial']; - $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; - - $_include_compiled .= $params['plugins_code']; - $_include_compiled .= "<?php"; - - $this_varname = ((double)phpversion() >= 5.0) ? '_smarty' : 'this'; - for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) { - $_match =& $_match_source[$_i]; - $source = $_match[4]; - if ($this_varname == '_smarty') { - /* rename $this to $_smarty in the sourcecode */ - $tokens = token_get_all('<?php ' . $_match[4]); - - /* remove trailing <?php */ - $open_tag = ''; - while ($tokens) { - $token = array_shift($tokens); - if (is_array($token)) { - $open_tag .= $token[1]; - } else { - $open_tag .= $token; - } - if ($open_tag == '<?php ') break; - } - - for ($i=0, $count = count($tokens); $i < $count; $i++) { - if (is_array($tokens[$i])) { - if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') { - $tokens[$i] = '$' . $this_varname; - } else { - $tokens[$i] = $tokens[$i][1]; - } - } - } - $source = implode('', $tokens); - } - - /* add function to compiled include */ - $_include_compiled .= " -function _smarty_tplfunc_$_match[2]_$_match[3](&\$$this_varname) -{ -$source -} - -"; - } - $_include_compiled .= "\n\n?>\n"; - - $_params = array('filename' => $_compile_path, - 'contents' => $_include_compiled, 'create_dirs' => true); - - require_once(SMARTY_CORE_DIR . 'core.write_file.php'); - smarty_core_write_file($_params, $smarty); - return true; -} - - -?> diff --git a/include/smarty/libs/internals/core.write_compiled_resource.php b/include/smarty/libs/internals/core.write_compiled_resource.php deleted file mode 100644 index b902eff3c..000000000 --- a/include/smarty/libs/internals/core.write_compiled_resource.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * write the compiled resource - * - * @param string $compile_path - * @param string $compiled_content - * @return true - */ -function smarty_core_write_compiled_resource($params, &$smarty) -{ - if(!@is_writable($smarty->compile_dir)) { - // compile_dir not writable, see if it exists - if(!@is_dir($smarty->compile_dir)) { - $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR); - return false; - } - $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR); - return false; - } - - $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true); - require_once(SMARTY_CORE_DIR . 'core.write_file.php'); - smarty_core_write_file($_params, $smarty); - return true; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/internals/core.write_file.php b/include/smarty/libs/internals/core.write_file.php deleted file mode 100644 index 8a3a3b398..000000000 --- a/include/smarty/libs/internals/core.write_file.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * write out a file to disk - * - * @param string $filename - * @param string $contents - * @param boolean $create_dirs - * @return boolean - */ -function smarty_core_write_file($params, &$smarty) -{ - $_dirname = dirname($params['filename']); - - if ($params['create_dirs']) { - $_params = array('dir' => $_dirname); - require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); - smarty_core_create_dir_structure($_params, $smarty); - } - - // write to tmp file, then rename it to avoid file locking race condition - $_tmp_file = tempnam($_dirname, 'wrt'); - - if (!($fd = @fopen($_tmp_file, 'wb'))) { - $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt'); - if (!($fd = @fopen($_tmp_file, 'wb'))) { - $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); - return false; - } - } - - fwrite($fd, $params['contents']); - fclose($fd); - - if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) { - // On platforms and filesystems that cannot overwrite with rename() - // delete the file before renaming it -- because windows always suffers - // this, it is short-circuited to avoid the initial rename() attempt - @unlink($params['filename']); - @rename($_tmp_file, $params['filename']); - } - @chmod($params['filename'], $smarty->_file_perms); - - return true; -} - -/* vim: set expandtab: */ - -?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/block.textformat.php b/include/smarty/libs/plugins/block.textformat.php index 8cd010acb..b22b104a5 100644 --- a/include/smarty/libs/plugins/block.textformat.php +++ b/include/smarty/libs/plugins/block.textformat.php @@ -1,8 +1,9 @@ <?php /** - * Smarty plugin + * Smarty plugin to format text blocks + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsBlock */ /** @@ -12,23 +13,26 @@ * Name: textformat<br> * Purpose: format text a certain way with preset styles * or custom wrap/indent settings<br> - * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat} - * (Smarty online manual) - * @param array + * Params: * <pre> - * Params: style: string (email) - * indent: integer (0) - * wrap: integer (80) - * wrap_char string ("\n") - * indent_char: string (" ") - * wrap_boundary: boolean (true) + * - style - string (email) + * - indent - integer (0) + * - wrap - integer (80) + * - wrap_char - string ("\n") + * - indent_char - string (" ") + * - wrap_boundary - boolean (true) * </pre> + * + * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * @param array $params parameters + * @param string $content contents of the block + * @param Smarty_Internal_Template $template template object + * @param boolean &$repeat repeat flag + * @return string content re-formatted * @author Monte Ohrt <monte at ohrt dot com> - * @param string contents of the block - * @param Smarty clever simulation of a method - * @return string string $content re-formatted */ -function smarty_block_textformat($params, $content, &$smarty) +function smarty_block_textformat($params, $content, $template, &$repeat) { if (is_null($content)) { return; @@ -42,7 +46,7 @@ function smarty_block_textformat($params, $content, &$smarty) $wrap_char = "\n"; $wrap_cut = false; $assign = null; - + foreach ($params as $_key => $_val) { switch ($_key) { case 'style': @@ -63,41 +67,47 @@ function smarty_block_textformat($params, $content, &$smarty) break; default: - $smarty->trigger_error("textformat: unknown attribute '$_key'"); + trigger_error("textformat: unknown attribute '$_key'"); } } if ($style == 'email') { $wrap = 72; } - // split into paragraphs - $_paragraphs = preg_split('![\r\n][\r\n]!',$content); + $_paragraphs = preg_split('![\r\n]{2}!', $content); $_output = ''; - for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) { - if ($_paragraphs[$_x] == '') { + + foreach ($_paragraphs as &$_paragraph) { + if (!$_paragraph) { continue; } // convert mult. spaces & special chars to single space - $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]); + $_paragraph = preg_replace(array('!\s+!' . Smarty::$_UTF8_MODIFIER, '!(^\s+)|(\s+$)!' . Smarty::$_UTF8_MODIFIER), array(' ', ''), $_paragraph); // indent first line - if($indent_first > 0) { - $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x]; + if ($indent_first > 0) { + $_paragraph = str_repeat($indent_char, $indent_first) . $_paragraph; } // wordwrap sentences - $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut); + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'); + $_paragraph = smarty_mb_wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } else { + $_paragraph = wordwrap($_paragraph, $wrap - $indent, $wrap_char, $wrap_cut); + } // indent lines - if($indent > 0) { - $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]); + if ($indent > 0) { + $_paragraph = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraph); } } $_output = implode($wrap_char . $wrap_char, $_paragraphs); - - return $assign ? $smarty->assign($assign, $_output) : $_output; - + + if ($assign) { + $template->assign($assign, $_output); + } else { + return $_output; + } } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/compiler.assign.php b/include/smarty/libs/plugins/compiler.assign.php deleted file mode 100644 index abef377f8..000000000 --- a/include/smarty/libs/plugins/compiler.assign.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Smarty {assign} compiler function plugin - * - * Type: compiler function<br> - * Name: assign<br> - * Purpose: assign a value to a template variable - * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> (initial author) - * @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function) - * @param string containing var-attribute and value-attribute - * @param Smarty_Compiler - */ -function smarty_compiler_assign($tag_attrs, &$compiler) -{ - $_params = $compiler->_parse_attrs($tag_attrs); - - if (!isset($_params['var'])) { - $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING); - return; - } - - if (!isset($_params['value'])) { - $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING); - return; - } - - return "\$this->assign({$_params['var']}, {$_params['value']});"; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/function.assign_debug_info.php b/include/smarty/libs/plugins/function.assign_debug_info.php deleted file mode 100644 index 654049876..000000000 --- a/include/smarty/libs/plugins/function.assign_debug_info.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Smarty {assign_debug_info} function plugin - * - * Type: function<br> - * Name: assign_debug_info<br> - * Purpose: assign debug info to the template<br> - * @author Monte Ohrt <monte at ohrt dot com> - * @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, - * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} - * @param Smarty - */ -function smarty_function_assign_debug_info($params, &$smarty) -{ - $assigned_vars = $smarty->_tpl_vars; - ksort($assigned_vars); - if (@is_array($smarty->_config[0])) { - $config_vars = $smarty->_config[0]; - ksort($config_vars); - $smarty->assign("_debug_config_keys", array_keys($config_vars)); - $smarty->assign("_debug_config_vals", array_values($config_vars)); - } - - $included_templates = $smarty->_smarty_debug_info; - - $smarty->assign("_debug_keys", array_keys($assigned_vars)); - $smarty->assign("_debug_vals", array_values($assigned_vars)); - - $smarty->assign("_debug_tpls", $included_templates); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/function.config_load.php b/include/smarty/libs/plugins/function.config_load.php deleted file mode 100644 index db89f638c..000000000 --- a/include/smarty/libs/plugins/function.config_load.php +++ /dev/null @@ -1,142 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - -/** - * Smarty {config_load} function plugin - * - * Type: function<br> - * Name: config_load<br> - * Purpose: load config file vars - * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load} - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @author messju mohr <messju at lammfellpuschen dot de> (added use of resources) - * @param array Format: - * <pre> - * array('file' => required config file name, - * 'section' => optional config file section to load - * 'scope' => local/parent/global - * 'global' => overrides scope, setting to parent if true) - * </pre> - * @param Smarty - */ -function smarty_function_config_load($params, &$smarty) -{ - if ($smarty->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $_debug_start_time = smarty_core_get_microtime($_params, $smarty); - } - - $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null; - $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null; - $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global'; - $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false; - - if (!isset($_file) || strlen($_file) == 0) { - $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__); - } - - if (isset($_scope)) { - if ($_scope != 'local' && - $_scope != 'parent' && - $_scope != 'global') { - $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__); - } - } else { - if ($_global) { - $_scope = 'parent'; - } else { - $_scope = 'local'; - } - } - - $_params = array('resource_name' => $_file, - 'resource_base_path' => $smarty->config_dir, - 'get_source' => false); - $smarty->_parse_resource_name($_params); - $_file_path = $_params['resource_type'] . ':' . $_params['resource_name']; - if (isset($_section)) - $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section); - else - $_compile_file = $smarty->_get_compile_path($_file_path); - - if($smarty->force_compile || !file_exists($_compile_file)) { - $_compile = true; - } elseif ($smarty->compile_check) { - $_params = array('resource_name' => $_file, - 'resource_base_path' => $smarty->config_dir, - 'get_source' => false); - $_compile = $smarty->_fetch_resource_info($_params) && - $_params['resource_timestamp'] > filemtime($_compile_file); - } else { - $_compile = false; - } - - if($_compile) { - // compile config file - if(!is_object($smarty->_conf_obj)) { - require_once SMARTY_DIR . $smarty->config_class . '.class.php'; - $smarty->_conf_obj = new $smarty->config_class(); - $smarty->_conf_obj->overwrite = $smarty->config_overwrite; - $smarty->_conf_obj->booleanize = $smarty->config_booleanize; - $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden; - $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines; - } - - $_params = array('resource_name' => $_file, - 'resource_base_path' => $smarty->config_dir, - $_params['get_source'] = true); - if (!$smarty->_fetch_resource_info($_params)) { - return; - } - $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']); - $_config_vars = array_merge($smarty->_conf_obj->get($_file), - $smarty->_conf_obj->get($_file, $_section)); - if(function_exists('var_export')) { - $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>'; - } else { - $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>'; - } - $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp'])); - require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); - smarty_core_write_compiled_resource($_params, $smarty); - } else { - include($_compile_file); - } - - if ($smarty->caching) { - $smarty->_cache_info['config'][$_file] = true; - } - - $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars); - $smarty->_config[0]['files'][$_file] = true; - - if ($_scope == 'parent') { - $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars); - $smarty->_config[1]['files'][$_file] = true; - } else if ($_scope == 'global') { - for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) { - $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars); - $smarty->_config[$i]['files'][$_file] = true; - } - } - - if ($smarty->debugging) { - $_params = array(); - require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); - $smarty->_smarty_debug_info[] = array('type' => 'config', - 'filename' => $_file.' ['.$_section.'] '.$_scope, - 'depth' => $smarty->_inclusion_depth, - 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time); - } - -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/function.counter.php b/include/smarty/libs/plugins/function.counter.php index 1f26db5fb..3906badf0 100644 --- a/include/smarty/libs/plugins/function.counter.php +++ b/include/smarty/libs/plugins/function.counter.php @@ -2,24 +2,24 @@ /** * Smarty plugin * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {counter} function plugin * * Type: function<br> * Name: counter<br> * Purpose: print out a counter value + * * @author Monte Ohrt <monte at ohrt dot com> - * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} + * @link http://www.smarty.net/manual/en/language.function.counter.php {counter} * (Smarty online manual) - * @param array parameters - * @param Smarty + * @param array $params parameters + * @param Smarty_Internal_Template $template template object * @return string|null */ -function smarty_function_counter($params, &$smarty) +function smarty_function_counter($params, $template) { static $counters = array(); @@ -43,7 +43,7 @@ function smarty_function_counter($params, &$smarty) } if (isset($counter['assign'])) { - $smarty->assign($counter['assign'], $counter['count']); + $template->assign($counter['assign'], $counter['count']); } if (isset($params['print'])) { @@ -75,6 +75,4 @@ function smarty_function_counter($params, &$smarty) } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.cycle.php b/include/smarty/libs/plugins/function.cycle.php index fe78bb87d..1778ffb53 100644 --- a/include/smarty/libs/plugins/function.cycle.php +++ b/include/smarty/libs/plugins/function.cycle.php @@ -1,8 +1,9 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ /** @@ -12,47 +13,48 @@ * Name: cycle<br> * Date: May 3, 2002<br> * Purpose: cycle through given values<br> - * Input: - * - name = name of cycle (optional) - * - values = comma separated list of values to cycle, - * or an array of values to cycle - * (this can be left out for subsequent calls) - * - reset = boolean - resets given var to true - * - print = boolean - print var or not. default is true - * - advance = boolean - whether or not to advance the cycle - * - delimiter = the value delimiter, default is "," - * - assign = boolean, assigns to template var instead of - * printed. - * + * Params: + * <pre> + * - name - name of cycle (optional) + * - values - comma separated list of values to cycle, or an array of values to cycle + * (this can be left out for subsequent calls) + * - reset - boolean - resets given var to true + * - print - boolean - print var or not. default is true + * - advance - boolean - whether or not to advance the cycle + * - delimiter - the value delimiter, default is "," + * - assign - boolean, assigns to template var instead of printed. + * </pre> * Examples:<br> * <pre> * {cycle values="#eeeeee,#d0d0d0d"} * {cycle name=row values="one,two,three" reset=true} * {cycle name=row} * </pre> - * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle} + * + * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle} * (Smarty online manual) * @author Monte Ohrt <monte at ohrt dot com> * @author credit to Mark Priatel <mpriatel@rogers.com> * @author credit to Gerard <gerard@interfold.com> * @author credit to Jason Sweat <jsweat_php@yahoo.com> * @version 1.3 - * @param array - * @param Smarty + * @param array $params parameters + * @param Smarty_Internal_Template $template template object * @return string|null */ -function smarty_function_cycle($params, &$smarty) + +function smarty_function_cycle($params, $template) { static $cycle_vars; - + $name = (empty($params['name'])) ? 'default' : $params['name']; $print = (isset($params['print'])) ? (bool)$params['print'] : true; $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true; $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false; - - if (!in_array('values', array_keys($params))) { + + if (!isset($params['values'])) { if(!isset($cycle_vars[$name]['values'])) { - $smarty->trigger_error("cycle: missing 'values' parameter"); + trigger_error("cycle: missing 'values' parameter"); return; } } else { @@ -63,23 +65,27 @@ function smarty_function_cycle($params, &$smarty) $cycle_vars[$name]['values'] = $params['values']; } - $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ','; - + if (isset($params['delimiter'])) { + $cycle_vars[$name]['delimiter'] = $params['delimiter']; + } elseif (!isset($cycle_vars[$name]['delimiter'])) { + $cycle_vars[$name]['delimiter'] = ','; + } + if(is_array($cycle_vars[$name]['values'])) { $cycle_array = $cycle_vars[$name]['values']; } else { $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); } - + if(!isset($cycle_vars[$name]['index']) || $reset ) { $cycle_vars[$name]['index'] = 0; } - + if (isset($params['assign'])) { $print = false; - $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); + $template->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); } - + if($print) { $retval = $cycle_array[$cycle_vars[$name]['index']]; } else { @@ -93,10 +99,8 @@ function smarty_function_cycle($params, &$smarty) $cycle_vars[$name]['index']++; } } - + return $retval; } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.debug.php b/include/smarty/libs/plugins/function.debug.php deleted file mode 100644 index 43452307b..000000000 --- a/include/smarty/libs/plugins/function.debug.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty {debug} function plugin - * - * Type: function<br> - * Name: debug<br> - * Date: July 1, 2002<br> - * Purpose: popup debug window - * @link http://smarty.php.net/manual/en/language.function.debug.php {debug} - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @version 1.0 - * @param array - * @param Smarty - * @return string output from {@link Smarty::_generate_debug_output()} - */ -function smarty_function_debug($params, &$smarty) -{ - if (isset($params['output'])) { - $smarty->assign('_smarty_debug_output', $params['output']); - } - require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); - return smarty_core_display_debug_console(null, $smarty); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/function.eval.php b/include/smarty/libs/plugins/function.eval.php deleted file mode 100644 index ff0472de2..000000000 --- a/include/smarty/libs/plugins/function.eval.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty {eval} function plugin - * - * Type: function<br> - * Name: eval<br> - * Purpose: evaluate a template variable as a template<br> - * @link http://smarty.php.net/manual/en/language.function.eval.php {eval} - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - */ -function smarty_function_eval($params, &$smarty) -{ - - if (!isset($params['var'])) { - $smarty->trigger_error("eval: missing 'var' parameter"); - return; - } - - if($params['var'] == '') { - return; - } - - $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled); - - ob_start(); - $smarty->_eval('?>' . $_var_compiled); - $_contents = ob_get_contents(); - ob_end_clean(); - - if (!empty($params['assign'])) { - $smarty->assign($params['assign'], $_contents); - } else { - return $_contents; - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/function.fetch.php b/include/smarty/libs/plugins/function.fetch.php index 81b1bfc6b..eca1182d5 100644 --- a/include/smarty/libs/plugins/function.fetch.php +++ b/include/smarty/libs/plugins/function.fetch.php @@ -1,221 +1,214 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {fetch} plugin * * Type: function<br> * Name: fetch<br> * Purpose: fetch file, web or ftp data and display results - * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} + * + * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch} * (Smarty online manual) * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - * @return string|null if the assign parameter is passed, Smarty assigns the - * result to a template variable + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable */ -function smarty_function_fetch($params, &$smarty) +function smarty_function_fetch($params, $template) { if (empty($params['file'])) { - $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty"); + trigger_error("[plugin] fetch parameter 'file' cannot be empty",E_USER_NOTICE); return; } - - $content = ''; - if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) { - $_params = array('resource_type' => 'file', 'resource_name' => $params['file']); - require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); - if(!smarty_core_is_secure($_params, $smarty)) { - $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed'); - return; - } - - // fetch the file - if($fp = @fopen($params['file'],'r')) { - while(!feof($fp)) { - $content .= fgets ($fp,4096); + + // strip file protocol + if (stripos($params['file'], 'file://') === 0) { + $params['file'] = substr($params['file'], 7); + } + + $protocol = strpos($params['file'], '://'); + if ($protocol !== false) { + $protocol = strtolower(substr($params['file'], 0, $protocol)); + } + + if (isset($template->smarty->security_policy)) { + if ($protocol) { + // remote resource (or php stream, …) + if(!$template->smarty->security_policy->isTrustedUri($params['file'])) { + return; } - fclose($fp); } else { - $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\''); - return; + // local file + if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) { + return; + } } - } else { - // not a local file - if(preg_match('!^http://!i',$params['file'])) { - // http fetch - if($uri_parts = parse_url($params['file'])) { - // set defaults - $host = $server_name = $uri_parts['host']; - $timeout = 30; - $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; - $agent = "Smarty Template Engine ".$smarty->_version; - $referer = ""; - $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; - $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; - $_is_proxy = false; - if(empty($uri_parts['port'])) { - $port = 80; - } else { - $port = $uri_parts['port']; - } - if(!empty($uri_parts['user'])) { - $user = $uri_parts['user']; - } - if(!empty($uri_parts['pass'])) { - $pass = $uri_parts['pass']; - } - // loop through parameters, setup headers - foreach($params as $param_key => $param_value) { - switch($param_key) { - case "file": - case "assign": - case "assign_headers": - break; - case "user": - if(!empty($param_value)) { - $user = $param_value; - } - break; - case "pass": - if(!empty($param_value)) { - $pass = $param_value; - } - break; - case "accept": - if(!empty($param_value)) { - $accept = $param_value; - } - break; - case "header": - if(!empty($param_value)) { - if(!preg_match('![\w\d-]+: .+!',$param_value)) { - $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'"); - return; - } else { - $extra_headers[] = $param_value; - } - } - break; - case "proxy_host": - if(!empty($param_value)) { - $proxy_host = $param_value; - } - break; - case "proxy_port": - if(!preg_match('!\D!', $param_value)) { - $proxy_port = (int) $param_value; - } else { - $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + } + + $content = ''; + if ($protocol == 'http') { + // http fetch + if($uri_parts = parse_url($params['file'])) { + // set defaults + $host = $server_name = $uri_parts['host']; + $timeout = 30; + $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + $agent = "Smarty Template Engine ". Smarty::SMARTY_VERSION; + $referer = ""; + $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; + $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $_is_proxy = false; + if(empty($uri_parts['port'])) { + $port = 80; + } else { + $port = $uri_parts['port']; + } + if(!empty($uri_parts['user'])) { + $user = $uri_parts['user']; + } + if(!empty($uri_parts['pass'])) { + $pass = $uri_parts['pass']; + } + // loop through parameters, setup headers + foreach($params as $param_key => $param_value) { + switch($param_key) { + case "file": + case "assign": + case "assign_headers": + break; + case "user": + if(!empty($param_value)) { + $user = $param_value; + } + break; + case "pass": + if(!empty($param_value)) { + $pass = $param_value; + } + break; + case "accept": + if(!empty($param_value)) { + $accept = $param_value; + } + break; + case "header": + if(!empty($param_value)) { + if(!preg_match('![\w\d-]+: .+!',$param_value)) { + trigger_error("[plugin] invalid header format '".$param_value."'",E_USER_NOTICE); return; - } - break; - case "agent": - if(!empty($param_value)) { - $agent = $param_value; - } - break; - case "referer": - if(!empty($param_value)) { - $referer = $param_value; - } - break; - case "timeout": - if(!preg_match('!\D!', $param_value)) { - $timeout = (int) $param_value; } else { - $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); - return; + $extra_headers[] = $param_value; } - break; - default: - $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'"); + } + break; + case "proxy_host": + if(!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case "proxy_port": + if(!preg_match('!\D!', $param_value)) { + $proxy_port = (int) $param_value; + } else { + trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE); return; - } - } - if(!empty($proxy_host) && !empty($proxy_port)) { - $_is_proxy = true; - $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); - } else { - $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + } + break; + case "agent": + if(!empty($param_value)) { + $agent = $param_value; + } + break; + case "referer": + if(!empty($param_value)) { + $referer = $param_value; + } + break; + case "timeout": + if(!preg_match('!\D!', $param_value)) { + $timeout = (int) $param_value; + } else { + trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE); + return; + } + break; + default: + trigger_error("[plugin] unrecognized attribute '".$param_key."'",E_USER_NOTICE); + return; } + } + if(!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); + } else { + $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + } - if(!$fp) { - $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)"); - return; + if(!$fp) { + trigger_error("[plugin] unable to fetch: $errstr ($errno)",E_USER_NOTICE); + return; + } else { + if($_is_proxy) { + fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); } else { - if($_is_proxy) { - fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); - } else { - fputs($fp, "GET $uri HTTP/1.0\r\n"); - } - if(!empty($host)) { - fputs($fp, "Host: $host\r\n"); - } - if(!empty($accept)) { - fputs($fp, "Accept: $accept\r\n"); - } - if(!empty($agent)) { - fputs($fp, "User-Agent: $agent\r\n"); - } - if(!empty($referer)) { - fputs($fp, "Referer: $referer\r\n"); - } - if(isset($extra_headers) && is_array($extra_headers)) { - foreach($extra_headers as $curr_header) { - fputs($fp, $curr_header."\r\n"); - } - } - if(!empty($user) && !empty($pass)) { - fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if(!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if(!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if(!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if(!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if(isset($extra_headers) && is_array($extra_headers)) { + foreach($extra_headers as $curr_header) { + fputs($fp, $curr_header."\r\n"); } + } + if(!empty($user) && !empty($pass)) { + fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + } - fputs($fp, "\r\n"); - while(!feof($fp)) { - $content .= fgets($fp,4096); - } - fclose($fp); - $csplit = split("\r\n\r\n",$content,2); + fputs($fp, "\r\n"); + while(!feof($fp)) { + $content .= fgets($fp,4096); + } + fclose($fp); + $csplit = preg_split("!\r\n\r\n!",$content,2); - $content = $csplit[1]; + $content = $csplit[1]; - if(!empty($params['assign_headers'])) { - $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); - } + if(!empty($params['assign_headers'])) { + $template->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0])); } - } else { - $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax"); - return; } } else { - // ftp fetch - if($fp = @fopen($params['file'],'r')) { - while(!feof($fp)) { - $content .= fgets ($fp,4096); - } - fclose($fp); - } else { - $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\''); - return; - } + trigger_error("[plugin fetch] unable to parse URL, check syntax",E_USER_NOTICE); + return; + } + } else { + $content = @file_get_contents($params['file']); + if ($content === false) { + throw new SmartyException("{fetch} cannot read resource '" . $params['file'] ."'"); } - } - if (!empty($params['assign'])) { - $smarty->assign($params['assign'],$content); + $template->assign($params['assign'], $content); } else { return $content; } } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_checkboxes.php b/include/smarty/libs/plugins/function.html_checkboxes.php index 7733eea74..1866bc2f3 100644 --- a/include/smarty/libs/plugins/function.html_checkboxes.php +++ b/include/smarty/libs/plugins/function.html_checkboxes.php @@ -1,11 +1,11 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {html_checkboxes} function plugin * @@ -14,40 +14,46 @@ * Name: html_checkboxes<br> * Date: 24.Feb.2003<br> * Purpose: Prints out a list of checkbox input types<br> - * Input:<br> - * - name (optional) - string default "checkbox" - * - values (required) - array - * - options (optional) - associative array - * - checked (optional) - array default not set - * - separator (optional) - ie <br> or - * - output (optional) - the output next to each checkbox - * - assign (optional) - assign the output as an array to this variable * Examples: * <pre> * {html_checkboxes values=$ids output=$names} * {html_checkboxes values=$ids name='box' separator='<br>' output=$names} * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names} * </pre> - * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * Params: + * <pre> + * - name (optional) - string default "checkbox" + * - values (required) - array + * - options (optional) - associative array + * - checked (optional) - array default not set + * - separator (optional) - ie <br> or + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * - escape (optional) - escape the content (not value), defaults to true + * </pre> + * + * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} * (Smarty online manual) * @author Christopher Kvarme <christopher.kvarme@flashjab.com> * @author credits to Monte Ohrt <monte at ohrt dot com> * @version 1.0 - * @param array - * @param Smarty + * @param array $params parameters + * @param object $template template object * @return string * @uses smarty_function_escape_special_chars() */ -function smarty_function_html_checkboxes($params, &$smarty) +function smarty_function_html_checkboxes($params, $template) { - require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); $name = 'checkbox'; $values = null; $options = null; - $selected = null; + $selected = array(); $separator = ''; + $escape = true; $labels = true; + $label_ids = false; $output = null; $extra = ''; @@ -56,40 +62,82 @@ function smarty_function_html_checkboxes($params, &$smarty) switch($_key) { case 'name': case 'separator': - $$_key = $_val; + $$_key = (string) $_val; break; + case 'escape': case 'labels': - $$_key = (bool)$_val; + case 'label_ids': + $$_key = (bool) $_val; break; case 'options': - $$_key = (array)$_val; + $$_key = (array) $_val; break; case 'values': case 'output': - $$_key = array_values((array)$_val); + $$_key = array_values((array) $_val); break; case 'checked': case 'selected': - $selected = array_map('strval', array_values((array)$_val)); + if (is_array($_val)) { + $selected = array(); + foreach ($_val as $_sel) { + if (is_object($_sel)) { + if (method_exists($_sel, "__toString")) { + $_sel = smarty_function_escape_special_chars((string) $_sel->__toString()); + } else { + trigger_error("html_checkboxes: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE); + continue; + } + } else { + $_sel = smarty_function_escape_special_chars((string) $_sel); + } + $selected[$_sel] = true; + } + } elseif (is_object($_val)) { + if (method_exists($_val, "__toString")) { + $selected = smarty_function_escape_special_chars((string) $_val->__toString()); + } else { + trigger_error("html_checkboxes: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE); + } + } else { + $selected = smarty_function_escape_special_chars((string) $_val); + } break; case 'checkboxes': - $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); - $options = (array)$_val; + trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING); + $options = (array) $_val; break; case 'assign': break; + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + default: if(!is_array($_val)) { $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; } else { - $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); } break; } @@ -98,46 +146,88 @@ function smarty_function_html_checkboxes($params, &$smarty) if (!isset($options) && !isset($values)) return ''; /* raise error here? */ - settype($selected, 'array'); $_html_result = array(); if (isset($options)) { - - foreach ($options as $_key=>$_val) - $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels); - - + foreach ($options as $_key=>$_val) { + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } } else { foreach ($values as $_i=>$_key) { $_val = isset($output[$_i]) ? $output[$_i] : ''; - $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels); + $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); } - } if(!empty($params['assign'])) { - $smarty->assign($params['assign'], $_html_result); + $template->assign($params['assign'], $_html_result); } else { - return implode("\n",$_html_result); + return implode("\n", $_html_result); } } -function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) { +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape=true) { $_output = ''; - if ($labels) $_output .= '<label>'; - $_output .= '<input type="checkbox" name="' - . smarty_function_escape_special_chars($name) . '[]" value="' - . smarty_function_escape_special_chars($value) . '"'; - - if (in_array((string)$value, $selected)) { + + if (is_object($value)) { + if (method_exists($value, "__toString")) { + $value = (string) $value->__toString(); + } else { + trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); + return ''; + } + } else { + $value = (string) $value; + } + + if (is_object($output)) { + if (method_exists($output, "__toString")) { + $output = (string) $output->__toString(); + } else { + trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE); + return ''; + } + } else { + $output = (string) $output; + } + + if ($labels) { + if ($label_ids) { + $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value)); + $_output .= '<label for="' . $_id . '">'; + } else { + $_output .= '<label>'; + } + } + + $name = smarty_function_escape_special_chars($name); + $value = smarty_function_escape_special_chars($value); + if ($escape) { + $output = smarty_function_escape_special_chars($output); + } + + $_output .= '<input type="checkbox" name="' . $name . '[]" value="' . $value . '"'; + + if ($labels && $label_ids) { + $_output .= ' id="' . $_id . '"'; + } + + if (is_array($selected)) { + if (isset($selected[$value])) { + $_output .= ' checked="checked"'; + } + } elseif ($value === $selected) { $_output .= ' checked="checked"'; } - $_output .= $extra . '>' . $output; - if ($labels) $_output .= '</label>'; + + $_output .= $extra . ' />' . $output; + if ($labels) { + $_output .= '</label>'; + } + $_output .= $separator; - return $_output; } -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_image.php b/include/smarty/libs/plugins/function.html_image.php index 96cd795c2..6521966bb 100644 --- a/include/smarty/libs/plugins/function.html_image.php +++ b/include/smarty/libs/plugins/function.html_image.php @@ -1,43 +1,43 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {html_image} function plugin - * + * * Type: function<br> * Name: html_image<br> * Date: Feb 24, 2003<br> * Purpose: format HTML tags for the image<br> - * Input:<br> - * - file = file (and path) of image (required) - * - height = image height (optional, default actual height) - * - width = image width (optional, default actual width) - * - basedir = base directory for absolute paths, default - * is environment variable DOCUMENT_ROOT - * - path_prefix = prefix for path output (optional, default empty) - * - * Examples: {html_image file="/images/masthead.gif"} - * Output: <img src="/images/masthead.gif" width=400 height=23> - * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} + * Examples: {html_image file="/images/masthead.gif"}<br> + * Output: <img src="/images/masthead.gif" width=400 height=23><br> + * Params: + * <pre> + * - file - (required) - file (and path) of image + * - height - (optional) - image height (default actual height) + * - width - (optional) - image width (default actual width) + * - basedir - (optional) - base directory for absolute paths, default is environment variable DOCUMENT_ROOT + * - path_prefix - prefix for path output (optional, default empty) + * </pre> + * + * @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image} * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @author credits to Duda <duda@big.hu> - wrote first image function - * in repository, helped with lots of functionality - * @version 1.0 - * @param array - * @param Smarty - * @return string + * @author Monte Ohrt <monte at ohrt dot com> + * @author credits to Duda <duda@big.hu> + * @version 1.0 + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string * @uses smarty_function_escape_special_chars() */ -function smarty_function_html_image($params, &$smarty) +function smarty_function_html_image($params, $template) { - require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); - + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + $alt = ''; $file = ''; $height = ''; @@ -46,10 +46,9 @@ function smarty_function_html_image($params, &$smarty) $prefix = ''; $suffix = ''; $path_prefix = ''; - $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; - $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : ''; + $basedir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : ''; foreach($params as $_key => $_val) { - switch($_key) { + switch ($_key) { case 'file': case 'height': case 'width': @@ -60,11 +59,11 @@ function smarty_function_html_image($params, &$smarty) break; case 'alt': - if(!is_array($_val)) { + if (!is_array($_val)) { $$_key = smarty_function_escape_special_chars($_val); } else { - $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); - } + throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } break; case 'link': @@ -74,69 +73,87 @@ function smarty_function_html_image($params, &$smarty) break; default: - if(!is_array($_val)) { - $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + if (!is_array($_val)) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; } else { - $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); - } + throw new SmartyException ("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } break; - } - } + } + } if (empty($file)) { - $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE); + trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE); return; - } + } - if (substr($file,0,1) == '/') { + if ($file[0] == '/') { $_image_path = $basedir . $file; } else { $_image_path = $file; } - if(!isset($params['width']) || !isset($params['height'])) { - if(!$_image_data = @getimagesize($_image_path)) { - if(!file_exists($_image_path)) { - $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE); + // strip file protocol + if (stripos($params['file'], 'file://') === 0) { + $params['file'] = substr($params['file'], 7); + } + + $protocol = strpos($params['file'], '://'); + if ($protocol !== false) { + $protocol = strtolower(substr($params['file'], 0, $protocol)); + } + + if (isset($template->smarty->security_policy)) { + if ($protocol) { + // remote resource (or php stream, …) + if(!$template->smarty->security_policy->isTrustedUri($params['file'])) { + return; + } + } else { + // local file + if(!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) { + return; + } + } + } + + if (!isset($params['width']) || !isset($params['height'])) { + // FIXME: (rodneyrehm) getimagesize() loads the complete file off a remote resource, use custom [jpg,png,gif]header reader! + if (!$_image_data = @getimagesize($_image_path)) { + if (!file_exists($_image_path)) { + trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE); return; - } else if(!is_readable($_image_path)) { - $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE); + } else if (!is_readable($_image_path)) { + trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE); return; } else { - $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE); + trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE); return; - } + } } - if ($smarty->security && - ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) && - (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) && - (!smarty_core_is_secure($_params, $smarty)) ) { - $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE); - } - - if(!isset($params['width'])) { + + if (!isset($params['width'])) { $width = $_image_data[0]; - } - if(!isset($params['height'])) { + } + if (!isset($params['height'])) { $height = $_image_data[1]; - } - - } + } + } - if(isset($params['dpi'])) { - if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) { + if (isset($params['dpi'])) { + if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mac')) { + // FIXME: (rodneyrehm) wrong dpi assumption + // don't know who thought this up… even if it was true in 1998, it's definitely wrong in 2011. $dpi_default = 72; } else { $dpi_default = 96; - } - $_resize = $dpi_default/$params['dpi']; + } + $_resize = $dpi_default / $params['dpi']; $width = round($width * $_resize); $height = round($height * $_resize); - } - - return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.'>' . $suffix; -} + } -/* vim: set expandtab: */ + return $prefix . '<img src="' . $path_prefix . $file . '" alt="' . $alt . '" width="' . $width . '" height="' . $height . '"' . $extra . ' />' . $suffix; +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_options.php b/include/smarty/libs/plugins/function.html_options.php index cebadde47..68fa0524a 100644 --- a/include/smarty/libs/plugins/function.html_options.php +++ b/include/smarty/libs/plugins/function.html_options.php @@ -1,122 +1,193 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {html_options} function plugin - * + * * Type: function<br> * Name: html_options<br> - * Input:<br> - * - name (optional) - string default "select" - * - values (required if no options supplied) - array - * - options (required if no values supplied) - associative array - * - selected (optional) - string default not set - * - output (required if not options supplied) - array * Purpose: Prints the list of <option> tags generated from - * the passed parameters - * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image} + * the passed parameters<br> + * Params: + * <pre> + * - name (optional) - string default "select" + * - values (required) - if no options supplied) - array + * - options (required) - if no values supplied) - associative array + * - selected (optional) - string default not set + * - output (required) - if not options supplied) - array + * - id (optional) - string default not set + * - class (optional) - string default not set + * </pre> + * + * @link http://www.smarty.net/manual/en/language.function.html.options.php {html_image} * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - * @return string + * @author Monte Ohrt <monte at ohrt dot com> + * @author Ralf Strehle (minor optimization) <ralf dot strehle at yahoo dot de> + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string * @uses smarty_function_escape_special_chars() */ -function smarty_function_html_options($params, &$smarty) +function smarty_function_html_options($params, $template) { - require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); - + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + $name = null; $values = null; $options = null; - $selected = array(); + $selected = null; $output = null; - + $id = null; + $class = null; + $extra = ''; - - foreach($params as $_key => $_val) { - switch($_key) { + + foreach ($params as $_key => $_val) { + switch ($_key) { case 'name': - $$_key = (string)$_val; + case 'class': + case 'id': + $$_key = (string) $_val; break; - + case 'options': - $$_key = (array)$_val; + $options = (array) $_val; break; - + case 'values': case 'output': - $$_key = array_values((array)$_val); + $$_key = array_values((array) $_val); break; case 'selected': - $$_key = array_map('strval', array_values((array)$_val)); + if (is_array($_val)) { + $selected = array(); + foreach ($_val as $_sel) { + if (is_object($_sel)) { + if (method_exists($_sel, "__toString")) { + $_sel = smarty_function_escape_special_chars((string) $_sel->__toString()); + } else { + trigger_error("html_options: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE); + continue; + } + } else { + $_sel = smarty_function_escape_special_chars((string) $_sel); + } + $selected[$_sel] = true; + } + } elseif (is_object($_val)) { + if (method_exists($_val, "__toString")) { + $selected = smarty_function_escape_special_chars((string) $_val->__toString()); + } else { + trigger_error("html_options: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE); + } + } else { + $selected = smarty_function_escape_special_chars((string) $_val); + } break; - + + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + default: - if(!is_array($_val)) { - $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + if (!is_array($_val)) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; } else { - $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE); - } + trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } break; - } + } } - if (!isset($options) && !isset($values)) - return ''; /* raise error here? */ + if (!isset($options) && !isset($values)) { + /* raise error here? */ + return ''; + } $_html_result = ''; + $_idx = 0; if (isset($options)) { - - foreach ($options as $_key=>$_val) - $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected); - + foreach ($options as $_key => $_val) { + $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx); + } } else { - - foreach ($values as $_i=>$_key) { + foreach ($values as $_i => $_key) { $_val = isset($output[$_i]) ? $output[$_i] : ''; - $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected); - } - + $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $id, $class, $_idx); + } } - if(!empty($name)) { - $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n"; - } + if (!empty($name)) { + $_html_class = !empty($class) ? ' class="'.$class.'"' : ''; + $_html_id = !empty($id) ? ' id="'.$id.'"' : ''; + $_html_result = '<select name="' . $name . '"' . $_html_class . $_html_id . $extra . '>' . "\n" . $_html_result . '</select>' . "\n"; + } return $_html_result; - } -function smarty_function_html_options_optoutput($key, $value, $selected) { - if(!is_array($value)) { - $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' . - smarty_function_escape_special_chars($key) . '"'; - if (in_array((string)$key, $selected)) +function smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, &$idx) +{ + if (!is_array($value)) { + $_key = smarty_function_escape_special_chars($key); + $_html_result = '<option value="' . $_key . '"'; + if (is_array($selected)) { + if (isset($selected[$_key])) { + $_html_result .= ' selected="selected"'; + } + } elseif ($_key === $selected) { $_html_result .= ' selected="selected"'; - $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n"; + } + $_html_class = !empty($class) ? ' class="'.$class.' option"' : ''; + $_html_id = !empty($id) ? ' id="'.$id.'-'.$idx.'"' : ''; + if (is_object($value)) { + if (method_exists($value, "__toString")) { + $value = smarty_function_escape_special_chars((string) $value->__toString()); + } else { + trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); + return ''; + } + } else { + $value = smarty_function_escape_special_chars((string) $value); + } + $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n"; + $idx++; } else { - $_html_result = smarty_function_html_options_optgroup($key, $value, $selected); + $_idx = 0; + $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id.'-'.$idx) : null, $class, $_idx); + $idx++; } return $_html_result; -} +} -function smarty_function_html_options_optgroup($key, $values, $selected) { +function smarty_function_html_options_optgroup($key, $values, $selected, $id, $class, &$idx) +{ $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n"; foreach ($values as $key => $value) { - $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected); - } + $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $id, $class, $idx); + } $optgroup_html .= "</optgroup>\n"; return $optgroup_html; -} - -/* vim: set expandtab: */ +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_radios.php b/include/smarty/libs/plugins/function.html_radios.php index c3bc903b0..a2741f68f 100644 --- a/include/smarty/libs/plugins/function.html_radios.php +++ b/include/smarty/libs/plugins/function.html_radios.php @@ -1,156 +1,217 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {html_radios} function plugin - * + * * File: function.html_radios.php<br> * Type: function<br> * Name: html_radios<br> * Date: 24.Feb.2003<br> * Purpose: Prints out a list of radio input types<br> - * Input:<br> - * - name (optional) - string default "radio" - * - values (required) - array - * - options (optional) - associative array - * - checked (optional) - array default not set - * - separator (optional) - ie <br> or - * - output (optional) - the output next to each radio button - * - assign (optional) - assign the output as an array to this variable + * Params: + * <pre> + * - name (optional) - string default "radio" + * - values (required) - array + * - options (required) - associative array + * - checked (optional) - array default not set + * - separator (optional) - ie <br> or + * - output (optional) - the output next to each radio button + * - assign (optional) - assign the output as an array to this variable + * - escape (optional) - escape the content (not value), defaults to true + * </pre> * Examples: * <pre> * {html_radios values=$ids output=$names} * {html_radios values=$ids name='box' separator='<br>' output=$names} * {html_radios values=$ids checked=$checked separator='<br>' output=$names} * </pre> + * * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios} * (Smarty online manual) - * @author Christopher Kvarme <christopher.kvarme@flashjab.com> - * @author credits to Monte Ohrt <monte at ohrt dot com> - * @version 1.0 - * @param array - * @param Smarty - * @return string + * @author Christopher Kvarme <christopher.kvarme@flashjab.com> + * @author credits to Monte Ohrt <monte at ohrt dot com> + * @version 1.0 + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string * @uses smarty_function_escape_special_chars() */ -function smarty_function_html_radios($params, &$smarty) +function smarty_function_html_radios($params, $template) { - require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); - + require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); + $name = 'radio'; $values = null; $options = null; $selected = null; $separator = ''; + $escape = true; $labels = true; $label_ids = false; $output = null; $extra = ''; foreach($params as $_key => $_val) { - switch($_key) { + switch ($_key) { case 'name': case 'separator': - $$_key = (string)$_val; + $$_key = (string) $_val; break; case 'checked': case 'selected': - if(is_array($_val)) { - $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING); + if (is_array($_val)) { + trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING); + } elseif (is_object($_val)) { + if (method_exists($_val, "__toString")) { + $selected = smarty_function_escape_special_chars((string) $_val->__toString()); + } else { + trigger_error("html_radios: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE); + } } else { - $selected = (string)$_val; - } + $selected = (string) $_val; + } break; + case 'escape': case 'labels': case 'label_ids': - $$_key = (bool)$_val; + $$_key = (bool) $_val; break; case 'options': - $$_key = (array)$_val; + $$_key = (array) $_val; break; case 'values': case 'output': - $$_key = array_values((array)$_val); + $$_key = array_values((array) $_val); break; case 'radios': - $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING); - $options = (array)$_val; + trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING); + $options = (array) $_val; break; case 'assign': break; + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + default: - if(!is_array($_val)) { - $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + if (!is_array($_val)) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; } else { - $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE); - } + trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } break; - } - } + } + } - if (!isset($options) && !isset($values)) - return ''; /* raise error here? */ + if (!isset($options) && !isset($values)) { + /* raise error here? */ + return ''; + } $_html_result = array(); if (isset($options)) { + foreach ($options as $_key => $_val) { + $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } + } else { + foreach ($values as $_i => $_key) { + $_val = isset($output[$_i]) ? $output[$_i] : ''; + $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); + } + } - foreach ($options as $_key=>$_val) - $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids); - + if (!empty($params['assign'])) { + $template->assign($params['assign'], $_html_result); } else { + return implode("\n", $_html_result); + } +} - foreach ($values as $_i=>$_key) { - $_val = isset($output[$_i]) ? $output[$_i] : ''; - $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids); +function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape) +{ + $_output = ''; + + if (is_object($value)) { + if (method_exists($value, "__toString")) { + $value = (string) $value->__toString(); + } else { + trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); + return ''; } - + } else { + $value = (string) $value; } - - if(!empty($params['assign'])) { - $smarty->assign($params['assign'], $_html_result); + + if (is_object($output)) { + if (method_exists($output, "__toString")) { + $output = (string) $output->__toString(); + } else { + trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE); + return ''; + } } else { - return implode("\n",$_html_result); + $output = (string) $output; } + + if ($labels) { + if ($label_ids) { + $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!' . Smarty::$_UTF8_MODIFIER, '_', $name . '_' . $value)); + $_output .= '<label for="' . $_id . '">'; + } else { + $_output .= '<label>'; + } + } + + $name = smarty_function_escape_special_chars($name); + $value = smarty_function_escape_special_chars($value); + if ($escape) { + $output = smarty_function_escape_special_chars($output); + } + + $_output .= '<input type="radio" name="' . $name . '" value="' . $value . '"'; -} + if ($labels && $label_ids) { + $_output .= ' id="' . $_id . '"'; + } -function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) { - $_output = ''; - if ($labels) { - if($label_ids) { - $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value)); - $_output .= '<label for="' . $_id . '">'; - } else { - $_output .= '<label>'; - } - } - $_output .= '<input type="radio" name="' - . smarty_function_escape_special_chars($name) . '" value="' - . smarty_function_escape_special_chars($value) . '"'; - - if ($labels && $label_ids) $_output .= ' id="' . $_id . '"'; - - if ((string)$value==$selected) { + if ($value === $selected) { $_output .= ' checked="checked"'; } - $_output .= $extra . '>' . $output; - if ($labels) $_output .= '</label>'; - $_output .= $separator; - + + $_output .= $extra . ' />' . $output; + if ($labels) { + $_output .= '</label>'; + } + + $_output .= $separator; return $_output; -} +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_select_date.php b/include/smarty/libs/plugins/function.html_select_date.php index ede9c7be1..13c500354 100644 --- a/include/smarty/libs/plugins/function.html_select_date.php +++ b/include/smarty/libs/plugins/function.html_select_date.php @@ -1,99 +1,142 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ /** + * @ignore + */ +require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); +/** + * @ignore + */ +require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); + +/** * Smarty {html_select_date} plugin - * + * * Type: function<br> * Name: html_select_date<br> * Purpose: Prints the dropdowns for date selection. - * - * ChangeLog:<br> - * - 1.0 initial release - * - 1.1 added support for +/- N syntax for begin - * and end year values. (Monte) - * - 1.2 added support for yyyy-mm-dd syntax for - * time value. (Jan Rosier) - * - 1.3 added support for choosing format for - * month values (Gary Loescher) - * - 1.3.1 added support for choosing format for - * day values (Marcus Bointon) - * - 1.3.2 support negative timestamps, force year - * dropdown to include given date unless explicitly set (Monte) - * - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that - * of 0000-00-00 dates (cybot, boots) - * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date} + * + * ChangeLog: + * <pre> + * - 1.0 initial release + * - 1.1 added support for +/- N syntax for begin + * and end year values. (Monte) + * - 1.2 added support for yyyy-mm-dd syntax for + * time value. (Jan Rosier) + * - 1.3 added support for choosing format for + * month values (Gary Loescher) + * - 1.3.1 added support for choosing format for + * day values (Marcus Bointon) + * - 1.3.2 support negative timestamps, force year + * dropdown to include given date unless explicitly set (Monte) + * - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that + * of 0000-00-00 dates (cybot, boots) + * - 2.0 complete rewrite for performance, + * added attributes month_names, *_id + * </pre> + * + * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date} * (Smarty online manual) - * @version 1.3.4 - * @author Andrei Zmievski - * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - * @return string + * @version 2.0 + * @author Andrei Zmievski + * @author Monte Ohrt <monte at ohrt dot com> + * @author Rodney Rehm + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string */ -function smarty_function_html_select_date($params, &$smarty) +function smarty_function_html_select_date($params, $template) { - require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); - require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); - require_once $smarty->_get_plugin_filepath('function','html_options'); + // generate timestamps used for month names only + static $_month_timestamps = null; + static $_current_year = null; + if ($_month_timestamps === null) { + $_current_year = date('Y'); + $_month_timestamps = array(); + for ($i = 1; $i <= 12; $i++) { + $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000); + } + } + /* Default values. */ - $prefix = "Date_"; - $start_year = strftime("%Y"); - $end_year = $start_year; - $display_days = true; - $display_months = true; - $display_years = true; - $month_format = "%B"; + $prefix = "Date_"; + $start_year = null; + $end_year = null; + $display_days = true; + $display_months = true; + $display_years = true; + $month_format = "%B"; /* Write months as numbers by default GL */ $month_value_format = "%m"; - $day_format = "%02d"; + $day_format = "%02d"; /* Write day values using this format MB */ $day_value_format = "%d"; - $year_as_text = false; + $year_as_text = false; /* Display years in reverse order? Ie. 2000,1999,.... */ - $reverse_years = false; + $reverse_years = false; /* Should the select boxes be part of an array when returned from PHP? e.g. setting it to "birthday", would create "birthday[Day]", "birthday[Month]" & "birthday[Year]". Can be combined with prefix */ - $field_array = null; + $field_array = null; /* <select size>'s of the different <select> tags. If not set, uses default dropdown. */ - $day_size = null; - $month_size = null; - $year_size = null; + $day_size = null; + $month_size = null; + $year_size = null; /* Unparsed attributes common to *ALL* the <select>/<input> tags. An example might be in the template: all_extra ='class ="foo"'. */ - $all_extra = null; + $all_extra = null; /* Separate attributes for the tags. */ - $day_extra = null; - $month_extra = null; - $year_extra = null; + $day_extra = null; + $month_extra = null; + $year_extra = null; /* Order in which to display the fields. "D" -> day, "M" -> month, "Y" -> year. */ - $field_order = 'MDY'; + $field_order = 'MDY'; /* String printed between the different fields. */ $field_separator = "\n"; - $time = time(); - $all_empty = null; - $day_empty = null; - $month_empty = null; - $year_empty = null; - $extra_attrs = ''; + $option_separator = "\n"; + $time = null; + // $all_empty = null; + // $day_empty = null; + // $month_empty = null; + // $year_empty = null; + $extra_attrs = ''; + $all_id = null; + $day_id = null; + $month_id = null; + $year_id = null; - foreach ($params as $_key=>$_value) { + foreach ($params as $_key => $_value) { switch ($_key) { - case 'prefix': case 'time': + if (!is_array($_value) && $_value !== null) { + $time = smarty_make_timestamp($_value); + } + break; + + case 'month_names': + if (is_array($_value) && count($_value) == 12) { + $$_key = $_value; + } else { + trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE); + } + break; + + case 'prefix': + case 'field_array': case 'start_year': case 'end_year': - case 'month_format': case 'day_format': case 'day_value_format': - case 'field_array': + case 'month_format': + case 'month_value_format': case 'day_size': case 'month_size': case 'year_size': @@ -103,18 +146,18 @@ function smarty_function_html_select_date($params, &$smarty) case 'year_extra': case 'field_order': case 'field_separator': - case 'month_value_format': + case 'option_separator': + case 'all_empty': case 'month_empty': case 'day_empty': case 'year_empty': + case 'all_id': + case 'month_id': + case 'day_id': + case 'year_id': $$_key = (string)$_value; break; - case 'all_empty': - $$_key = (string)$_value; - $day_empty = $month_empty = $year_empty = $all_empty; - break; - case 'display_days': case 'display_months': case 'display_years': @@ -124,208 +167,228 @@ function smarty_function_html_select_date($params, &$smarty) break; default: - if(!is_array($_value)) { - $extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"'; + if (!is_array($_value)) { + $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"'; } else { - $smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE); - } + trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } break; - } - } - - if (preg_match('!^-\d+$!', $time)) { - // negative timestamp, use date() - $time = date('Y-m-d', $time); - } - // If $time is not in format yyyy-mm-dd - if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) { - $time = $found[1]; - } else { - // use smarty_make_timestamp to get an unix timestamp and - // strftime to make yyyy-mm-dd - $time = strftime('%Y-%m-%d', smarty_make_timestamp($time)); + } } - // Now split this in pieces, which later can be used to set the select - $time = explode("-", $time); - - // make syntax "+N" or "-N" work with start_year and end_year - if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) { - if ($match[1] == '+') { - $end_year = strftime('%Y') + $match[2]; + + // Note: date() is faster than strftime() + // Note: explode(date()) is faster than date() date() date() + if (isset($params['time']) && is_array($params['time'])) { + if (isset($params['time'][$prefix . 'Year'])) { + // $_REQUEST[$field_array] given + foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { + $_variableName = '_' . strtolower($_elementName); + $$_variableName = isset($params['time'][$prefix . $_elementName]) + ? $params['time'][$prefix . $_elementName] + : date($_elementKey); + } + $time = mktime(0, 0, 0, $_month, $_day, $_year); + } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) { + // $_REQUEST given + foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { + $_variableName = '_' . strtolower($_elementName); + $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName]) + ? $params['time'][$field_array][$prefix . $_elementName] + : date($_elementKey); + } + $time = mktime(0, 0, 0, $_month, $_day, $_year); } else { - $end_year = strftime('%Y') - $match[2]; + // no date found, use NOW + list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); } - } - if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) { - if ($match[1] == '+') { - $start_year = strftime('%Y') + $match[2]; + } elseif ($time === null) { + if (array_key_exists('time', $params)) { + $_year = $_month = $_day = $time = null; } else { - $start_year = strftime('%Y') - $match[2]; + list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); } + } else { + list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time)); } - if (strlen($time[0]) > 0) { - if ($start_year > $time[0] && !isset($params['start_year'])) { - // force start year to include given date if not explicitly set - $start_year = $time[0]; - } - if($end_year < $time[0] && !isset($params['end_year'])) { - // force end year to include given date if not explicitly set - $end_year = $time[0]; + + // make syntax "+N" or "-N" work with $start_year and $end_year + // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr + foreach (array('start', 'end') as $key) { + $key .= '_year'; + $t = $$key; + if ($t === null) { + $$key = (int)$_current_year; + } else if ($t[0] == '+') { + $$key = (int)($_current_year + trim(substr($t, 1))); + } else if ($t[0] == '-') { + $$key = (int)($_current_year - trim(substr($t, 1))); + } else { + $$key = (int)$$key; } } - $field_order = strtoupper($field_order); - - $html_result = $month_result = $day_result = $year_result = ""; + // flip for ascending or descending + if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) { + $t = $end_year; + $end_year = $start_year; + $start_year = $t; + } - $field_separator_count = -1; - if ($display_months) { - $field_separator_count++; - $month_names = array(); - $month_values = array(); - if(isset($month_empty)) { - $month_names[''] = $month_empty; - $month_values[''] = ''; - } - for ($i = 1; $i <= 12; $i++) { - $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000)); - $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000)); + // generate year <select> or <input> + if ($display_years) { + $_html_years = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; + } + if ($year_extra) { + $_extra .= ' ' . $year_extra; } - - $month_result .= '<select name='; - if (null !== $field_array){ - $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"'; + + if ($year_as_text) { + $_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />'; } else { - $month_result .= '"' . $prefix . 'Month"'; - } - if (null !== $month_size){ - $month_result .= ' size="' . $month_size . '"'; - } - if (null !== $month_extra){ - $month_result .= ' ' . $month_extra; - } - if (null !== $all_extra){ - $month_result .= ' ' . $all_extra; + $_html_years = '<select name="' . $_name . '"'; + if ($year_id !== null || $all_id !== null) { + $_html_years .= ' id="' . smarty_function_escape_special_chars( + $year_id !== null ? ( $year_id ? $year_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; + } + if ($year_size) { + $_html_years .= ' size="' . $year_size . '"'; + } + $_html_years .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($year_empty) || isset($all_empty)) { + $_html_years .= '<option value="">' . ( isset($year_empty) ? $year_empty : $all_empty ) . '</option>' . $option_separator; + } + + $op = $start_year > $end_year ? -1 : 1; + for ($i=$start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) { + $_html_years .= '<option value="' . $i . '"' + . ($_year == $i ? ' selected="selected"' : '') + . '>' . $i . '</option>' . $option_separator; + } + + $_html_years .= '</select>'; } - $month_result .= $extra_attrs . '>'."\n"; - - $month_result .= smarty_function_html_options(array('output' => $month_names, - 'values' => $month_values, - 'selected' => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '', - 'print_result' => false), - $smarty); - $month_result .= '</select>'; } - - if ($display_days) { - $field_separator_count++; - $days = array(); - if (isset($day_empty)) { - $days[''] = $day_empty; - $day_values[''] = ''; + + // generate month <select> or <input> + if ($display_months) { + $_html_month = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; + } + if ($month_extra) { + $_extra .= ' ' . $month_extra; } - for ($i = 1; $i <= 31; $i++) { - $days[] = sprintf($day_format, $i); - $day_values[] = sprintf($day_value_format, $i); + + $_html_months = '<select name="' . $_name . '"'; + if ($month_id !== null || $all_id !== null) { + $_html_months .= ' id="' . smarty_function_escape_special_chars( + $month_id !== null ? ( $month_id ? $month_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; } - - $day_result .= '<select name='; - if (null !== $field_array){ - $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"'; - } else { - $day_result .= '"' . $prefix . 'Day"'; + if ($month_size) { + $_html_months .= ' size="' . $month_size . '"'; + } + $_html_months .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($month_empty) || isset($all_empty)) { + $_html_months .= '<option value="">' . ( isset($month_empty) ? $month_empty : $all_empty ) . '</option>' . $option_separator; } - if (null !== $day_size){ - $day_result .= ' size="' . $day_size . '"'; + + for ($i = 1; $i <= 12; $i++) { + $_val = sprintf('%02d', $i); + $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i])); + $_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]); + $_html_months .= '<option value="' . $_value . '"' + . ($_val == $_month ? ' selected="selected"' : '') + . '>' . $_text . '</option>' . $option_separator; } - if (null !== $all_extra){ - $day_result .= ' ' . $all_extra; + + $_html_months .= '</select>'; + } + + // generate day <select> or <input> + if ($display_days) { + $_html_day = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; + } + if ($day_extra) { + $_extra .= ' ' . $day_extra; } - if (null !== $day_extra){ - $day_result .= ' ' . $day_extra; + + $_html_days = '<select name="' . $_name . '"'; + if ($day_id !== null || $all_id !== null) { + $_html_days .= ' id="' . smarty_function_escape_special_chars( + $day_id !== null ? ( $day_id ? $day_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; } - $day_result .= $extra_attrs . '>'."\n"; - $day_result .= smarty_function_html_options(array('output' => $days, - 'values' => $day_values, - 'selected' => $time[2], - 'print_result' => false), - $smarty); - $day_result .= '</select>'; - } - - if ($display_years) { - $field_separator_count++; - if (null !== $field_array){ - $year_name = $field_array . '[' . $prefix . 'Year]'; - } else { - $year_name = $prefix . 'Year'; + if ($day_size) { + $_html_days .= ' size="' . $day_size . '"'; + } + $_html_days .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($day_empty) || isset($all_empty)) { + $_html_days .= '<option value="">' . ( isset($day_empty) ? $day_empty : $all_empty ) . '</option>' . $option_separator; } - if ($year_as_text) { - $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"'; - if (null !== $all_extra){ - $year_result .= ' ' . $all_extra; - } - if (null !== $year_extra){ - $year_result .= ' ' . $year_extra; - } - $year_result .= '>'; - } else { - $years = range((int)$start_year, (int)$end_year); - if ($reverse_years) { - rsort($years, SORT_NUMERIC); - } else { - sort($years, SORT_NUMERIC); - } - $yearvals = $years; - if(isset($year_empty)) { - array_unshift($years, $year_empty); - array_unshift($yearvals, ''); - } - $year_result .= '<select name="' . $year_name . '"'; - if (null !== $year_size){ - $year_result .= ' size="' . $year_size . '"'; - } - if (null !== $all_extra){ - $year_result .= ' ' . $all_extra; - } - if (null !== $year_extra){ - $year_result .= ' ' . $year_extra; - } - $year_result .= $extra_attrs . '>'."\n"; - $year_result .= smarty_function_html_options(array('output' => $years, - 'values' => $yearvals, - 'selected' => $time[0], - 'print_result' => false), - $smarty); - $year_result .= '</select>'; + + for ($i = 1; $i <= 31; $i++) { + $_val = sprintf('%02d', $i); + $_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i); + $_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i); + $_html_days .= '<option value="' . $_value . '"' + . ($_val == $_day ? ' selected="selected"' : '') + . '>' . $_text . '</option>' . $option_separator; } + + $_html_days .= '</select>'; } - // Loop thru the field_order field - for ($i = 0; $i <= 2; $i++){ - $c = substr($field_order, $i, 1); - switch ($c){ - case 'D': - $html_result .= $day_result; - break; - - case 'M': - $html_result .= $month_result; - break; - + // order the fields for output + $_html = ''; + for ($i=0; $i <= 2; $i++) { + switch ($field_order[$i]) { case 'Y': - $html_result .= $year_result; - break; - } - // Add the field seperator - if($i < $field_separator_count) { - $html_result .= $field_separator; + case 'y': + if (isset($_html_years)) { + if ($_html) { + $_html .= $field_separator; + } + $_html .= $_html_years; + } + break; + + case 'm': + case 'M': + if (isset($_html_months)) { + if ($_html) { + $_html .= $field_separator; + } + $_html .= $_html_months; + } + break; + + case 'd': + case 'D': + if (isset($_html_days)) { + if ($_html) { + $_html .= $field_separator; + } + $_html .= $_html_days; + } + break; } } - - return $html_result; + return $_html; } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_select_time.php b/include/smarty/libs/plugins/function.html_select_time.php index 2e5be7efe..9fb8038e4 100644 --- a/include/smarty/libs/plugins/function.html_select_time.php +++ b/include/smarty/libs/plugins/function.html_select_time.php @@ -1,10 +1,19 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ +/** + * @ignore + */ +require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); +/** + * @ignore + */ +require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); /** * Smarty {html_select_time} function plugin @@ -12,50 +21,102 @@ * Type: function<br> * Name: html_select_time<br> * Purpose: Prints the dropdowns for time selection - * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time} + * + * @link http://www.smarty.net/manual/en/language.function.html.select.time.php {html_select_time} * (Smarty online manual) * @author Roberto Berto <roberto@berto.net> - * @credits Monte Ohrt <monte AT ohrt DOT com> - * @param array - * @param Smarty + * @author Monte Ohrt <monte AT ohrt DOT com> + * @param array $params parameters + * @param Smarty_Internal_Template $template template object * @return string * @uses smarty_make_timestamp() */ -function smarty_function_html_select_time($params, &$smarty) +function smarty_function_html_select_time($params, $template) { - require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); - require_once $smarty->_get_plugin_filepath('function','html_options'); - /* Default values. */ - $prefix = "Time_"; - $time = time(); - $display_hours = true; - $display_minutes = true; - $display_seconds = true; - $display_meridian = true; - $use_24_hours = true; - $minute_interval = 1; - $second_interval = 1; - /* Should the select boxes be part of an array when returned from PHP? - e.g. setting it to "birthday", would create "birthday[Hour]", - "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]". - Can be combined with prefix. */ - $field_array = null; - $all_extra = null; - $hour_extra = null; - $minute_extra = null; - $second_extra = null; - $meridian_extra = null; - - foreach ($params as $_key=>$_value) { + $prefix = "Time_"; + $field_array = null; + $field_separator = "\n"; + $option_separator = "\n"; + $time = null; + + $display_hours = true; + $display_minutes = true; + $display_seconds = true; + $display_meridian = true; + + $hour_format = '%02d'; + $hour_value_format = '%02d'; + $minute_format = '%02d'; + $minute_value_format = '%02d'; + $second_format = '%02d'; + $second_value_format = '%02d'; + + $hour_size = null; + $minute_size = null; + $second_size = null; + $meridian_size = null; + + $all_empty = null; + $hour_empty = null; + $minute_empty = null; + $second_empty = null; + $meridian_empty = null; + + $all_id = null; + $hour_id = null; + $minute_id = null; + $second_id = null; + $meridian_id = null; + + $use_24_hours = true; + $minute_interval = 1; + $second_interval = 1; + + $extra_attrs = ''; + $all_extra = null; + $hour_extra = null; + $minute_extra = null; + $second_extra = null; + $meridian_extra = null; + + foreach ($params as $_key => $_value) { switch ($_key) { - case 'prefix': case 'time': + if (!is_array($_value) && $_value !== null) { + $time = smarty_make_timestamp($_value); + } + break; + + case 'prefix': case 'field_array': + + case 'field_separator': + case 'option_separator': + case 'all_extra': case 'hour_extra': case 'minute_extra': case 'second_extra': case 'meridian_extra': + + case 'all_empty': + case 'hour_empty': + case 'minute_empty': + case 'second_empty': + case 'meridian_empty': + + case 'all_id': + case 'hour_id': + case 'minute_id': + case 'second_id': + case 'meridian_id': + + case 'hour_format': + case 'hour_value_format': + case 'minute_format': + case 'minute_value_format': + case 'second_format': + case 'second_value_format': $$_key = (string)$_value; break; @@ -69,126 +130,237 @@ function smarty_function_html_select_time($params, &$smarty) case 'minute_interval': case 'second_interval': + + case 'hour_size': + case 'minute_size': + case 'second_size': + case 'meridian_size': $$_key = (int)$_value; break; default: - $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING); + if (!is_array($_value)) { + $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"'; + } else { + trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; } } - $time = smarty_make_timestamp($time); - - $html_result = ''; + if (isset($params['time']) && is_array($params['time'])) { + if (isset($params['time'][$prefix . 'Hour'])) { + // $_REQUEST[$field_array] given + foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) { + $_variableName = '_' . strtolower($_elementName); + $$_variableName = isset($params['time'][$prefix . $_elementName]) + ? $params['time'][$prefix . $_elementName] + : date($_elementKey); + } + $_meridian = isset($params['time'][$prefix . 'Meridian']) + ? (' ' . $params['time'][$prefix . 'Meridian']) + : ''; + $time = strtotime( $_hour . ':' . $_minute . ':' . $_second . $_meridian ); + list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time)); + } elseif (isset($params['time'][$field_array][$prefix . 'Hour'])) { + // $_REQUEST given + foreach (array('H' => 'Hour', 'i' => 'Minute', 's' => 'Second') as $_elementKey => $_elementName) { + $_variableName = '_' . strtolower($_elementName); + $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName]) + ? $params['time'][$field_array][$prefix . $_elementName] + : date($_elementKey); + } + $_meridian = isset($params['time'][$field_array][$prefix . 'Meridian']) + ? (' ' . $params['time'][$field_array][$prefix . 'Meridian']) + : ''; + $time = strtotime( $_hour . ':' . $_minute . ':' . $_second . $_meridian ); + list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time)); + } else { + // no date found, use NOW + list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); + } + } elseif ($time === null) { + if (array_key_exists('time', $params)) { + $_hour = $_minute = $_second = $time = null; + } else { + list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s')); + } + } else { + list($_hour, $_minute, $_second) = $time = explode('-', date('H-i-s', $time)); + } + // generate hour <select> if ($display_hours) { - $hours = $use_24_hours ? range(0, 23) : range(1, 12); - $hour_fmt = $use_24_hours ? '%H' : '%I'; - for ($i = 0, $for_max = count($hours); $i < $for_max; $i++) - $hours[$i] = sprintf('%02d', $hours[$i]); - $html_result .= '<select name='; - if (null !== $field_array) { - $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"'; - } else { - $html_result .= '"' . $prefix . 'Hour"'; + $_html_hours = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Hour]') : ($prefix . 'Hour'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; } - if (null !== $hour_extra){ - $html_result .= ' ' . $hour_extra; + if ($hour_extra) { + $_extra .= ' ' . $hour_extra; + } + + $_html_hours = '<select name="' . $_name . '"'; + if ($hour_id !== null || $all_id !== null) { + $_html_hours .= ' id="' . smarty_function_escape_special_chars( + $hour_id !== null ? ( $hour_id ? $hour_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; } - if (null !== $all_extra){ - $html_result .= ' ' . $all_extra; + if ($hour_size) { + $_html_hours .= ' size="' . $hour_size . '"'; + } + $_html_hours .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($hour_empty) || isset($all_empty)) { + $_html_hours .= '<option value="">' . ( isset($hour_empty) ? $hour_empty : $all_empty ) . '</option>' . $option_separator; + } + + $start = $use_24_hours ? 0 : 1; + $end = $use_24_hours ? 23 : 12; + for ($i=$start; $i <= $end; $i++) { + $_val = sprintf('%02d', $i); + $_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i); + $_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i); + + if (!$use_24_hours) { + $_hour12 = $_hour == 0 + ? 12 + : ($_hour <= 12 ? $_hour : $_hour -12); + } + + $selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null; + $_html_hours .= '<option value="' . $_value . '"' + . ($selected ? ' selected="selected"' : '') + . '>' . $_text . '</option>' . $option_separator; } - $html_result .= '>'."\n"; - $html_result .= smarty_function_html_options(array('output' => $hours, - 'values' => $hours, - 'selected' => strftime($hour_fmt, $time), - 'print_result' => false), - $smarty); - $html_result .= "</select>\n"; + + $_html_hours .= '</select>'; } + // generate minute <select> if ($display_minutes) { - $all_minutes = range(0, 59); - for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval) - $minutes[] = sprintf('%02d', $all_minutes[$i]); - $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval); - $html_result .= '<select name='; - if (null !== $field_array) { - $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"'; - } else { - $html_result .= '"' . $prefix . 'Minute"'; - } - if (null !== $minute_extra){ - $html_result .= ' ' . $minute_extra; - } - if (null !== $all_extra){ - $html_result .= ' ' . $all_extra; - } - $html_result .= '>'."\n"; - - $html_result .= smarty_function_html_options(array('output' => $minutes, - 'values' => $minutes, - 'selected' => $selected, - 'print_result' => false), - $smarty); - $html_result .= "</select>\n"; + $_html_minutes = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Minute]') : ($prefix . 'Minute'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; + } + if ($minute_extra) { + $_extra .= ' ' . $minute_extra; + } + + $_html_minutes = '<select name="' . $_name . '"'; + if ($minute_id !== null || $all_id !== null) { + $_html_minutes .= ' id="' . smarty_function_escape_special_chars( + $minute_id !== null ? ( $minute_id ? $minute_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; + } + if ($minute_size) { + $_html_minutes .= ' size="' . $minute_size . '"'; + } + $_html_minutes .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($minute_empty) || isset($all_empty)) { + $_html_minutes .= '<option value="">' . ( isset($minute_empty) ? $minute_empty : $all_empty ) . '</option>' . $option_separator; + } + + $selected = $_minute !== null ? ($_minute - $_minute % $minute_interval) : null; + for ($i=0; $i <= 59; $i += $minute_interval) { + $_val = sprintf('%02d', $i); + $_text = $minute_format == '%02d' ? $_val : sprintf($minute_format, $i); + $_value = $minute_value_format == '%02d' ? $_val : sprintf($minute_value_format, $i); + $_html_minutes .= '<option value="' . $_value . '"' + . ($selected === $i ? ' selected="selected"' : '') + . '>' . $_text . '</option>' . $option_separator; + } + + $_html_minutes .= '</select>'; } + // generate second <select> if ($display_seconds) { - $all_seconds = range(0, 59); - for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval) - $seconds[] = sprintf('%02d', $all_seconds[$i]); - $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval); - $html_result .= '<select name='; - if (null !== $field_array) { - $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"'; - } else { - $html_result .= '"' . $prefix . 'Second"'; - } - - if (null !== $second_extra){ - $html_result .= ' ' . $second_extra; - } - if (null !== $all_extra){ - $html_result .= ' ' . $all_extra; - } - $html_result .= '>'."\n"; - - $html_result .= smarty_function_html_options(array('output' => $seconds, - 'values' => $seconds, - 'selected' => $selected, - 'print_result' => false), - $smarty); - $html_result .= "</select>\n"; + $_html_seconds = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Second]') : ($prefix . 'Second'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; + } + if ($second_extra) { + $_extra .= ' ' . $second_extra; + } + + $_html_seconds = '<select name="' . $_name . '"'; + if ($second_id !== null || $all_id !== null) { + $_html_seconds .= ' id="' . smarty_function_escape_special_chars( + $second_id !== null ? ( $second_id ? $second_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; + } + if ($second_size) { + $_html_seconds .= ' size="' . $second_size . '"'; + } + $_html_seconds .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($second_empty) || isset($all_empty)) { + $_html_seconds .= '<option value="">' . ( isset($second_empty) ? $second_empty : $all_empty ) . '</option>' . $option_separator; + } + + $selected = $_second !== null ? ($_second - $_second % $second_interval) : null; + for ($i=0; $i <= 59; $i += $second_interval) { + $_val = sprintf('%02d', $i); + $_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i); + $_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i); + $_html_seconds .= '<option value="' . $_value . '"' + . ($selected === $i ? ' selected="selected"' : '') + . '>' . $_text . '</option>' . $option_separator; + } + + $_html_seconds .= '</select>'; } + // generate meridian <select> if ($display_meridian && !$use_24_hours) { - $html_result .= '<select name='; - if (null !== $field_array) { - $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"'; - } else { - $html_result .= '"' . $prefix . 'Meridian"'; - } - - if (null !== $meridian_extra){ - $html_result .= ' ' . $meridian_extra; - } - if (null !== $all_extra){ - $html_result .= ' ' . $all_extra; - } - $html_result .= '>'."\n"; - - $html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'), - 'values' => array('am', 'pm'), - 'selected' => strtolower(strftime('%p', $time)), - 'print_result' => false), - $smarty); - $html_result .= "</select>\n"; + $_html_meridian = ''; + $_extra = ''; + $_name = $field_array ? ($field_array . '[' . $prefix . 'Meridian]') : ($prefix . 'Meridian'); + if ($all_extra) { + $_extra .= ' ' . $all_extra; + } + if ($meridian_extra) { + $_extra .= ' ' . $meridian_extra; + } + + $_html_meridian = '<select name="' . $_name . '"'; + if ($meridian_id !== null || $all_id !== null) { + $_html_meridian .= ' id="' . smarty_function_escape_special_chars( + $meridian_id !== null ? ( $meridian_id ? $meridian_id : $_name ) : ( $all_id ? ($all_id . $_name) : $_name ) + ) . '"'; + } + if ($meridian_size) { + $_html_meridian .= ' size="' . $meridian_size . '"'; + } + $_html_meridian .= $_extra . $extra_attrs . '>' . $option_separator; + + if (isset($meridian_empty) || isset($all_empty)) { + $_html_meridian .= '<option value="">' . ( isset($meridian_empty) ? $meridian_empty : $all_empty ) . '</option>' . $option_separator; + } + + $_html_meridian .= '<option value="am"'. ($_hour < 12 ? ' selected="selected"' : '') .'>AM</option>' . $option_separator + . '<option value="pm"'. ($_hour < 12 ? '' : ' selected="selected"') .'>PM</option>' . $option_separator + . '</select>'; } - return $html_result; -} + $_html = ''; + foreach (array('_html_hours', '_html_minutes', '_html_seconds', '_html_meridian') as $k) { + if (isset($$k)) { + if ($_html) { + $_html .= $field_separator; + } + $_html .= $$k; + } + } -/* vim: set expandtab: */ + return $_html; +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.html_table.php b/include/smarty/libs/plugins/function.html_table.php index 32aeba83c..6b9cb9d12 100644 --- a/include/smarty/libs/plugins/function.html_table.php +++ b/include/smarty/libs/plugins/function.html_table.php @@ -1,11 +1,11 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {html_table} function plugin * @@ -13,40 +13,41 @@ * Name: html_table<br> * Date: Feb 17, 2003<br> * Purpose: make an html table from an array of data<br> - * Input:<br> - * - loop = array to loop through - * - cols = number of columns, comma separated list of column names - * or array of column names - * - rows = number of rows - * - table_attr = table attributes - * - th_attr = table heading attributes (arrays are cycled) - * - tr_attr = table row attributes (arrays are cycled) - * - td_attr = table cell attributes (arrays are cycled) - * - trailpad = value to pad trailing cells with - * - caption = text for caption element - * - vdir = vertical direction (default: "down", means top-to-bottom) - * - hdir = horizontal direction (default: "right", means left-to-right) - * - inner = inner loop (default "cols": print $loop line by line, - * $loop will be printed column by column otherwise) - * - * + * Params: + * <pre> + * - loop - array to loop through + * - cols - number of columns, comma separated list of column names + * or array of column names + * - rows - number of rows + * - table_attr - table attributes + * - th_attr - table heading attributes (arrays are cycled) + * - tr_attr - table row attributes (arrays are cycled) + * - td_attr - table cell attributes (arrays are cycled) + * - trailpad - value to pad trailing cells with + * - caption - text for caption element + * - vdir - vertical direction (default: "down", means top-to-bottom) + * - hdir - horizontal direction (default: "right", means left-to-right) + * - inner - inner loop (default "cols": print $loop line by line, + * $loop will be printed column by column otherwise) + * </pre> * Examples: * <pre> * {table loop=$data} * {table loop=$data cols=4 tr_attr='"bgcolor=red"'} * {table loop=$data cols="first,second,third" tr_attr=$colors} * </pre> - * @author Monte Ohrt <monte at ohrt dot com> + * + * @author Monte Ohrt <monte at ohrt dot com> * @author credit to Messju Mohr <messju at lammfellpuschen dot de> * @author credit to boots <boots dot smarty at yahoo dot com> - * @version 1.1 - * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table} + * @version 1.1 + * @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table} * (Smarty online manual) - * @param array - * @param Smarty + * @param array $params parameters + * @param Smarty_Internal_Template $template template object * @return string */ -function smarty_function_html_table($params, &$smarty) +function smarty_function_html_table($params, $template) { $table_attr = 'border="1"'; $tr_attr = ''; @@ -59,13 +60,14 @@ function smarty_function_html_table($params, &$smarty) $hdir = 'right'; $inner = 'cols'; $caption = ''; + $loop = null; if (!isset($params['loop'])) { - $smarty->trigger_error("html_table: missing 'loop' parameter"); + trigger_error("html_table: missing 'loop' parameter",E_USER_WARNING); return; } - foreach ($params as $_key=>$_value) { + foreach ($params as $_key => $_value) { switch ($_key) { case 'loop': $$_key = (array)$_value; @@ -109,11 +111,11 @@ function smarty_function_html_table($params, &$smarty) $loop_count = count($loop); if (empty($params['rows'])) { /* no rows specified */ - $rows = ceil($loop_count/$cols_count); + $rows = ceil($loop_count / $cols_count); } elseif (empty($params['cols'])) { if (!empty($params['rows'])) { /* no cols specified, but rows */ - $cols_count = ceil($loop_count/$rows); + $cols_count = ceil($loop_count / $rows); } } @@ -127,7 +129,7 @@ function smarty_function_html_table($params, &$smarty) $cols = ($hdir == 'right') ? $cols : array_reverse($cols); $output .= "<thead><tr>\n"; - for ($r=0; $r<$cols_count; $r++) { + for ($r = 0; $r < $cols_count; $r++) { $output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>'; $output .= $cols[$r]; $output .= "</th>\n"; @@ -136,18 +138,18 @@ function smarty_function_html_table($params, &$smarty) } $output .= "<tbody>\n"; - for ($r=0; $r<$rows; $r++) { + for ($r = 0; $r < $rows; $r++) { $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n"; - $rx = ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count; + $rx = ($vdir == 'down') ? $r * $cols_count : ($rows-1 - $r) * $cols_count; - for ($c=0; $c<$cols_count; $c++) { - $x = ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c; - if ($inner!='cols') { + for ($c = 0; $c < $cols_count; $c++) { + $x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count-1 - $c; + if ($inner != 'cols') { /* shuffle x to loop over rows*/ - $x = floor($x/$cols_count) + ($x%$cols_count)*$rows; + $x = floor($x / $cols_count) + ($x % $cols_count) * $rows; } - if ($x<$loop_count) { + if ($x < $loop_count) { $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n"; } else { $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n"; @@ -157,21 +159,19 @@ function smarty_function_html_table($params, &$smarty) } $output .= "</tbody>\n"; $output .= "</table>\n"; - + return $output; } -function smarty_function_html_table_cycle($name, $var, $no) { - if(!is_array($var)) { +function smarty_function_html_table_cycle($name, $var, $no) +{ + if (!is_array($var)) { $ret = $var; } else { $ret = $var[$no % count($var)]; } - - return ($ret) ? ' '.$ret : ''; -} - -/* vim: set expandtab: */ + return ($ret) ? ' ' . $ret : ''; +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.mailto.php b/include/smarty/libs/plugins/function.mailto.php index 20e9ed984..55d5c0602 100644 --- a/include/smarty/libs/plugins/function.mailto.php +++ b/include/smarty/libs/plugins/function.mailto.php @@ -1,34 +1,34 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {mailto} function plugin * * Type: function<br> * Name: mailto<br> * Date: May 21, 2002 - * Purpose: automate mailto address link creation, and optionally - * encode them.<br> - * Input:<br> - * - address = e-mail address - * - text = (optional) text to display, default is address - * - encode = (optional) can be one of: - * * none : no encoding (default) - * * javascript : encode with javascript - * * javascript_charcode : encode with javascript charcode - * * hex : encode with hexidecimal (no javascript) - * - cc = (optional) address(es) to carbon copy - * - bcc = (optional) address(es) to blind carbon copy - * - subject = (optional) e-mail subject - * - newsgroups = (optional) newsgroup(s) to post to - * - followupto = (optional) address(es) to follow up to - * - extra = (optional) extra tags for the href link - * + * Purpose: automate mailto address link creation, and optionally encode them.<br> + * Params: + * <pre> + * - address - (required) - e-mail address + * - text - (optional) - text to display, default is address + * - encode - (optional) - can be one of: + * * none : no encoding (default) + * * javascript : encode with javascript + * * javascript_charcode : encode with javascript charcode + * * hex : encode with hexidecimal (no javascript) + * - cc - (optional) - address(es) to carbon copy + * - bcc - (optional) - address(es) to blind carbon copy + * - subject - (optional) - e-mail subject + * - newsgroups - (optional) - newsgroup(s) to post to + * - followupto - (optional) - address(es) to follow up to + * - extra - (optional) - extra tags for the href link + * </pre> * Examples: * <pre> * {mailto address="me@domain.com"} @@ -38,45 +38,46 @@ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"} * {mailto address="me@domain.com" extra='class="mailto"'} * </pre> - * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto} + * + * @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto} * (Smarty online manual) - * @version 1.2 - * @author Monte Ohrt <monte at ohrt dot com> - * @author credits to Jason Sweat (added cc, bcc and subject functionality) - * @param array - * @param Smarty - * @return string + * @version 1.2 + * @author Monte Ohrt <monte at ohrt dot com> + * @author credits to Jason Sweat (added cc, bcc and subject functionality) + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string */ -function smarty_function_mailto($params, &$smarty) +function smarty_function_mailto($params, $template) { + static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true); $extra = ''; if (empty($params['address'])) { - $smarty->trigger_error("mailto: missing 'address' parameter"); + trigger_error("mailto: missing 'address' parameter",E_USER_WARNING); return; } else { $address = $params['address']; } $text = $address; - // netscape and mozilla do not decode %40 (@) in BCC field (bug?) // so, don't encode it. $search = array('%40', '%2C'); - $replace = array('@', ','); + $replace = array('@', ','); $mail_parms = array(); - foreach ($params as $var=>$value) { + foreach ($params as $var => $value) { switch ($var) { case 'cc': case 'bcc': case 'followupto': if (!empty($value)) - $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value)); + $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value)); break; - + case 'subject': case 'newsgroups': - $mail_parms[] = $var.'='.rawurlencode($value); + $mail_parms[] = $var . '=' . rawurlencode($value); break; case 'extra': @@ -87,79 +88,65 @@ function smarty_function_mailto($params, &$smarty) } } - $mail_parm_vals = ''; - for ($i=0; $i<count($mail_parms); $i++) { - $mail_parm_vals .= (0==$i) ? '?' : '&'; - $mail_parm_vals .= $mail_parms[$i]; + if ($mail_parms) { + $address .= '?' . join('&', $mail_parms); } - $address .= $mail_parm_vals; - + $encode = (empty($params['encode'])) ? 'none' : $params['encode']; - if (!in_array($encode,array('javascript','javascript_charcode','hex','none')) ) { - $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex"); + if (!isset($_allowed_encoding[$encode])) { + trigger_error("mailto: 'encode' parameter must be none, javascript, javascript_charcode or hex", E_USER_WARNING); return; } - - if ($encode == 'javascript' ) { - $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');'; + // FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed! + if ($encode == 'javascript') { + $string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');'; $js_encode = ''; - for ($x=0; $x < strlen($string); $x++) { + for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { $js_encode .= '%' . bin2hex($string[$x]); } - return '<script type="text/javascript">eval(unescape(\''.$js_encode.'\'))</script>'; - - } elseif ($encode == 'javascript_charcode' ) { - $string = '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>'; + return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>'; + } elseif ($encode == 'javascript_charcode') { + $string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>'; - for($x = 0, $y = strlen($string); $x < $y; $x++ ) { - $ord[] = ord($string[$x]); + for($x = 0, $y = strlen($string); $x < $y; $x++) { + $ord[] = ord($string[$x]); } - $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n"; - $_ret .= "<!--\n"; - $_ret .= "{document.write(String.fromCharCode("; - $_ret .= implode(',',$ord); - $_ret .= "))"; - $_ret .= "}\n"; - $_ret .= "//-->\n"; - $_ret .= "</script>\n"; - + $_ret = "<script type=\"text/javascript\" language=\"javascript\">\n" + . "{document.write(String.fromCharCode(" + . implode(',', $ord) + . "))" + . "}\n" + . "</script>\n"; + return $_ret; - - } elseif ($encode == 'hex') { - - preg_match('!^(.*)(\?.*)$!',$address,$match); - if(!empty($match[2])) { - $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript."); + preg_match('!^(.*)(\?.*)$!', $address, $match); + if (!empty($match[2])) { + trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.",E_USER_WARNING); return; } $address_encode = ''; - for ($x=0; $x < strlen($address); $x++) { - if(preg_match('!\w!',$address[$x])) { + for ($x = 0, $_length = strlen($address); $x < $_length; $x++) { + if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) { $address_encode .= '%' . bin2hex($address[$x]); } else { $address_encode .= $address[$x]; } } $text_encode = ''; - for ($x=0; $x < strlen($text); $x++) { - $text_encode .= '&#x' . bin2hex($text[$x]).';'; + for ($x = 0, $_length = strlen($text); $x < $_length; $x++) { + $text_encode .= '&#x' . bin2hex($text[$x]) . ';'; } $mailto = "mailto:"; - return '<a href="'.$mailto.$address_encode.'" '.$extra.'>'.$text_encode.'</a>'; - + return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>'; } else { // no encoding - return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>'; - + return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>'; } - } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.math.php b/include/smarty/libs/plugins/function.math.php index bb78dac22..f4d3f05ee 100644 --- a/include/smarty/libs/plugins/function.math.php +++ b/include/smarty/libs/plugins/function.math.php @@ -1,49 +1,53 @@ <?php /** * Smarty plugin + * + * This plugin is only for Smarty2 BC * @package Smarty - * @subpackage plugins + * @subpackage PluginsFunction */ - /** * Smarty {math} function plugin * * Type: function<br> * Name: math<br> - * Purpose: handle math computations in template<br> - * @link http://smarty.php.net/manual/en/language.function.math.php {math} + * Purpose: handle math computations in template + * + * @link http://www.smarty.net/manual/en/language.function.math.php {math} * (Smarty online manual) * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - * @return string + * @param array $params parameters + * @param Smarty_Internal_Template $template template object + * @return string|null */ -function smarty_function_math($params, &$smarty) +function smarty_function_math($params, $template) { + static $_allowed_funcs = array( + 'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, + 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, + 'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true ,'tan' => true + ); // be sure equation parameter is present if (empty($params['equation'])) { - $smarty->trigger_error("math: missing equation parameter"); + trigger_error("math: missing equation parameter",E_USER_WARNING); return; } - // strip out backticks, not necessary for math - $equation = str_replace('`','',$params['equation']); + $equation = $params['equation']; // make sure parenthesis are balanced if (substr_count($equation,"(") != substr_count($equation,")")) { - $smarty->trigger_error("math: unbalanced parenthesis"); + trigger_error("math: unbalanced parenthesis",E_USER_WARNING); return; } // match all vars in equation, make sure all are passed - preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match); - $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10', - 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan'); - + preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match); + foreach($match[1] as $curr_var) { - if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) { - $smarty->trigger_error("math: function call $curr_var not allowed"); + if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) { + trigger_error("math: function call $curr_var not allowed",E_USER_WARNING); return; } } @@ -52,34 +56,32 @@ function smarty_function_math($params, &$smarty) if ($key != "equation" && $key != "format" && $key != "assign") { // make sure value is not empty if (strlen($val)==0) { - $smarty->trigger_error("math: parameter $key is empty"); + trigger_error("math: parameter $key is empty",E_USER_WARNING); return; } if (!is_numeric($val)) { - $smarty->trigger_error("math: parameter $key: is not numeric"); + trigger_error("math: parameter $key: is not numeric",E_USER_WARNING); return; } $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation); } } - + $smarty_math_result = null; eval("\$smarty_math_result = ".$equation.";"); if (empty($params['format'])) { if (empty($params['assign'])) { return $smarty_math_result; } else { - $smarty->assign($params['assign'],$smarty_math_result); + $template->assign($params['assign'],$smarty_math_result); } } else { if (empty($params['assign'])){ printf($params['format'],$smarty_math_result); } else { - $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result)); + $template->assign($params['assign'],sprintf($params['format'],$smarty_math_result)); } } } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/function.popup.php b/include/smarty/libs/plugins/function.popup.php deleted file mode 100644 index 3a76b785a..000000000 --- a/include/smarty/libs/plugins/function.popup.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty {popup} function plugin - * - * Type: function<br> - * Name: popup<br> - * Purpose: make text pop up in windows via overlib - * @link http://smarty.php.net/manual/en/language.function.popup.php {popup} - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - * @return string - */ -function smarty_function_popup($params, &$smarty) -{ - $append = ''; - foreach ($params as $_key=>$_value) { - switch ($_key) { - case 'text': - case 'trigger': - case 'function': - case 'inarray': - $$_key = (string)$_value; - if ($_key == 'function' || $_key == 'inarray') - $append .= ',' . strtoupper($_key) . ",'$_value'"; - break; - - case 'caption': - case 'closetext': - case 'status': - $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'"; - break; - - case 'fgcolor': - case 'bgcolor': - case 'textcolor': - case 'capcolor': - case 'closecolor': - case 'textfont': - case 'captionfont': - case 'closefont': - case 'fgbackground': - case 'bgbackground': - case 'caparray': - case 'capicon': - case 'background': - case 'frame': - $append .= ',' . strtoupper($_key) . ",'$_value'"; - break; - - case 'textsize': - case 'captionsize': - case 'closesize': - case 'width': - case 'height': - case 'border': - case 'offsetx': - case 'offsety': - case 'snapx': - case 'snapy': - case 'fixx': - case 'fixy': - case 'padx': - case 'pady': - case 'timeout': - case 'delay': - $append .= ',' . strtoupper($_key) . ",$_value"; - break; - - case 'sticky': - case 'left': - case 'right': - case 'center': - case 'above': - case 'below': - case 'noclose': - case 'autostatus': - case 'autostatuscap': - case 'fullhtml': - case 'hauto': - case 'vauto': - case 'mouseoff': - case 'followmouse': - case 'closeclick': - if ($_value) $append .= ',' . strtoupper($_key); - break; - - default: - $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING); - } - } - - if (empty($text) && !isset($inarray) && empty($function)) { - $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required"); - return false; - } - - if (empty($trigger)) { $trigger = "onmouseover"; } - - $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\''; - $retval .= $append . ');"'; - if ($trigger == 'onmouseover') - $retval .= ' onmouseout="nd();"'; - - - return $retval; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/function.popup_init.php b/include/smarty/libs/plugins/function.popup_init.php deleted file mode 100644 index 93cb45450..000000000 --- a/include/smarty/libs/plugins/function.popup_init.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty {popup_init} function plugin - * - * Type: function<br> - * Name: popup_init<br> - * Purpose: initialize overlib - * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init} - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param array - * @param Smarty - * @return string - */ -function smarty_function_popup_init($params, &$smarty) -{ - $zindex = 1000; - - if (!empty($params['zindex'])) { - $zindex = $params['zindex']; - } - - if (!empty($params['src'])) { - return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n" - . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n"; - } else { - $smarty->trigger_error("popup_init: missing src parameter"); - } -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.capitalize.php b/include/smarty/libs/plugins/modifier.capitalize.php index 4a611d9f0..a78e3632a 100644 --- a/include/smarty/libs/plugins/modifier.capitalize.php +++ b/include/smarty/libs/plugins/modifier.capitalize.php @@ -1,43 +1,65 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ - /** * Smarty capitalize modifier plugin - * + * * Type: modifier<br> * Name: capitalize<br> * Purpose: capitalize words in the string - * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE - * capitalize (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return string + * + * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }} + * + * @param string $string string to capitalize + * @param boolean $uc_digits also capitalize "x123" to "X123" + * @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa" + * @return string capitalized string + * @author Monte Ohrt <monte at ohrt dot com> + * @author Rodney Rehm */ -function smarty_modifier_capitalize($string, $uc_digits = false) -{ - smarty_modifier_capitalize_ucfirst(null, $uc_digits); - return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string); -} - -function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null) +function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false) { - static $_uc_digits = false; - - if(isset($uc_digits)) { - $_uc_digits = $uc_digits; - return; + if (Smarty::$_MBSTRING) { + if ($lc_rest) { + // uppercase (including hyphenated words) + $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET ); + } else { + // uppercase word breaks + $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); + } + // check uc_digits case + if (!$uc_digits) { + if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { + foreach($matches[1] as $match) { + $upper_string = substr_replace($upper_string, mb_strtolower($match[0], Smarty::$_CHARSET), $match[1], strlen($match[0])); + } + } + } + $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); + return $upper_string; } - if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits) - return ucfirst($string[0]); - else - return $string[0]; -} - + // lowercase first + if ($lc_rest) { + $string = strtolower($string); + } + // uppercase (including hyphenated words) + $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string); + // check uc_digits case + if (!$uc_digits) { + if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { + foreach($matches[1] as $match) { + $upper_string = substr_replace($upper_string, strtolower($match[0]), $match[1], strlen($match[0])); + } + } + } + $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string); + return $upper_string; +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.cat.php b/include/smarty/libs/plugins/modifier.cat.php deleted file mode 100644 index 2e37940d4..000000000 --- a/include/smarty/libs/plugins/modifier.cat.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty cat modifier plugin - * - * Type: modifier<br> - * Name: cat<br> - * Date: Feb 24, 2003 - * Purpose: catenate a value to a variable - * Input: string to catenate - * Example: {$var|cat:"foo"} - * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat - * (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @version 1.0 - * @param string - * @param string - * @return string - */ -function smarty_modifier_cat($string, $cat) -{ - return $string . $cat; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.count_characters.php b/include/smarty/libs/plugins/modifier.count_characters.php deleted file mode 100644 index 5ed9a87cd..000000000 --- a/include/smarty/libs/plugins/modifier.count_characters.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty count_characters modifier plugin - * - * Type: modifier<br> - * Name: count_characteres<br> - * Purpose: count the number of characters in a text - * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php - * count_characters (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param boolean include whitespace in the character count - * @return integer - */ -function smarty_modifier_count_characters($string, $include_spaces = false) -{ - if ($include_spaces) - return(strlen($string)); - - return preg_match_all("/[^\s]/",$string, $match); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.count_paragraphs.php b/include/smarty/libs/plugins/modifier.count_paragraphs.php deleted file mode 100644 index e0e274da7..000000000 --- a/include/smarty/libs/plugins/modifier.count_paragraphs.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty count_paragraphs modifier plugin - * - * Type: modifier<br> - * Name: count_paragraphs<br> - * Purpose: count the number of paragraphs in a text - * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php - * count_paragraphs (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return integer - */ -function smarty_modifier_count_paragraphs($string) -{ - // count \r or \n characters - return count(preg_split('/[\r\n]+/', $string)); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.count_sentences.php b/include/smarty/libs/plugins/modifier.count_sentences.php deleted file mode 100644 index f66ea1703..000000000 --- a/include/smarty/libs/plugins/modifier.count_sentences.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty count_sentences modifier plugin - * - * Type: modifier<br> - * Name: count_sentences - * Purpose: count the number of sentences in a text - * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php - * count_sentences (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return integer - */ -function smarty_modifier_count_sentences($string) -{ - // find periods with a word before but not after. - return preg_match_all('/[^\s]\.(?!\w)/', $string, $match); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.count_words.php b/include/smarty/libs/plugins/modifier.count_words.php deleted file mode 100644 index 9d339f542..000000000 --- a/include/smarty/libs/plugins/modifier.count_words.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty count_words modifier plugin - * - * Type: modifier<br> - * Name: count_words<br> - * Purpose: count the number of words in a text - * @link http://smarty.php.net/manual/en/language.modifier.count.words.php - * count_words (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return integer - */ -function smarty_modifier_count_words($string) -{ - // split text by ' ',\r,\n,\f,\t - $split_array = preg_split('/\s+/',$string); - // count matches that contain alphanumerics - $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array); - - return count($word_count); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.date_format.php b/include/smarty/libs/plugins/modifier.date_format.php index 8cf7d5e14..f3eaba057 100644 --- a/include/smarty/libs/plugins/modifier.date_format.php +++ b/include/smarty/libs/plugins/modifier.date_format.php @@ -1,58 +1,65 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ /** - * Include the {@link shared.make_timestamp.php} plugin - */ -require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp'); -/** * Smarty date_format modifier plugin - * + * * Type: modifier<br> * Name: date_format<br> * Purpose: format datestamps via strftime<br> * Input:<br> - * - string: input date string - * - format: strftime format for output - * - default_date: default date if $string is empty - * @link http://smarty.php.net/manual/en/language.modifier.date.format.php - * date_format (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param string - * @param string - * @return string|void + * - string: input date string + * - format: strftime format for output + * - default_date: default date if $string is empty + * + * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string input date string + * @param string $format strftime format for output + * @param string $default_date default date if $string is empty + * @param string $formatter either 'strftime' or 'auto' + * @return string |void * @uses smarty_make_timestamp() */ -function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '') +function smarty_modifier_date_format($string, $format=null, $default_date='', $formatter='auto') { - if ($string != '') { + if ($format === null) { + $format = Smarty::$_DATE_FORMAT; + } + /** + * Include the {@link shared.make_timestamp.php} plugin + */ + require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); + if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') { $timestamp = smarty_make_timestamp($string); } elseif ($default_date != '') { $timestamp = smarty_make_timestamp($default_date); } else { return; + } + if($formatter=='strftime'||($formatter=='auto'&&strpos($format,'%')!==false)) { + if (DS == '\\') { + $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); + $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S'); + if (strpos($format, '%e') !== false) { + $_win_from[] = '%e'; + $_win_to[] = sprintf('%\' 2d', date('j', $timestamp)); + } + if (strpos($format, '%l') !== false) { + $_win_from[] = '%l'; + $_win_to[] = sprintf('%\' 2d', date('h', $timestamp)); + } + $format = str_replace($_win_from, $_win_to, $format); + } + return strftime($format, $timestamp); + } else { + return date($format, $timestamp); } - if (DIRECTORY_SEPARATOR == '\\') { - $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); - $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S'); - if (strpos($format, '%e') !== false) { - $_win_from[] = '%e'; - $_win_to[] = sprintf('%\' 2d', date('j', $timestamp)); - } - if (strpos($format, '%l') !== false) { - $_win_from[] = '%l'; - $_win_to[] = sprintf('%\' 2d', date('h', $timestamp)); - } - $format = str_replace($_win_from, $_win_to, $format); - } - return strftime($format, $timestamp); -} - -/* vim: set expandtab: */ +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.debug_print_var.php b/include/smarty/libs/plugins/modifier.debug_print_var.php index e4f7bc0cc..fa44100e8 100644 --- a/include/smarty/libs/plugins/modifier.debug_print_var.php +++ b/include/smarty/libs/plugins/modifier.debug_print_var.php @@ -1,53 +1,53 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage Debug */ - /** * Smarty debug_print_var modifier plugin - * + * * Type: modifier<br> * Name: debug_print_var<br> * Purpose: formats variable contents for display in the console - * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php - * debug_print_var (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param array|object - * @param integer - * @param integer - * @return string + * + * @author Monte Ohrt <monte at ohrt dot com> + * @param array|object $var variable to be formatted + * @param integer $depth maximum recursion depth if $var is an array + * @param integer $length maximum string length if $var is a string + * @return string */ -function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) +function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40) { - $_replace = array( - "\n" => '<i>\n</i>', + $_replace = array("\n" => '<i>\n</i>', "\r" => '<i>\r</i>', "\t" => '<i>\t</i>' - ); + ); switch (gettype($var)) { case 'array' : $results = '<b>Array (' . count($var) . ')</b>'; foreach ($var as $curr_key => $curr_val) { $results .= '<br>' . str_repeat(' ', $depth * 2) - . '<b>' . strtr($curr_key, $_replace) . '</b> => ' - . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); - $depth--; - } + . '<b>' . strtr($curr_key, $_replace) . '</b> => ' + . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); + $depth--; + } break; + case 'object' : $object_vars = get_object_vars($var); $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>'; foreach ($object_vars as $curr_key => $curr_val) { $results .= '<br>' . str_repeat(' ', $depth * 2) - . '<b> ->' . strtr($curr_key, $_replace) . '</b> = ' - . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); - $depth--; - } + . '<b> ->' . strtr($curr_key, $_replace) . '</b> = ' + . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); + $depth--; + } break; + case 'boolean' : case 'NULL' : case 'resource' : @@ -59,32 +59,47 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) $results = 'null'; } else { $results = htmlspecialchars((string) $var); - } + } $results = '<i>' . $results . '</i>'; break; + case 'integer' : case 'float' : $results = htmlspecialchars((string) $var); break; + case 'string' : $results = strtr($var, $_replace); - if (strlen($var) > $length ) { - $results = substr($var, 0, $length - 3) . '...'; + if (Smarty::$_MBSTRING) { + if (mb_strlen($var, Smarty::$_CHARSET) > $length) { + $results = mb_substr($var, 0, $length - 3, Smarty::$_CHARSET) . '...'; + } + } else { + if (isset($var[$length])) { + $results = substr($var, 0, $length - 3) . '...'; + } } + $results = htmlspecialchars('"' . $results . '"'); break; + case 'unknown type' : default : $results = strtr((string) $var, $_replace); - if (strlen($results) > $length ) { - $results = substr($results, 0, $length - 3) . '...'; + if (Smarty::$_MBSTRING) { + if (mb_strlen($results, Smarty::$_CHARSET) > $length) { + $results = mb_substr($results, 0, $length - 3, Smarty::$_CHARSET) . '...'; + } + } else { + if (strlen($results) > $length) { + $results = substr($results, 0, $length - 3) . '...'; + } } + $results = htmlspecialchars($results); - } + } return $results; -} - -/* vim: set expandtab: */ +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.default.php b/include/smarty/libs/plugins/modifier.default.php deleted file mode 100644 index 70011fd6b..000000000 --- a/include/smarty/libs/plugins/modifier.default.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty default modifier plugin - * - * Type: modifier<br> - * Name: default<br> - * Purpose: designate default value for empty variables - * @link http://smarty.php.net/manual/en/language.modifier.default.php - * default (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param string - * @return string - */ -function smarty_modifier_default($string, $default = '') -{ - if (!isset($string) || $string === '') - return $default; - else - return $string; -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.escape.php b/include/smarty/libs/plugins/modifier.escape.php index a2f52b232..5ca8e7796 100644 --- a/include/smarty/libs/plugins/modifier.escape.php +++ b/include/smarty/libs/plugins/modifier.escape.php @@ -1,93 +1,188 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ - /** * Smarty escape modifier plugin * * Type: modifier<br> * Name: escape<br> - * Purpose: Escape the string according to escapement type - * @link http://smarty.php.net/manual/en/language.modifier.escape.php - * escape (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param html|htmlall|url|quotes|hex|hexentity|javascript - * @return string + * Purpose: escape string for output + * + * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string input string + * @param string $esc_type escape type + * @param string $char_set character set, used for htmlspecialchars() or htmlentities() + * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities() + * @return string escaped input string */ -function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1') +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) { + static $_double_encode = null; + if ($_double_encode === null) { + $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>='); + } + + if (!$char_set) { + $char_set = Smarty::$_CHARSET; + } + switch ($esc_type) { case 'html': - return htmlspecialchars($string, ENT_QUOTES, $char_set); + if ($_double_encode) { + // php >=5.3.2 - go native + return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); + } else { + if ($double_encode) { + // php <5.2.3 - only handle double encoding + return htmlspecialchars($string, ENT_QUOTES, $char_set); + } else { + // php <5.2.3 - prevent double encoding + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlspecialchars($string, ENT_QUOTES, $char_set); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + return $string; + } + } case 'htmlall': - return htmlentities($string, ENT_QUOTES, $char_set); + if (Smarty::$_MBSTRING) { + // mb_convert_encoding ignores htmlspecialchars() + if ($_double_encode) { + // php >=5.3.2 - go native + $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); + } else { + if ($double_encode) { + // php <5.2.3 - only handle double encoding + $string = htmlspecialchars($string, ENT_QUOTES, $char_set); + } else { + // php <5.2.3 - prevent double encoding + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlspecialchars($string, ENT_QUOTES, $char_set); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + return $string; + } + } + + // htmlentities() won't convert everything, so use mb_convert_encoding + return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set); + } + + // no MBString fallback + if ($_double_encode) { + return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); + } else { + if ($double_encode) { + return htmlentities($string, ENT_QUOTES, $char_set); + } else { + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlentities($string, ENT_QUOTES, $char_set); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + return $string; + } + } case 'url': return rawurlencode($string); case 'urlpathinfo': - return str_replace('%2F','/',rawurlencode($string)); - + return str_replace('%2F', '/', rawurlencode($string)); + case 'quotes': // escape unescaped single quotes return preg_replace("%(?<!\\\\)'%", "\\'", $string); case 'hex': - // escape every character into hex + // escape every byte into hex + // Note that the UTF-8 encoded character ä will be represented as %c3%a4 $return = ''; - for ($x=0; $x < strlen($string); $x++) { + $_length = strlen($string); + for ($x = 0; $x < $_length; $x++) { $return .= '%' . bin2hex($string[$x]); } return $return; - + case 'hexentity': $return = ''; - for ($x=0; $x < strlen($string); $x++) { + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php'); + $return = ''; + foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) { + $return .= '&#x' . strtoupper(dechex($unicode)) . ';'; + } + return $return; + } + // no MBString fallback + $_length = strlen($string); + for ($x = 0; $x < $_length; $x++) { $return .= '&#x' . bin2hex($string[$x]) . ';'; } return $return; case 'decentity': $return = ''; - for ($x=0; $x < strlen($string); $x++) { + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php'); + $return = ''; + foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) { + $return .= '&#' . $unicode . ';'; + } + return $return; + } + // no MBString fallback + $_length = strlen($string); + for ($x = 0; $x < $_length; $x++) { $return .= '&#' . ord($string[$x]) . ';'; } return $return; case 'javascript': // escape quotes and backslashes, newlines, etc. - return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/')); - + return strtr($string, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/')); + case 'mail': - // safe way to display e-mail address on a web page - return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string); - + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php'); + return smarty_mb_str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string); + } + // no MBString fallback + return str_replace(array('@', '.'), array(' [AT] ', ' [DOT] '), $string); + case 'nonstd': - // escape non-standard chars, such as ms document quotes - $_res = ''; - for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) { - $_ord = ord(substr($string, $_i, 1)); - // non-standard char, escape it - if($_ord >= 126){ - $_res .= '&#' . $_ord . ';'; - } - else { - $_res .= substr($string, $_i, 1); - } - } - return $_res; + // escape non-standard chars, such as ms document quotes + $return = ''; + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_unicode.php'); + foreach (smarty_mb_to_unicode($string, Smarty::$_CHARSET) as $unicode) { + if ($unicode >= 126) { + $return .= '&#' . $unicode . ';'; + } else { + $return .= chr($unicode); + } + } + return $return; + } + + $_length = strlen($string); + for ($_i = 0; $_i < $_length; $_i++) { + $_ord = ord(substr($string, $_i, 1)); + // non-standard char, escape it + if ($_ord >= 126) { + $return .= '&#' . $_ord . ';'; + } else { + $return .= substr($string, $_i, 1); + } + } + return $return; default: return $string; } } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.indent.php b/include/smarty/libs/plugins/modifier.indent.php deleted file mode 100644 index 394147a29..000000000 --- a/include/smarty/libs/plugins/modifier.indent.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty indent modifier plugin - * - * Type: modifier<br> - * Name: indent<br> - * Purpose: indent lines of text - * @link http://smarty.php.net/manual/en/language.modifier.indent.php - * indent (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param integer - * @param string - * @return string - */ -function smarty_modifier_indent($string,$chars=4,$char=" ") -{ - return preg_replace('!^!m',str_repeat($char,$chars),$string); -} - -?> diff --git a/include/smarty/libs/plugins/modifier.lower.php b/include/smarty/libs/plugins/modifier.lower.php deleted file mode 100644 index 20e7a8d39..000000000 --- a/include/smarty/libs/plugins/modifier.lower.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty lower modifier plugin - * - * Type: modifier<br> - * Name: lower<br> - * Purpose: convert string to lowercase - * @link http://smarty.php.net/manual/en/language.modifier.lower.php - * lower (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return string - */ -function smarty_modifier_lower($string) -{ - return strtolower($string); -} - -?> diff --git a/include/smarty/libs/plugins/modifier.nl2br.php b/include/smarty/libs/plugins/modifier.nl2br.php deleted file mode 100644 index d6fabff64..000000000 --- a/include/smarty/libs/plugins/modifier.nl2br.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty plugin - * - * Type: modifier<br> - * Name: nl2br<br> - * Date: Feb 26, 2003 - * Purpose: convert \r\n, \r or \n to <<br>> - * Input:<br> - * - contents = contents to replace - * - preceed_test = if true, includes preceeding break tags - * in replacement - * Example: {$text|nl2br} - * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php - * nl2br (Smarty online manual) - * @version 1.0 - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return string - */ -function smarty_modifier_nl2br($string) -{ - return nl2br($string); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.regex_replace.php b/include/smarty/libs/plugins/modifier.regex_replace.php index 100b58ce4..f9fd5fa53 100644 --- a/include/smarty/libs/plugins/modifier.regex_replace.php +++ b/include/smarty/libs/plugins/modifier.regex_replace.php @@ -1,48 +1,55 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ - /** * Smarty regex_replace modifier plugin * * Type: modifier<br> * Name: regex_replace<br> * Purpose: regular expression search/replace + * * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php * regex_replace (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param string|array - * @param string|array + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string input string + * @param string|array $search regular expression(s) to search for + * @param string|array $replace string(s) that should be replaced * @return string */ function smarty_modifier_regex_replace($string, $search, $replace) { if(is_array($search)) { - foreach($search as $idx => $s) - $search[$idx] = _smarty_regex_replace_check($s); + foreach($search as $idx => $s) { + $search[$idx] = _smarty_regex_replace_check($s); + } } else { - $search = _smarty_regex_replace_check($search); - } - + $search = _smarty_regex_replace_check($search); + } return preg_replace($search, $replace, $string); } +/** + * @param string $search string(s) that should be replaced + * @return string + * @ignore + */ function _smarty_regex_replace_check($search) { - if (($pos = strpos($search,"\0")) !== false) - $search = substr($search,0,$pos); + // null-byte injection detection + // anything behind the first null-byte is ignored + if (($pos = strpos($search,"\0")) !== false) { + $search = substr($search,0,$pos); + } + // remove eval-modifier from $search if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { - /* remove eval-modifier from $search */ $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); } return $search; } -/* vim: set expandtab: */ - -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.replace.php b/include/smarty/libs/plugins/modifier.replace.php index df041c884..4d71a6e9b 100644 --- a/include/smarty/libs/plugins/modifier.replace.php +++ b/include/smarty/libs/plugins/modifier.replace.php @@ -2,29 +2,32 @@ /** * Smarty plugin * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ - /** * Smarty replace modifier plugin - * + * * Type: modifier<br> * Name: replace<br> * Purpose: simple search/replace - * @link http://smarty.php.net/manual/en/language.modifier.replace.php - * replace (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param string - * @param string - * @return string + * + * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @author Uwe Tews + * @param string $string input string + * @param string $search text to search for + * @param string $replace replacement text + * @return string */ function smarty_modifier_replace($string, $search, $replace) { + if (Smarty::$_MBSTRING) { + require_once(SMARTY_PLUGINS_DIR . 'shared.mb_str_replace.php'); + return smarty_mb_str_replace($search, $replace, $string); + } + return str_replace($search, $replace, $string); -} - -/* vim: set expandtab: */ +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.spacify.php b/include/smarty/libs/plugins/modifier.spacify.php index c2423f4f2..a907232ff 100644 --- a/include/smarty/libs/plugins/modifier.spacify.php +++ b/include/smarty/libs/plugins/modifier.spacify.php @@ -2,29 +2,26 @@ /** * Smarty plugin * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ - /** * Smarty spacify modifier plugin - * + * * Type: modifier<br> * Name: spacify<br> * Purpose: add spaces between characters in a string - * @link http://smarty.php.net/manual/en/language.modifier.spacify.php - * spacify (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param string + * + * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string input string + * @param string $spacify_char string to insert between characters. * @return string */ function smarty_modifier_spacify($string, $spacify_char = ' ') { - return implode($spacify_char, - preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY)); -} - -/* vim: set expandtab: */ + // well… what about charsets besides latin and UTF-8? + return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY)); +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.string_format.php b/include/smarty/libs/plugins/modifier.string_format.php deleted file mode 100644 index 9e051a578..000000000 --- a/include/smarty/libs/plugins/modifier.string_format.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty string_format modifier plugin - * - * Type: modifier<br> - * Name: string_format<br> - * Purpose: format strings via sprintf - * @link http://smarty.php.net/manual/en/language.modifier.string.format.php - * string_format (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param string - * @return string - */ -function smarty_modifier_string_format($string, $format) -{ - return sprintf($format, $string); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.strip.php b/include/smarty/libs/plugins/modifier.strip.php deleted file mode 100644 index cc5c453c8..000000000 --- a/include/smarty/libs/plugins/modifier.strip.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty strip modifier plugin - * - * Type: modifier<br> - * Name: strip<br> - * Purpose: Replace all repeated spaces, newlines, tabs - * with a single space or supplied replacement string.<br> - * Example: {$var|strip} {$var|strip:" "} - * Date: September 25th, 2002 - * @link http://smarty.php.net/manual/en/language.modifier.strip.php - * strip (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @version 1.0 - * @param string - * @param string - * @return string - */ -function smarty_modifier_strip($text, $replace = ' ') -{ - return preg_replace('!\s+!', $replace, $text); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.strip_tags.php b/include/smarty/libs/plugins/modifier.strip_tags.php deleted file mode 100644 index 93011a892..000000000 --- a/include/smarty/libs/plugins/modifier.strip_tags.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty strip_tags modifier plugin - * - * Type: modifier<br> - * Name: strip_tags<br> - * Purpose: strip html tags from text - * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php - * strip_tags (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param boolean - * @return string - */ -function smarty_modifier_strip_tags($string, $replace_with_space = true) -{ - if ($replace_with_space) - return preg_replace('!<[^>]*?>!', ' ', $string); - else - return strip_tags($string); -} - -/* vim: set expandtab: */ - -?> diff --git a/include/smarty/libs/plugins/modifier.truncate.php b/include/smarty/libs/plugins/modifier.truncate.php index 35c89690a..9a803ec99 100644 --- a/include/smarty/libs/plugins/modifier.truncate.php +++ b/include/smarty/libs/plugins/modifier.truncate.php @@ -1,50 +1,59 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsModifier */ - - + /** * Smarty truncate modifier plugin - * + * * Type: modifier<br> * Name: truncate<br> * Purpose: Truncate a string to a certain length if necessary, - * optionally splitting in the middle of a word, and - * appending the $etc string or inserting $etc into the middle. - * @link http://smarty.php.net/manual/en/language.modifier.truncate.php - * truncate (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param integer - * @param string - * @param boolean - * @param boolean - * @return string + * optionally splitting in the middle of a word, and + * appending the $etc string or inserting $etc into the middle. + * + * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual) + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string input string + * @param integer $length length of truncated text + * @param string $etc end string + * @param boolean $break_words truncate at word boundary + * @param boolean $middle truncate in the middle of text + * @return string truncated string */ -function smarty_modifier_truncate($string, $length = 80, $etc = '...', - $break_words = false, $middle = false) -{ +function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) { if ($length == 0) return ''; - if (strlen($string) > $length) { + if (Smarty::$_MBSTRING) { + if (mb_strlen($string, Smarty::$_CHARSET) > $length) { + $length -= min($length, mb_strlen($etc, Smarty::$_CHARSET)); + if (!$break_words && !$middle) { + $string = preg_replace('/\s+?(\S+)?$/' . Smarty::$_UTF8_MODIFIER, '', mb_substr($string, 0, $length + 1, Smarty::$_CHARSET)); + } + if (!$middle) { + return mb_substr($string, 0, $length, Smarty::$_CHARSET) . $etc; + } + return mb_substr($string, 0, $length / 2, Smarty::$_CHARSET) . $etc . mb_substr($string, - $length / 2, $length, Smarty::$_CHARSET); + } + return $string; + } + + // no MBString fallback + if (isset($string[$length])) { $length -= min($length, strlen($etc)); if (!$break_words && !$middle) { - $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1)); - } - if(!$middle) { + $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1)); + } + if (!$middle) { return substr($string, 0, $length) . $etc; - } else { - return substr($string, 0, $length/2) . $etc . substr($string, -$length/2); } - } else { - return $string; + return substr($string, 0, $length / 2) . $etc . substr($string, - $length / 2); } -} - -/* vim: set expandtab: */ + return $string; +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifier.upper.php b/include/smarty/libs/plugins/modifier.upper.php deleted file mode 100644 index c12480fbd..000000000 --- a/include/smarty/libs/plugins/modifier.upper.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty upper modifier plugin - * - * Type: modifier<br> - * Name: upper<br> - * Purpose: convert string to uppercase - * @link http://smarty.php.net/manual/en/language.modifier.upper.php - * upper (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return string - */ -function smarty_modifier_upper($string) -{ - return strtoupper($string); -} - -?> diff --git a/include/smarty/libs/plugins/modifier.wordwrap.php b/include/smarty/libs/plugins/modifier.wordwrap.php deleted file mode 100644 index ce0718156..000000000 --- a/include/smarty/libs/plugins/modifier.wordwrap.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Smarty plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * Smarty wordwrap modifier plugin - * - * Type: modifier<br> - * Name: wordwrap<br> - * Purpose: wrap a string of text at a given length - * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php - * wordwrap (Smarty online manual) - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @param integer - * @param string - * @param boolean - * @return string - */ -function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false) -{ - return wordwrap($string,$length,$break,$cut); -} - -?> diff --git a/include/smarty/libs/plugins/modifiercompiler.cat.php b/include/smarty/libs/plugins/modifiercompiler.cat.php new file mode 100644 index 000000000..1cfe6308a --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.cat.php @@ -0,0 +1,30 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: cat<br>
+ * Date: Feb 24, 2003<br>
+ * Purpose: catenate a value to a variable<br>
+ * Input: string to catenate<br>
+ * Example: {$var|cat:"foo"}
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ * (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_cat($params, $compiler)
+{
+ return '('.implode(').(', $params).')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.count_characters.php b/include/smarty/libs/plugins/modifiercompiler.count_characters.php new file mode 100644 index 000000000..98e8efa0d --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.count_characters.php @@ -0,0 +1,33 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_characteres<br>
+ * Purpose: count the number of characters in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_characters($params, $compiler)
+{
+ if (!isset($params[1]) || $params[1] != 'true') {
+ return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[0] . ', $tmp)';
+ }
+ if (Smarty::$_MBSTRING) {
+ return 'mb_strlen(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')';
+ }
+ // no MBString fallback
+ return 'strlen(' . $params[0] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.count_paragraphs.php b/include/smarty/libs/plugins/modifiercompiler.count_paragraphs.php new file mode 100644 index 000000000..0e1b0af83 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.count_paragraphs.php @@ -0,0 +1,28 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_paragraphs<br>
+ * Purpose: count the number of paragraphs in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ * count_paragraphs (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_paragraphs($params, $compiler)
+{
+ // count \r or \n characters
+ return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.count_sentences.php b/include/smarty/libs/plugins/modifiercompiler.count_sentences.php new file mode 100644 index 000000000..2f517be96 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.count_sentences.php @@ -0,0 +1,28 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_sentences
+ * Purpose: count the number of sentences in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
+ * count_sentences (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_count_sentences($params, $compiler)
+{
+ // find periods, question marks, exclamation marks with a word before but not after.
+ return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[0] . ', $tmp)';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.count_words.php b/include/smarty/libs/plugins/modifiercompiler.count_words.php new file mode 100644 index 000000000..e05738c01 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.count_words.php @@ -0,0 +1,32 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_words<br>
+ * Purpose: count the number of words in a text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+*/
+function smarty_modifiercompiler_count_words($params, $compiler)
+{
+ if (Smarty::$_MBSTRING) {
+ // return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
+ // expression taken from http://de.php.net/manual/en/function.str-word-count.php#85592
+ return 'preg_match_all(\'/\p{L}[\p{L}\p{Mn}\p{Pd}\\\'\x{2019}]*/' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)';
+ }
+ // no MBString fallback
+ return 'str_word_count(' . $params[0] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.default.php b/include/smarty/libs/plugins/modifiercompiler.default.php new file mode 100644 index 000000000..4f831a589 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.default.php @@ -0,0 +1,35 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: default<br>
+ * Purpose: designate default value for empty variables
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_default ($params, $compiler)
+{
+ $output = $params[0];
+ if (!isset($params[1])) {
+ $params[1] = "''";
+ }
+
+ array_shift($params);
+ foreach ($params as $param) {
+ $output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
+ }
+ return $output;
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.escape.php b/include/smarty/libs/plugins/modifiercompiler.escape.php new file mode 100644 index 000000000..f50028bd9 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.escape.php @@ -0,0 +1,125 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * @ignore
+ */
+require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' );
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: escape<br>
+ * Purpose: escape string for output
+ *
+ * @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_escape($params, $compiler)
+{
+ static $_double_encode = null;
+ if ($_double_encode === null) {
+ $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
+ }
+
+ try {
+ $esc_type = smarty_literal_compiler_param($params, 1, 'html');
+ $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
+ $double_encode = smarty_literal_compiler_param($params, 3, true);
+
+ if (!$char_set) {
+ $char_set = Smarty::$_CHARSET;
+ }
+
+ switch ($esc_type) {
+ case 'html':
+ if ($_double_encode) {
+ return 'htmlspecialchars('
+ . $params[0] .', ENT_QUOTES, '
+ . var_export($char_set, true) . ', '
+ . var_export($double_encode, true) . ')';
+ } else if ($double_encode) {
+ return 'htmlspecialchars('
+ . $params[0] .', ENT_QUOTES, '
+ . var_export($char_set, true) . ')';
+ } else {
+ // fall back to modifier.escape.php
+ }
+
+ case 'htmlall':
+ if (Smarty::$_MBSTRING) {
+ if ($_double_encode) {
+ // php >=5.2.3 - go native
+ return 'mb_convert_encoding(htmlspecialchars('
+ . $params[0] .', ENT_QUOTES, '
+ . var_export($char_set, true) . ', '
+ . var_export($double_encode, true)
+ . '), "HTML-ENTITIES", '
+ . var_export($char_set, true) . ')';
+ } else if ($double_encode) {
+ // php <5.2.3 - only handle double encoding
+ return 'mb_convert_encoding(htmlspecialchars('
+ . $params[0] .', ENT_QUOTES, '
+ . var_export($char_set, true)
+ . '), "HTML-ENTITIES", '
+ . var_export($char_set, true) . ')';
+ } else {
+ // fall back to modifier.escape.php
+ }
+ }
+
+ // no MBString fallback
+ if ($_double_encode) {
+ // php >=5.2.3 - go native
+ return 'htmlentities('
+ . $params[0] .', ENT_QUOTES, '
+ . var_export($char_set, true) . ', '
+ . var_export($double_encode, true) . ')';
+ } else if ($double_encode) {
+ // php <5.2.3 - only handle double encoding
+ return 'htmlentities('
+ . $params[0] .', ENT_QUOTES, '
+ . var_export($char_set, true) . ')';
+ } else {
+ // fall back to modifier.escape.php
+ }
+
+ case 'url':
+ return 'rawurlencode(' . $params[0] . ')';
+
+ case 'urlpathinfo':
+ return 'str_replace("%2F", "/", rawurlencode(' . $params[0] . '))';
+
+ case 'quotes':
+ // escape unescaped single quotes
+ return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[0] . ')';
+
+ case 'javascript':
+ // escape quotes and backslashes, newlines, etc.
+ return 'strtr(' . $params[0] . ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
+
+ }
+ } catch(SmartyException $e) {
+ // pass through to regular plugin fallback
+ }
+
+ // could not optimize |escape call, so fallback to regular plugin
+ if ($compiler->tag_nocache | $compiler->nocache) {
+ $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
+ $compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
+ } else {
+ $compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
+ $compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape';
+ }
+ return 'smarty_modifier_escape(' . join( ', ', $params ) . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.from_charset.php b/include/smarty/libs/plugins/modifiercompiler.from_charset.php new file mode 100644 index 000000000..93b568a5a --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.from_charset.php @@ -0,0 +1,34 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty from_charset modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: from_charset<br>
+ * Purpose: convert character encoding from $charset to internal encoding
+ *
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_from_charset($params, $compiler)
+{
+ if (!Smarty::$_MBSTRING) {
+ // FIXME: (rodneyrehm) shouldn't this throw an error?
+ return $params[0];
+ }
+
+ if (!isset($params[1])) {
+ $params[1] = '"ISO-8859-1"';
+ }
+
+ return 'mb_convert_encoding(' . $params[0] . ', "' . addslashes(Smarty::$_CHARSET) . '", ' . $params[1] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.indent.php b/include/smarty/libs/plugins/modifiercompiler.indent.php new file mode 100644 index 000000000..020c4fdb3 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.indent.php @@ -0,0 +1,32 @@ +<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: indent<br>
+ * Purpose: indent lines of text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_indent($params, $compiler)
+{
+ if (!isset($params[1])) {
+ $params[1] = 4;
+ }
+ if (!isset($params[2])) {
+ $params[2] = "' '";
+ }
+ return 'preg_replace(\'!^!m\',str_repeat(' . $params[2] . ',' . $params[1] . '),' . $params[0] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.lower.php b/include/smarty/libs/plugins/modifiercompiler.lower.php new file mode 100644 index 000000000..1845cc1d2 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.lower.php @@ -0,0 +1,31 @@ +<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: lower<br>
+ * Purpose: convert string to lowercase
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
+ * @author Monte Ohrt <monte at ohrt dot com>
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_lower($params, $compiler)
+{
+ if (Smarty::$_MBSTRING) {
+ return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ;
+ }
+ // no MBString fallback
+ return 'strtolower(' . $params[0] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.noprint.php b/include/smarty/libs/plugins/modifiercompiler.noprint.php new file mode 100644 index 000000000..3ca26571a --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.noprint.php @@ -0,0 +1,25 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty noprint modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: noprint<br>
+ * Purpose: return an empty string
+ *
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_noprint($params, $compiler)
+{
+ return "''";
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.string_format.php b/include/smarty/libs/plugins/modifiercompiler.string_format.php new file mode 100644 index 000000000..83345977b --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.string_format.php @@ -0,0 +1,26 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: string_format<br>
+ * Purpose: format strings via sprintf
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_string_format($params, $compiler)
+{
+ return 'sprintf(' . $params[1] . ',' . $params[0] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.strip.php b/include/smarty/libs/plugins/modifiercompiler.strip.php new file mode 100644 index 000000000..f1d5db045 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.strip.php @@ -0,0 +1,33 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: strip<br>
+ * Purpose: Replace all repeated spaces, newlines, tabs
+ * with a single space or supplied replacement string.<br>
+ * Example: {$var|strip} {$var|strip:" "}<br>
+ * Date: September 25th, 2002
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+
+function smarty_modifiercompiler_strip($params, $compiler)
+{
+ if (!isset($params[1])) {
+ $params[1] = "' '";
+ }
+ return "preg_replace('!\s+!" . Smarty::$_UTF8_MODIFIER . "', {$params[1]},{$params[0]})";
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.strip_tags.php b/include/smarty/libs/plugins/modifiercompiler.strip_tags.php new file mode 100644 index 000000000..296a3a2da --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.strip_tags.php @@ -0,0 +1,33 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: strip_tags<br>
+ * Purpose: strip html tags from text
+ *
+ * @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_strip_tags($params, $compiler)
+{
+ if (!isset($params[1])) {
+ $params[1] = true;
+ }
+ if ($params[1] === true) {
+ return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
+ } else {
+ return 'strip_tags(' . $params[0] . ')';
+ }
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.to_charset.php b/include/smarty/libs/plugins/modifiercompiler.to_charset.php new file mode 100644 index 000000000..f5cdf455f --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.to_charset.php @@ -0,0 +1,34 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty to_charset modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: to_charset<br>
+ * Purpose: convert character encoding from internal encoding to $charset
+ *
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_to_charset($params, $compiler)
+{
+ if (!Smarty::$_MBSTRING) {
+ // FIXME: (rodneyrehm) shouldn't this throw an error?
+ return $params[0];
+ }
+
+ if (!isset($params[1])) {
+ $params[1] = '"ISO-8859-1"';
+ }
+
+ return 'mb_convert_encoding(' . $params[0] . ', ' . $params[1] . ', "' . addslashes(Smarty::$_CHARSET) . '")';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.unescape.php b/include/smarty/libs/plugins/modifiercompiler.unescape.php new file mode 100644 index 000000000..4321ff18d --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.unescape.php @@ -0,0 +1,51 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty unescape modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: unescape<br>
+ * Purpose: unescape html entities
+ *
+ * @author Rodney Rehm
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_unescape($params, $compiler)
+{
+ if (!isset($params[1])) {
+ $params[1] = 'html';
+ }
+ if (!isset($params[2])) {
+ $params[2] = '\'' . addslashes(Smarty::$_CHARSET) . '\'';
+ } else {
+ $params[2] = "'" . $params[2] . "'";
+ }
+
+ switch (trim($params[1], '"\'')) {
+ case 'entity':
+ case 'htmlall':
+ if (Smarty::$_MBSTRING) {
+ return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
+ }
+
+ return 'html_entity_decode(' . $params[0] . ', ENT_NOQUOTES, ' . $params[2] . ')';
+
+ case 'html':
+ return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)';
+
+ case 'url':
+ return 'rawurldecode(' . $params[0] . ')';
+
+ default:
+ return $params[0];
+ }
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.upper.php b/include/smarty/libs/plugins/modifiercompiler.upper.php new file mode 100644 index 000000000..f368e37dc --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.upper.php @@ -0,0 +1,30 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty upper modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: lower<br>
+ * Purpose: convert string to uppercase
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_upper($params, $compiler)
+{
+ if (Smarty::$_MBSTRING) {
+ return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ;
+ }
+ // no MBString fallback
+ return 'strtoupper(' . $params[0] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/modifiercompiler.wordwrap.php b/include/smarty/libs/plugins/modifiercompiler.wordwrap.php new file mode 100644 index 000000000..f6845ad37 --- /dev/null +++ b/include/smarty/libs/plugins/modifiercompiler.wordwrap.php @@ -0,0 +1,46 @@ +<?php
+/**
+ * Smarty plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsModifierCompiler
+ */
+
+/**
+ * Smarty wordwrap modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: wordwrap<br>
+ * Purpose: wrap a string of text at a given length
+ *
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
+ * @author Uwe Tews
+ * @param array $params parameters
+ * @return string with compiled code
+ */
+function smarty_modifiercompiler_wordwrap($params, $compiler)
+{
+ if (!isset($params[1])) {
+ $params[1] = 80;
+ }
+ if (!isset($params[2])) {
+ $params[2] = '"\n"';
+ }
+ if (!isset($params[3])) {
+ $params[3] = 'false';
+ }
+ $function = 'wordwrap';
+ if (Smarty::$_MBSTRING) {
+ if ($compiler->tag_nocache | $compiler->nocache) {
+ $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
+ $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
+ } else {
+ $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
+ $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
+ }
+ $function = 'smarty_mb_wordwrap';
+ }
+ return $function . '(' . $params[0] . ',' . $params[1] . ',' . $params[2] . ',' . $params[3] . ')';
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/outputfilter.trimwhitespace.php b/include/smarty/libs/plugins/outputfilter.trimwhitespace.php index 739fa39b0..87cf8c781 100644 --- a/include/smarty/libs/plugins/outputfilter.trimwhitespace.php +++ b/include/smarty/libs/plugins/outputfilter.trimwhitespace.php @@ -1,75 +1,94 @@ <?php /** * Smarty plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsFilter */ /** * Smarty trimwhitespace outputfilter plugin * - * File: outputfilter.trimwhitespace.php<br> - * Type: outputfilter<br> - * Name: trimwhitespace<br> - * Date: Jan 25, 2003<br> - * Purpose: trim leading white space and blank lines from - * template source after it gets interpreted, cleaning - * up code and saving bandwidth. Does not affect - * <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br> - * Install: Drop into the plugin directory, call - * <code>$smarty->load_filter('output','trimwhitespace');</code> - * from application. - * @author Monte Ohrt <monte at ohrt dot com> - * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de> - * @version 1.3 - * @param string - * @param Smarty + * Trim unnecessary whitespace from HTML markup. + * + * @author Rodney Rehm + * @param string $source input string + * @param Smarty_Internal_Template $smarty Smarty object + * @return string filtered output + * @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail! */ -function smarty_outputfilter_trimwhitespace($source, &$smarty) +function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty) { - // Pull out the script blocks - preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match); - $_script_blocks = $match[0]; - $source = preg_replace("!<script[^>]*?>.*?</script>!is", - '@@@SMARTY:TRIM:SCRIPT@@@', $source); + $store = array(); + $_store = 0; + $_offset = 0; - // Pull out the pre blocks - preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match); - $_pre_blocks = $match[0]; - $source = preg_replace("!<pre[^>]*?>.*?</pre>!is", - '@@@SMARTY:TRIM:PRE@@@', $source); - - // Pull out the textarea blocks - preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match); - $_textarea_blocks = $match[0]; - $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is", - '@@@SMARTY:TRIM:TEXTAREA@@@', $source); + // Unify Line-Breaks to \n + $source = preg_replace("/\015\012|\015|\012/", "\n", $source); - // remove all leading spaces, tabs and carriage returns NOT - // preceeded by a php close tag. - $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source)); + // capture Internet Explorer Conditional Comments + if (preg_match_all('#<!--\[[^\]]+\]>.*?<!\[[^\]]+\]-->#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) { + foreach ($matches as $match) { + $store[] = $match[0][0]; + $_length = strlen($match[0][0]); + $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@'; + $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length); - // replace textarea blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); + $_offset += $_length - strlen($replace); + $_store++; + } + } - // replace pre blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); + // Strip all HTML-Comments + // yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124 + $source = preg_replace( '#<!--.*?-->#ms', '', $source ); - // replace script blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); + // capture html elements not to be messed with + $_offset = 0; + if (preg_match_all('#<(script|pre|textarea)[^>]*>.*?</\\1>#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) { + foreach ($matches as $match) { + $store[] = $match[0][0]; + $_length = strlen($match[0][0]); + $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@'; + $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length); - return $source; -} + $_offset += $_length - strlen($replace); + $_store++; + } + } -function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) { - $_len = strlen($search_str); - $_pos = 0; - for ($_i=0, $_count=count($replace); $_i<$_count; $_i++) - if (($_pos=strpos($subject, $search_str, $_pos))!==false) - $subject = substr_replace($subject, $replace[$_i], $_pos, $_len); - else - break; + $expressions = array( + // replace multiple spaces between tags by a single space + // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements + '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2', + // remove spaces between attributes (but not in attribute values!) + '#(([a-z0-9]\s*=\s*(["\'])[^\3]*?\3)|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \4', + // note: for some very weird reason trim() seems to remove spaces inside attributes. + // maybe a \0 byte or something is interfering? + '#^\s+<#Ss' => '<', + '#>\s+$#Ss' => '>', + ); + $source = preg_replace( array_keys($expressions), array_values($expressions), $source ); + // note: for some very weird reason trim() seems to remove spaces inside attributes. + // maybe a \0 byte or something is interfering? + // $source = trim( $source ); + + // capture html elements not to be messed with + $_offset = 0; + if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) { + foreach ($matches as $match) { + $store[] = $match[0][0]; + $_length = strlen($match[0][0]); + $replace = array_shift($store); + $source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length); + + $_offset += strlen($replace) - $_length; + $_store++; + } + } + + return $source; } -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/shared.escape_special_chars.php b/include/smarty/libs/plugins/shared.escape_special_chars.php index c07ce31be..d2609b674 100644 --- a/include/smarty/libs/plugins/shared.escape_special_chars.php +++ b/include/smarty/libs/plugins/shared.escape_special_chars.php @@ -1,31 +1,51 @@ <?php /** * Smarty shared plugin - * @package Smarty - * @subpackage plugins - */ - - -/** - * escape_special_chars common function * - * Function: smarty_function_escape_special_chars<br> - * Purpose: used by other smarty functions to escape - * special chars except for already escaped ones - * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return string + * @package Smarty + * @subpackage PluginsShared */ -function smarty_function_escape_special_chars($string) -{ - if(!is_array($string)) { - $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); - $string = htmlspecialchars($string); - $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string); - } - return $string; -} -/* vim: set expandtab: */ +if (version_compare(PHP_VERSION, '5.2.3', '>=')) { + /** + * escape_special_chars common function + * + * Function: smarty_function_escape_special_chars<br> + * Purpose: used by other smarty functions to escape + * special chars except for already escaped ones + * + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string text that should by escaped + * @return string + */ + function smarty_function_escape_special_chars($string) + { + if (!is_array($string)) { + $string = htmlspecialchars($string, ENT_COMPAT, Smarty::$_CHARSET, false); + } + return $string; + } +} else { + /** + * escape_special_chars common function + * + * Function: smarty_function_escape_special_chars<br> + * Purpose: used by other smarty functions to escape + * special chars except for already escaped ones + * + * @author Monte Ohrt <monte at ohrt dot com> + * @param string $string text that should by escaped + * @return string + */ + function smarty_function_escape_special_chars($string) + { + if (!is_array($string)) { + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlspecialchars($string); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + } + return $string; + } +} -?> +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/shared.literal_compiler_param.php b/include/smarty/libs/plugins/shared.literal_compiler_param.php new file mode 100644 index 000000000..dbcd9374c --- /dev/null +++ b/include/smarty/libs/plugins/shared.literal_compiler_param.php @@ -0,0 +1,33 @@ +<?php +/** + * Smarty plugin + * + * @package Smarty + * @subpackage PluginsShared + */ + +/** + * evaluate compiler parameter + * + * @param array $params parameter array as given to the compiler function + * @param integer $index array index of the parameter to convert + * @param mixed $default value to be returned if the parameter is not present + * @return mixed evaluated value of parameter or $default + * @throws SmartyException if parameter is not a literal (but an expression, variable, …) + * @author Rodney Rehm + */ +function smarty_literal_compiler_param($params, $index, $default=null) +{ + // not set, go default + if (!isset($params[$index])) { + return $default; + } + // test if param is a literal + if (!preg_match('/^([\'"]?)[a-zA-Z0-9]+(\\1)$/', $params[$index])) { + throw new SmartyException('$param[' . $index . '] is not a literal and is thus not evaluatable at compile time'); + } + + $t = null; + eval("\$t = " . $params[$index] . ";"); + return $t; +} diff --git a/include/smarty/libs/plugins/shared.make_timestamp.php b/include/smarty/libs/plugins/shared.make_timestamp.php index b42eb11d8..5d7c97e91 100644 --- a/include/smarty/libs/plugins/shared.make_timestamp.php +++ b/include/smarty/libs/plugins/shared.make_timestamp.php @@ -1,46 +1,42 @@ <?php /** * Smarty shared plugin + * * @package Smarty - * @subpackage plugins + * @subpackage PluginsShared */ - /** * Function: smarty_make_timestamp<br> - * Purpose: used by other smarty functions to make a timestamp - * from a string. + * Purpose: used by other smarty functions to make a timestamp from a string. + * * @author Monte Ohrt <monte at ohrt dot com> - * @param string - * @return string + * @param DateTime|int|string $string date object, timestamp or string that can be converted using strtotime() + * @return int */ function smarty_make_timestamp($string) { - if(empty($string)) { + if (empty($string)) { // use "now": - $time = time(); - - } elseif (preg_match('/^\d{14}$/', $string)) { - // it is mysql timestamp format of YYYYMMDDHHMMSS? - $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2), + return time(); + } elseif ($string instanceof DateTime) { + return $string->getTimestamp(); + } elseif (strlen($string) == 14 && ctype_digit($string)) { + // it is mysql timestamp format of YYYYMMDDHHMMSS? + return mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2), substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4)); - } elseif (is_numeric($string)) { // it is a numeric string, we handle it as timestamp - $time = (int)$string; - + return (int) $string; } else { // strtotime should handle it $time = strtotime($string); if ($time == -1 || $time === false) { // strtotime() was not able to parse $string, use "now": - $time = time(); + return time(); } + return $time; } - return $time; - } -/* vim: set expandtab: */ - ?> diff --git a/include/smarty/libs/plugins/shared.mb_str_replace.php b/include/smarty/libs/plugins/shared.mb_str_replace.php new file mode 100644 index 000000000..ecafeb74a --- /dev/null +++ b/include/smarty/libs/plugins/shared.mb_str_replace.php @@ -0,0 +1,55 @@ +<?php +/** + * Smarty shared plugin + * + * @package Smarty + * @subpackage PluginsShared + */ +if (!function_exists('smarty_mb_str_replace')) { + + /** + * Multibyte string replace + * + * @param string $search the string to be searched + * @param string $replace the replacement string + * @param string $subject the source string + * @param int &$count number of matches found + * @return string replaced string + * @author Rodney Rehm + */ + function smarty_mb_str_replace($search, $replace, $subject, &$count=0) + { + if (!is_array($search) && is_array($replace)) { + return false; + } + if (is_array($subject)) { + // call mb_replace for each single string in $subject + foreach ($subject as &$string) { + $string = &smarty_mb_str_replace($search, $replace, $string, $c); + $count += $c; + } + } elseif (is_array($search)) { + if (!is_array($replace)) { + foreach ($search as &$string) { + $subject = smarty_mb_str_replace($string, $replace, $subject, $c); + $count += $c; + } + } else { + $n = max(count($search), count($replace)); + while ($n--) { + $subject = smarty_mb_str_replace(current($search), current($replace), $subject, $c); + $count += $c; + next($search); + next($replace); + } + } + } else { + $parts = mb_split(preg_quote($search), $subject); + $count = count($parts) - 1; + $subject = implode($replace, $parts); + } + return $subject; + } + +} +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/shared.mb_unicode.php b/include/smarty/libs/plugins/shared.mb_unicode.php new file mode 100644 index 000000000..e7f839ec8 --- /dev/null +++ b/include/smarty/libs/plugins/shared.mb_unicode.php @@ -0,0 +1,48 @@ +<?php +/** + * Smarty shared plugin + * + * @package Smarty + * @subpackage PluginsShared + */ + +/** + * convert characters to their decimal unicode equivalents + * + * @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration + * @param string $string characters to calculate unicode of + * @param string $encoding encoding of $string, if null mb_internal_encoding() is used + * @return array sequence of unicodes + * @author Rodney Rehm + */ +function smarty_mb_to_unicode($string, $encoding=null) { + if ($encoding) { + $expanded = mb_convert_encoding($string, "UTF-32BE", $encoding); + } else { + $expanded = mb_convert_encoding($string, "UTF-32BE"); + } + return unpack("N*", $expanded); +} + +/** + * convert unicodes to the character of given encoding + * + * @link http://www.ibm.com/developerworks/library/os-php-unicode/index.html#listing3 for inspiration + * @param integer|array $unicode single unicode or list of unicodes to convert + * @param string $encoding encoding of returned string, if null mb_internal_encoding() is used + * @return string unicode as character sequence in given $encoding + * @author Rodney Rehm + */ +function smarty_mb_from_unicode($unicode, $encoding=null) { + $t = ''; + if (!$encoding) { + $encoding = mb_internal_encoding(); + } + foreach((array) $unicode as $utf32be) { + $character = pack("N*", $utf32be); + $t .= mb_convert_encoding($character, $encoding, "UTF-32BE"); + } + return $t; +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/shared.mb_wordwrap.php b/include/smarty/libs/plugins/shared.mb_wordwrap.php new file mode 100644 index 000000000..ba3498c70 --- /dev/null +++ b/include/smarty/libs/plugins/shared.mb_wordwrap.php @@ -0,0 +1,83 @@ +<?php +/** + * Smarty shared plugin + * + * @package Smarty + * @subpackage PluginsShared + */ + +if(!function_exists('smarty_mb_wordwrap')) { + + /** + * Wrap a string to a given number of characters + * + * @link http://php.net/manual/en/function.wordwrap.php for similarity + * @param string $str the string to wrap + * @param int $width the width of the output + * @param string $break the character used to break the line + * @param boolean $cut ignored parameter, just for the sake of + * @return string wrapped string + * @author Rodney Rehm + */ + function smarty_mb_wordwrap($str, $width=75, $break="\n", $cut=false) + { + // break words into tokens using white space as a delimiter + $tokens = preg_split('!(\s)!S' . Smarty::$_UTF8_MODIFIER, $str, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE); + $length = 0; + $t = ''; + $_previous = false; + + foreach ($tokens as $_token) { + $token_length = mb_strlen($_token, Smarty::$_CHARSET); + $_tokens = array($_token); + if ($token_length > $width) { + // remove last space + $t = mb_substr($t, 0, -1, Smarty::$_CHARSET); + $_previous = false; + $length = 0; + + if ($cut) { + $_tokens = preg_split('!(.{' . $width . '})!S' . Smarty::$_UTF8_MODIFIER, $_token, -1, PREG_SPLIT_NO_EMPTY + PREG_SPLIT_DELIM_CAPTURE); + // broken words go on a new line + $t .= $break; + } + } + + foreach ($_tokens as $token) { + $_space = !!preg_match('!^\s$!S' . Smarty::$_UTF8_MODIFIER, $token); + $token_length = mb_strlen($token, Smarty::$_CHARSET); + $length += $token_length; + + if ($length > $width) { + // remove space before inserted break + if ($_previous && $token_length < $width) { + $t = mb_substr($t, 0, -1, Smarty::$_CHARSET); + } + + // add the break before the token + $t .= $break; + $length = $token_length; + + // skip space after inserting a break + if ($_space) { + $length = 0; + continue; + } + } else if ($token == "\n") { + // hard break must reset counters + $_previous = 0; + $length = 0; + } else { + // remember if we had a space or not + $_previous = $_space; + } + // add the token + $t .= $token; + } + } + + return $t; + } + +} +?>
\ No newline at end of file diff --git a/include/smarty/libs/plugins/variablefilter.htmlspecialchars.php b/include/smarty/libs/plugins/variablefilter.htmlspecialchars.php new file mode 100644 index 000000000..aff711e48 --- /dev/null +++ b/include/smarty/libs/plugins/variablefilter.htmlspecialchars.php @@ -0,0 +1,21 @@ +<?php +/** + * Smarty plugin + * + * @package Smarty + * @subpackage PluginsFilter + */ + +/** + * Smarty htmlspecialchars variablefilter plugin + * + * @param string $source input string + * @param Smarty_Internal_Template $smarty Smarty object + * @return string filtered output + */ +function smarty_variablefilter_htmlspecialchars($source, $smarty) +{ + return htmlspecialchars($source, ENT_QUOTES, Smarty::$_CHARSET); +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_cacheresource.php b/include/smarty/libs/sysplugins/smarty_cacheresource.php new file mode 100644 index 000000000..ca18add5e --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_cacheresource.php @@ -0,0 +1,381 @@ +<?php +/** +* Smarty Internal Plugin +* +* @package Smarty +* @subpackage Cacher +*/ + +/** +* Cache Handler API +* +* @package Smarty +* @subpackage Cacher +* @author Rodney Rehm +*/ +abstract class Smarty_CacheResource { + /** + * cache for Smarty_CacheResource instances + * @var array + */ + public static $resources = array(); + + /** + * resource types provided by the core + * @var array + */ + protected static $sysplugins = array( + 'file' => true, + ); + + /** + * populate Cached Object with meta data from Resource + * + * @param Smarty_Template_Cached $cached cached object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public abstract function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template); + + /** + * populate Cached Object with timestamp and exists from Resource + * + * @param Smarty_Template_Cached $source cached object + * @return void + */ + public abstract function populateTimestamp(Smarty_Template_Cached $cached); + + /** + * Read the cached template and process header + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if the cached content does not exist + */ + public abstract function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null); + + /** + * Write the rendered template output to cache + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public abstract function writeCachedContent(Smarty_Internal_Template $_template, $content); + + /** + * Return cached content + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content of cache + */ + public function getCachedContent(Smarty_Internal_Template $_template) + { + if ($_template->cached->handler->process($_template)) { + ob_start(); + $_template->properties['unifunc']($_template); + return ob_get_clean(); + } + return null; + } + + /** + * Empty cache + * + * @param Smarty $smarty Smarty object + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public abstract function clearAll(Smarty $smarty, $exp_time=null); + + /** + * Empty cache for a specific template + * + * @param Smarty $smarty Smarty object + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public abstract function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time); + + + public function locked(Smarty $smarty, Smarty_Template_Cached $cached) + { + // theoretically locking_timeout should be checked against time_limit (max_execution_time) + $start = microtime(true); + $hadLock = null; + while ($this->hasLock($smarty, $cached)) { + $hadLock = true; + if (microtime(true) - $start > $smarty->locking_timeout) { + // abort waiting for lock release + return false; + } + sleep(1); + } + return $hadLock; + } + + public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + // check if lock exists + return false; + } + + public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + // create lock + return true; + } + + public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + // release lock + return true; + } + + + /** + * Load Cache Resource Handler + * + * @param Smarty $smarty Smarty object + * @param string $type name of the cache resource + * @return Smarty_CacheResource Cache Resource Handler + */ + public static function load(Smarty $smarty, $type = null) + { + if (!isset($type)) { + $type = $smarty->caching_type; + } + + // try smarty's cache + if (isset($smarty->_cacheresource_handlers[$type])) { + return $smarty->_cacheresource_handlers[$type]; + } + + // try registered resource + if (isset($smarty->registered_cache_resources[$type])) { + // do not cache these instances as they may vary from instance to instance + return $smarty->_cacheresource_handlers[$type] = $smarty->registered_cache_resources[$type]; + } + // try sysplugins dir + if (isset(self::$sysplugins[$type])) { + if (!isset(self::$resources[$type])) { + $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type); + self::$resources[$type] = new $cache_resource_class(); + } + return $smarty->_cacheresource_handlers[$type] = self::$resources[$type]; + } + // try plugins dir + $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); + if ($smarty->loadPlugin($cache_resource_class)) { + if (!isset(self::$resources[$type])) { + self::$resources[$type] = new $cache_resource_class(); + } + return $smarty->_cacheresource_handlers[$type] = self::$resources[$type]; + } + // give up + throw new SmartyException("Unable to load cache resource '{$type}'"); + } + + /** + * Invalid Loaded Cache Files + * + * @param Smarty $smarty Smarty object + */ + public static function invalidLoadedCache(Smarty $smarty) + { + foreach ($smarty->template_objects as $tpl) { + if (isset($tpl->cached)) { + $tpl->cached->valid = false; + $tpl->cached->processed = false; + } + } + } +} + +/** +* Smarty Resource Data Object +* +* Cache Data Container for Template Files +* +* @package Smarty +* @subpackage TemplateResources +* @author Rodney Rehm +*/ +class Smarty_Template_Cached { + /** + * Source Filepath + * @var string + */ + public $filepath = false; + + /** + * Source Content + * @var string + */ + public $content = null; + + /** + * Source Timestamp + * @var integer + */ + public $timestamp = false; + + /** + * Source Existance + * @var boolean + */ + public $exists = false; + + /** + * Cache Is Valid + * @var boolean + */ + public $valid = false; + + /** + * Cache was processed + * @var boolean + */ + public $processed = false; + + /** + * CacheResource Handler + * @var Smarty_CacheResource + */ + public $handler = null; + + /** + * Template Compile Id (Smarty_Internal_Template::$compile_id) + * @var string + */ + public $compile_id = null; + + /** + * Template Cache Id (Smarty_Internal_Template::$cache_id) + * @var string + */ + public $cache_id = null; + + /** + * Id for cache locking + * @var string + */ + public $lock_id = null; + + /** + * flag that cache is locked by this instance + * @var bool + */ + public $is_locked = false; + + /** + * Source Object + * @var Smarty_Template_Source + */ + public $source = null; + + /** + * create Cached Object container + * + * @param Smarty_Internal_Template $_template template object + */ + public function __construct(Smarty_Internal_Template $_template) + { + $this->compile_id = $_template->compile_id; + $this->cache_id = $_template->cache_id; + $this->source = $_template->source; + $_template->cached = $this; + $smarty = $_template->smarty; + + // + // load resource handler + // + $this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references + + // + // check if cache is valid + // + if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) { + $handler->populate($this, $_template); + return; + } + while (true) { + while (true) { + $handler->populate($this, $_template); + if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) { + $this->valid = false; + } else { + $this->valid = true; + } + if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) { + // lifetime expired + $this->valid = false; + } + if ($this->valid || !$_template->smarty->cache_locking) { + break; + } + if (!$this->handler->locked($_template->smarty, $this)) { + $this->handler->acquireLock($_template->smarty, $this); + break 2; + } + } + if ($this->valid) { + if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) { + // load cache file for the following checks + if ($smarty->debugging) { + Smarty_Internal_Debug::start_cache($_template); + } + if($handler->process($_template, $this) === false) { + $this->valid = false; + } else { + $this->processed = true; + } + if ($smarty->debugging) { + Smarty_Internal_Debug::end_cache($_template); + } + } else { + continue; + } + } else { + return; + } + if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) { + $this->valid = false; + } + if (!$this->valid && $_template->smarty->cache_locking) { + $this->handler->acquireLock($_template->smarty, $this); + return; + } else { + return; + } + } + } + + /** + * Write this cache object to handler + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public function write(Smarty_Internal_Template $_template, $content) + { + if (!$_template->source->recompiled) { + if ($this->handler->writeCachedContent($_template, $content)) { + $this->timestamp = time(); + $this->exists = true; + $this->valid = true; + if ($_template->smarty->cache_locking) { + $this->handler->releaseLock($_template->smarty, $this); + } + return true; + } + } + return false; + } + +} +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_cacheresource_custom.php b/include/smarty/libs/sysplugins/smarty_cacheresource_custom.php new file mode 100644 index 000000000..ee9de157b --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_cacheresource_custom.php @@ -0,0 +1,237 @@ +<?php +/** + * Smarty Internal Plugin + * + * @package Smarty + * @subpackage Cacher + */ + +/** + * Cache Handler API + * + * @package Smarty + * @subpackage Cacher + * @author Rodney Rehm + */ +abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource { + + /** + * fetch cached content and its modification time from data source + * + * @param string $id unique cache content identifier + * @param string $name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param string $content cached content + * @param integer $mtime cache modification timestamp (epoch) + * @return void + */ + protected abstract function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime); + + /** + * Fetch cached content's modification timestamp from data source + * + * {@internal implementing this method is optional. + * Only implement it if modification times can be accessed faster than loading the complete cached content.}} + * + * @param string $id unique cache content identifier + * @param string $name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @return integer|boolean timestamp (epoch) the template was modified, or false if not found + */ + protected function fetchTimestamp($id, $name, $cache_id, $compile_id) + { + return null; + } + + /** + * Save content to cache + * + * @param string $id unique cache content identifier + * @param string $name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer|null $exp_time seconds till expiration or null + * @param string $content content to cache + * @return boolean success + */ + protected abstract function save($id, $name, $cache_id, $compile_id, $exp_time, $content); + + /** + * Delete content from cache + * + * @param string $name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer|null $exp_time seconds till expiration time in seconds or null + * @return integer number of deleted caches + */ + protected abstract function delete($name, $cache_id, $compile_id, $exp_time); + + /** + * populate Cached Object with meta data from Resource + * + * @param Smarty_Template_Cached $cached cached object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) + { + $_cache_id = isset($cached->cache_id) ? preg_replace('![^\w\|]+!', '_', $cached->cache_id) : null; + $_compile_id = isset($cached->compile_id) ? preg_replace('![^\w\|]+!', '_', $cached->compile_id) : null; + + $cached->filepath = sha1($cached->source->filepath . $_cache_id . $_compile_id); + $this->populateTimestamp($cached); + } + + /** + * populate Cached Object with timestamp and exists from Resource + * + * @param Smarty_Template_Cached $source cached object + * @return void + */ + public function populateTimestamp(Smarty_Template_Cached $cached) + { + $mtime = $this->fetchTimestamp($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id); + if ($mtime !== null) { + $cached->timestamp = $mtime; + $cached->exists = !!$cached->timestamp; + return; + } + $timestamp = null; + $this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $cached->content, $timestamp); + $cached->timestamp = isset($timestamp) ? $timestamp : false; + $cached->exists = !!$cached->timestamp; + } + + /** + * Read the cached template and process the header + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if the cached content does not exist + */ + public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null) + { + if (!$cached) { + $cached = $_template->cached; + } + $content = $cached->content ? $cached->content : null; + $timestamp = $cached->timestamp ? $cached->timestamp : null; + if ($content === null || !$timestamp) { + $this->fetch( + $_template->cached->filepath, + $_template->source->name, + $_template->cache_id, + $_template->compile_id, + $content, + $timestamp + ); + } + if (isset($content)) { + $_smarty_tpl = $_template; + eval("?>" . $content); + return true; + } + return false; + } + + /** + * Write the rendered template output to cache + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public function writeCachedContent(Smarty_Internal_Template $_template, $content) + { + return $this->save( + $_template->cached->filepath, + $_template->source->name, + $_template->cache_id, + $_template->compile_id, + $_template->properties['cache_lifetime'], + $content + ); + } + + /** + * Empty cache + * + * @param Smarty $smarty Smarty object + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public function clearAll(Smarty $smarty, $exp_time=null) + { + $this->cache = array(); + return $this->delete(null, null, null, $exp_time); + } + + /** + * Empty cache for a specific template + * + * @param Smarty $smarty Smarty object + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) + { + $this->cache = array(); + return $this->delete($resource_name, $cache_id, $compile_id, $exp_time); + } + + /** + * Check is cache is locked for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if cache is locked + */ + public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $id = $cached->filepath; + $name = $cached->source->name . '.lock'; + + $mtime = $this->fetchTimestamp($id, $name, null, null); + if ($mtime === null) { + $this->fetch($id, $name, null, null, $content, $mtime); + } + + return $mtime && time() - $mtime < $smarty->locking_timeout; + } + + /** + * Lock cache for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + */ + public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $cached->is_locked = true; + + $id = $cached->filepath; + $name = $cached->source->name . '.lock'; + $this->save($id, $name, null, null, $smarty->locking_timeout, ''); + } + + /** + * Unlock cache for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + */ + public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $cached->is_locked = false; + + $name = $cached->source->name . '.lock'; + $this->delete($name, null, null, null); + } +} +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_cacheresource_keyvaluestore.php b/include/smarty/libs/sysplugins/smarty_cacheresource_keyvaluestore.php new file mode 100644 index 000000000..dff9b65aa --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_cacheresource_keyvaluestore.php @@ -0,0 +1,463 @@ +<?php +/** + * Smarty Internal Plugin + * + * @package Smarty + * @subpackage Cacher + */ + +/** + * Smarty Cache Handler Base for Key/Value Storage Implementations + * + * This class implements the functionality required to use simple key/value stores + * for hierarchical cache groups. key/value stores like memcache or APC do not support + * wildcards in keys, therefore a cache group cannot be cleared like "a|*" - which + * is no problem to filesystem and RDBMS implementations. + * + * This implementation is based on the concept of invalidation. While one specific cache + * can be identified and cleared, any range of caches cannot be identified. For this reason + * each level of the cache group hierarchy can have its own value in the store. These values + * are nothing but microtimes, telling us when a particular cache group was cleared for the + * last time. These keys are evaluated for every cache read to determine if the cache has + * been invalidated since it was created and should hence be treated as inexistent. + * + * Although deep hierarchies are possible, they are not recommended. Try to keep your + * cache groups as shallow as possible. Anything up 3-5 parents should be ok. So + * »a|b|c« is a good depth where »a|b|c|d|e|f|g|h|i|j|k« isn't. Try to join correlating + * cache groups: if your cache groups look somewhat like »a|b|$page|$items|$whatever« + * consider using »a|b|c|$page-$items-$whatever« instead. + * + * @package Smarty + * @subpackage Cacher + * @author Rodney Rehm + */ +abstract class Smarty_CacheResource_KeyValueStore extends Smarty_CacheResource { + + /** + * cache for contents + * @var array + */ + protected $contents = array(); + /** + * cache for timestamps + * @var array + */ + protected $timestamps = array(); + + /** + * populate Cached Object with meta data from Resource + * + * @param Smarty_Template_Cached $cached cached object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) + { + $cached->filepath = $_template->source->uid + . '#' . $this->sanitize($cached->source->name) + . '#' . $this->sanitize($cached->cache_id) + . '#' . $this->sanitize($cached->compile_id); + + $this->populateTimestamp($cached); + } + + /** + * populate Cached Object with timestamp and exists from Resource + * + * @param Smarty_Template_Cached $cached cached object + * @return void + */ + public function populateTimestamp(Smarty_Template_Cached $cached) + { + if (!$this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $content, $timestamp, $cached->source->uid)) { + return; + } + $cached->content = $content; + $cached->timestamp = (int) $timestamp; + $cached->exists = $cached->timestamp; + } + + /** + * Read the cached template and process the header + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if the cached content does not exist + */ + public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null) + { + if (!$cached) { + $cached = $_template->cached; + } + $content = $cached->content ? $cached->content : null; + $timestamp = $cached->timestamp ? $cached->timestamp : null; + if ($content === null || !$timestamp) { + if (!$this->fetch($_template->cached->filepath, $_template->source->name, $_template->cache_id, $_template->compile_id, $content, $timestamp, $_template->source->uid)) { + return false; + } + } + if (isset($content)) { + $_smarty_tpl = $_template; + eval("?>" . $content); + return true; + } + return false; + } + + /** + * Write the rendered template output to cache + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public function writeCachedContent(Smarty_Internal_Template $_template, $content) + { + $this->addMetaTimestamp($content); + return $this->write(array($_template->cached->filepath => $content), $_template->properties['cache_lifetime']); + } + + /** + * Empty cache + * + * {@internal the $exp_time argument is ignored altogether }} + * + * @param Smarty $smarty Smarty object + * @param integer $exp_time expiration time [being ignored] + * @return integer number of cache files deleted [always -1] + * @uses purge() to clear the whole store + * @uses invalidate() to mark everything outdated if purge() is inapplicable + */ + public function clearAll(Smarty $smarty, $exp_time=null) + { + if (!$this->purge()) { + $this->invalidate(null); + } + return -1; + } + + /** + * Empty cache for a specific template + * + * {@internal the $exp_time argument is ignored altogether}} + * + * @param Smarty $smarty Smarty object + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time [being ignored] + * @return integer number of cache files deleted [always -1] + * @uses buildCachedFilepath() to generate the CacheID + * @uses invalidate() to mark CacheIDs parent chain as outdated + * @uses delete() to remove CacheID from cache + */ + public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) + { + $uid = $this->getTemplateUid($smarty, $resource_name, $cache_id, $compile_id); + $cid = $uid . '#' . $this->sanitize($resource_name) . '#' . $this->sanitize($cache_id) . '#' . $this->sanitize($compile_id); + $this->delete(array($cid)); + $this->invalidate($cid, $resource_name, $cache_id, $compile_id, $uid); + return -1; + } + /** + * Get template's unique ID + * + * @param Smarty $smarty Smarty object + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @return string filepath of cache file + */ + protected function getTemplateUid(Smarty $smarty, $resource_name, $cache_id, $compile_id) + { + $uid = ''; + if (isset($resource_name)) { + $tpl = new $smarty->template_class($resource_name, $smarty); + if ($tpl->source->exists) { + $uid = $tpl->source->uid; + } + + // remove from template cache + if ($smarty->allow_ambiguous_resources) { + $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id; + } else { + $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id; + } + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); + } + unset($smarty->template_objects[$_templateId]); + } + return $uid; + } + + /** + * Sanitize CacheID components + * + * @param string $string CacheID component to sanitize + * @return string sanitized CacheID component + */ + protected function sanitize($string) + { + // some poeple smoke bad weed + $string = trim($string, '|'); + if (!$string) { + return null; + } + return preg_replace('#[^\w\|]+#S', '_', $string); + } + + /** + * Fetch and prepare a cache object. + * + * @param string $cid CacheID to fetch + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param string $content cached content + * @param integer &$timestamp cached timestamp (epoch) + * @param string $resource_uid resource's uid + * @return boolean success + */ + protected function fetch($cid, $resource_name = null, $cache_id = null, $compile_id = null, &$content = null, &$timestamp = null, $resource_uid = null) + { + $t = $this->read(array($cid)); + $content = !empty($t[$cid]) ? $t[$cid] : null; + $timestamp = null; + + if ($content && ($timestamp = $this->getMetaTimestamp($content))) { + $invalidated = $this->getLatestInvalidationTimestamp($cid, $resource_name, $cache_id, $compile_id, $resource_uid); + if ($invalidated > $timestamp) { + $timestamp = null; + $content = null; + } + } + + return !!$content; + } + + /** + * Add current microtime to the beginning of $cache_content + * + * {@internal the header uses 8 Bytes, the first 4 Bytes are the seconds, the second 4 Bytes are the microseconds}} + * + * @param string &$content the content to be cached + */ + protected function addMetaTimestamp(&$content) + { + $mt = explode(" ", microtime()); + $ts = pack("NN", $mt[1], (int) ($mt[0] * 100000000)); + $content = $ts . $content; + } + + /** + * Extract the timestamp the $content was cached + * + * @param string &$content the cached content + * @return float the microtime the content was cached + */ + protected function getMetaTimestamp(&$content) + { + $s = unpack("N", substr($content, 0, 4)); + $m = unpack("N", substr($content, 4, 4)); + $content = substr($content, 8); + return $s[1] + ($m[1] / 100000000); + } + + /** + * Invalidate CacheID + * + * @param string $cid CacheID + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param string $resource_uid source's uid + * @return void + */ + protected function invalidate($cid = null, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null) + { + $now = microtime(true); + $key = null; + // invalidate everything + if (!$resource_name && !$cache_id && !$compile_id) { + $key = 'IVK#ALL'; + } + // invalidate all caches by template + else if ($resource_name && !$cache_id && !$compile_id) { + $key = 'IVK#TEMPLATE#' . $resource_uid . '#' . $this->sanitize($resource_name); + } + // invalidate all caches by cache group + else if (!$resource_name && $cache_id && !$compile_id) { + $key = 'IVK#CACHE#' . $this->sanitize($cache_id); + } + // invalidate all caches by compile id + else if (!$resource_name && !$cache_id && $compile_id) { + $key = 'IVK#COMPILE#' . $this->sanitize($compile_id); + } + // invalidate by combination + else { + $key = 'IVK#CID#' . $cid; + } + $this->write(array($key => $now)); + } + + /** + * Determine the latest timestamp known to the invalidation chain + * + * @param string $cid CacheID to determine latest invalidation timestamp of + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param string $resource_uid source's filepath + * @return float the microtime the CacheID was invalidated + */ + protected function getLatestInvalidationTimestamp($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null) + { + // abort if there is no CacheID + if (false && !$cid) { + return 0; + } + // abort if there are no InvalidationKeys to check + if (!($_cid = $this->listInvalidationKeys($cid, $resource_name, $cache_id, $compile_id, $resource_uid))) { + return 0; + } + + // there are no InValidationKeys + if (!($values = $this->read($_cid))) { + return 0; + } + // make sure we're dealing with floats + $values = array_map('floatval', $values); + return max($values); + } + + /** + * Translate a CacheID into the list of applicable InvalidationKeys. + * + * Splits "some|chain|into|an|array" into array( '#clearAll#', 'some', 'some|chain', 'some|chain|into', ... ) + * + * @param string $cid CacheID to translate + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param string $resource_uid source's filepath + * @return array list of InvalidationKeys + * @uses $invalidationKeyPrefix to prepend to each InvalidationKey + */ + protected function listInvalidationKeys($cid, $resource_name = null, $cache_id = null, $compile_id = null, $resource_uid = null) + { + $t = array('IVK#ALL'); + $_name = $_compile = '#'; + if ($resource_name) { + $_name .= $resource_uid . '#' . $this->sanitize($resource_name); + $t[] = 'IVK#TEMPLATE' . $_name; + } + if ($compile_id) { + $_compile .= $this->sanitize($compile_id); + $t[] = 'IVK#COMPILE' . $_compile; + } + $_name .= '#'; + // some poeple smoke bad weed + $cid = trim($cache_id, '|'); + if (!$cid) { + return $t; + } + $i = 0; + while (true) { + // determine next delimiter position + $i = strpos($cid, '|', $i); + // add complete CacheID if there are no more delimiters + if ($i === false) { + $t[] = 'IVK#CACHE#' . $cid; + $t[] = 'IVK#CID' . $_name . $cid . $_compile; + $t[] = 'IVK#CID' . $_name . $_compile; + break; + } + $part = substr($cid, 0, $i); + // add slice to list + $t[] = 'IVK#CACHE#' . $part; + $t[] = 'IVK#CID' . $_name . $part . $_compile; + // skip past delimiter position + $i++; + } + return $t; + } + + /** + * Check is cache is locked for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if cache is locked + */ + public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $key = 'LOCK#' . $cached->filepath; + $data = $this->read(array($key)); + return $data && time() - $data[$key] < $smarty->locking_timeout; + } + + /** + * Lock cache for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + */ + public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $cached->is_locked = true; + $key = 'LOCK#' . $cached->filepath; + $this->write(array($key => time()), $smarty->locking_timeout); + } + + /** + * Unlock cache for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + */ + public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $cached->is_locked = false; + $key = 'LOCK#' . $cached->filepath; + $this->delete(array($key)); + } + + /** + * Read values for a set of keys from cache + * + * @param array $keys list of keys to fetch + * @return array list of values with the given keys used as indexes + */ + protected abstract function read(array $keys); + + /** + * Save values for a set of keys to cache + * + * @param array $keys list of values to save + * @param int $expire expiration time + * @return boolean true on success, false on failure + */ + protected abstract function write(array $keys, $expire=null); + + /** + * Remove values from cache + * + * @param array $keys list of keys to delete + * @return boolean true on success, false on failure + */ + protected abstract function delete(array $keys); + + /** + * Remove *all* values from cache + * + * @return boolean true on success, false on failure + */ + protected function purge() + { + return false; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_config_source.php b/include/smarty/libs/sysplugins/smarty_config_source.php new file mode 100644 index 000000000..043ff13e9 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_config_source.php @@ -0,0 +1,95 @@ +<?php +/** + * Smarty Internal Plugin + * + * @package Smarty + * @subpackage TemplateResources + */ + +/** + * Smarty Resource Data Object + * + * Meta Data Container for Config Files + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + * + * @property string $content + * @property int $timestamp + * @property bool $exists + */ +class Smarty_Config_Source extends Smarty_Template_Source { + + /** + * create Config Object container + * + * @param Smarty_Resource $handler Resource Handler this source object communicates with + * @param Smarty $smarty Smarty instance this source object belongs to + * @param string $resource full config_resource + * @param string $type type of resource + * @param string $name resource name + * @param string $unique_resource unqiue resource name + */ + public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource) + { + $this->handler = $handler; // Note: prone to circular references + + // Note: these may be ->config_compiler_class etc in the future + //$this->config_compiler_class = $handler->config_compiler_class; + //$this->config_lexer_class = $handler->config_lexer_class; + //$this->config_parser_class = $handler->config_parser_class; + + $this->smarty = $smarty; + $this->resource = $resource; + $this->type = $type; + $this->name = $name; + $this->unique_resource = $unique_resource; + } + + /** + * <<magic>> Generic setter. + * + * @param string $property_name valid: content, timestamp, exists + * @param mixed $value newly assigned value (not check for correct type) + * @throws SmartyException when the given property name is not valid + */ + public function __set($property_name, $value) + { + switch ($property_name) { + case 'content': + case 'timestamp': + case 'exists': + $this->$property_name = $value; + break; + + default: + throw new SmartyException("invalid config property '$property_name'."); + } + } + + /** + * <<magic>> Generic getter. + * + * @param string $property_name valid: content, timestamp, exists + * @throws SmartyException when the given property name is not valid + */ + public function __get($property_name) + { + switch ($property_name) { + case 'timestamp': + case 'exists': + $this->handler->populateTimestamp($this); + return $this->$property_name; + + case 'content': + return $this->content = $this->handler->getContent($this); + + default: + throw new SmartyException("config property '$property_name' does not exist."); + } + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_cacheresource_file.php b/include/smarty/libs/sysplugins/smarty_internal_cacheresource_file.php new file mode 100644 index 000000000..04194b396 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_cacheresource_file.php @@ -0,0 +1,266 @@ +<?php +/** + * Smarty Internal Plugin CacheResource File + * + * @package Smarty + * @subpackage Cacher + * @author Uwe Tews + * @author Rodney Rehm + */ + +/** + * This class does contain all necessary methods for the HTML cache on file system + * + * Implements the file system as resource for the HTML cache Version ussing nocache inserts. + * + * @package Smarty + * @subpackage Cacher + */ +class Smarty_Internal_CacheResource_File extends Smarty_CacheResource { + + /** + * populate Cached Object with meta data from Resource + * + * @param Smarty_Template_Cached $cached cached object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) + { + $_source_file_path = str_replace(':', '.', $_template->source->filepath); + $_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null; + $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null; + $_filepath = $_template->source->uid; + // if use_sub_dirs, break file into directories + if ($_template->smarty->use_sub_dirs) { + $_filepath = substr($_filepath, 0, 2) . DS + . substr($_filepath, 2, 2) . DS + . substr($_filepath, 4, 2) . DS + . $_filepath; + } + $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^'; + if (isset($_cache_id)) { + $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep; + } else { + $_cache_id = ''; + } + if (isset($_compile_id)) { + $_compile_id = $_compile_id . $_compile_dir_sep; + } else { + $_compile_id = ''; + } + $_cache_dir = $_template->smarty->getCacheDir(); + if ($_template->smarty->cache_locking) { + // create locking file name + // relative file name? + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) { + $_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir; + } else { + $_lock_dir = $_cache_dir; + } + $cached->lock_id = $_lock_dir.sha1($_cache_id.$_compile_id.$_template->source->uid).'.lock'; + } + $cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php'; + $cached->timestamp = @filemtime($cached->filepath); + $cached->exists = !!$cached->timestamp; + } + + /** + * populate Cached Object with timestamp and exists from Resource + * + * @param Smarty_Template_Cached $cached cached object + * @return void + */ + public function populateTimestamp(Smarty_Template_Cached $cached) + { + $cached->timestamp = @filemtime($cached->filepath); + $cached->exists = !!$cached->timestamp; + } + + /** + * Read the cached template and process its header + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if the cached content does not exist + */ + public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null) + { + $_smarty_tpl = $_template; + return @include $_template->cached->filepath; + } + + /** + * Write the rendered template output to cache + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public function writeCachedContent(Smarty_Internal_Template $_template, $content) + { + if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) { + $_template->cached->timestamp = @filemtime($_template->cached->filepath); + $_template->cached->exists = !!$_template->cached->timestamp; + if ($_template->cached->exists) { + return true; + } + } + return false; + } + + /** + * Empty cache + * + * @param Smarty_Internal_Template $_template template object + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public function clearAll(Smarty $smarty, $exp_time = null) + { + return $this->clear($smarty, null, null, null, $exp_time); + } + + /** + * Empty cache for a specific template + * + * @param Smarty $_template template object + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) + { + $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null; + $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null; + $_dir_sep = $smarty->use_sub_dirs ? '/' : '^'; + $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0; + $_dir = $smarty->getCacheDir(); + $_dir_length = strlen($_dir); + if (isset($_cache_id)) { + $_cache_id_parts = explode('|', $_cache_id); + $_cache_id_parts_count = count($_cache_id_parts); + if ($smarty->use_sub_dirs) { + foreach ($_cache_id_parts as $id_part) { + $_dir .= $id_part . DS; + } + } + } + if (isset($resource_name)) { + $_save_stat = $smarty->caching; + $smarty->caching = true; + $tpl = new $smarty->template_class($resource_name, $smarty); + $smarty->caching = $_save_stat; + + // remove from template cache + $tpl->source; // have the template registered before unset() + if ($smarty->allow_ambiguous_resources) { + $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id; + } else { + $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id; + } + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); + } + unset($smarty->template_objects[$_templateId]); + + if ($tpl->source->exists) { + $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath)); + } else { + return 0; + } + } + $_count = 0; + $_time = time(); + if (file_exists($_dir)) { + $_cacheDirs = new RecursiveDirectoryIterator($_dir); + $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST); + foreach ($_cache as $_file) { + if (substr(basename($_file->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue; + // directory ? + if ($_file->isDir()) { + if (!$_cache->isDot()) { + // delete folder if empty + @rmdir($_file->getPathname()); + } + } else { + $_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length))); + $_parts_count = count($_parts); + // check name + if (isset($resource_name)) { + if ($_parts[$_parts_count-1] != $_resourcename_parts) { + continue; + } + } + // check compile id + if (isset($_compile_id) && (!isset($_parts[$_parts_count-2 - $_compile_id_offset]) || $_parts[$_parts_count-2 - $_compile_id_offset] != $_compile_id)) { + continue; + } + // check cache id + if (isset($_cache_id)) { + // count of cache id parts + $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset; + if ($_parts_count < $_cache_id_parts_count) { + continue; + } + for ($i = 0; $i < $_cache_id_parts_count; $i++) { + if ($_parts[$i] != $_cache_id_parts[$i]) continue 2; + } + } + // expired ? + if (isset($exp_time) && $_time - @filemtime($_file) < $exp_time) { + continue; + } + $_count += @unlink((string) $_file) ? 1 : 0; + } + } + } + return $_count; + } + + /** + * Check is cache is locked for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + * @return booelan true or false if cache is locked + */ + public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + if (version_compare(PHP_VERSION, '5.3.0', '>=')) { + clearstatcache(true, $cached->lock_id); + } else { + clearstatcache(); + } + $t = @filemtime($cached->lock_id); + return $t && (time() - $t < $smarty->locking_timeout); + } + + /** + * Lock cache for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + */ + public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $cached->is_locked = true; + touch($cached->lock_id); + } + + /** + * Unlock cache for this template + * + * @param Smarty $smarty Smarty object + * @param Smarty_Template_Cached $cached cached object + */ + public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + $cached->is_locked = false; + @unlink($cached->lock_id); + } +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_append.php b/include/smarty/libs/sysplugins/smarty_internal_compile_append.php new file mode 100644 index 000000000..f6036e883 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_append.php @@ -0,0 +1,53 @@ +<?php +/** + * Smarty Internal Plugin Compile Append + * + * Compiles the {append} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Append Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Append extends Smarty_Internal_Compile_Assign { + + /** + * Compiles code for the {append} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // the following must be assigned at runtime because it will be overwritten in parent class + $this->required_attributes = array('var', 'value'); + $this->shorttag_order = array('var', 'value'); + $this->optional_attributes = array('scope', 'index'); + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // map to compile assign attributes + if (isset($_attr['index'])) { + $_params['smarty_internal_index'] = '[' . $_attr['index'] . ']'; + unset($_attr['index']); + } else { + $_params['smarty_internal_index'] = '[]'; + } + $_new_attr = array(); + foreach ($_attr as $key => $value) { + $_new_attr[] = array($key => $value); + } + // call compile assign + return parent::compile($_new_attr, $compiler, $_params); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_assign.php b/include/smarty/libs/sysplugins/smarty_internal_compile_assign.php new file mode 100644 index 000000000..f2dfedfb8 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_assign.php @@ -0,0 +1,88 @@ +<?php +/** + * Smarty Internal Plugin Compile Assign + * + * Compiles the {assign} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Assign Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {assign} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // the following must be assigned at runtime because it will be overwritten in Smarty_Internal_Compile_Append + $this->required_attributes = array('var', 'value'); + $this->shorttag_order = array('var', 'value'); + $this->optional_attributes = array('scope'); + $_nocache = 'null'; + $_scope = Smarty::SCOPE_LOCAL; + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // nocache ? + if ($compiler->tag_nocache || $compiler->nocache) { + $_nocache = 'true'; + // create nocache var to make it know for further compiling + if (isset($compiler->template->tpl_vars[trim($_attr['var'], "'")])) { + $compiler->template->tpl_vars[trim($_attr['var'], "'")]->nocache = true; + } else { + $compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true); + } + } + // scope setup + if (isset($_attr['scope'])) { + $_attr['scope'] = trim($_attr['scope'], "'\""); + if ($_attr['scope'] == 'parent') { + $_scope = Smarty::SCOPE_PARENT; + } elseif ($_attr['scope'] == 'root') { + $_scope = Smarty::SCOPE_ROOT; + } elseif ($_attr['scope'] == 'global') { + $_scope = Smarty::SCOPE_GLOBAL; + } else { + $compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno); + } + } + // compiled output + if (isset($parameter['smarty_internal_index'])) { + $output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];"; + } else { + // implement Smarty2's behaviour of variables assigned by reference + if ($compiler->template->smarty instanceof SmartyBC) { + $output = "<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; + $output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache; \$_smarty_tpl->tpl_vars[$_attr[var]]->scope = $_scope;"; + $output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);"; + } else { + $output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);"; + } + } + if ($_scope == Smarty::SCOPE_PARENT) { + $output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; + } elseif ($_scope == Smarty::SCOPE_ROOT || $_scope == Smarty::SCOPE_GLOBAL) { + $output .= "\n\$_ptr = \$_smarty_tpl->parent; while (\$_ptr != null) {\$_ptr->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]]; \$_ptr = \$_ptr->parent; }"; + } + if ( $_scope == Smarty::SCOPE_GLOBAL) { + $output .= "\nSmarty::\$global_tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; + } + $output .= '?>'; + return $output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_block.php b/include/smarty/libs/sysplugins/smarty_internal_compile_block.php new file mode 100644 index 000000000..f760e551d --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_block.php @@ -0,0 +1,282 @@ +<?php + +/** + * Smarty Internal Plugin Compile Block + * + * Compiles the {block}{/block} tags + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Block Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('name'); + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name', 'hide'); + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('hide'); + + /** + * Compiles code for the {block} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return boolean true + */ + public function compile($args, $compiler) { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + $save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code); + $this->openTag($compiler, 'block', $save); + if ($_attr['nocache'] == true) { + $compiler->nocache = true; + } + // set flag for {block} tag + $compiler->inheritance = true; + // must merge includes + $compiler->smarty->merge_compiled_includes = true; + + $compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser); + $compiler->has_code = false; + return true; + } + + /** + * Save or replace child block source by block name during parsing + * + * @param string $block_content block source content + * @param string $block_tag opening block tag + * @param object $template template object + * @param string $filepath filepath of template source + */ + public static function saveBlockData($block_content, $block_tag, $template, $filepath) { + $_rdl = preg_quote($template->smarty->right_delimiter); + $_ldl = preg_quote($template->smarty->left_delimiter); + if (!$template->smarty->auto_literal) { + $al = '\s*'; + } else { + $al = ''; + } + if (0 == preg_match("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) { + $error_text = 'Syntax Error in template "' . $template->source->filepath . '" "' . htmlspecialchars($block_tag) . '" illegal options'; + throw new SmartyCompilerException($error_text); + } else { + $_name = trim($_match[3], '\'"'); + if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child} + // get nested block tags + if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?)(hide)?(\s*{$_rdl})([\s\S]*?)(.*)?({$_ldl}{$al}/block\s*{$_rdl})!", $block_content, $_match2)) { + foreach ($_match2[3] as $key => $name) { + // get it's replacement + $_name2 = trim($name, '\'"'); + if ($_match2[5][$key] != 'hide' || isset($template->block_data[$_name2])) { + if (isset($template->block_data[$_name2])) { + $replacement = $template->block_data[$_name2]['source']; + } else { + $replacement = ''; + } + // replace {$smarty.block.child} tag + if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[7][$key])) { + $replacement = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $_match2[7][$key]); + $block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content); + } + if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[8][$key])) { + $replacement = preg_replace("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!", $replacement, $_match2[8][$key]); + $block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl})(.*)?({$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content); + } + } else { + // remove hidden blocks + $block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", '', $block_content); + } + } + } + // do we have not nested {$smart.block.child} + if (0 != preg_match("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $block_content, $_match2)) { + // get child replacement for this block + if (isset($template->block_data[$_name])) { + $replacement = $template->block_data[$_name]['source']; + unset($template->block_data[$_name]); + } else { + $replacement = ''; + } + $block_content = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $block_content); + } + if (isset($template->block_data[$_name])) { + if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) { + $template->block_data[$_name]['source'] = + str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']); + } elseif ($template->block_data[$_name]['mode'] == 'prepend') { + $template->block_data[$_name]['source'] .= $block_content; + } elseif ($template->block_data[$_name]['mode'] == 'append') { + $template->block_data[$_name]['source'] = $block_content . $template->block_data[$_name]['source']; + } + } else { + $template->block_data[$_name]['source'] = $block_content; + $template->block_data[$_name]['file'] = $filepath; + } + if ($_match[6] == 'append') { + $template->block_data[$_name]['mode'] = 'append'; + } elseif ($_match[6] == 'prepend') { + $template->block_data[$_name]['mode'] = 'prepend'; + } else { + $template->block_data[$_name]['mode'] = 'replace'; + } + } + } + } + + /** + * Compile saved child block source + * + * @param object $compiler compiler object + * @param string $_name optional name of child block + * @return string compiled code of schild block + */ + public static function compileChildBlock($compiler, $_name = null) { + $_output = ''; + // if called by {$smarty.block.child} we must search the name of enclosing {block} + if ($_name == null) { + $stack_count = count($compiler->_tag_stack); + while (--$stack_count >= 0) { + if ($compiler->_tag_stack[$stack_count][0] == 'block') { + $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "'\""); + break; + } + } + // flag that child is already compile by {$smarty.block.child} inclusion + $compiler->template->block_data[$_name]['compiled'] = true; + } + if ($_name == null) { + $compiler->trigger_template_error('{$smarty.block.child} used out of context', $compiler->lex->taglineno); + } + // undefined child? + if (!isset($compiler->template->block_data[$_name]['source'])) { + return ''; + } + $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id, + $compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime); + $_tpl->variable_filters = $compiler->template->variable_filters; + $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash']; + $_tpl->source->filepath = $compiler->template->block_data[$_name]['file']; + $_tpl->allow_relative_path = true; + if ($compiler->nocache) { + $_tpl->compiler->forceNocache = 2; + } else { + $_tpl->compiler->forceNocache = 1; + } + $_tpl->compiler->suppressHeader = true; + $_tpl->compiler->suppressTemplatePropertyHeader = true; + $_tpl->compiler->suppressMergedTemplates = true; + if (strpos($compiler->template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) { + $_output = str_replace('%%%%SMARTY_PARENT%%%%', $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl)); + } elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') { + $_output = $_tpl->compiler->compileTemplate($_tpl) . $compiler->parser->current_buffer->to_smarty_php(); + } elseif ($compiler->template->block_data[$_name]['mode'] == 'append') { + $_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl); + } elseif (!empty($compiler->template->block_data[$_name])) { + $_output = $_tpl->compiler->compileTemplate($_tpl); + } + $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']); + $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']); + $compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates); + $compiler->template->variable_filters = $_tpl->variable_filters; + if ($_tpl->has_nocache_code) { + $compiler->template->has_nocache_code = true; + } + foreach ($_tpl->required_plugins as $key => $tmp1) { + if ($compiler->nocache && $compiler->template->caching) { + $code = 'nocache'; + } else { + $code = $key; + } + foreach ($tmp1 as $name => $tmp) { + foreach ($tmp as $type => $data) { + $compiler->template->required_plugins[$code][$name][$type] = $data; + } + } + } + unset($_tpl); + return $_output; + } + +} + +/** + * Smarty Internal Plugin Compile BlockClose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/block} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) { + $compiler->has_code = true; + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + $saved_data = $this->closeTag($compiler, array('block')); + $_name = trim($saved_data[0]['name'], "\"'"); + if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) { + // restore to status before {block} tag as new subtemplate code of parent {block} is not needed + // TODO: Below code was disabled in 3.1.8 because of problems with {include} in nested {block} tags in child templates + // combined with append/prepend or $smarty.block.parent + // For later versions it should be checked under which conditions it could run for optimisation + // + //$compiler->merged_templates = $saved_data[4]; + //$compiler->smarty->merged_templates_func = $saved_data[5]; + //$compiler->template->properties = $saved_data[6]; + //$compiler->template->has_nocache_code = $saved_data[7]; + $_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name); + } else { + if (isset($saved_data[0]['hide']) && !isset($compiler->template->block_data[$_name]['source'])) { + $_output = ''; + } else { + $_output = $compiler->parser->current_buffer->to_smarty_php(); + } + unset($compiler->template->block_data[$_name]['compiled']); + } + // reset flags + $compiler->parser->current_buffer = $saved_data[1]; + $compiler->nocache = $saved_data[2]; + $compiler->smarty->merge_compiled_includes = $saved_data[3]; + // reset flag for {block} tag + $compiler->inheritance = false; + // $_output content has already nocache code processed + $compiler->suppressNocacheProcessing = true; + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_break.php b/include/smarty/libs/sysplugins/smarty_internal_compile_break.php new file mode 100644 index 000000000..259c66e2b --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_break.php @@ -0,0 +1,77 @@ +<?php
+/**
+ * Smarty Internal Plugin Compile Break
+ *
+ * Compiles the {break} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+/**
+ * Smarty Internal Plugin Compile Break Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('levels');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('levels');
+
+ /**
+ * Compiles code for the {break} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter)
+ {
+ static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+
+ if (isset($_attr['levels'])) {
+ if (!is_numeric($_attr['levels'])) {
+ $compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
+ }
+ $_levels = $_attr['levels'];
+ } else {
+ $_levels = 1;
+ }
+ $level_count = $_levels;
+ $stack_count = count($compiler->_tag_stack) - 1;
+ while ($level_count > 0 && $stack_count >= 0) {
+ if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
+ $level_count--;
+ }
+ $stack_count--;
+ }
+ if ($level_count != 0) {
+ $compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
+ }
+ $compiler->has_code = true;
+ return "<?php break {$_levels}?>";
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_call.php b/include/smarty/libs/sysplugins/smarty_internal_compile_call.php new file mode 100644 index 000000000..af12a048c --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_call.php @@ -0,0 +1,130 @@ +<?php +/** + * Smarty Internal Plugin Compile Function_Call + * + * Compiles the calls of user defined tags defined by {function} + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Function_Call Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles the calls of user defined tags defined by {function} + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // save possible attributes + if (isset($_attr['assign'])) { + // output will be stored in a smarty variable instead of beind displayed + $_assign = $_attr['assign']; + } + $_name = $_attr['name']; + if ($compiler->compiles_template_function) { + $compiler->called_functions[] = trim($_name, "'\""); + } + unset($_attr['name'], $_attr['assign'], $_attr['nocache']); + // set flag (compiled code of {function} must be included in cache file + if ($compiler->nocache || $compiler->tag_nocache) { + $_nocache = 'true'; + } else { + $_nocache = 'false'; + } + $_paramsArray = array(); + foreach ($_attr as $_key => $_value) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + if (isset($compiler->template->properties['function'][$_name]['parameter'])) { + foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) { + if (!isset($_attr[$_key])) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + } + } elseif (isset($compiler->smarty->template_functions[$_name]['parameter'])) { + foreach ($compiler->smarty->template_functions[$_name]['parameter'] as $_key => $_value) { + if (!isset($_attr[$_key])) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + } + } + //varibale name? + if (!(strpos($_name, '$') === false)) { + $call_cache = $_name; + $call_function = '$tmp = "smarty_template_function_".' . $_name . '; $tmp'; + } else { + $_name = trim($_name, "'\""); + $call_cache = "'{$_name}'"; + $call_function = 'smarty_template_function_' . $_name; + } + + $_params = 'array(' . implode(",", $_paramsArray) . ')'; + $_hash = str_replace('-', '_', $compiler->template->properties['nocache_hash']); + // was there an assign attribute + if (isset($_assign)) { + if ($compiler->template->caching) { + $_output = "<?php ob_start(); Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n"; + } else { + $_output = "<?php ob_start(); {$call_function}(\$_smarty_tpl,{$_params}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n"; + } + } else { + if ($compiler->template->caching) { + $_output = "<?php Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache});?>\n"; + } else { + $_output = "<?php {$call_function}(\$_smarty_tpl,{$_params});?>\n"; + } + } + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_capture.php b/include/smarty/libs/sysplugins/smarty_internal_compile_capture.php new file mode 100644 index 000000000..9a5071ebe --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_capture.php @@ -0,0 +1,98 @@ +<?php +/** + * Smarty Internal Plugin Compile Capture + * + * Compiles the {capture} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Capture Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Capture extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('name', 'assign', 'append'); + + /** + * Compiles code for the {capture} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + $buffer = isset($_attr['name']) ? $_attr['name'] : "'default'"; + $assign = isset($_attr['assign']) ? $_attr['assign'] : 'null'; + $append = isset($_attr['append']) ? $_attr['append'] : 'null'; + + $compiler->_capture_stack[0][] = array($buffer, $assign, $append, $compiler->nocache); + // maybe nocache because of nocache variables + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + $_output = "<?php \$_smarty_tpl->_capture_stack[0][] = array($buffer, $assign, $append); ob_start(); ?>"; + + return $_output; + } + +} + +/** + * Smarty Internal Plugin Compile Captureclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_CaptureClose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/capture} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + + list($buffer, $assign, $append, $compiler->nocache) = array_pop($compiler->_capture_stack[0]); + + $_output = "<?php list(\$_capture_buffer, \$_capture_assign, \$_capture_append) = array_pop(\$_smarty_tpl->_capture_stack[0]);\n"; + $_output .= "if (!empty(\$_capture_buffer)) {\n"; + $_output .= " if (isset(\$_capture_assign)) \$_smarty_tpl->assign(\$_capture_assign, ob_get_contents());\n"; + $_output .= " if (isset( \$_capture_append)) \$_smarty_tpl->append( \$_capture_append, ob_get_contents());\n"; + $_output .= " Smarty::\$_smarty_vars['capture'][\$_capture_buffer]=ob_get_clean();\n"; + $_output .= "} else \$_smarty_tpl->capture_error();?>"; + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_config_load.php b/include/smarty/libs/sysplugins/smarty_internal_compile_config_load.php new file mode 100644 index 000000000..deaa052c5 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_config_load.php @@ -0,0 +1,85 @@ +<?php +/** + * Smarty Internal Plugin Compile Config Load + * + * Compiles the {config load} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Config Load Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('file'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('file','section'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('section', 'scope'); + + /** + * Compiles code for the {config_load} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + static $_is_legal_scope = array('local' => true,'parent' => true,'root' => true,'global' => true); + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + if ($_attr['nocache'] === true) { + $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); + } + + + // save posible attributes + $conf_file = $_attr['file']; + if (isset($_attr['section'])) { + $section = $_attr['section']; + } else { + $section = 'null'; + } + $scope = 'local'; + // scope setup + if (isset($_attr['scope'])) { + $_attr['scope'] = trim($_attr['scope'], "'\""); + if (isset($_is_legal_scope[$_attr['scope']])) { + $scope = $_attr['scope']; + } else { + $compiler->trigger_template_error('illegal value for "scope" attribute', $compiler->lex->taglineno); + } + } + // create config object + $_output = "<?php \$_config = new Smarty_Internal_Config($conf_file, \$_smarty_tpl->smarty, \$_smarty_tpl);"; + $_output .= "\$_config->loadConfigVars($section, '$scope'); ?>"; + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_continue.php b/include/smarty/libs/sysplugins/smarty_internal_compile_continue.php new file mode 100644 index 000000000..4082a93b3 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_continue.php @@ -0,0 +1,78 @@ +<?php
+/**
+ * Smarty Internal Plugin Compile Continue
+ *
+ * Compiles the {continue} tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Continue Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('levels');
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $shorttag_order = array('levels');
+
+ /**
+ * Compiles code for the {continue} tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter)
+ {
+ static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+
+ if ($_attr['nocache'] === true) {
+ $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
+ }
+
+ if (isset($_attr['levels'])) {
+ if (!is_numeric($_attr['levels'])) {
+ $compiler->trigger_template_error('level attribute must be a numeric constant', $compiler->lex->taglineno);
+ }
+ $_levels = $_attr['levels'];
+ } else {
+ $_levels = 1;
+ }
+ $level_count = $_levels;
+ $stack_count = count($compiler->_tag_stack) - 1;
+ while ($level_count > 0 && $stack_count >= 0) {
+ if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
+ $level_count--;
+ }
+ $stack_count--;
+ }
+ if ($level_count != 0) {
+ $compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
+ }
+ $compiler->has_code = true;
+ return "<?php continue {$_levels}?>";
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_debug.php b/include/smarty/libs/sysplugins/smarty_internal_compile_debug.php new file mode 100644 index 000000000..f50c7aee2 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_debug.php @@ -0,0 +1,43 @@ +<?php +/** + * Smarty Internal Plugin Compile Debug + * + * Compiles the {debug} tag. + * It opens a window the the Smarty Debugging Console. + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Debug Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Debug extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {debug} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + // compile always as nocache + $compiler->tag_nocache = true; + + // display debug template + $_output = "<?php \$_smarty_tpl->smarty->loadPlugin('Smarty_Internal_Debug'); Smarty_Internal_Debug::display_debug(\$_smarty_tpl); ?>"; + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_eval.php b/include/smarty/libs/sysplugins/smarty_internal_compile_eval.php new file mode 100644 index 000000000..6cf481b50 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_eval.php @@ -0,0 +1,73 @@ +<?php +/** + * Smarty Internal Plugin Compile Eval + * + * Compiles the {eval} tag. + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Eval Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Eval extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('var'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('assign'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('var','assign'); + + /** + * Compiles code for the {eval} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + $this->required_attributes = array('var'); + $this->optional_attributes = array('assign'); + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if (isset($_attr['assign'])) { + // output will be stored in a smarty variable instead of beind displayed + $_assign = $_attr['assign']; + } + + // create template object + $_output = "\$_template = new {$compiler->smarty->template_class}('eval:'.".$_attr['var'].", \$_smarty_tpl->smarty, \$_smarty_tpl);"; + //was there an assign attribute? + if (isset($_assign)) { + $_output .= "\$_smarty_tpl->assign($_assign,\$_template->fetch());"; + } else { + $_output .= "echo \$_template->fetch();"; + } + return "<?php $_output ?>"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_extends.php b/include/smarty/libs/sysplugins/smarty_internal_compile_extends.php new file mode 100644 index 000000000..fe14a4081 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_extends.php @@ -0,0 +1,133 @@ +<?php + +/** +* Smarty Internal Plugin Compile extend +* +* Compiles the {extends} tag +* +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ + +/** +* Smarty Internal Plugin Compile extend Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('file'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('file'); + /** + * mbstring.overload flag + * + * @var int + */ + public $mbstring_overload = 0; + + /** + * Compiles code for the {extends} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + static $_is_stringy = array('string' => true, 'eval' => true); + $this->_rdl = preg_quote($compiler->smarty->right_delimiter); + $this->_ldl = preg_quote($compiler->smarty->left_delimiter); + if (!$compiler->smarty->auto_literal) { + $al = '\s*'; + } else { + $al = ''; + } + $filepath = $compiler->template->source->filepath; + $this->mbstring_overload = ini_get('mbstring.func_overload') & 2; + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); + } + + $_smarty_tpl = $compiler->template; + $include_file = null; + if (strpos($_attr['file'], '$_tmp') !== false) { + $compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno); + } + eval('$include_file = ' . $_attr['file'] . ';'); + // create template object + $_template = new $compiler->smarty->template_class($include_file, $compiler->smarty, $compiler->template); + // save file dependency + if (isset($_is_stringy[$_template->source->type])) { + $template_sha1 = sha1($include_file); + } else { + $template_sha1 = sha1($_template->source->filepath); + } + if (isset($compiler->template->properties['file_dependency'][$template_sha1])) { + $compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1); + } + $compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); + $_content = ($this->mbstring_overload ? mb_substr($compiler->lex->data, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->lex->data, $compiler->lex->counter - 1)); + if (preg_match_all("!({$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) != + preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) { + $compiler->trigger_template_error('unmatched {block} {/block} pairs'); + } + preg_match_all("!{$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl}|{$this->_ldl}{$al}/block\s*{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); + $_result_count = count($_result[0]); + $_start = 0; + while ($_start+1 < $_result_count) { + $_end = 0; + $_level = 1; + if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') { + $_start++; + continue; + } + while ($_level != 0) { + $_end++; + if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') { + continue; + } + if (!strpos($_result[0][$_start + $_end][0], '/')) { + $_level++; + } else { + $_level--; + } + } + $_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', + ($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])))); + Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath); + $_start = $_start + $_end + 1; + } + if ($_template->source->type == 'extends') { + $_template->block_data = $compiler->template->block_data; + } + $compiler->template->source->content = $_template->source->content; + if ($_template->source->type == 'extends') { + $compiler->template->block_data = $_template->block_data; + foreach ($_template->source->components as $key => $component) { + $compiler->template->properties['file_dependency'][$key] = array($component->filepath, $component->timestamp, $component->type); + } + } + $compiler->template->source->filepath = $_template->source->filepath; + $compiler->abort_and_recompile = true; + return ''; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_for.php b/include/smarty/libs/sysplugins/smarty_internal_compile_for.php new file mode 100644 index 000000000..057f4fb79 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_for.php @@ -0,0 +1,151 @@ +<?php +/** + * Smarty Internal Plugin Compile For + * + * Compiles the {for} {forelse} {/for} tags + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile For Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_For extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {for} tag + * + * Smarty 3 does implement two different sytaxes: + * + * - {for $var in $array} + * For looping over arrays or iterators + * + * - {for $x=0; $x<$y; $x++} + * For general loops + * + * The parser is gereration different sets of attribute by which this compiler can + * determin which syntax is used. + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + if ($parameter == 0) { + $this->required_attributes = array('start', 'to'); + $this->optional_attributes = array('max', 'step'); + } else { + $this->required_attributes = array('start', 'ifexp', 'var', 'step'); + $this->optional_attributes = array(); + } + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + $output = "<?php "; + if ($parameter == 1) { + foreach ($_attr['start'] as $_statement) { + $output .= " \$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;"; + $output .= " \$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value];\n"; + } + $output .= " if ($_attr[ifexp]){ for (\$_foo=true;$_attr[ifexp]; \$_smarty_tpl->tpl_vars[$_attr[var]]->value$_attr[step]){\n"; + } else { + $_statement = $_attr['start']; + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]] = new Smarty_Variable;"; + if (isset($_attr['step'])) { + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = $_attr[step];"; + } else { + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->step = 1;"; + } + if (isset($_attr['max'])) { + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int)min(ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step)),$_attr[max]);\n"; + } else { + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->total = (int)ceil((\$_smarty_tpl->tpl_vars[$_statement[var]]->step > 0 ? $_attr[to]+1 - ($_statement[value]) : $_statement[value]-($_attr[to])+1)/abs(\$_smarty_tpl->tpl_vars[$_statement[var]]->step));\n"; + } + $output .= "if (\$_smarty_tpl->tpl_vars[$_statement[var]]->total > 0){\n"; + $output .= "for (\$_smarty_tpl->tpl_vars[$_statement[var]]->value = $_statement[value], \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration = 1;\$_smarty_tpl->tpl_vars[$_statement[var]]->iteration <= \$_smarty_tpl->tpl_vars[$_statement[var]]->total;\$_smarty_tpl->tpl_vars[$_statement[var]]->value += \$_smarty_tpl->tpl_vars[$_statement[var]]->step, \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration++){\n"; + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->first = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == 1;"; + $output .= "\$_smarty_tpl->tpl_vars[$_statement[var]]->last = \$_smarty_tpl->tpl_vars[$_statement[var]]->iteration == \$_smarty_tpl->tpl_vars[$_statement[var]]->total;"; + } + $output .= "?>"; + + $this->openTag($compiler, 'for', array('for', $compiler->nocache)); + // maybe nocache because of nocache variables + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + // return compiled code + return $output; + } + +} + +/** + * Smarty Internal Plugin Compile Forelse Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Forelse extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {forelse} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + list($openTag, $nocache) = $this->closeTag($compiler, array('for')); + $this->openTag($compiler, 'forelse', array('forelse', $nocache)); + return "<?php }} else { ?>"; + } + +} + +/** + * Smarty Internal Plugin Compile Forclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Forclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/for} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + + list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('for', 'forelse')); + + if ($openTag == 'forelse') { + return "<?php } ?>"; + } else { + return "<?php }} ?>"; + } + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_foreach.php b/include/smarty/libs/sysplugins/smarty_internal_compile_foreach.php new file mode 100644 index 000000000..1354c89d5 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_foreach.php @@ -0,0 +1,231 @@ +<?php +/** + * Smarty Internal Plugin Compile Foreach + * + * Compiles the {foreach} {foreachelse} {/foreach} tags + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Foreach Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Foreach extends Smarty_Internal_CompileBase { + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('from', 'item'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('name', 'key'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('from','item','key','name'); + + /** + * Compiles code for the {foreach} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + $tpl = $compiler->template; + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + $from = $_attr['from']; + $item = $_attr['item']; + if (!strncmp("\$_smarty_tpl->tpl_vars[$item]", $from, strlen($item) + 24)) { + $compiler->trigger_template_error("item variable {$item} may not be the same variable as at 'from'", $compiler->lex->taglineno); + } + + if (isset($_attr['key'])) { + $key = $_attr['key']; + } else { + $key = null; + } + + $this->openTag($compiler, 'foreach', array('foreach', $compiler->nocache, $item, $key)); + // maybe nocache because of nocache variables + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + + if (isset($_attr['name'])) { + $name = $_attr['name']; + $has_name = true; + $SmartyVarName = '$smarty.foreach.' . trim($name, '\'"') . '.'; + } else { + $name = null; + $has_name = false; + } + $ItemVarName = '$' . trim($item, '\'"') . '@'; + // evaluates which Smarty variables and properties have to be computed + if ($has_name) { + $usesSmartyFirst = strpos($tpl->source->content, $SmartyVarName . 'first') !== false; + $usesSmartyLast = strpos($tpl->source->content, $SmartyVarName . 'last') !== false; + $usesSmartyIndex = strpos($tpl->source->content, $SmartyVarName . 'index') !== false; + $usesSmartyIteration = strpos($tpl->source->content, $SmartyVarName . 'iteration') !== false; + $usesSmartyShow = strpos($tpl->source->content, $SmartyVarName . 'show') !== false; + $usesSmartyTotal = strpos($tpl->source->content, $SmartyVarName . 'total') !== false; + } else { + $usesSmartyFirst = false; + $usesSmartyLast = false; + $usesSmartyTotal = false; + $usesSmartyShow = false; + } + + $usesPropFirst = $usesSmartyFirst || strpos($tpl->source->content, $ItemVarName . 'first') !== false; + $usesPropLast = $usesSmartyLast || strpos($tpl->source->content, $ItemVarName . 'last') !== false; + $usesPropIndex = $usesPropFirst || strpos($tpl->source->content, $ItemVarName . 'index') !== false; + $usesPropIteration = $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'iteration') !== false; + $usesPropShow = strpos($tpl->source->content, $ItemVarName . 'show') !== false; + $usesPropTotal = $usesSmartyTotal || $usesSmartyShow || $usesPropShow || $usesPropLast || strpos($tpl->source->content, $ItemVarName . 'total') !== false; + // generate output code + $output = "<?php "; + $output .= " \$_smarty_tpl->tpl_vars[$item] = new Smarty_Variable; \$_smarty_tpl->tpl_vars[$item]->_loop = false;\n"; + if ($key != null) { + $output .= " \$_smarty_tpl->tpl_vars[$key] = new Smarty_Variable;\n"; + } + $output .= " \$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array');}\n"; + if ($usesPropTotal) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->total= \$_smarty_tpl->_count(\$_from);\n"; + } + if ($usesPropIteration) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->iteration=0;\n"; + } + if ($usesPropIndex) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->index=-1;\n"; + } + if ($usesPropShow) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->show = (\$_smarty_tpl->tpl_vars[$item]->total > 0);\n"; + } + if ($has_name) { + if ($usesSmartyTotal) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['total'] = \$_smarty_tpl->tpl_vars[$item]->total;\n"; + } + if ($usesSmartyIteration) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']=0;\n"; + } + if ($usesSmartyIndex) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']=-1;\n"; + } + if ($usesSmartyShow) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['show']=(\$_smarty_tpl->tpl_vars[$item]->total > 0);\n"; + } + } + $output .= "foreach (\$_from as \$_smarty_tpl->tpl_vars[$item]->key => \$_smarty_tpl->tpl_vars[$item]->value){\n\$_smarty_tpl->tpl_vars[$item]->_loop = true;\n"; + if ($key != null) { + $output .= " \$_smarty_tpl->tpl_vars[$key]->value = \$_smarty_tpl->tpl_vars[$item]->key;\n"; + } + if ($usesPropIteration) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->iteration++;\n"; + } + if ($usesPropIndex) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->index++;\n"; + } + if ($usesPropFirst) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->first = \$_smarty_tpl->tpl_vars[$item]->index === 0;\n"; + } + if ($usesPropLast) { + $output .= " \$_smarty_tpl->tpl_vars[$item]->last = \$_smarty_tpl->tpl_vars[$item]->iteration === \$_smarty_tpl->tpl_vars[$item]->total;\n"; + } + if ($has_name) { + if ($usesSmartyFirst) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['first'] = \$_smarty_tpl->tpl_vars[$item]->first;\n"; + } + if ($usesSmartyIteration) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['iteration']++;\n"; + } + if ($usesSmartyIndex) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['index']++;\n"; + } + if ($usesSmartyLast) { + $output .= " \$_smarty_tpl->tpl_vars['smarty']->value['foreach'][$name]['last'] = \$_smarty_tpl->tpl_vars[$item]->last;\n"; + } + } + $output .= "?>"; + + return $output; + } +} + +/** + * Smarty Internal Plugin Compile Foreachelse Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Foreachelse extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {foreachelse} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + list($openTag, $nocache, $item, $key) = $this->closeTag($compiler, array('foreach')); + $this->openTag($compiler, 'foreachelse', array('foreachelse', $nocache, $item, $key)); + + return "<?php }\nif (!\$_smarty_tpl->tpl_vars[$item]->_loop) {\n?>"; + } + +} + +/** + * Smarty Internal Plugin Compile Foreachclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Foreachclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/foreach} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + + list($openTag, $compiler->nocache, $item, $key) = $this->closeTag($compiler, array('foreach', 'foreachelse')); + + return "<?php } ?>"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_function.php b/include/smarty/libs/sysplugins/smarty_internal_compile_function.php new file mode 100644 index 000000000..7821d2038 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_function.php @@ -0,0 +1,166 @@ +<?php +/** + * Smarty Internal Plugin Compile Function + * + * Compiles the {function} {/function} tags + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Function Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the {function} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return boolean true + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + if ($_attr['nocache'] === true) { + $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); + } + unset($_attr['nocache']); + $save = array($_attr, $compiler->parser->current_buffer, + $compiler->template->has_nocache_code, $compiler->template->required_plugins); + $this->openTag($compiler, 'function', $save); + $_name = trim($_attr['name'], "'\""); + unset($_attr['name']); + // set flag that we are compiling a template function + $compiler->compiles_template_function = true; + $compiler->template->properties['function'][$_name]['parameter'] = array(); + $_smarty_tpl = $compiler->template; + foreach ($_attr as $_key => $_data) { + eval ('$tmp='.$_data.';'); + $compiler->template->properties['function'][$_name]['parameter'][$_key] = $tmp; + } + $compiler->smarty->template_functions[$_name]['parameter'] = $compiler->template->properties['function'][$_name]['parameter']; + if ($compiler->template->caching) { + $output = ''; + } else { + $output = "<?php if (!function_exists('smarty_template_function_{$_name}')) { + function smarty_template_function_{$_name}(\$_smarty_tpl,\$params) { + \$saved_tpl_vars = \$_smarty_tpl->tpl_vars; + foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}; + foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>"; + } + // Init temporay context + $compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array()); + $compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser); + $compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output)); + $compiler->template->has_nocache_code = false; + $compiler->has_code = false; + $compiler->template->properties['function'][$_name]['compiled'] = ''; + return true; + } + +} + +/** + * Smarty Internal Plugin Compile Functionclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/function} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return boolean true + */ + public function compile($args, $compiler, $parameter) + { + $_attr = $this->getAttributes($compiler, $args); + $saved_data = $this->closeTag($compiler, array('function')); + $_name = trim($saved_data[0]['name'], "'\""); + // build plugin include code + $plugins_string = ''; + if (!empty($compiler->template->required_plugins['compiled'])) { + $plugins_string = '<?php '; + foreach($compiler->template->required_plugins['compiled'] as $tmp) { + foreach($tmp as $data) { + $plugins_string .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n"; + } + } + $plugins_string .= '?>'; + } + if (!empty($compiler->template->required_plugins['nocache'])) { + $plugins_string .= "<?php echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php "; + foreach($compiler->template->required_plugins['nocache'] as $tmp) { + foreach($tmp as $data) { + $plugins_string .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n"; + } + } + $plugins_string .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';?>\n"; + } + // remove last line break from function definition + $last = count($compiler->parser->current_buffer->subtrees) - 1; + if ($compiler->parser->current_buffer->subtrees[$last] instanceof _smarty_linebreak) { + unset($compiler->parser->current_buffer->subtrees[$last]); + } + // if caching save template function for possible nocache call + if ($compiler->template->caching) { + $compiler->template->properties['function'][$_name]['compiled'] .= $plugins_string + . $compiler->parser->current_buffer->to_smarty_php(); + $compiler->template->properties['function'][$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash']; + $compiler->template->properties['function'][$_name]['has_nocache_code'] = $compiler->template->has_nocache_code; + $compiler->template->properties['function'][$_name]['called_functions'] = $compiler->called_functions; + $compiler->called_functions = array(); + $compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name]; + $compiler->has_code = false; + $output = true; + } else { + $output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars; +foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n"; + } + // reset flag that we are compiling a template function + $compiler->compiles_template_function = false; + // restore old compiler status + $compiler->parser->current_buffer = $saved_data[1]; + $compiler->template->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[2]; + $compiler->template->required_plugins = $saved_data[3]; + return $output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_if.php b/include/smarty/libs/sysplugins/smarty_internal_compile_if.php new file mode 100644 index 000000000..8794b014b --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_if.php @@ -0,0 +1,207 @@ +<?php +/** +* Smarty Internal Plugin Compile If +* +* Compiles the {if} {else} {elseif} {/if} tags +* +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ + +/** +* Smarty Internal Plugin Compile If Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_If extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {if} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + $this->openTag($compiler, 'if', array(1, $compiler->nocache)); + // must whole block be nocache ? + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + + if (!array_key_exists("if condition",$parameter)) { + $compiler->trigger_template_error("missing if condition", $compiler->lex->taglineno); + } + + if (is_array($parameter['if condition'])) { + if ($compiler->nocache) { + $_nocache = ',true'; + // create nocache var to make it know for further compiling + if (is_array($parameter['if condition']['var'])) { + $compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true); + } else { + $compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true); + } + } else { + $_nocache = ''; + } + if (is_array($parameter['if condition']['var'])) { + $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]) || !is_array(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]->value)) \$_smarty_tpl->createLocalArrayVariable(".$parameter['if condition']['var']['var']."$_nocache);\n"; + $_output .= "if (\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']['var']."]->value".$parameter['if condition']['var']['smarty_internal_index']." = ".$parameter['if condition']['value']."){?>"; + } else { + $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."])) \$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."] = new Smarty_Variable(null{$_nocache});"; + $_output .= "if (\$_smarty_tpl->tpl_vars[".$parameter['if condition']['var']."]->value = ".$parameter['if condition']['value']."){?>"; + } + return $_output; + } else { + return "<?php if ({$parameter['if condition']}){?>"; + } + } + +} + +/** +* Smarty Internal Plugin Compile Else Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_Else extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {else} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif')); + $this->openTag($compiler, 'else', array($nesting, $compiler->tag_nocache)); + + return "<?php }else{ ?>"; + } + +} + +/** +* Smarty Internal Plugin Compile ElseIf Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_Elseif extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {elseif} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + list($nesting, $compiler->tag_nocache) = $this->closeTag($compiler, array('if', 'elseif')); + + if (!array_key_exists("if condition",$parameter)) { + $compiler->trigger_template_error("missing elseif condition", $compiler->lex->taglineno); + } + + if (is_array($parameter['if condition'])) { + $condition_by_assign = true; + if ($compiler->nocache) { + $_nocache = ',true'; + // create nocache var to make it know for further compiling + if (is_array($parameter['if condition']['var'])) { + $compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true); + } else { + $compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true); + } + } else { + $_nocache = ''; + } + } else { + $condition_by_assign = false; + } + + if (empty($compiler->prefix_code)) { + if ($condition_by_assign) { + $this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache)); + if (is_array($parameter['if condition']['var'])) { + $_output = "<?php }else{ if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n"; + $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>"; + } else { + $_output = "<?php }else{ if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});"; + $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>"; + } + return $_output; + } else { + $this->openTag($compiler, 'elseif', array($nesting, $compiler->tag_nocache)); + return "<?php }elseif({$parameter['if condition']}){?>"; + } + } else { + $tmp = ''; + foreach ($compiler->prefix_code as $code) + $tmp .= $code; + $compiler->prefix_code = array(); + $this->openTag($compiler, 'elseif', array($nesting + 1, $compiler->tag_nocache)); + if ($condition_by_assign) { + if (is_array($parameter['if condition']['var'])) { + $_output = "<?php }else{?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n"; + $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>"; + } else { + $_output = "<?php }else{?>{$tmp}<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});"; + $_output .= "if (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>"; + } + return $_output; + } else { + return "<?php }else{?>{$tmp}<?php if ({$parameter['if condition']}){?>"; + } + } + } + +} + +/** +* Smarty Internal Plugin Compile Ifclose Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_Ifclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/if} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + list($nesting, $compiler->nocache) = $this->closeTag($compiler, array('if', 'else', 'elseif')); + $tmp = ''; + for ($i = 0; $i < $nesting; $i++) { + $tmp .= '}'; + } + return "<?php {$tmp}?>"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_include.php b/include/smarty/libs/sysplugins/smarty_internal_compile_include.php new file mode 100644 index 000000000..43a144f94 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_include.php @@ -0,0 +1,215 @@ +<?php +/** +* Smarty Internal Plugin Compile Include +* +* Compiles the {include} tag +* +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ + +/** +* Smarty Internal Plugin Compile Include Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase { + + /** + * caching mode to create nocache code but no cache file + */ + const CACHING_NOCACHE_CODE = 9999; + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('file'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('file'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $option_flags = array('nocache', 'inline', 'caching'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the {include} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // save posible attributes + $include_file = $_attr['file']; + + if (isset($_attr['assign'])) { + // output will be stored in a smarty variable instead of beind displayed + $_assign = $_attr['assign']; + } + + $_parent_scope = Smarty::SCOPE_LOCAL; + if (isset($_attr['scope'])) { + $_attr['scope'] = trim($_attr['scope'], "'\""); + if ($_attr['scope'] == 'parent') { + $_parent_scope = Smarty::SCOPE_PARENT; + } elseif ($_attr['scope'] == 'root') { + $_parent_scope = Smarty::SCOPE_ROOT; + } elseif ($_attr['scope'] == 'global') { + $_parent_scope = Smarty::SCOPE_GLOBAL; + } + } + $_caching = 'null'; + if ($compiler->nocache || $compiler->tag_nocache) { + $_caching = Smarty::CACHING_OFF; + } + // default for included templates + if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) { + $_caching = self::CACHING_NOCACHE_CODE; + } + /* + * if the {include} tag provides individual parameter for caching + * it will not be included into the common cache file and treated like + * a nocache section + */ + if (isset($_attr['cache_lifetime'])) { + $_cache_lifetime = $_attr['cache_lifetime']; + $compiler->tag_nocache = true; + $_caching = Smarty::CACHING_LIFETIME_CURRENT; + } else { + $_cache_lifetime = 'null'; + } + if (isset($_attr['cache_id'])) { + $_cache_id = $_attr['cache_id']; + $compiler->tag_nocache = true; + $_caching = Smarty::CACHING_LIFETIME_CURRENT; + } else { + $_cache_id = '$_smarty_tpl->cache_id'; + } + if (isset($_attr['compile_id'])) { + $_compile_id = $_attr['compile_id']; + } else { + $_compile_id = '$_smarty_tpl->compile_id'; + } + if ($_attr['caching'] === true) { + $_caching = Smarty::CACHING_LIFETIME_CURRENT; + } + if ($_attr['nocache'] === true) { + $compiler->tag_nocache = true; + $_caching = Smarty::CACHING_OFF; + } + + $has_compiled_template = false; + if (($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->recompiled + && !($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache)) && $_caching != Smarty::CACHING_LIFETIME_CURRENT) { + // check if compiled code can be merged (contains no variable part) + if (!$compiler->has_variable_string && (substr_count($include_file, '"') == 2 or substr_count($include_file, "'") == 2) + and substr_count($include_file, '(') == 0 and substr_count($include_file, '$_smarty_tpl->') == 0) { + $tpl_name = null; + eval("\$tpl_name = $include_file;"); + if (!isset($compiler->smarty->merged_templates_func[$tpl_name]) || $compiler->inheritance) { + $tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id); + // save unique function name + $compiler->smarty->merged_templates_func[$tpl_name]['func'] = $tpl->properties['unifunc'] = 'content_'. str_replace('.', '_', uniqid('', true)); + // use current nocache hash for inlined code + $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash']; + if ($compiler->template->caching) { + // needs code for cached page but no cache file + $tpl->caching = self::CACHING_NOCACHE_CODE; + } + // make sure whole chain gest compiled + $tpl->mustCompile = true; + if (!($tpl->source->uncompiled) && $tpl->source->exists) { + // get compiled code + $compiled_code = $tpl->compiler->compileTemplate($tpl); + // release compiler object to free memory + unset($tpl->compiler); + // merge compiled code for {function} tags + $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']); + // merge filedependency + $tpl->properties['file_dependency'][$tpl->source->uid] = array($tpl->source->filepath, $tpl->source->timestamp,$tpl->source->type); + $compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $tpl->properties['file_dependency']); + // remove header code + $compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code); + if ($tpl->has_nocache_code) { + // replace nocache_hash + $compiled_code = str_replace("{$tpl->properties['nocache_hash']}", $compiler->template->properties['nocache_hash'], $compiled_code); + $compiler->template->has_nocache_code = true; + } + $compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code; + $has_compiled_template = true; + } + } else { + $has_compiled_template = true; + } + } + } + // delete {include} standard attributes + unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']); + // remaining attributes must be assigned as smarty variable + if (!empty($_attr)) { + if ($_parent_scope == Smarty::SCOPE_LOCAL) { + // create variables + foreach ($_attr as $key => $value) { + $_pairs[] = "'$key'=>$value"; + } + $_vars = 'array('.join(',',$_pairs).')'; + $_has_vars = true; + } else { + $compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno); + } + } else { + $_vars = 'array()'; + $_has_vars = false; + } + if ($has_compiled_template) { + $_hash = $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash']; + $_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n"; + $_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n"; + $_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n"; + if (isset($_assign)) { + $_output .= 'ob_start(); '; + } + $_output .= $compiler->smarty->merged_templates_func[$tpl_name]['func']. "(\$_smarty_tpl);\n"; + $_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); "; + if (isset($_assign)) { + $_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());"; + } + $_output .= "/* End of included template \"" . $tpl_name . "\" */?>"; + return $_output; + } + + // was there an assign attribute + if (isset($_assign)) { + $_output = "<?php \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(\$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope));?>\n";; + } else { + $_output = "<?php echo \$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope);?>\n"; + } + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_include_php.php b/include/smarty/libs/sysplugins/smarty_internal_compile_include_php.php new file mode 100644 index 000000000..d52712368 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_include_php.php @@ -0,0 +1,108 @@ +<?php +/** + * Smarty Internal Plugin Compile Include PHP + * + * Compiles the {include_php} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Insert Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('file'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('file'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('once', 'assign'); + + /** + * Compiles code for the {include_php} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + if (!($compiler->smarty instanceof SmartyBC)) { + throw new SmartyException("{include_php} is deprecated, use SmartyBC class to enable"); + } + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + $_output = '<?php '; + + $_smarty_tpl = $compiler->template; + $_filepath = false; + eval('$_file = ' . $_attr['file'] . ';'); + if (!isset($compiler->smarty->security_policy) && file_exists($_file)) { + $_filepath = $_file; + } else { + if (isset($compiler->smarty->security_policy)) { + $_dir = $compiler->smarty->security_policy->trusted_dir; + } else { + $_dir = $compiler->smarty->trusted_dir; + } + if (!empty($_dir)) { + foreach((array)$_dir as $_script_dir) { + $_script_dir = rtrim($_script_dir, '/\\') . DS; + if (file_exists($_script_dir . $_file)) { + $_filepath = $_script_dir . $_file; + break; + } + } + } + } + if ($_filepath == false) { + $compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", $compiler->lex->taglineno); + } + + if (isset($compiler->smarty->security_policy)) { + $compiler->smarty->security_policy->isTrustedPHPDir($_filepath); + } + + if (isset($_attr['assign'])) { + // output will be stored in a smarty variable instead of being displayed + $_assign = $_attr['assign']; + } + $_once = '_once'; + if (isset($_attr['once'])) { + if ($_attr['once'] == 'false') { + $_once = ''; + } + } + + if (isset($_assign)) { + return "<?php ob_start(); include{$_once} ('{$_filepath}'); \$_smarty_tpl->assign({$_assign},ob_get_contents()); ob_end_clean();?>"; + } else { + return "<?php include{$_once} ('{$_filepath}');?>\n"; + } + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_insert.php b/include/smarty/libs/sysplugins/smarty_internal_compile_insert.php new file mode 100644 index 000000000..e4d3f9355 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_insert.php @@ -0,0 +1,142 @@ +<?php + +/** + * Smarty Internal Plugin Compile Insert + * + * Compiles the {insert} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Insert Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the {insert} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // never compile as nocache code + $compiler->suppressNocacheProcessing = true; + $compiler->tag_nocache = true; + $_smarty_tpl = $compiler->template; + $_name = null; + $_script = null; + + $_output = '<?php '; + // save posible attributes + eval('$_name = ' . $_attr['name'] . ';'); + if (isset($_attr['assign'])) { + // output will be stored in a smarty variable instead of being displayed + $_assign = $_attr['assign']; + // create variable to make shure that the compiler knows about its nocache status + $compiler->template->tpl_vars[trim($_attr['assign'], "'")] = new Smarty_Variable(null, true); + } + if (isset($_attr['script'])) { + // script which must be included + $_function = "smarty_insert_{$_name}"; + $_smarty_tpl = $compiler->template; + $_filepath = false; + eval('$_script = ' . $_attr['script'] . ';'); + if (!isset($compiler->smarty->security_policy) && file_exists($_script)) { + $_filepath = $_script; + } else { + if (isset($compiler->smarty->security_policy)) { + $_dir = $compiler->smarty->security_policy->trusted_dir; + } else { + $_dir = $compiler->smarty->trusted_dir; + } + if (!empty($_dir)) { + foreach((array)$_dir as $_script_dir) { + $_script_dir = rtrim($_script_dir, '/\\') . DS; + if (file_exists($_script_dir . $_script)) { + $_filepath = $_script_dir . $_script; + break; + } + } + } + } + if ($_filepath == false) { + $compiler->trigger_template_error("{insert} missing script file '{$_script}'", $compiler->lex->taglineno); + } + // code for script file loading + $_output .= "require_once '{$_filepath}' ;"; + require_once $_filepath; + if (!is_callable($_function)) { + $compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", $compiler->lex->taglineno); + } + } else { + $_filepath = 'null'; + $_function = "insert_{$_name}"; + // function in PHP script ? + if (!is_callable($_function)) { + // try plugin + if (!$_function = $compiler->getPlugin($_name, 'insert')) { + $compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", $compiler->lex->taglineno); + } + } + } + // delete {insert} standard attributes + unset($_attr['name'], $_attr['assign'], $_attr['script'], $_attr['nocache']); + // convert attributes into parameter array string + $_paramsArray = array(); + foreach ($_attr as $_key => $_value) { + $_paramsArray[] = "'$_key' => $_value"; + } + $_params = 'array(' . implode(", ", $_paramsArray) . ')'; + // call insert + if (isset($_assign)) { + if ($_smarty_tpl->caching) { + $_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}',{$_assign});?>"; + } else { + $_output .= "\$_smarty_tpl->assign({$_assign} , {$_function} ({$_params},\$_smarty_tpl), true);?>"; + } + } else { + $compiler->has_output = true; + if ($_smarty_tpl->caching) { + $_output .= "echo Smarty_Internal_Nocache_Insert::compile ('{$_function}',{$_params}, \$_smarty_tpl, '{$_filepath}');?>"; + } else { + $_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>"; + } + } + return $_output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_ldelim.php b/include/smarty/libs/sysplugins/smarty_internal_compile_ldelim.php new file mode 100644 index 000000000..990632590 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_ldelim.php @@ -0,0 +1,41 @@ +<?php +/** + * Smarty Internal Plugin Compile Ldelim + * + * Compiles the {ldelim} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Ldelim Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Ldelim extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {ldelim} tag + * + * This tag does output the left delimiter + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); + } + // this tag does not return compiled code + $compiler->has_code = true; + return $compiler->smarty->left_delimiter; + } + +} + +?> diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_nocache.php b/include/smarty/libs/sysplugins/smarty_internal_compile_nocache.php new file mode 100644 index 000000000..5fb71b71d --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_nocache.php @@ -0,0 +1,73 @@ +<?php +/** + * Smarty Internal Plugin Compile Nocache + * + * Compiles the {nocache} {/nocache} tags. + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Nocache Classv + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {nocache} tag + * + * This tag does not generate compiled output. It only sets a compiler flag. + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return bool + */ + public function compile($args, $compiler) + { + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); + } + // enter nocache mode + $compiler->nocache = true; + // this tag does not return compiled code + $compiler->has_code = false; + return true; + } + +} + +/** + * Smarty Internal Plugin Compile Nocacheclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Nocacheclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/nocache} tag + * + * This tag does not generate compiled output. It only sets a compiler flag. + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return bool + */ + public function compile($args, $compiler) + { + $_attr = $this->getAttributes($compiler, $args); + // leave nocache mode + $compiler->nocache = false; + // this tag does not return compiled code + $compiler->has_code = false; + return true; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_block_plugin.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_block_plugin.php new file mode 100644 index 000000000..5288f4560 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_block_plugin.php @@ -0,0 +1,87 @@ +<?php +/** + * Smarty Internal Plugin Compile Block Plugin + * + * Compiles code for the execution of block plugin + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Block Plugin Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Private_Block_Plugin extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the execution of block plugin + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @param string $tag name of block plugin + * @param string $function PHP function name + * @return string compiled code + */ + public function compile($args, $compiler, $parameter, $tag, $function) + { + if (!isset($tag[5]) || substr($tag, -5) != 'close') { + // opening tag of block plugin + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->tag_nocache = true; + } + unset($_attr['nocache']); + // convert attributes into parameter array string + $_paramsArray = array(); + foreach ($_attr as $_key => $_value) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + $_params = 'array(' . implode(",", $_paramsArray) . ')'; + + $this->openTag($compiler, $tag, array($_params, $compiler->nocache)); + // maybe nocache because of nocache variables or nocache plugin + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + // compile code + $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>"; + } else { + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + // closing tag of block plugin, restore nocache + list($_params, $compiler->nocache) = $this->closeTag($compiler, substr($tag, 0, -5)); + // This tag does create output + $compiler->has_output = true; + // compile code + if (!isset($parameter['modifier_list'])) { + $mod_pre = $mod_post =''; + } else { + $mod_pre = ' ob_start(); '; + $mod_post = 'echo '.$compiler->compileTag('private_modifier',array(),array('modifierlist'=>$parameter['modifier_list'],'value'=>'ob_get_clean()')).';'; + } + $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); ".$mod_post." } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>"; + } + return $output . "\n"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_function_plugin.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_function_plugin.php new file mode 100644 index 000000000..70e764318 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_function_plugin.php @@ -0,0 +1,73 @@ +<?php +/** + * Smarty Internal Plugin Compile Function Plugin + * + * Compiles code for the execution of function plugin + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Function Plugin Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Private_Function_Plugin extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array(); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the execution of function plugin + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @param string $tag name of function plugin + * @param string $function PHP function name + * @return string compiled code + */ + public function compile($args, $compiler, $parameter, $tag, $function) + { + // This tag does create output + $compiler->has_output = true; + + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->tag_nocache = true; + } + unset($_attr['nocache']); + // convert attributes into parameter array string + $_paramsArray = array(); + foreach ($_attr as $_key => $_value) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + $_params = 'array(' . implode(",", $_paramsArray) . ')'; + // compile code + $output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n"; + return $output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_modifier.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_modifier.php new file mode 100644 index 000000000..120f3ff10 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_modifier.php @@ -0,0 +1,140 @@ +<?php
+
+/**
+ * Smarty Internal Plugin Compile Modifier
+ *
+ * Compiles code for modifier execution
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Modifier Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBase {
+
+ /**
+ * Compiles code for modifier execution
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter) {
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ $output = $parameter['value'];
+ // loop over list of modifiers
+ foreach ($parameter['modifierlist'] as $single_modifier) {
+ $modifier = $single_modifier[0];
+ $single_modifier[0] = $output;
+ $params = implode(',', $single_modifier);
+ // check if we know already the type of modifier
+ if (isset($compiler->known_modifier_type[$modifier])) {
+ $modifier_types = array($compiler->known_modifier_type[$modifier]);
+ } else {
+ $modifier_types = array(1, 2, 3, 4, 5, 6);
+ }
+ foreach ($modifier_types as $type) {
+ switch ($type) {
+ case 1:
+ // registered modifier
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) {
+ $function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
+ if (!is_array($function)) {
+ $output = "{$function}({$params})";
+ } else {
+ if (is_object($function[0])) {
+ $output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
+ } else {
+ $output = $function[0] . '::' . $function[1] . '(' . $params . ')';
+ }
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 2:
+ // registered modifier compiler
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
+ $output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 3:
+ // modifiercompiler plugin
+ if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+ $plugin = 'smarty_modifiercompiler_' . $modifier;
+ $output = $plugin($single_modifier, $compiler);
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 4:
+ // modifier plugin
+ if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+ $output = "{$function}({$params})";
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 5:
+ // PHP function
+ if (is_callable($modifier)) {
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
+ $output = "{$modifier}({$params})";
+ }
+ $compiler->known_modifier_type[$modifier] = $type;
+ break 2;
+ }
+ break;
+ case 6:
+ // default plugin handler
+ if (isset($compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier]) || (is_callable($compiler->smarty->default_plugin_handler_func) && $compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))) {
+ $function = $compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
+ // check if modifier allowed
+ if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
+ if (!is_array($function)) {
+ $output = "{$function}({$params})";
+ } else {
+ if (is_object($function[0])) {
+ $output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
+ } else {
+ $output = $function[0] . '::' . $function[1] . '(' . $params . ')';
+ }
+ }
+ }
+ if (isset($compiler->template->required_plugins['nocache'][$modifier][Smarty::PLUGIN_MODIFIER]['file']) || isset($compiler->template->required_plugins['compiled'][$modifier][Smarty::PLUGIN_MODIFIER]['file'])) {
+ // was a plugin
+ $compiler->known_modifier_type[$modifier] = 4;
+ } else {
+ $compiler->known_modifier_type[$modifier] = $type;
+ }
+ break 2;
+ }
+ }
+ }
+ if (!isset($compiler->known_modifier_type[$modifier])) {
+ $compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno);
+ }
+ }
+ return $output;
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_object_block_function.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_object_block_function.php new file mode 100644 index 000000000..cca924d10 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_object_block_function.php @@ -0,0 +1,88 @@ +<?php +/** + * Smarty Internal Plugin Compile Object Block Function + * + * Compiles code for registered objects as block function + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Object Block Function Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Private_Object_Block_Function extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the execution of block plugin + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @param string $tag name of block object + * @param string $method name of method to call + * @return string compiled code + */ + public function compile($args, $compiler, $parameter, $tag, $method) + { + if (!isset($tag[5]) || substr($tag, -5) != 'close') { + // opening tag of block plugin + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->tag_nocache = true; + } + unset($_attr['nocache']); + // convert attributes into parameter array string + $_paramsArray = array(); + foreach ($_attr as $_key => $_value) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + $_params = 'array(' . implode(",", $_paramsArray) . ')'; + + $this->openTag($compiler, $tag . '->' . $method, array($_params, $compiler->nocache)); + // maybe nocache because of nocache variables or nocache plugin + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + // compile code + $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}->{$method}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>"; + } else { + $base_tag = substr($tag, 0, -5); + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + // closing tag of block plugin, restore nocache + list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag . '->' . $method); + // This tag does create output + $compiler->has_output = true; + // compile code + if (!isset($parameter['modifier_list'])) { + $mod_pre = $mod_post = ''; + } else { + $mod_pre = ' ob_start(); '; + $mod_post = 'echo ' . $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifier_list'], 'value' => 'ob_get_clean()')) . ';'; + } + $output = "<?php \$_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;" . $mod_pre . " echo \$_smarty_tpl->smarty->registered_objects['{$base_tag}'][0]->{$method}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); " . $mod_post . " } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>"; + } + return $output . "\n"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_object_function.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_object_function.php new file mode 100644 index 000000000..f649084c3 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_object_function.php @@ -0,0 +1,79 @@ +<?php +/** + * Smarty Internal Plugin Compile Object Funtion + * + * Compiles code for registered objects as function + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Object Function Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Private_Object_Function extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('_any'); + + /** + * Compiles code for the execution of function plugin + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @param string $tag name of function + * @param string $method name of method to call + * @return string compiled code + */ + public function compile($args, $compiler, $parameter, $tag, $method) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->tag_nocache = true; + } + unset($_attr['nocache']); + $_assign = null; + if (isset($_attr['assign'])) { + $_assign = $_attr['assign']; + unset($_attr['assign']); + } + // convert attributes into parameter array string + if ($compiler->smarty->registered_objects[$tag][2]) { + $_paramsArray = array(); + foreach ($_attr as $_key => $_value) { + if (is_int($_key)) { + $_paramsArray[] = "$_key=>$_value"; + } else { + $_paramsArray[] = "'$_key'=>$_value"; + } + } + $_params = 'array(' . implode(",", $_paramsArray) . ')'; + $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params},\$_smarty_tpl)"; + } else { + $_params = implode(",", $_attr); + $return = "\$_smarty_tpl->smarty->registered_objects['{$tag}'][0]->{$method}({$_params})"; + } + if (empty($_assign)) { + // This tag does create output + $compiler->has_output = true; + $output = "<?php echo {$return};?>\n"; + } else { + $output = "<?php \$_smarty_tpl->assign({$_assign},{$return});?>\n"; + } + return $output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_print_expression.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_print_expression.php new file mode 100644 index 000000000..a37119547 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_print_expression.php @@ -0,0 +1,156 @@ +<?php +/** +* Smarty Internal Plugin Compile Print Expression +* +* Compiles any tag which will output an expression or variable +* +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ + +/** +* Smarty Internal Plugin Compile Print Expression Class +* +* @package Smarty +* @subpackage Compiler +*/ +class Smarty_Internal_Compile_Private_Print_Expression extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('assign'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $option_flags = array('nocache', 'nofilter'); + + /** + * Compiles code for gererting output from any expression + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + // nocache option + if ($_attr['nocache'] === true) { + $compiler->tag_nocache = true; + } + // filter handling + if ($_attr['nofilter'] === true) { + $_filter = 'false'; + } else { + $_filter = 'true'; + } + if (isset($_attr['assign'])) { + // assign output to variable + $output = "<?php \$_smarty_tpl->assign({$_attr['assign']},{$parameter['value']});?>"; + } else { + // display value + $output = $parameter['value']; + // tag modifier + if (!empty($parameter['modifierlist'])) { + $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $parameter['modifierlist'], 'value' => $output)); + } + if (!$_attr['nofilter']) { + // default modifier + if (!empty($compiler->smarty->default_modifiers)) { + if (empty($compiler->default_modifier_list)) { + $modifierlist = array(); + foreach ($compiler->smarty->default_modifiers as $key => $single_default_modifier) { + preg_match_all('/(\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|:|[^:]+)/', $single_default_modifier, $mod_array); + for ($i = 0, $count = count($mod_array[0]);$i < $count;$i++) { + if ($mod_array[0][$i] != ':') { + $modifierlist[$key][] = $mod_array[0][$i]; + } + } + } + $compiler->default_modifier_list = $modifierlist; + } + $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => $compiler->default_modifier_list, 'value' => $output)); + } + // autoescape html + if ($compiler->template->smarty->escape_html) { + $output = "htmlspecialchars({$output}, ENT_QUOTES, '" . addslashes(Smarty::$_CHARSET) . "')"; + } + // loop over registerd filters + if (!empty($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE])) { + foreach ($compiler->template->smarty->registered_filters[Smarty::FILTER_VARIABLE] as $key => $function) { + if (!is_array($function)) { + $output = "{$function}({$output},\$_smarty_tpl)"; + } else if (is_object($function[0])) { + $output = "\$_smarty_tpl->smarty->registered_filters[Smarty::FILTER_VARIABLE][{$key}][0]->{$function[1]}({$output},\$_smarty_tpl)"; + } else { + $output = "{$function[0]}::{$function[1]}({$output},\$_smarty_tpl)"; + } + } + } + // auto loaded filters + if (isset($compiler->smarty->autoload_filters[Smarty::FILTER_VARIABLE])) { + foreach ((array)$compiler->template->smarty->autoload_filters[Smarty::FILTER_VARIABLE] as $name) { + $result = $this->compile_output_filter($compiler, $name, $output); + if ($result !== false) { + $output = $result; + } else { + // not found, throw exception + throw new SmartyException("Unable to load filter '{$name}'"); + } + } + } + if (isset($compiler->template->variable_filters)) { + foreach ($compiler->template->variable_filters as $filter) { + if (count($filter) == 1 && ($result = $this->compile_output_filter($compiler, $filter[0], $output)) !== false) { + $output = $result; + } else { + $output = $compiler->compileTag('private_modifier', array(), array('modifierlist' => array($filter), 'value' => $output)); + } + } + } + } + + $compiler->has_output = true; + $output = "<?php echo {$output};?>"; + } + return $output; + } + + /** + * @param object $compiler compiler object + * @param string $name name of variable filter + * @param type $output embedded output + * @return string + */ + private function compile_output_filter($compiler, $name, $output) + { + $plugin_name = "smarty_variablefilter_{$name}"; + $path = $compiler->smarty->loadPlugin($plugin_name, false); + if ($path) { + if ($compiler->template->caching) { + $compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['file'] = $path; + $compiler->template->required_plugins['nocache'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name; + } else { + $compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['file'] = $path; + $compiler->template->required_plugins['compiled'][$name][Smarty::FILTER_VARIABLE]['function'] = $plugin_name; + } + } else { + // not found + return false; + } + return "{$plugin_name}({$output},\$_smarty_tpl)"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_registered_block.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_registered_block.php new file mode 100644 index 000000000..9fed36c3b --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_registered_block.php @@ -0,0 +1,113 @@ +<?php
+/**
+ * Smarty Internal Plugin Compile Registered Block
+ *
+ * Compiles code for the execution of a registered block function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Registered Block Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Registered_Block extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of a block function
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of block function
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag)
+ {
+ if (!isset($tag[5]) || substr($tag,-5) != 'close') {
+ // opening tag of block plugin
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache']) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag])) {
+ $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$tag];
+ } else {
+ $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$tag];
+ }
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } elseif ($compiler->template->caching && in_array($_key,$tag_info[2])) {
+ $_value = str_replace("'","^#^",$_value);
+ $_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+
+ $this->openTag($compiler, $tag, array($_params, $compiler->nocache));
+ // maybe nocache because of nocache variables or nocache plugin
+ $compiler->nocache = !$tag_info[1] | $compiler->nocache | $compiler->tag_nocache;
+ $function = $tag_info[0];
+ // compile code
+ if (!is_array($function)) {
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ } else if (is_object($function[0])) {
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo \$_smarty_tpl->smarty->registered_plugins['block']['{$tag}'][0][0]->{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ } else {
+ $output = "<?php \$_smarty_tpl->smarty->_tag_stack[] = array('{$tag}', {$_params}); \$_block_repeat=true; echo {$function[0]}::{$function[1]}({$_params}, null, \$_smarty_tpl, \$_block_repeat);while (\$_block_repeat) { ob_start();?>";
+ }
+ } else {
+ // must endblock be nocache?
+ if ($compiler->nocache) {
+ $compiler->tag_nocache = true;
+ }
+ $base_tag = substr($tag, 0, -5);
+ // closing tag of block plugin, restore nocache
+ list($_params, $compiler->nocache) = $this->closeTag($compiler, $base_tag);
+ // This tag does create output
+ $compiler->has_output = true;
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
+ $function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
+ } else {
+ $function = $compiler->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag][0];
+ }
+ // compile code
+ if (!isset($parameter['modifier_list'])) {
+ $mod_pre = $mod_post ='';
+ } else {
+ $mod_pre = ' ob_start(); ';
+ $mod_post = 'echo '.$compiler->compileTag('private_modifier',array(),array('modifierlist'=>$parameter['modifier_list'],'value'=>'ob_get_clean()')).';';
+ }
+ if (!is_array($function)) {
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo {$function}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat);".$mod_post." } array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ } else if (is_object($function[0])) {
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo \$_smarty_tpl->smarty->registered_plugins['block']['{$base_tag}'][0][0]->{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); ".$mod_post."} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ } else {
+ $output = "<?php \$_block_content = ob_get_clean(); \$_block_repeat=false;".$mod_pre." echo {$function[0]}::{$function[1]}({$_params}, \$_block_content, \$_smarty_tpl, \$_block_repeat); ".$mod_post."} array_pop(\$_smarty_tpl->smarty->_tag_stack);?>";
+ }
+ }
+ return $output . "\n";
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_registered_function.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_registered_function.php new file mode 100644 index 000000000..5058bfbbd --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_registered_function.php @@ -0,0 +1,81 @@ +<?php
+/**
+ * Smarty Internal Plugin Compile Registered Function
+ *
+ * Compiles code for the execution of a registered function
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Registered Function Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Private_Registered_Function extends Smarty_Internal_CompileBase {
+
+ /**
+ * Attribute definition: Overwrites base class.
+ *
+ * @var array
+ * @see Smarty_Internal_CompileBase
+ */
+ public $optional_attributes = array('_any');
+
+ /**
+ * Compiles code for the execution of a registered function
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @param string $tag name of function
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter, $tag)
+ {
+ // This tag does create output
+ $compiler->has_output = true;
+ // check and get attributes
+ $_attr = $this->getAttributes($compiler, $args);
+ if ($_attr['nocache']) {
+ $compiler->tag_nocache = true;
+ }
+ unset($_attr['nocache']);
+ if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag])) {
+ $tag_info = $compiler->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION][$tag];
+ } else {
+ $tag_info = $compiler->default_handler_plugins[Smarty::PLUGIN_FUNCTION][$tag];
+ }
+ // not cachable?
+ $compiler->tag_nocache = $compiler->tag_nocache || !$tag_info[1];
+ // convert attributes into parameter array string
+ $_paramsArray = array();
+ foreach ($_attr as $_key => $_value) {
+ if (is_int($_key)) {
+ $_paramsArray[] = "$_key=>$_value";
+ } elseif ($compiler->template->caching && in_array($_key,$tag_info[2])) {
+ $_value = str_replace("'","^#^",$_value);
+ $_paramsArray[] = "'$_key'=>^#^.var_export($_value,true).^#^";
+ } else {
+ $_paramsArray[] = "'$_key'=>$_value";
+ }
+ }
+ $_params = 'array(' . implode(",", $_paramsArray) . ')';
+ $function = $tag_info[0];
+ // compile code
+ if (!is_array($function)) {
+ $output = "<?php echo {$function}({$_params},\$_smarty_tpl);?>\n";
+ } else if (is_object($function[0])) {
+ $output = "<?php echo \$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['{$tag}'][0][0]->{$function[1]}({$_params},\$_smarty_tpl);?>\n";
+ } else {
+ $output = "<?php echo {$function[0]}::{$function[1]}({$_params},\$_smarty_tpl);?>\n";
+ }
+ return $output;
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php b/include/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php new file mode 100644 index 000000000..af8fcd372 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_private_special_variable.php @@ -0,0 +1,111 @@ +<?php +/** + * Smarty Internal Plugin Compile Special Smarty Variable + * + * Compiles the special $smarty variables + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile special Smarty Variable Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the speical $smarty variables + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + $_index = preg_split("/\]\[/",substr($parameter, 1, strlen($parameter)-2)); + $compiled_ref = ' '; + $variable = trim($_index[0], "'"); + switch ($variable) { + case 'foreach': + return "\$_smarty_tpl->getVariable('smarty')->value$parameter"; + case 'section': + return "\$_smarty_tpl->getVariable('smarty')->value$parameter"; + case 'capture': + return "Smarty::\$_smarty_vars$parameter"; + case 'now': + return 'time()'; + case 'cookies': + if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) { + $compiler->trigger_template_error("(secure mode) super globals not permitted"); + break; + } + $compiled_ref = '$_COOKIE'; + break; + + case 'get': + case 'post': + case 'env': + case 'server': + case 'session': + case 'request': + if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_super_globals) { + $compiler->trigger_template_error("(secure mode) super globals not permitted"); + break; + } + $compiled_ref = '$_'.strtoupper($variable); + break; + + case 'template': + return 'basename($_smarty_tpl->source->filepath)'; + + case 'template_object': + return '$_smarty_tpl'; + + case 'current_dir': + return 'dirname($_smarty_tpl->source->filepath)'; + + case 'version': + $_version = Smarty::SMARTY_VERSION; + return "'$_version'"; + + case 'const': + if (isset($compiler->smarty->security_policy) && !$compiler->smarty->security_policy->allow_constants) { + $compiler->trigger_template_error("(secure mode) constants not permitted"); + break; + } + return "@constant({$_index[1]})"; + + case 'config': + if (isset($_index[2])) { + return "(is_array(\$tmp = \$_smarty_tpl->getConfigVariable($_index[1])) ? \$tmp[$_index[2]] : null)"; + } else { + return "\$_smarty_tpl->getConfigVariable($_index[1])"; + } + case 'ldelim': + $_ldelim = $compiler->smarty->left_delimiter; + return "'$_ldelim'"; + + case 'rdelim': + $_rdelim = $compiler->smarty->right_delimiter; + return "'$_rdelim'"; + + default: + $compiler->trigger_template_error('$smarty.' . trim($_index[0], "'") . ' is invalid'); + break; + } + if (isset($_index[1])) { + array_shift($_index); + foreach ($_index as $_ind) { + $compiled_ref = $compiled_ref . "[$_ind]"; + } + } + return $compiled_ref; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_rdelim.php b/include/smarty/libs/sysplugins/smarty_internal_compile_rdelim.php new file mode 100644 index 000000000..807c7e2b9 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_rdelim.php @@ -0,0 +1,41 @@ +<?php +/** + * Smarty Internal Plugin Compile Rdelim + * + * Compiles the {rdelim} tag + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Rdelim Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Rdelim extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {rdelim} tag + * + * This tag does output the right delimiter. + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + $_attr = $this->getAttributes($compiler, $args); + if ($_attr['nocache'] === true) { + $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); + } + // this tag does not return compiled code + $compiler->has_code = true; + return $compiler->smarty->right_delimiter; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_section.php b/include/smarty/libs/sysplugins/smarty_internal_compile_section.php new file mode 100644 index 000000000..ccb7673d8 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_section.php @@ -0,0 +1,203 @@ +<?php +/** + * Smarty Internal Plugin Compile Section + * + * Compiles the {section} {sectionelse} {/section} tags + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile Section Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Section extends Smarty_Internal_CompileBase { + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $required_attributes = array('name', 'loop'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name', 'loop'); + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('start', 'step', 'max', 'show'); + + /** + * Compiles code for the {section} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + $this->openTag($compiler, 'section', array('section', $compiler->nocache)); + // maybe nocache because of nocache variables + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + + $output = "<?php "; + + $section_name = $_attr['name']; + + $output .= "if (isset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name])) unset(\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]);\n"; + $section_props = "\$_smarty_tpl->tpl_vars['smarty']->value['section'][$section_name]"; + + foreach ($_attr as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $show_attr_value = $attr_value ? 'true' : 'false'; + else + $show_attr_value = "(bool)$attr_value"; + $output .= "{$section_props}['show'] = $show_attr_value;\n"; + break; + + case 'name': + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + case 'max': + case 'start': + $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; + break; + + case 'step': + $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; + break; + } + } + + if (!isset($_attr['show'])) + $output .= "{$section_props}['show'] = true;\n"; + + if (!isset($_attr['loop'])) + $output .= "{$section_props}['loop'] = 1;\n"; + + if (!isset($_attr['max'])) + $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; + else + $output .= "if ({$section_props}['max'] < 0)\n" . " {$section_props}['max'] = {$section_props}['loop'];\n"; + + if (!isset($_attr['step'])) + $output .= "{$section_props}['step'] = 1;\n"; + + if (!isset($_attr['start'])) + $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; + else { + $output .= "if ({$section_props}['start'] < 0)\n" . " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . "else\n" . " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; + } + + $output .= "if ({$section_props}['show']) {\n"; + if (!isset($_attr['start']) && !isset($_attr['step']) && !isset($_attr['max'])) { + $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; + } else { + $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; + } + $output .= " if ({$section_props}['total'] == 0)\n" . " {$section_props}['show'] = false;\n" . "} else\n" . " {$section_props}['total'] = 0;\n"; + + $output .= "if ({$section_props}['show']):\n"; + $output .= " + for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; + {$section_props}['iteration'] <= {$section_props}['total']; + {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; + $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; + $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; + $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; + $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; + + $output .= "?>"; + return $output; + } + +} + +/** + * Smarty Internal Plugin Compile Sectionelse Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Sectionelse extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {sectionelse} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + list($openTag, $nocache) = $this->closeTag($compiler, array('section')); + $this->openTag($compiler, 'sectionelse', array('sectionelse', $nocache)); + + return "<?php endfor; else: ?>"; + } + +} + +/** + * Smarty Internal Plugin Compile Sectionclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Sectionclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/section} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + + list($openTag, $compiler->nocache) = $this->closeTag($compiler, array('section', 'sectionelse')); + + if ($openTag == 'sectionelse') { + return "<?php endif; ?>"; + } else { + return "<?php endfor; endif; ?>"; + } + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_setfilter.php b/include/smarty/libs/sysplugins/smarty_internal_compile_setfilter.php new file mode 100644 index 000000000..d1dd90cf8 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_setfilter.php @@ -0,0 +1,72 @@ +<?php
+/**
+ * Smarty Internal Plugin Compile Setfilter
+ *
+ * Compiles code for setfilter tag
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Setfilter Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Setfilter extends Smarty_Internal_CompileBase {
+
+ /**
+ * Compiles code for setfilter tag
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @param array $parameter array with compilation parameter
+ * @return string compiled code
+ */
+ public function compile($args, $compiler, $parameter)
+ {
+ $compiler->variable_filter_stack[] = $compiler->template->variable_filters;
+ $compiler->template->variable_filters = $parameter['modifier_list'];
+ // this tag does not return compiled code
+ $compiler->has_code = false;
+ return true;
+ }
+
+}
+
+/**
+ * Smarty Internal Plugin Compile Setfilterclose Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Compile_Setfilterclose extends Smarty_Internal_CompileBase {
+
+ /**
+ * Compiles code for the {/setfilter} tag
+ *
+ * This tag does not generate compiled output. It resets variable filter.
+ *
+ * @param array $args array with attributes from parser
+ * @param object $compiler compiler object
+ * @return string compiled code
+ */
+ public function compile($args, $compiler)
+ {
+ $_attr = $this->getAttributes($compiler, $args);
+ // reset variable filter to previous state
+ if (count($compiler->variable_filter_stack)) {
+ $compiler->template->variable_filters = array_pop($compiler->variable_filter_stack);
+ } else {
+ $compiler->template->variable_filters = array();
+ }
+ // this tag does not return compiled code
+ $compiler->has_code = false;
+ return true;
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compile_while.php b/include/smarty/libs/sysplugins/smarty_internal_compile_while.php new file mode 100644 index 000000000..d7d986c34 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compile_while.php @@ -0,0 +1,94 @@ +<?php +/** + * Smarty Internal Plugin Compile While + * + * Compiles the {while} tag + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Compile While Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_While extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {while} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @param array $parameter array with compilation parameter + * @return string compiled code + */ + public function compile($args, $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + $this->openTag($compiler, 'while', $compiler->nocache); + + if (!array_key_exists("if condition",$parameter)) { + $compiler->trigger_template_error("missing while condition", $compiler->lex->taglineno); + } + + // maybe nocache because of nocache variables + $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; + if (is_array($parameter['if condition'])) { + if ($compiler->nocache) { + $_nocache = ',true'; + // create nocache var to make it know for further compiling + if (is_array($parameter['if condition']['var'])) { + $compiler->template->tpl_vars[trim($parameter['if condition']['var']['var'], "'")] = new Smarty_variable(null, true); + } else { + $compiler->template->tpl_vars[trim($parameter['if condition']['var'], "'")] = new Smarty_variable(null, true); + } + } else { + $_nocache = ''; + } + if (is_array($parameter['if condition']['var'])) { + $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]) || !is_array(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value)) \$_smarty_tpl->createLocalArrayVariable(" . $parameter['if condition']['var']['var'] . "$_nocache);\n"; + $_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var']['var'] . "]->value" . $parameter['if condition']['var']['smarty_internal_index'] . " = " . $parameter['if condition']['value'] . "){?>"; + } else { + $_output = "<?php if (!isset(\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "])) \$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "] = new Smarty_Variable(null{$_nocache});"; + $_output .= "while (\$_smarty_tpl->tpl_vars[" . $parameter['if condition']['var'] . "]->value = " . $parameter['if condition']['value'] . "){?>"; + } + return $_output; + } else { + return "<?php while ({$parameter['if condition']}){?>"; + } + } + +} + +/** + * Smarty Internal Plugin Compile Whileclose Class + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_Compile_Whileclose extends Smarty_Internal_CompileBase { + + /** + * Compiles code for the {/while} tag + * + * @param array $args array with attributes from parser + * @param object $compiler compiler object + * @return string compiled code + */ + public function compile($args, $compiler) + { + // must endblock be nocache? + if ($compiler->nocache) { + $compiler->tag_nocache = true; + } + $compiler->nocache = $this->closeTag($compiler, array('while')); + return "<?php }?>"; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_compilebase.php b/include/smarty/libs/sysplugins/smarty_internal_compilebase.php new file mode 100644 index 000000000..5fb56f371 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_compilebase.php @@ -0,0 +1,176 @@ +<?php +/** + * Smarty Internal Plugin CompileBase + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * This class does extend all internal compile plugins + * + * @package Smarty + * @subpackage Compiler + */ +abstract class Smarty_Internal_CompileBase { + + /** + * Array of names of required attribute required by tag + * + * @var array + */ + public $required_attributes = array(); + /** + * Array of names of optional attribute required by tag + * use array('_any') if there is no restriction of attributes names + * + * @var array + */ + public $optional_attributes = array(); + /** + * Shorttag attribute order defined by its names + * + * @var array + */ + public $shorttag_order = array(); + /** + * Array of names of valid option flags + * + * @var array + */ + public $option_flags = array('nocache'); + + /** + * This function checks if the attributes passed are valid + * + * The attributes passed for the tag to compile are checked against the list of required and + * optional attributes. Required attributes must be present. Optional attributes are check against + * the corresponding list. The keyword '_any' specifies that any attribute will be accepted + * as valid + * + * @param object $compiler compiler object + * @param array $attributes attributes applied to the tag + * @return array of mapped attributes for further processing + */ + public function getAttributes($compiler, $attributes) + { + $_indexed_attr = array(); + // loop over attributes + foreach ($attributes as $key => $mixed) { + // shorthand ? + if (!is_array($mixed)) { + // option flag ? + if (in_array(trim($mixed, '\'"'), $this->option_flags)) { + $_indexed_attr[trim($mixed, '\'"')] = true; + // shorthand attribute ? + } else if (isset($this->shorttag_order[$key])) { + $_indexed_attr[$this->shorttag_order[$key]] = $mixed; + } else { + // too many shorthands + $compiler->trigger_template_error('too many shorthand attributes', $compiler->lex->taglineno); + } + // named attribute + } else { + $kv = each($mixed); + // option flag? + if (in_array($kv['key'], $this->option_flags)) { + if (is_bool($kv['value'])) { + $_indexed_attr[$kv['key']] = $kv['value']; + } else if (is_string($kv['value']) && in_array(trim($kv['value'], '\'"'), array('true', 'false'))) { + if (trim($kv['value']) == 'true') { + $_indexed_attr[$kv['key']] = true; + } else { + $_indexed_attr[$kv['key']] = false; + } + } else if (is_numeric($kv['value']) && in_array($kv['value'], array(0, 1))) { + if ($kv['value'] == 1) { + $_indexed_attr[$kv['key']] = true; + } else { + $_indexed_attr[$kv['key']] = false; + } + } else { + $compiler->trigger_template_error("illegal value of option flag \"{$kv['key']}\"", $compiler->lex->taglineno); + } + // must be named attribute + } else { + reset($mixed); + $_indexed_attr[key($mixed)] = $mixed[key($mixed)]; + } + } + } + // check if all required attributes present + foreach ($this->required_attributes as $attr) { + if (!array_key_exists($attr, $_indexed_attr)) { + $compiler->trigger_template_error("missing \"" . $attr . "\" attribute", $compiler->lex->taglineno); + } + } + // check for unallowed attributes + if ($this->optional_attributes != array('_any')) { + $tmp_array = array_merge($this->required_attributes, $this->optional_attributes, $this->option_flags); + foreach ($_indexed_attr as $key => $dummy) { + if (!in_array($key, $tmp_array) && $key !== 0) { + $compiler->trigger_template_error("unexpected \"" . $key . "\" attribute", $compiler->lex->taglineno); + } + } + } + // default 'false' for all option flags not set + foreach ($this->option_flags as $flag) { + if (!isset($_indexed_attr[$flag])) { + $_indexed_attr[$flag] = false; + } + } + + return $_indexed_attr; + } + + /** + * Push opening tag name on stack + * + * Optionally additional data can be saved on stack + * + * @param object $compiler compiler object + * @param string $openTag the opening tag's name + * @param mixed $data optional data saved + */ + public function openTag($compiler, $openTag, $data = null) + { + array_push($compiler->_tag_stack, array($openTag, $data)); + } + + /** + * Pop closing tag + * + * Raise an error if this stack-top doesn't match with expected opening tags + * + * @param object $compiler compiler object + * @param array|string $expectedTag the expected opening tag names + * @return mixed any type the opening tag's name or saved data + */ + public function closeTag($compiler, $expectedTag) + { + if (count($compiler->_tag_stack) > 0) { + // get stacked info + list($_openTag, $_data) = array_pop($compiler->_tag_stack); + // open tag must match with the expected ones + if (in_array($_openTag, (array) $expectedTag)) { + if (is_null($_data)) { + // return opening tag + return $_openTag; + } else { + // return restored data + return $_data; + } + } + // wrong nesting of tags + $compiler->trigger_template_error("unclosed {" . $_openTag . "} tag"); + return; + } + // wrong nesting of tags + $compiler->trigger_template_error("unexpected closing tag", $compiler->lex->taglineno); + return; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_config.php b/include/smarty/libs/sysplugins/smarty_internal_config.php new file mode 100644 index 000000000..bcb3ce054 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_config.php @@ -0,0 +1,302 @@ +<?php +/** + * Smarty Internal Plugin Config + * + * @package Smarty + * @subpackage Config + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Config + * + * Main class for config variables + * + * @package Smarty + * @subpackage Config + * + * @property Smarty_Config_Source $source + * @property Smarty_Config_Compiled $compiled + * @ignore + */ +class Smarty_Internal_Config { + + /** + * Samrty instance + * + * @var Smarty object + */ + public $smarty = null; + /** + * Object of config var storage + * + * @var object + */ + public $data = null; + /** + * Config resource + * @var string + */ + public $config_resource = null; + /** + * Compiled config file + * + * @var string + */ + public $compiled_config = null; + /** + * filepath of compiled config file + * + * @var string + */ + public $compiled_filepath = null; + /** + * Filemtime of compiled config Filemtime + * + * @var int + */ + public $compiled_timestamp = null; + /** + * flag if compiled config file is invalid and must be (re)compiled + * @var bool + */ + public $mustCompile = null; + /** + * Config file compiler object + * + * @var Smarty_Internal_Config_File_Compiler object + */ + public $compiler_object = null; + + /** + * Constructor of config file object + * + * @param string $config_resource config file resource name + * @param Smarty $smarty Smarty instance + * @param object $data object for config vars storage + */ + public function __construct($config_resource, $smarty, $data = null) + { + $this->data = $data; + $this->smarty = $smarty; + $this->config_resource = $config_resource; + } + + /** + * Returns the compiled filepath + * + * @return string the compiled filepath + */ + public function getCompiledFilepath() + { + return $this->compiled_filepath === null ? + ($this->compiled_filepath = $this->buildCompiledFilepath()) : + $this->compiled_filepath; + } + + /** + * Get file path. + * + * @return string + */ + public function buildCompiledFilepath() + { + $_compile_id = isset($this->smarty->compile_id) ? preg_replace('![^\w\|]+!', '_', $this->smarty->compile_id) : null; + $_flag = (int) $this->smarty->config_read_hidden + (int) $this->smarty->config_booleanize * 2 + + (int) $this->smarty->config_overwrite * 4; + $_filepath = sha1($this->source->name . $_flag); + // if use_sub_dirs, break file into directories + if ($this->smarty->use_sub_dirs) { + $_filepath = substr($_filepath, 0, 2) . DS + . substr($_filepath, 2, 2) . DS + . substr($_filepath, 4, 2) . DS + . $_filepath; + } + $_compile_dir_sep = $this->smarty->use_sub_dirs ? DS : '^'; + if (isset($_compile_id)) { + $_filepath = $_compile_id . $_compile_dir_sep . $_filepath; + } + $_compile_dir = $this->smarty->getCompileDir(); + return $_compile_dir . $_filepath . '.' . basename($this->source->name) . '.config' . '.php'; + } + + /** + * Returns the timpestamp of the compiled file + * + * @return integer the file timestamp + */ + public function getCompiledTimestamp() + { + return $this->compiled_timestamp === null + ? ($this->compiled_timestamp = (file_exists($this->getCompiledFilepath())) ? filemtime($this->getCompiledFilepath()) : false) + : $this->compiled_timestamp; + } + + /** + * Returns if the current config file must be compiled + * + * It does compare the timestamps of config source and the compiled config and checks the force compile configuration + * + * @return boolean true if the file must be compiled + */ + public function mustCompile() + { + return $this->mustCompile === null ? + $this->mustCompile = ($this->smarty->force_compile || $this->getCompiledTimestamp () === false || $this->smarty->compile_check && $this->getCompiledTimestamp () < $this->source->timestamp): + $this->mustCompile; + } + + /** + * Returns the compiled config file + * + * It checks if the config file must be compiled or just read the compiled version + * + * @return string the compiled config file + */ + public function getCompiledConfig() + { + if ($this->compiled_config === null) { + // see if template needs compiling. + if ($this->mustCompile()) { + $this->compileConfigSource(); + } else { + $this->compiled_config = file_get_contents($this->getCompiledFilepath()); + } + } + return $this->compiled_config; + } + + /** + * Compiles the config files + * + * @throws Exception + */ + public function compileConfigSource() + { + // compile template + if (!is_object($this->compiler_object)) { + // load compiler + $this->compiler_object = new Smarty_Internal_Config_File_Compiler($this->smarty); + } + // compile locking + if ($this->smarty->compile_locking) { + if ($saved_timestamp = $this->getCompiledTimestamp()) { + touch($this->getCompiledFilepath()); + } + } + // call compiler + try { + $this->compiler_object->compileSource($this); + } catch (Exception $e) { + // restore old timestamp in case of error + if ($this->smarty->compile_locking && $saved_timestamp) { + touch($this->getCompiledFilepath(), $saved_timestamp); + } + throw $e; + } + // compiling succeded + // write compiled template + Smarty_Internal_Write_File::writeFile($this->getCompiledFilepath(), $this->getCompiledConfig(), $this->smarty); + } + + /** + * load config variables + * + * @param mixed $sections array of section names, single section or null + * @param object $scope global,parent or local + */ + public function loadConfigVars($sections = null, $scope = 'local') + { + if ($this->data instanceof Smarty_Internal_Template) { + $this->data->properties['file_dependency'][sha1($this->source->filepath)] = array($this->source->filepath, $this->source->timestamp, 'file'); + } + if ($this->mustCompile()) { + $this->compileConfigSource(); + } + // pointer to scope + if ($scope == 'local') { + $scope_ptr = $this->data; + } elseif ($scope == 'parent') { + if (isset($this->data->parent)) { + $scope_ptr = $this->data->parent; + } else { + $scope_ptr = $this->data; + } + } elseif ($scope == 'root' || $scope == 'global') { + $scope_ptr = $this->data; + while (isset($scope_ptr->parent)) { + $scope_ptr = $scope_ptr->parent; + } + } + $_config_vars = array(); + include($this->getCompiledFilepath()); + // copy global config vars + foreach ($_config_vars['vars'] as $variable => $value) { + if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { + $scope_ptr->config_vars[$variable] = $value; + } else { + $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value); + } + } + // scan sections + if (!empty($sections)) { + foreach ((array) $sections as $this_section) { + if (isset($_config_vars['sections'][$this_section])) { + foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) { + if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { + $scope_ptr->config_vars[$variable] = $value; + } else { + $scope_ptr->config_vars[$variable] = array_merge((array) $scope_ptr->config_vars[$variable], (array) $value); + } + } + } + } + } + } + + /** + * set Smarty property in template context + * + * @param string $property_name property name + * @param mixed $value value + * @throws SmartyException if $property_name is not valid + */ + public function __set($property_name, $value) + { + switch ($property_name) { + case 'source': + case 'compiled': + $this->$property_name = $value; + return; + } + + throw new SmartyException("invalid config property '$property_name'."); + } + + /** + * get Smarty property in template context + * + * @param string $property_name property name + * @throws SmartyException if $property_name is not valid + */ + public function __get($property_name) + { + switch ($property_name) { + case 'source': + if (empty($this->config_resource)) { + throw new SmartyException("Unable to parse resource name \"{$this->config_resource}\""); + } + $this->source = Smarty_Resource::config($this); + return $this->source; + + case 'compiled': + $this->compiled = $this->source->getCompiled($this); + return $this->compiled; + } + + throw new SmartyException("config attribute '$property_name' does not exist."); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php b/include/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php new file mode 100644 index 000000000..b16a6940d --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_config_file_compiler.php @@ -0,0 +1,144 @@ +<?php +/** + * Smarty Internal Plugin Config File Compiler + * + * This is the config file compiler class. It calls the lexer and parser to + * perform the compiling. + * + * @package Smarty + * @subpackage Config + * @author Uwe Tews + */ + +/** + * Main config file compiler class + * + * @package Smarty + * @subpackage Config + */ +class Smarty_Internal_Config_File_Compiler { + + /** + * Lexer object + * + * @var object + */ + public $lex; + + /** + * Parser object + * + * @var object + */ + public $parser; + + /** + * Smarty object + * + * @var Smarty object + */ + public $smarty; + + /** + * Smarty object + * + * @var Smarty_Internal_Config object + */ + public $config; + + /** + * Compiled config data sections and variables + * + * @var array + */ + public $config_data = array(); + + /** + * Initialize compiler + * + * @param Smarty $smarty base instance + */ + public function __construct($smarty) + { + $this->smarty = $smarty; + $this->config_data['sections'] = array(); + $this->config_data['vars'] = array(); + } + + /** + * Method to compile a Smarty template. + * + * @param Smarty_Internal_Config $config config object + * @return bool true if compiling succeeded, false if it failed + */ + public function compileSource(Smarty_Internal_Config $config) + { + /* here is where the compiling takes place. Smarty + tags in the templates are replaces with PHP code, + then written to compiled files. */ + $this->config = $config; + // get config file source + $_content = $config->source->content . "\n"; + // on empty template just return + if ($_content == '') { + return true; + } + // init the lexer/parser to compile the config file + $lex = new Smarty_Internal_Configfilelexer($_content, $this->smarty); + $parser = new Smarty_Internal_Configfileparser($lex, $this); + if ($this->smarty->_parserdebug) $parser->PrintTrace(); + // get tokens from lexer and parse them + while ($lex->yylex()) { + if ($this->smarty->_parserdebug) echo "<br>Parsing {$parser->yyTokenName[$lex->token]} Token {$lex->value} Line {$lex->line} \n"; + $parser->doParse($lex->token, $lex->value); + } + // finish parsing process + $parser->doParse(0, 0); + $config->compiled_config = '<?php $_config_vars = ' . var_export($this->config_data, true) . '; ?>'; + } + + /** + * display compiler error messages without dying + * + * If parameter $args is empty it is a parser detected syntax error. + * In this case the parser is called to obtain information about exspected tokens. + * + * If parameter $args contains a string this is used as error message + * + * @param string $args individual error message or null + */ + public function trigger_config_file_error($args = null) + { + $this->lex = Smarty_Internal_Configfilelexer::instance(); + $this->parser = Smarty_Internal_Configfileparser::instance(); + // get template source line which has error + $line = $this->lex->line; + if (isset($args)) { + // $line--; + } + $match = preg_split("/\n/", $this->lex->data); + $error_text = "Syntax error in config file '{$this->config->source->filepath}' on line {$line} '{$match[$line-1]}' "; + if (isset($args)) { + // individual error message + $error_text .= $args; + } else { + // exspected token from parser + foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) { + $exp_token = $this->parser->yyTokenName[$token]; + if (isset($this->lex->smarty_token_names[$exp_token])) { + // token type from lexer + $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"'; + } else { + // otherwise internal token name + $expect[] = $this->parser->yyTokenName[$token]; + } + } + // output parser error message + $error_text .= ' - Unexpected "' . $this->lex->value . '", expected one of: ' . implode(' , ', $expect); + } + throw new SmartyCompilerException($error_text); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_configfilelexer.php b/include/smarty/libs/sysplugins/smarty_internal_configfilelexer.php new file mode 100644 index 000000000..bade2fe74 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_configfilelexer.php @@ -0,0 +1,622 @@ +<?php +/** +* Smarty Internal Plugin Configfilelexer +* +* This is the lexer to break the config file source into tokens +* @package Smarty +* @subpackage Config +* @author Uwe Tews +*/ +/** +* Smarty Internal Plugin Configfilelexer +*/ +class Smarty_Internal_Configfilelexer +{ + + public $data; + public $counter; + public $token; + public $value; + public $node; + public $line; + private $state = 1; + public $smarty_token_names = array ( // Text for parser error messages + ); + + + function __construct($data, $smarty) + { + // set instance object + self::instance($this); + $this->data = $data . "\n"; //now all lines are \n-terminated + $this->counter = 0; + $this->line = 1; + $this->smarty = $smarty; + $this->mbstring_overload = ini_get('mbstring.func_overload') & 2; + } + public static function &instance($new_instance = null) + { + static $instance = null; + if (isset($new_instance) && is_object($new_instance)) + $instance = $new_instance; + return $instance; + } + + + + private $_yy_state = 1; + private $_yy_stack = array(); + + function yylex() + { + return $this->{'yylex' . $this->_yy_state}(); + } + + function yypushstate($state) + { + array_push($this->_yy_stack, $this->_yy_state); + $this->_yy_state = $state; + } + + function yypopstate() + { + $this->_yy_state = array_pop($this->_yy_stack); + } + + function yybegin($state) + { + $this->_yy_state = $state; + } + + + + + function yylex1() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + 3 => 0, + 4 => 0, + 5 => 0, + 6 => 0, + 7 => 0, + 8 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state START'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r1_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const START = 1; + function yy_r1_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART; + $this->yypushstate(self::COMMENT); + } + function yy_r1_2($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_OPENB; + $this->yypushstate(self::SECTION); + } + function yy_r1_3($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB; + } + function yy_r1_4($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL; + $this->yypushstate(self::VALUE); + } + function yy_r1_5($yy_subpatterns) + { + + return false; + } + function yy_r1_6($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE; + } + function yy_r1_7($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_ID; + } + function yy_r1_8($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_OTHER; + } + + + + function yylex2() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + 3 => 0, + 4 => 0, + 5 => 0, + 6 => 0, + 7 => 0, + 8 => 0, + 9 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state VALUE'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r2_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const VALUE = 2; + function yy_r2_1($yy_subpatterns) + { + + return false; + } + function yy_r2_2($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT; + $this->yypopstate(); + } + function yy_r2_3($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_INT; + $this->yypopstate(); + } + function yy_r2_4($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES; + $this->yypushstate(self::TRIPPLE); + } + function yy_r2_5($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING; + $this->yypopstate(); + } + function yy_r2_6($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING; + $this->yypopstate(); + } + function yy_r2_7($yy_subpatterns) + { + + if (!$this->smarty->config_booleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) { + $this->yypopstate(); + $this->yypushstate(self::NAKED_STRING_VALUE); + return true; //reprocess in new state + } else { + $this->token = Smarty_Internal_Configfileparser::TPC_BOOL; + $this->yypopstate(); + } + } + function yy_r2_8($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + $this->yypopstate(); + } + function yy_r2_9($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + $this->value = ""; + $this->yypopstate(); + } + + + + function yylex3() + { + $tokenMap = array ( + 1 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G([^\n]+?(?=[ \t\r]*\n))/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state NAKED_STRING_VALUE'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r3_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const NAKED_STRING_VALUE = 3; + function yy_r3_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + $this->yypopstate(); + } + + + + function yylex4() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + 3 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state COMMENT'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r4_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const COMMENT = 4; + function yy_r4_1($yy_subpatterns) + { + + return false; + } + function yy_r4_2($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING; + } + function yy_r4_3($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE; + $this->yypopstate(); + } + + + + function yylex5() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state SECTION'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r5_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const SECTION = 5; + function yy_r5_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_DOT; + } + function yy_r5_2($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_SECTION; + $this->yypopstate(); + } + + + function yylex6() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state TRIPPLE'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r6_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const TRIPPLE = 6; + function yy_r6_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END; + $this->yypopstate(); + $this->yypushstate(self::START); + } + function yy_r6_2($yy_subpatterns) + { + + if ($this->mbstring_overload) { + $to = mb_strlen($this->data,'latin1'); + } else { + $to = strlen($this->data); + } + preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } else { + $this->compiler->trigger_template_error ("missing or misspelled literal closing tag"); + } + if ($this->mbstring_overload) { + $this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1'); + } else { + $this->value = substr($this->data,$this->counter,$to-$this->counter); + } + $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT; + } + + +} +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_configfileparser.php b/include/smarty/libs/sysplugins/smarty_internal_configfileparser.php new file mode 100644 index 000000000..784bc684d --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_configfileparser.php @@ -0,0 +1,921 @@ +<?php +/** +* Smarty Internal Plugin Configfileparser +* +* This is the config file parser. +* It is generated from the internal.configfileparser.y file +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ + +class TPC_yyToken implements ArrayAccess +{ + public $string = ''; + public $metadata = array(); + + function __construct($s, $m = array()) + { + if ($s instanceof TPC_yyToken) { + $this->string = $s->string; + $this->metadata = $s->metadata; + } else { + $this->string = (string) $s; + if ($m instanceof TPC_yyToken) { + $this->metadata = $m->metadata; + } elseif (is_array($m)) { + $this->metadata = $m; + } + } + } + + function __toString() + { + return $this->_string; + } + + function offsetExists($offset) + { + return isset($this->metadata[$offset]); + } + + function offsetGet($offset) + { + return $this->metadata[$offset]; + } + + function offsetSet($offset, $value) + { + if ($offset === null) { + if (isset($value[0])) { + $x = ($value instanceof TPC_yyToken) ? + $value->metadata : $value; + $this->metadata = array_merge($this->metadata, $x); + return; + } + $offset = count($this->metadata); + } + if ($value === null) { + return; + } + if ($value instanceof TPC_yyToken) { + if ($value->metadata) { + $this->metadata[$offset] = $value->metadata; + } + } elseif ($value) { + $this->metadata[$offset] = $value; + } + } + + function offsetUnset($offset) + { + unset($this->metadata[$offset]); + } +} + +class TPC_yyStackEntry +{ + public $stateno; /* The state-number */ + public $major; /* The major token value. This is the code + ** number for the token at this stack level */ + public $minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; + + +#line 12 "smarty_internal_configfileparser.y" +class Smarty_Internal_Configfileparser#line 79 "smarty_internal_configfileparser.php" +{ +#line 14 "smarty_internal_configfileparser.y" + + // states whether the parse was successful or not + public $successful = true; + public $retvalue = 0; + private $lex; + private $internalError = false; + + function __construct($lex, $compiler) { + // set instance object + self::instance($this); + $this->lex = $lex; + $this->smarty = $compiler->smarty; + $this->compiler = $compiler; + } + public static function &instance($new_instance = null) + { + static $instance = null; + if (isset($new_instance) && is_object($new_instance)) + $instance = $new_instance; + return $instance; + } + + private function parse_bool($str) { + if (in_array(strtolower($str) ,array('on','yes','true'))) { + $res = true; + } else { + $res = false; + } + return $res; + } + + private static $escapes_single = Array('\\' => '\\', + '\'' => '\''); + private static function parse_single_quoted_string($qstr) { + $escaped_string = substr($qstr, 1, strlen($qstr)-2); //remove outer quotes + + $ss = preg_split('/(\\\\.)/', $escaped_string, -1, PREG_SPLIT_DELIM_CAPTURE); + + $str = ""; + foreach ($ss as $s) { + if (strlen($s) === 2 && $s[0] === '\\') { + if (isset(self::$escapes_single[$s[1]])) { + $s = self::$escapes_single[$s[1]]; + } + } + + $str .= $s; + } + + return $str; + } + + private static function parse_double_quoted_string($qstr) { + $inner_str = substr($qstr, 1, strlen($qstr)-2); + return stripcslashes($inner_str); + } + + private static function parse_tripple_double_quoted_string($qstr) { + return stripcslashes($qstr); + } + + private function set_var(Array $var, Array &$target_array) { + $key = $var["key"]; + $value = $var["value"]; + + if ($this->smarty->config_overwrite || !isset($target_array['vars'][$key])) { + $target_array['vars'][$key] = $value; + } else { + settype($target_array['vars'][$key], 'array'); + $target_array['vars'][$key][] = $value; + } + } + + private function add_global_vars(Array $vars) { + if (!isset($this->compiler->config_data['vars'])) { + $this->compiler->config_data['vars'] = Array(); + } + foreach ($vars as $var) { + $this->set_var($var, $this->compiler->config_data); + } + } + + private function add_section_vars($section_name, Array $vars) { + if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) { + $this->compiler->config_data['sections'][$section_name]['vars'] = Array(); + } + foreach ($vars as $var) { + $this->set_var($var, $this->compiler->config_data['sections'][$section_name]); + } + } +#line 173 "smarty_internal_configfileparser.php" + + const TPC_OPENB = 1; + const TPC_SECTION = 2; + const TPC_CLOSEB = 3; + const TPC_DOT = 4; + const TPC_ID = 5; + const TPC_EQUAL = 6; + const TPC_FLOAT = 7; + const TPC_INT = 8; + const TPC_BOOL = 9; + const TPC_SINGLE_QUOTED_STRING = 10; + const TPC_DOUBLE_QUOTED_STRING = 11; + const TPC_TRIPPLE_QUOTES = 12; + const TPC_TRIPPLE_TEXT = 13; + const TPC_TRIPPLE_QUOTES_END = 14; + const TPC_NAKED_STRING = 15; + const TPC_OTHER = 16; + const TPC_NEWLINE = 17; + const TPC_COMMENTSTART = 18; + const YY_NO_ACTION = 60; + const YY_ACCEPT_ACTION = 59; + const YY_ERROR_ACTION = 58; + + const YY_SZ_ACTTAB = 38; +static public $yy_action = array( + /* 0 */ 29, 30, 34, 33, 24, 13, 19, 25, 35, 21, + /* 10 */ 59, 8, 3, 1, 20, 12, 14, 31, 20, 12, + /* 20 */ 15, 17, 23, 18, 27, 26, 4, 5, 6, 32, + /* 30 */ 2, 11, 28, 22, 16, 9, 7, 10, + ); + static public $yy_lookahead = array( + /* 0 */ 7, 8, 9, 10, 11, 12, 5, 27, 15, 16, + /* 10 */ 20, 21, 23, 23, 17, 18, 13, 14, 17, 18, + /* 20 */ 15, 2, 17, 4, 25, 26, 6, 3, 3, 14, + /* 30 */ 23, 1, 24, 17, 2, 25, 22, 25, +); + const YY_SHIFT_USE_DFLT = -8; + const YY_SHIFT_MAX = 19; + static public $yy_shift_ofst = array( + /* 0 */ -8, 1, 1, 1, -7, -3, -3, 30, -8, -8, + /* 10 */ -8, 19, 5, 3, 15, 16, 24, 25, 32, 20, +); + const YY_REDUCE_USE_DFLT = -21; + const YY_REDUCE_MAX = 10; + static public $yy_reduce_ofst = array( + /* 0 */ -10, -1, -1, -1, -20, 10, 12, 8, 14, 7, + /* 10 */ -11, +); + static public $yyExpectedTokens = array( + /* 0 */ array(), + /* 1 */ array(5, 17, 18, ), + /* 2 */ array(5, 17, 18, ), + /* 3 */ array(5, 17, 18, ), + /* 4 */ array(7, 8, 9, 10, 11, 12, 15, 16, ), + /* 5 */ array(17, 18, ), + /* 6 */ array(17, 18, ), + /* 7 */ array(1, ), + /* 8 */ array(), + /* 9 */ array(), + /* 10 */ array(), + /* 11 */ array(2, 4, ), + /* 12 */ array(15, 17, ), + /* 13 */ array(13, 14, ), + /* 14 */ array(14, ), + /* 15 */ array(17, ), + /* 16 */ array(3, ), + /* 17 */ array(3, ), + /* 18 */ array(2, ), + /* 19 */ array(6, ), + /* 20 */ array(), + /* 21 */ array(), + /* 22 */ array(), + /* 23 */ array(), + /* 24 */ array(), + /* 25 */ array(), + /* 26 */ array(), + /* 27 */ array(), + /* 28 */ array(), + /* 29 */ array(), + /* 30 */ array(), + /* 31 */ array(), + /* 32 */ array(), + /* 33 */ array(), + /* 34 */ array(), + /* 35 */ array(), +); + static public $yy_default = array( + /* 0 */ 44, 37, 41, 40, 58, 58, 58, 36, 39, 44, + /* 10 */ 44, 58, 58, 58, 58, 58, 58, 58, 58, 58, + /* 20 */ 55, 54, 57, 56, 50, 45, 43, 42, 38, 46, + /* 30 */ 47, 52, 51, 49, 48, 53, +); + const YYNOCODE = 29; + const YYSTACKDEPTH = 100; + const YYNSTATE = 36; + const YYNRULE = 22; + const YYERRORSYMBOL = 19; + const YYERRSYMDT = 'yy0'; + const YYFALLBACK = 0; + static public $yyFallback = array( + ); + static function Trace($TraceFILE, $zTracePrompt) + { + if (!$TraceFILE) { + $zTracePrompt = 0; + } elseif (!$zTracePrompt) { + $TraceFILE = 0; + } + self::$yyTraceFILE = $TraceFILE; + self::$yyTracePrompt = $zTracePrompt; + } + + static function PrintTrace() + { + self::$yyTraceFILE = fopen('php://output', 'w'); + self::$yyTracePrompt = '<br>'; + } + + static public $yyTraceFILE; + static public $yyTracePrompt; + public $yyidx; /* Index of top element in stack */ + public $yyerrcnt; /* Shifts left before out of the error */ + public $yystack = array(); /* The parser's stack */ + + public $yyTokenName = array( + '$', 'OPENB', 'SECTION', 'CLOSEB', + 'DOT', 'ID', 'EQUAL', 'FLOAT', + 'INT', 'BOOL', 'SINGLE_QUOTED_STRING', 'DOUBLE_QUOTED_STRING', + 'TRIPPLE_QUOTES', 'TRIPPLE_TEXT', 'TRIPPLE_QUOTES_END', 'NAKED_STRING', + 'OTHER', 'NEWLINE', 'COMMENTSTART', 'error', + 'start', 'global_vars', 'sections', 'var_list', + 'section', 'newline', 'var', 'value', + ); + + static public $yyRuleName = array( + /* 0 */ "start ::= global_vars sections", + /* 1 */ "global_vars ::= var_list", + /* 2 */ "sections ::= sections section", + /* 3 */ "sections ::=", + /* 4 */ "section ::= OPENB SECTION CLOSEB newline var_list", + /* 5 */ "section ::= OPENB DOT SECTION CLOSEB newline var_list", + /* 6 */ "var_list ::= var_list newline", + /* 7 */ "var_list ::= var_list var", + /* 8 */ "var_list ::=", + /* 9 */ "var ::= ID EQUAL value", + /* 10 */ "value ::= FLOAT", + /* 11 */ "value ::= INT", + /* 12 */ "value ::= BOOL", + /* 13 */ "value ::= SINGLE_QUOTED_STRING", + /* 14 */ "value ::= DOUBLE_QUOTED_STRING", + /* 15 */ "value ::= TRIPPLE_QUOTES TRIPPLE_TEXT TRIPPLE_QUOTES_END", + /* 16 */ "value ::= TRIPPLE_QUOTES TRIPPLE_QUOTES_END", + /* 17 */ "value ::= NAKED_STRING", + /* 18 */ "value ::= OTHER", + /* 19 */ "newline ::= NEWLINE", + /* 20 */ "newline ::= COMMENTSTART NEWLINE", + /* 21 */ "newline ::= COMMENTSTART NAKED_STRING NEWLINE", + ); + + function tokenName($tokenType) + { + if ($tokenType === 0) { + return 'End of Input'; + } + if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) { + return $this->yyTokenName[$tokenType]; + } else { + return "Unknown"; + } + } + + static function yy_destructor($yymajor, $yypminor) + { + switch ($yymajor) { + default: break; /* If no destructor action specified: do nothing */ + } + } + + function yy_pop_parser_stack() + { + if (!count($this->yystack)) { + return; + } + $yytos = array_pop($this->yystack); + if (self::$yyTraceFILE && $this->yyidx >= 0) { + fwrite(self::$yyTraceFILE, + self::$yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] . + "\n"); + } + $yymajor = $yytos->major; + self::yy_destructor($yymajor, $yytos->minor); + $this->yyidx--; + return $yymajor; + } + + function __destruct() + { + while ($this->yystack !== Array()) { + $this->yy_pop_parser_stack(); + } + if (is_resource(self::$yyTraceFILE)) { + fclose(self::$yyTraceFILE); + } + } + + function yy_get_expected_tokens($token) + { + $state = $this->yystack[$this->yyidx]->stateno; + $expected = self::$yyExpectedTokens[$state]; + if (in_array($token, self::$yyExpectedTokens[$state], true)) { + return $expected; + } + $stack = $this->yystack; + $yyidx = $this->yyidx; + do { + $yyact = $this->yy_find_shift_action($token); + if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) { + // reduce action + $done = 0; + do { + if ($done++ == 100) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // too much recursion prevents proper detection + // so give up + return array_unique($expected); + } + $yyruleno = $yyact - self::YYNSTATE; + $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs']; + $nextstate = $this->yy_find_reduce_action( + $this->yystack[$this->yyidx]->stateno, + self::$yyRuleInfo[$yyruleno]['lhs']); + if (isset(self::$yyExpectedTokens[$nextstate])) { + $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]); + if (in_array($token, + self::$yyExpectedTokens[$nextstate], true)) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + return array_unique($expected); + } + } + if ($nextstate < self::YYNSTATE) { + // we need to shift a non-terminal + $this->yyidx++; + $x = new TPC_yyStackEntry; + $x->stateno = $nextstate; + $x->major = self::$yyRuleInfo[$yyruleno]['lhs']; + $this->yystack[$this->yyidx] = $x; + continue 2; + } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // the last token was just ignored, we can't accept + // by ignoring input, this is in essence ignoring a + // syntax error! + return array_unique($expected); + } elseif ($nextstate === self::YY_NO_ACTION) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // input accepted, but not shifted (I guess) + return $expected; + } else { + $yyact = $nextstate; + } + } while (true); + } + break; + } while (true); + $this->yyidx = $yyidx; + $this->yystack = $stack; + return array_unique($expected); + } + + function yy_is_expected_token($token) + { + if ($token === 0) { + return true; // 0 is not part of this + } + $state = $this->yystack[$this->yyidx]->stateno; + if (in_array($token, self::$yyExpectedTokens[$state], true)) { + return true; + } + $stack = $this->yystack; + $yyidx = $this->yyidx; + do { + $yyact = $this->yy_find_shift_action($token); + if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) { + // reduce action + $done = 0; + do { + if ($done++ == 100) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // too much recursion prevents proper detection + // so give up + return true; + } + $yyruleno = $yyact - self::YYNSTATE; + $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs']; + $nextstate = $this->yy_find_reduce_action( + $this->yystack[$this->yyidx]->stateno, + self::$yyRuleInfo[$yyruleno]['lhs']); + if (isset(self::$yyExpectedTokens[$nextstate]) && + in_array($token, self::$yyExpectedTokens[$nextstate], true)) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + return true; + } + if ($nextstate < self::YYNSTATE) { + // we need to shift a non-terminal + $this->yyidx++; + $x = new TPC_yyStackEntry; + $x->stateno = $nextstate; + $x->major = self::$yyRuleInfo[$yyruleno]['lhs']; + $this->yystack[$this->yyidx] = $x; + continue 2; + } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + if (!$token) { + // end of input: this is valid + return true; + } + // the last token was just ignored, we can't accept + // by ignoring input, this is in essence ignoring a + // syntax error! + return false; + } elseif ($nextstate === self::YY_NO_ACTION) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // input accepted, but not shifted (I guess) + return true; + } else { + $yyact = $nextstate; + } + } while (true); + } + break; + } while (true); + $this->yyidx = $yyidx; + $this->yystack = $stack; + return true; + } + + function yy_find_shift_action($iLookAhead) + { + $stateno = $this->yystack[$this->yyidx]->stateno; + + /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */ + if (!isset(self::$yy_shift_ofst[$stateno])) { + // no shift actions + return self::$yy_default[$stateno]; + } + $i = self::$yy_shift_ofst[$stateno]; + if ($i === self::YY_SHIFT_USE_DFLT) { + return self::$yy_default[$stateno]; + } + if ($iLookAhead == self::YYNOCODE) { + return self::YY_NO_ACTION; + } + $i += $iLookAhead; + if ($i < 0 || $i >= self::YY_SZ_ACTTAB || + self::$yy_lookahead[$i] != $iLookAhead) { + if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) + && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) { + if (self::$yyTraceFILE) { + fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " . + $this->yyTokenName[$iLookAhead] . " => " . + $this->yyTokenName[$iFallback] . "\n"); + } + return $this->yy_find_shift_action($iFallback); + } + return self::$yy_default[$stateno]; + } else { + return self::$yy_action[$i]; + } + } + + function yy_find_reduce_action($stateno, $iLookAhead) + { + /* $stateno = $this->yystack[$this->yyidx]->stateno; */ + + if (!isset(self::$yy_reduce_ofst[$stateno])) { + return self::$yy_default[$stateno]; + } + $i = self::$yy_reduce_ofst[$stateno]; + if ($i == self::YY_REDUCE_USE_DFLT) { + return self::$yy_default[$stateno]; + } + if ($iLookAhead == self::YYNOCODE) { + return self::YY_NO_ACTION; + } + $i += $iLookAhead; + if ($i < 0 || $i >= self::YY_SZ_ACTTAB || + self::$yy_lookahead[$i] != $iLookAhead) { + return self::$yy_default[$stateno]; + } else { + return self::$yy_action[$i]; + } + } + + function yy_shift($yyNewState, $yyMajor, $yypMinor) + { + $this->yyidx++; + if ($this->yyidx >= self::YYSTACKDEPTH) { + $this->yyidx--; + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt); + } + while ($this->yyidx >= 0) { + $this->yy_pop_parser_stack(); + } +#line 125 "smarty_internal_configfileparser.y" + + $this->internalError = true; + $this->compiler->trigger_config_file_error("Stack overflow in configfile parser"); +#line 593 "smarty_internal_configfileparser.php" + return; + } + $yytos = new TPC_yyStackEntry; + $yytos->stateno = $yyNewState; + $yytos->major = $yyMajor; + $yytos->minor = $yypMinor; + array_push($this->yystack, $yytos); + if (self::$yyTraceFILE && $this->yyidx > 0) { + fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt, + $yyNewState); + fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt); + for($i = 1; $i <= $this->yyidx; $i++) { + fprintf(self::$yyTraceFILE, " %s", + $this->yyTokenName[$this->yystack[$i]->major]); + } + fwrite(self::$yyTraceFILE,"\n"); + } + } + + static public $yyRuleInfo = array( + array( 'lhs' => 20, 'rhs' => 2 ), + array( 'lhs' => 21, 'rhs' => 1 ), + array( 'lhs' => 22, 'rhs' => 2 ), + array( 'lhs' => 22, 'rhs' => 0 ), + array( 'lhs' => 24, 'rhs' => 5 ), + array( 'lhs' => 24, 'rhs' => 6 ), + array( 'lhs' => 23, 'rhs' => 2 ), + array( 'lhs' => 23, 'rhs' => 2 ), + array( 'lhs' => 23, 'rhs' => 0 ), + array( 'lhs' => 26, 'rhs' => 3 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 27, 'rhs' => 3 ), + array( 'lhs' => 27, 'rhs' => 2 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 27, 'rhs' => 1 ), + array( 'lhs' => 25, 'rhs' => 1 ), + array( 'lhs' => 25, 'rhs' => 2 ), + array( 'lhs' => 25, 'rhs' => 3 ), + ); + + static public $yyReduceMap = array( + 0 => 0, + 2 => 0, + 3 => 0, + 19 => 0, + 20 => 0, + 21 => 0, + 1 => 1, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + 9 => 9, + 10 => 10, + 11 => 11, + 12 => 12, + 13 => 13, + 14 => 14, + 15 => 15, + 16 => 16, + 17 => 17, + 18 => 17, + ); +#line 131 "smarty_internal_configfileparser.y" + function yy_r0(){ + $this->_retvalue = null; + } +#line 666 "smarty_internal_configfileparser.php" +#line 136 "smarty_internal_configfileparser.y" + function yy_r1(){ + $this->add_global_vars($this->yystack[$this->yyidx + 0]->minor); $this->_retvalue = null; + } +#line 671 "smarty_internal_configfileparser.php" +#line 149 "smarty_internal_configfileparser.y" + function yy_r4(){ + $this->add_section_vars($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor); + $this->_retvalue = null; + } +#line 677 "smarty_internal_configfileparser.php" +#line 154 "smarty_internal_configfileparser.y" + function yy_r5(){ + if ($this->smarty->config_read_hidden) { + $this->add_section_vars($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + 0]->minor); + } + $this->_retvalue = null; + } +#line 685 "smarty_internal_configfileparser.php" +#line 162 "smarty_internal_configfileparser.y" + function yy_r6(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + } +#line 690 "smarty_internal_configfileparser.php" +#line 166 "smarty_internal_configfileparser.y" + function yy_r7(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor, Array($this->yystack[$this->yyidx + 0]->minor)); + } +#line 695 "smarty_internal_configfileparser.php" +#line 170 "smarty_internal_configfileparser.y" + function yy_r8(){ + $this->_retvalue = Array(); + } +#line 700 "smarty_internal_configfileparser.php" +#line 176 "smarty_internal_configfileparser.y" + function yy_r9(){ + $this->_retvalue = Array("key" => $this->yystack[$this->yyidx + -2]->minor, "value" => $this->yystack[$this->yyidx + 0]->minor); + } +#line 705 "smarty_internal_configfileparser.php" +#line 181 "smarty_internal_configfileparser.y" + function yy_r10(){ + $this->_retvalue = (float) $this->yystack[$this->yyidx + 0]->minor; + } +#line 710 "smarty_internal_configfileparser.php" +#line 185 "smarty_internal_configfileparser.y" + function yy_r11(){ + $this->_retvalue = (int) $this->yystack[$this->yyidx + 0]->minor; + } +#line 715 "smarty_internal_configfileparser.php" +#line 189 "smarty_internal_configfileparser.y" + function yy_r12(){ + $this->_retvalue = $this->parse_bool($this->yystack[$this->yyidx + 0]->minor); + } +#line 720 "smarty_internal_configfileparser.php" +#line 193 "smarty_internal_configfileparser.y" + function yy_r13(){ + $this->_retvalue = self::parse_single_quoted_string($this->yystack[$this->yyidx + 0]->minor); + } +#line 725 "smarty_internal_configfileparser.php" +#line 197 "smarty_internal_configfileparser.y" + function yy_r14(){ + $this->_retvalue = self::parse_double_quoted_string($this->yystack[$this->yyidx + 0]->minor); + } +#line 730 "smarty_internal_configfileparser.php" +#line 201 "smarty_internal_configfileparser.y" + function yy_r15(){ + $this->_retvalue = self::parse_tripple_double_quoted_string($this->yystack[$this->yyidx + -1]->minor); + } +#line 735 "smarty_internal_configfileparser.php" +#line 205 "smarty_internal_configfileparser.y" + function yy_r16(){ + $this->_retvalue = ''; + } +#line 740 "smarty_internal_configfileparser.php" +#line 209 "smarty_internal_configfileparser.y" + function yy_r17(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; + } +#line 745 "smarty_internal_configfileparser.php" + + private $_retvalue; + + function yy_reduce($yyruleno) + { + $yymsp = $this->yystack[$this->yyidx]; + if (self::$yyTraceFILE && $yyruleno >= 0 + && $yyruleno < count(self::$yyRuleName)) { + fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n", + self::$yyTracePrompt, $yyruleno, + self::$yyRuleName[$yyruleno]); + } + + $this->_retvalue = $yy_lefthand_side = null; + if (array_key_exists($yyruleno, self::$yyReduceMap)) { + // call the action + $this->_retvalue = null; + $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}(); + $yy_lefthand_side = $this->_retvalue; + } + $yygoto = self::$yyRuleInfo[$yyruleno]['lhs']; + $yysize = self::$yyRuleInfo[$yyruleno]['rhs']; + $this->yyidx -= $yysize; + for($i = $yysize; $i; $i--) { + // pop all of the right-hand side parameters + array_pop($this->yystack); + } + $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto); + if ($yyact < self::YYNSTATE) { + if (!self::$yyTraceFILE && $yysize) { + $this->yyidx++; + $x = new TPC_yyStackEntry; + $x->stateno = $yyact; + $x->major = $yygoto; + $x->minor = $yy_lefthand_side; + $this->yystack[$this->yyidx] = $x; + } else { + $this->yy_shift($yyact, $yygoto, $yy_lefthand_side); + } + } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) { + $this->yy_accept(); + } + } + + function yy_parse_failed() + { + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt); + } + while ($this->yyidx >= 0) { + $this->yy_pop_parser_stack(); + } + } + + function yy_syntax_error($yymajor, $TOKEN) + { +#line 118 "smarty_internal_configfileparser.y" + + $this->internalError = true; + $this->yymajor = $yymajor; + $this->compiler->trigger_config_file_error(); +#line 808 "smarty_internal_configfileparser.php" + } + + function yy_accept() + { + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt); + } + while ($this->yyidx >= 0) { + $stack = $this->yy_pop_parser_stack(); + } +#line 110 "smarty_internal_configfileparser.y" + + $this->successful = !$this->internalError; + $this->internalError = false; + $this->retvalue = $this->_retvalue; + //echo $this->retvalue."\n\n"; +#line 826 "smarty_internal_configfileparser.php" + } + + function doParse($yymajor, $yytokenvalue) + { + $yyerrorhit = 0; /* True if yymajor has invoked an error */ + + if ($this->yyidx === null || $this->yyidx < 0) { + $this->yyidx = 0; + $this->yyerrcnt = -1; + $x = new TPC_yyStackEntry; + $x->stateno = 0; + $x->major = 0; + $this->yystack = array(); + array_push($this->yystack, $x); + } + $yyendofinput = ($yymajor==0); + + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sInput %s\n", + self::$yyTracePrompt, $this->yyTokenName[$yymajor]); + } + + do { + $yyact = $this->yy_find_shift_action($yymajor); + if ($yymajor < self::YYERRORSYMBOL && + !$this->yy_is_expected_token($yymajor)) { + // force a syntax error + $yyact = self::YY_ERROR_ACTION; + } + if ($yyact < self::YYNSTATE) { + $this->yy_shift($yyact, $yymajor, $yytokenvalue); + $this->yyerrcnt--; + if ($yyendofinput && $this->yyidx >= 0) { + $yymajor = 0; + } else { + $yymajor = self::YYNOCODE; + } + } elseif ($yyact < self::YYNSTATE + self::YYNRULE) { + $this->yy_reduce($yyact - self::YYNSTATE); + } elseif ($yyact == self::YY_ERROR_ACTION) { + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sSyntax Error!\n", + self::$yyTracePrompt); + } + if (self::YYERRORSYMBOL) { + if ($this->yyerrcnt < 0) { + $this->yy_syntax_error($yymajor, $yytokenvalue); + } + $yymx = $this->yystack[$this->yyidx]->major; + if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){ + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n", + self::$yyTracePrompt, $this->yyTokenName[$yymajor]); + } + $this->yy_destructor($yymajor, $yytokenvalue); + $yymajor = self::YYNOCODE; + } else { + while ($this->yyidx >= 0 && + $yymx != self::YYERRORSYMBOL && + ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE + ){ + $this->yy_pop_parser_stack(); + } + if ($this->yyidx < 0 || $yymajor==0) { + $this->yy_destructor($yymajor, $yytokenvalue); + $this->yy_parse_failed(); + $yymajor = self::YYNOCODE; + } elseif ($yymx != self::YYERRORSYMBOL) { + $u2 = 0; + $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2); + } + } + $this->yyerrcnt = 3; + $yyerrorhit = 1; + } else { + if ($this->yyerrcnt <= 0) { + $this->yy_syntax_error($yymajor, $yytokenvalue); + } + $this->yyerrcnt = 3; + $this->yy_destructor($yymajor, $yytokenvalue); + if ($yyendofinput) { + $this->yy_parse_failed(); + } + $yymajor = self::YYNOCODE; + } + } else { + $this->yy_accept(); + $yymajor = self::YYNOCODE; + } + } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0); + } +} +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_data.php b/include/smarty/libs/sysplugins/smarty_internal_data.php new file mode 100644 index 000000000..1d7b1d334 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_data.php @@ -0,0 +1,556 @@ +<?php +/** + * Smarty Internal Plugin Data + * + * This file contains the basic classes and methodes for template and variable creation + * + * @package Smarty + * @subpackage Template + * @author Uwe Tews + */ + +/** + * Base class with template and variable methodes + * + * @package Smarty + * @subpackage Template + */ +class Smarty_Internal_Data { + + /** + * name of class used for templates + * + * @var string + */ + public $template_class = 'Smarty_Internal_Template'; + /** + * template variables + * + * @var array + */ + public $tpl_vars = array(); + /** + * parent template (if any) + * + * @var Smarty_Internal_Template + */ + public $parent = null; + /** + * configuration settings + * + * @var array + */ + public $config_vars = array(); + + /** + * assigns a Smarty variable + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign + * @param boolean $nocache if true any output of this variable will be not cached + * @param boolean $scope the scope the variable will have (local,parent or root) + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function assign($tpl_var, $value = null, $nocache = false) + { + if (is_array($tpl_var)) { + foreach ($tpl_var as $_key => $_val) { + if ($_key != '') { + $this->tpl_vars[$_key] = new Smarty_variable($_val, $nocache); + } + } + } else { + if ($tpl_var != '') { + $this->tpl_vars[$tpl_var] = new Smarty_variable($value, $nocache); + } + } + + return $this; + } + + /** + * assigns a global Smarty variable + * + * @param string $varname the global variable name + * @param mixed $value the value to assign + * @param boolean $nocache if true any output of this variable will be not cached + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function assignGlobal($varname, $value = null, $nocache = false) + { + if ($varname != '') { + Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache); + $ptr = $this; + while ($ptr instanceof Smarty_Internal_Template) { + $ptr->tpl_vars[$varname] = clone Smarty::$global_tpl_vars[$varname]; + $ptr = $ptr->parent; + } + } + + return $this; + } + /** + * assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $ &$value the referenced value to assign + * @param boolean $nocache if true any output of this variable will be not cached + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function assignByRef($tpl_var, &$value, $nocache = false) + { + if ($tpl_var != '') { + $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache); + $this->tpl_vars[$tpl_var]->value = &$value; + } + + return $this; + } + + /** + * appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + * @param boolean $merge flag if array elements shall be merged + * @param boolean $nocache if true any output of this variable will be not cached + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function append($tpl_var, $value = null, $merge = false, $nocache = false) + { + if (is_array($tpl_var)) { + // $tpl_var is an array, ignore $value + foreach ($tpl_var as $_key => $_val) { + if ($_key != '') { + if (!isset($this->tpl_vars[$_key])) { + $tpl_var_inst = $this->getVariable($_key, null, true, false); + if ($tpl_var_inst instanceof Undefined_Smarty_Variable) { + $this->tpl_vars[$_key] = new Smarty_variable(null, $nocache); + } else { + $this->tpl_vars[$_key] = clone $tpl_var_inst; + } + } + if (!(is_array($this->tpl_vars[$_key]->value) || $this->tpl_vars[$_key]->value instanceof ArrayAccess)) { + settype($this->tpl_vars[$_key]->value, 'array'); + } + if ($merge && is_array($_val)) { + foreach($_val as $_mkey => $_mval) { + $this->tpl_vars[$_key]->value[$_mkey] = $_mval; + } + } else { + $this->tpl_vars[$_key]->value[] = $_val; + } + } + } + } else { + if ($tpl_var != '' && isset($value)) { + if (!isset($this->tpl_vars[$tpl_var])) { + $tpl_var_inst = $this->getVariable($tpl_var, null, true, false); + if ($tpl_var_inst instanceof Undefined_Smarty_Variable) { + $this->tpl_vars[$tpl_var] = new Smarty_variable(null, $nocache); + } else { + $this->tpl_vars[$tpl_var] = clone $tpl_var_inst; + } + } + if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) { + settype($this->tpl_vars[$tpl_var]->value, 'array'); + } + if ($merge && is_array($value)) { + foreach($value as $_mkey => $_mval) { + $this->tpl_vars[$tpl_var]->value[$_mkey] = $_mval; + } + } else { + $this->tpl_vars[$tpl_var]->value[] = $value; + } + } + } + + return $this; + } + + /** + * appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed &$value the referenced value to append + * @param boolean $merge flag if array elements shall be merged + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function appendByRef($tpl_var, &$value, $merge = false) + { + if ($tpl_var != '' && isset($value)) { + if (!isset($this->tpl_vars[$tpl_var])) { + $this->tpl_vars[$tpl_var] = new Smarty_variable(); + } + if (!is_array($this->tpl_vars[$tpl_var]->value)) { + settype($this->tpl_vars[$tpl_var]->value, 'array'); + } + if ($merge && is_array($value)) { + foreach($value as $_key => $_val) { + $this->tpl_vars[$tpl_var]->value[$_key] = &$value[$_key]; + } + } else { + $this->tpl_vars[$tpl_var]->value[] = &$value; + } + } + + return $this; + } + + /** + * Returns a single or all template variables + * + * @param string $varname variable name or null + * @param string $_ptr optional pointer to data object + * @param boolean $search_parents include parent templates? + * @return string variable value or or array of variables + */ + public function getTemplateVars($varname = null, $_ptr = null, $search_parents = true) + { + if (isset($varname)) { + $_var = $this->getVariable($varname, $_ptr, $search_parents, false); + if (is_object($_var)) { + return $_var->value; + } else { + return null; + } + } else { + $_result = array(); + if ($_ptr === null) { + $_ptr = $this; + } while ($_ptr !== null) { + foreach ($_ptr->tpl_vars AS $key => $var) { + if (!array_key_exists($key, $_result)) { + $_result[$key] = $var->value; + } + } + // not found, try at parent + if ($search_parents) { + $_ptr = $_ptr->parent; + } else { + $_ptr = null; + } + } + if ($search_parents && isset(Smarty::$global_tpl_vars)) { + foreach (Smarty::$global_tpl_vars AS $key => $var) { + if (!array_key_exists($key, $_result)) { + $_result[$key] = $var->value; + } + } + } + return $_result; + } + } + + /** + * clear the given assigned template variable. + * + * @param string|array $tpl_var the template variable(s) to clear + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function clearAssign($tpl_var) + { + if (is_array($tpl_var)) { + foreach ($tpl_var as $curr_var) { + unset($this->tpl_vars[$curr_var]); + } + } else { + unset($this->tpl_vars[$tpl_var]); + } + + return $this; + } + + /** + * clear all the assigned template variables. + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function clearAllAssign() + { + $this->tpl_vars = array(); + return $this; + } + + /** + * load a config file, optionally load just selected sections + * + * @param string $config_file filename + * @param mixed $sections array of section names, single section or null + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function configLoad($config_file, $sections = null) + { + // load Config class + $config = new Smarty_Internal_Config($config_file, $this->smarty, $this); + $config->loadConfigVars($sections); + return $this; + } + + /** + * gets the object of a Smarty variable + * + * @param string $variable the name of the Smarty variable + * @param object $_ptr optional pointer to data object + * @param boolean $search_parents search also in parent data + * @return object the object of the variable + */ + public function getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true) + { + if ($_ptr === null) { + $_ptr = $this; + } while ($_ptr !== null) { + if (isset($_ptr->tpl_vars[$variable])) { + // found it, return it + return $_ptr->tpl_vars[$variable]; + } + // not found, try at parent + if ($search_parents) { + $_ptr = $_ptr->parent; + } else { + $_ptr = null; + } + } + if (isset(Smarty::$global_tpl_vars[$variable])) { + // found it, return it + return Smarty::$global_tpl_vars[$variable]; + } + if ($this->smarty->error_unassigned && $error_enable) { + // force a notice + $x = $$variable; + } + return new Undefined_Smarty_Variable; + } + + /** + * gets a config variable + * + * @param string $variable the name of the config variable + * @return mixed the value of the config variable + */ + public function getConfigVariable($variable, $error_enable = true) + { + $_ptr = $this; + while ($_ptr !== null) { + if (isset($_ptr->config_vars[$variable])) { + // found it, return it + return $_ptr->config_vars[$variable]; + } + // not found, try at parent + $_ptr = $_ptr->parent; + } + if ($this->smarty->error_unassigned && $error_enable) { + // force a notice + $x = $$variable; + } + return null; + } + + /** + * gets a stream variable + * + * @param string $variable the stream of the variable + * @return mixed the value of the stream variable + */ + public function getStreamVariable($variable) + { + $_result = ''; + $fp = fopen($variable, 'r+'); + if ($fp) { + while (!feof($fp) && ($current_line = fgets($fp)) !== false ) { + $_result .= $current_line; + } + fclose($fp); + return $_result; + } + + if ($this->smarty->error_unassigned) { + throw new SmartyException('Undefined stream variable "' . $variable . '"'); + } else { + return null; + } + } + + /** + * Returns a single or all config variables + * + * @param string $varname variable name or null + * @return string variable value or or array of variables + */ + public function getConfigVars($varname = null, $search_parents = true) + { + $_ptr = $this; + $var_array = array(); + while ($_ptr !== null) { + if (isset($varname)) { + if (isset($_ptr->config_vars[$varname])) { + return $_ptr->config_vars[$varname]; + } + } else { + $var_array = array_merge($_ptr->config_vars, $var_array); + } + // not found, try at parent + if ($search_parents) { + $_ptr = $_ptr->parent; + } else { + $_ptr = null; + } + } + if (isset($varname)) { + return ''; + } else { + return $var_array; + } + } + + /** + * Deassigns a single or all config variables + * + * @param string $varname variable name or null + * @return Smarty_Internal_Data current Smarty_Internal_Data (or Smarty or Smarty_Internal_Template) instance for chaining + */ + public function clearConfig($varname = null) + { + if (isset($varname)) { + unset($this->config_vars[$varname]); + } else { + $this->config_vars = array(); + } + return $this; + } + +} + +/** + * class for the Smarty data object + * + * The Smarty data object will hold Smarty variables in the current scope + * + * @package Smarty + * @subpackage Template + */ +class Smarty_Data extends Smarty_Internal_Data { + + /** + * Smarty object + * + * @var Smarty + */ + public $smarty = null; + + /** + * create Smarty data object + * + * @param Smarty|array $_parent parent template + * @param Smarty $smarty global smarty instance + */ + public function __construct ($_parent = null, $smarty = null) + { + $this->smarty = $smarty; + if (is_object($_parent)) { + // when object set up back pointer + $this->parent = $_parent; + } elseif (is_array($_parent)) { + // set up variable values + foreach ($_parent as $_key => $_val) { + $this->tpl_vars[$_key] = new Smarty_variable($_val); + } + } elseif ($_parent != null) { + throw new SmartyException("Wrong type for template variables"); + } + } + +} + +/** + * class for the Smarty variable object + * + * This class defines the Smarty variable object + * + * @package Smarty + * @subpackage Template + */ +class Smarty_Variable { + + /** + * template variable + * + * @var mixed + */ + public $value = null; + /** + * if true any output of this variable will be not cached + * + * @var boolean + */ + public $nocache = false; + /** + * the scope the variable will have (local,parent or root) + * + * @var int + */ + public $scope = Smarty::SCOPE_LOCAL; + + /** + * create Smarty variable object + * + * @param mixed $value the value to assign + * @param boolean $nocache if true any output of this variable will be not cached + * @param int $scope the scope the variable will have (local,parent or root) + */ + public function __construct($value = null, $nocache = false, $scope = Smarty::SCOPE_LOCAL) + { + $this->value = $value; + $this->nocache = $nocache; + $this->scope = $scope; + } + + /** + * <<magic>> String conversion + * + * @return string + */ + public function __toString() + { + return (string) $this->value; + } + +} + +/** + * class for undefined variable object + * + * This class defines an object for undefined variable handling + * + * @package Smarty + * @subpackage Template + */ +class Undefined_Smarty_Variable { + + /** + * Returns FALSE for 'nocache' and NULL otherwise. + * + * @param string $name + * @return bool + */ + public function __get($name) + { + if ($name == 'nocache') { + return false; + } else { + return null; + } + } + + /** + * Always returns an empty string. + * + * @return string + */ + public function __toString() + { + return ""; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_debug.php b/include/smarty/libs/sysplugins/smarty_internal_debug.php new file mode 100644 index 000000000..2aea13f30 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_debug.php @@ -0,0 +1,206 @@ +<?php +/** + * Smarty Internal Plugin Debug + * + * Class to collect data for the Smarty Debugging Consol + * + * @package Smarty + * @subpackage Debug + * @author Uwe Tews + */ + +/** + * Smarty Internal Plugin Debug Class + * + * @package Smarty + * @subpackage Debug + */ +class Smarty_Internal_Debug extends Smarty_Internal_Data { + + /** + * template data + * + * @var array + */ + public static $template_data = array(); + + /** + * Start logging of compile time + * + * @param object $template + */ + public static function start_compile($template) + { + $key = self::get_key($template); + self::$template_data[$key]['start_time'] = microtime(true); + } + + /** + * End logging of compile time + * + * @param object $template + */ + public static function end_compile($template) + { + $key = self::get_key($template); + self::$template_data[$key]['compile_time'] += microtime(true) - self::$template_data[$key]['start_time']; + } + + /** + * Start logging of render time + * + * @param object $template + */ + public static function start_render($template) + { + $key = self::get_key($template); + self::$template_data[$key]['start_time'] = microtime(true); + } + + /** + * End logging of compile time + * + * @param object $template + */ + public static function end_render($template) + { + $key = self::get_key($template); + self::$template_data[$key]['render_time'] += microtime(true) - self::$template_data[$key]['start_time']; + } + + /** + * Start logging of cache time + * + * @param object $template cached template + */ + public static function start_cache($template) + { + $key = self::get_key($template); + self::$template_data[$key]['start_time'] = microtime(true); + } + + /** + * End logging of cache time + * + * @param object $template cached template + */ + public static function end_cache($template) + { + $key = self::get_key($template); + self::$template_data[$key]['cache_time'] += microtime(true) - self::$template_data[$key]['start_time']; + } + + /** + * Opens a window for the Smarty Debugging Consol and display the data + * + * @param Smarty_Internal_Template|Smarty $obj object to debug + */ + public static function display_debug($obj) + { + // prepare information of assigned variables + $ptr = self::get_debug_vars($obj); + if ($obj instanceof Smarty) { + $smarty = clone $obj; + } else { + $smarty = clone $obj->smarty; + } + $_assigned_vars = $ptr->tpl_vars; + ksort($_assigned_vars); + $_config_vars = $ptr->config_vars; + ksort($_config_vars); + $smarty->registered_filters = array(); + $smarty->autoload_filters = array(); + $smarty->default_modifiers = array(); + $smarty->force_compile = false; + $smarty->left_delimiter = '{'; + $smarty->right_delimiter = '}'; + $smarty->debugging = false; + $smarty->force_compile = false; + $_template = new Smarty_Internal_Template($smarty->debug_tpl, $smarty); + $_template->caching = false; + $_template->disableSecurity(); + $_template->cache_id = null; + $_template->compile_id = null; + if ($obj instanceof Smarty_Internal_Template) { + $_template->assign('template_name', $obj->source->type . ':' . $obj->source->name); + } + if ($obj instanceof Smarty) { + $_template->assign('template_data', self::$template_data); + } else { + $_template->assign('template_data', null); + } + $_template->assign('assigned_vars', $_assigned_vars); + $_template->assign('config_vars', $_config_vars); + $_template->assign('execution_time', microtime(true) - $smarty->start_time); + echo $_template->fetch(); + } + + /** + * Recursively gets variables from all template/data scopes + * + * @param Smarty_Internal_Template|Smarty_Data $obj object to debug + * @return StdClass + */ + public static function get_debug_vars($obj) + { + $config_vars = $obj->config_vars; + $tpl_vars = array(); + foreach ($obj->tpl_vars as $key => $var) { + $tpl_vars[$key] = clone $var; + if ($obj instanceof Smarty_Internal_Template) { + $tpl_vars[$key]->scope = $obj->source->type . ':' . $obj->source->name; + } elseif ($obj instanceof Smarty_Data) { + $tpl_vars[$key]->scope = 'Data object'; + } else { + $tpl_vars[$key]->scope = 'Smarty root'; + } + } + + if (isset($obj->parent)) { + $parent = self::get_debug_vars($obj->parent); + $tpl_vars = array_merge($parent->tpl_vars, $tpl_vars); + $config_vars = array_merge($parent->config_vars, $config_vars); + } else { + foreach (Smarty::$global_tpl_vars as $name => $var) { + if (!array_key_exists($name, $tpl_vars)) { + $clone = clone $var; + $clone->scope = 'Global'; + $tpl_vars[$name] = $clone; + } + } + } + return (object) array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars); + } + + /** + * Return key into $template_data for template + * + * @param object $template template object + * @return string key into $template_data + */ + private static function get_key($template) + { + static $_is_stringy = array('string' => true, 'eval' => true); + // calculate Uid if not already done + if ($template->source->uid == '') { + $template->source->filepath; + } + $key = $template->source->uid; + if (isset(self::$template_data[$key])) { + return $key; + } else { + if (isset($_is_stringy[$template->source->type])) { + self::$template_data[$key]['name'] = '\''.substr($template->source->name,0,25).'...\''; + } else { + self::$template_data[$key]['name'] = $template->source->filepath; + } + self::$template_data[$key]['compile_time'] = 0; + self::$template_data[$key]['render_time'] = 0; + self::$template_data[$key]['cache_time'] = 0; + return $key; + } + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_filter_handler.php b/include/smarty/libs/sysplugins/smarty_internal_filter_handler.php new file mode 100644 index 000000000..c9370e1ac --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_filter_handler.php @@ -0,0 +1,70 @@ +<?php +/** + * Smarty Internal Plugin Filter Handler + * + * Smarty filter handler class + * + * @package Smarty + * @subpackage PluginsInternal + * @author Uwe Tews + */ + +/** + * Class for filter processing + * + * @package Smarty + * @subpackage PluginsInternal + */ +class Smarty_Internal_Filter_Handler { + + /** + * Run filters over content + * + * The filters will be lazy loaded if required + * class name format: Smarty_FilterType_FilterName + * plugin filename format: filtertype.filtername.php + * Smarty2 filter plugins could be used + * + * @param string $type the type of filter ('pre','post','output') which shall run + * @param string $content the content which shall be processed by the filters + * @param Smarty_Internal_Template $template template object + * @return string the filtered content + */ + public static function runFilter($type, $content, Smarty_Internal_Template $template) + { + $output = $content; + // loop over autoload filters of specified type + if (!empty($template->smarty->autoload_filters[$type])) { + foreach ((array)$template->smarty->autoload_filters[$type] as $name) { + $plugin_name = "Smarty_{$type}filter_{$name}"; + if ($template->smarty->loadPlugin($plugin_name)) { + if (function_exists($plugin_name)) { + // use loaded Smarty2 style plugin + $output = $plugin_name($output, $template); + } elseif (class_exists($plugin_name, false)) { + // loaded class of filter plugin + $output = call_user_func(array($plugin_name, 'execute'), $output, $template); + } + } else { + // nothing found, throw exception + throw new SmartyException("Unable to load filter {$plugin_name}"); + } + } + } + // loop over registerd filters of specified type + if (!empty($template->smarty->registered_filters[$type])) { + foreach ($template->smarty->registered_filters[$type] as $key => $name) { + if (is_array($template->smarty->registered_filters[$type][$key])) { + $output = call_user_func($template->smarty->registered_filters[$type][$key], $output, $template); + } else { + $output = $template->smarty->registered_filters[$type][$key]($output, $template); + } + } + } + // return filtered output + return $output; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_function_call_handler.php b/include/smarty/libs/sysplugins/smarty_internal_function_call_handler.php new file mode 100644 index 000000000..010d63592 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_function_call_handler.php @@ -0,0 +1,55 @@ +<?php
+/**
+ * Smarty Internal Plugin Function Call Handler
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Uwe Tews
+ */
+
+/**
+ * This class does call function defined with the {function} tag
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Function_Call_Handler {
+
+ /**
+ * This function handles calls to template functions defined by {function}
+ * It does create a PHP function at the first call
+ *
+ * @param string $_name template function name
+ * @param Smarty_Internal_Template $_template template object
+ * @param array $_params Smarty variables passed as call parameter
+ * @param string $_hash nocache hash value
+ * @param bool $_nocache nocache flag
+ */
+ public static function call($_name, Smarty_Internal_Template $_template, $_params, $_hash, $_nocache)
+ {
+ if ($_nocache) {
+ $_function = "smarty_template_function_{$_name}_nocache";
+ } else {
+ $_function = "smarty_template_function_{$_hash}_{$_name}";
+ }
+ if (!is_callable($_function)) {
+ $_code = "function {$_function}(\$_smarty_tpl,\$params) {
+ \$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
+ foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
+ foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
+ if ($_nocache) {
+ $_code .= preg_replace(array("!<\?php echo \\'/\*%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/|/\*/%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/\\';\?>!",
+ "!\\\'!"), array('', "'"), $_template->smarty->template_functions[$_name]['compiled']);
+ $_template->smarty->template_functions[$_name]['called_nocache'] = true;
+ } else {
+ $_code .= preg_replace("/{$_template->smarty->template_functions[$_name]['nocache_hash']}/", $_template->properties['nocache_hash'], $_template->smarty->template_functions[$_name]['compiled']);
+ }
+ $_code .= "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}";
+ eval($_code);
+ }
+ $_function($_template, $_params);
+ }
+
+}
+
+?>
diff --git a/include/smarty/libs/sysplugins/smarty_internal_get_include_path.php b/include/smarty/libs/sysplugins/smarty_internal_get_include_path.php new file mode 100644 index 000000000..518c406aa --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_get_include_path.php @@ -0,0 +1,48 @@ +<?php
+/**
+ * Smarty read include path plugin
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ * @author Monte Ohrt
+ */
+
+/**
+ * Smarty Internal Read Include Path Class
+ *
+ * @package Smarty
+ * @subpackage PluginsInternal
+ */
+class Smarty_Internal_Get_Include_Path {
+
+ /**
+ * Return full file path from PHP include_path
+ *
+ * @param string $filepath filepath
+ * @return string|boolean full filepath or false
+ */
+ public static function getIncludePath($filepath)
+ {
+ static $_include_path = null;
+
+ if (function_exists('stream_resolve_include_path')) {
+ // available since PHP 5.3.2
+ return stream_resolve_include_path($filepath);
+ }
+
+ if ($_include_path === null) {
+ $_include_path = explode(PATH_SEPARATOR, get_include_path());
+ }
+
+ foreach ($_include_path as $_path) {
+ if (file_exists($_path . DS . $filepath)) {
+ return $_path . DS . $filepath;
+ }
+ }
+
+ return false;
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_nocache_insert.php b/include/smarty/libs/sysplugins/smarty_internal_nocache_insert.php new file mode 100644 index 000000000..faae49af6 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_nocache_insert.php @@ -0,0 +1,53 @@ +<?php
+/**
+ * Smarty Internal Plugin Nocache Insert
+ *
+ * Compiles the {insert} tag into the cache file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty Internal Plugin Compile Insert Class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+class Smarty_Internal_Nocache_Insert {
+
+ /**
+ * Compiles code for the {insert} tag into cache file
+ *
+ * @param string $_function insert function name
+ * @param array $_attr array with parameter
+ * @param Smarty_Internal_Template $_template template object
+ * @param string $_script script name to load or 'null'
+ * @param string $_assign optional variable name
+ * @return string compiled code
+ */
+ public static function compile($_function, $_attr, $_template, $_script, $_assign = null)
+ {
+ $_output = '<?php ';
+ if ($_script != 'null') {
+ // script which must be included
+ // code for script file loading
+ $_output .= "require_once '{$_script}';";
+ }
+ // call insert
+ if (isset($_assign)) {
+ $_output .= "\$_smarty_tpl->assign('{$_assign}' , {$_function} (" . var_export($_attr, true) . ",\$_smarty_tpl), true);?>";
+ } else {
+ $_output .= "echo {$_function}(" . var_export($_attr, true) . ",\$_smarty_tpl);?>";
+ }
+ $_tpl = $_template;
+ while ($_tpl->parent instanceof Smarty_Internal_Template) {
+ $_tpl = $_tpl->parent;
+ }
+ return "/*%%SmartyNocache:{$_tpl->properties['nocache_hash']}%%*/" . $_output . "/*/%%SmartyNocache:{$_tpl->properties['nocache_hash']}%%*/";
+ }
+
+}
+
+?>
diff --git a/include/smarty/libs/sysplugins/smarty_internal_parsetree.php b/include/smarty/libs/sysplugins/smarty_internal_parsetree.php new file mode 100644 index 000000000..c9fb1f762 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_parsetree.php @@ -0,0 +1,395 @@ +<?php
+/**
+ * Smarty Internal Plugin Templateparser Parsetrees
+ *
+ * These are classes to build parsetrees in the template parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Thue Kristensen
+ * @author Uwe Tews
+ */
+
+/**
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+abstract class _smarty_parsetree {
+
+ /**
+ * Parser object
+ * @var object
+ */
+ public $parser;
+ /**
+ * Buffer content
+ * @var mixed
+ */
+ public $data;
+
+ /**
+ * Return buffer
+ *
+ * @return string buffer content
+ */
+ abstract public function to_smarty_php();
+
+}
+
+/**
+ * A complete smarty tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_tag extends _smarty_parsetree {
+
+ /**
+ * Saved block nesting level
+ * @var int
+ */
+ public $saved_block_nesting;
+
+ /**
+ * Create parse tree buffer for Smarty tag
+ *
+ * @param object $parser parser object
+ * @param string $data content
+ */
+ public function __construct($parser, $data)
+ {
+ $this->parser = $parser;
+ $this->data = $data;
+ $this->saved_block_nesting = $parser->block_nesting_level;
+ }
+
+ /**
+ * Return buffer content
+ *
+ * @return string content
+ */
+ public function to_smarty_php()
+ {
+ return $this->data;
+ }
+
+ /**
+ * Return complied code that loads the evaluated outout of buffer content into a temporary variable
+ *
+ * @return string template code
+ */
+ public function assign_to_var()
+ {
+ $var = sprintf('$_tmp%d', ++$this->parser->prefix_number);
+ $this->parser->compiler->prefix_code[] = sprintf('<?php ob_start();?>%s<?php %s=ob_get_clean();?>', $this->data, $var);
+ return $var;
+ }
+
+}
+
+/**
+ * Code fragment inside a tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_code extends _smarty_parsetree {
+
+
+ /**
+ * Create parse tree buffer for code fragment
+ *
+ * @param object $parser parser object
+ * @param string $data content
+ */
+ public function __construct($parser, $data)
+ {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return buffer content in parentheses
+ *
+ * @return string content
+ */
+ public function to_smarty_php()
+ {
+ return sprintf("(%s)", $this->data);
+ }
+
+}
+
+/**
+ * Double quoted string inside a tag.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_doublequoted extends _smarty_parsetree {
+
+ /**
+ * Create parse tree buffer for double quoted string subtrees
+ *
+ * @param object $parser parser object
+ * @param _smarty_parsetree $subtree parsetree buffer
+ */
+ public function __construct($parser, _smarty_parsetree $subtree)
+ {
+ $this->parser = $parser;
+ $this->subtrees[] = $subtree;
+ if ($subtree instanceof _smarty_tag) {
+ $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);
+ }
+ }
+
+ /**
+ * Append buffer to subtree
+ *
+ * @param _smarty_parsetree $subtree parsetree buffer
+ */
+ public function append_subtree(_smarty_parsetree $subtree)
+ {
+ $last_subtree = count($this->subtrees) - 1;
+ if ($last_subtree >= 0 && $this->subtrees[$last_subtree] instanceof _smarty_tag && $this->subtrees[$last_subtree]->saved_block_nesting < $this->parser->block_nesting_level) {
+ if ($subtree instanceof _smarty_code) {
+ $this->subtrees[$last_subtree]->data .= '<?php echo ' . $subtree->data . ';?>';
+ } elseif ($subtree instanceof _smarty_dq_content) {
+ $this->subtrees[$last_subtree]->data .= '<?php echo "' . $subtree->data . '";?>';
+ } else {
+ $this->subtrees[$last_subtree]->data .= $subtree->data;
+ }
+ } else {
+ $this->subtrees[] = $subtree;
+ }
+ if ($subtree instanceof _smarty_tag) {
+ $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);
+ }
+ }
+
+ /**
+ * Merge subtree buffer content together
+ *
+ * @return string compiled template code
+ */
+ public function to_smarty_php()
+ {
+ $code = '';
+ foreach ($this->subtrees as $subtree) {
+ if ($code !== "") {
+ $code .= ".";
+ }
+ if ($subtree instanceof _smarty_tag) {
+ $more_php = $subtree->assign_to_var();
+ } else {
+ $more_php = $subtree->to_smarty_php();
+ }
+
+ $code .= $more_php;
+
+ if (!$subtree instanceof _smarty_dq_content) {
+ $this->parser->compiler->has_variable_string = true;
+ }
+ }
+ return $code;
+ }
+
+}
+
+/**
+ * Raw chars as part of a double quoted string.
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_dq_content extends _smarty_parsetree {
+
+
+ /**
+ * Create parse tree buffer with string content
+ *
+ * @param object $parser parser object
+ * @param string $data string section
+ */
+ public function __construct($parser, $data)
+ {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return content as double quoted string
+ *
+ * @return string doubled quoted string
+ */
+ public function to_smarty_php()
+ {
+ return '"' . $this->data . '"';
+ }
+
+}
+
+/**
+ * Template element
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_template_buffer extends _smarty_parsetree {
+
+ /**
+ * Array of template elements
+ *
+ * @var array
+ */
+ public $subtrees = Array();
+
+ /**
+ * Create root of parse tree for template elements
+ *
+ * @param object $parser parse object
+ */
+ public function __construct($parser)
+ {
+ $this->parser = $parser;
+ }
+
+ /**
+ * Append buffer to subtree
+ *
+ * @param _smarty_parsetree $subtree
+ */
+ public function append_subtree(_smarty_parsetree $subtree)
+ {
+ $this->subtrees[] = $subtree;
+ }
+
+ /**
+ * Sanitize and merge subtree buffers together
+ *
+ * @return string template code content
+ */
+ public function to_smarty_php()
+ {
+ $code = '';
+ for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {
+ if ($key + 2 < $cnt) {
+ if ($this->subtrees[$key] instanceof _smarty_linebreak && $this->subtrees[$key + 1] instanceof _smarty_tag && $this->subtrees[$key + 1]->data == '' && $this->subtrees[$key + 2] instanceof _smarty_linebreak) {
+ $key = $key + 1;
+ continue;
+ }
+ if (substr($this->subtrees[$key]->data, -1) == '<' && $this->subtrees[$key + 1]->data == '' && substr($this->subtrees[$key + 2]->data, -1) == '?') {
+ $key = $key + 2;
+ continue;
+ }
+ }
+ if (substr($code, -1) == '<') {
+ $subtree = $this->subtrees[$key]->to_smarty_php();
+ if (substr($subtree, 0, 1) == '?') {
+ $code = substr($code, 0, strlen($code) - 1) . '<<?php ?>?' . substr($subtree, 1);
+ } elseif ($this->parser->asp_tags && substr($subtree, 0, 1) == '%') {
+ $code = substr($code, 0, strlen($code) - 1) . '<<?php ?>%' . substr($subtree, 1);
+ } else {
+ $code .= $subtree;
+ }
+ continue;
+ }
+ if ($this->parser->asp_tags && substr($code, -1) == '%') {
+ $subtree = $this->subtrees[$key]->to_smarty_php();
+ if (substr($subtree, 0, 1) == '>') {
+ $code = substr($code, 0, strlen($code) - 1) . '%<?php ?>>' . substr($subtree, 1);
+ } else {
+ $code .= $subtree;
+ }
+ continue;
+ }
+ if (substr($code, -1) == '?') {
+ $subtree = $this->subtrees[$key]->to_smarty_php();
+ if (substr($subtree, 0, 1) == '>') {
+ $code = substr($code, 0, strlen($code) - 1) . '?<?php ?>>' . substr($subtree, 1);
+ } else {
+ $code .= $subtree;
+ }
+ continue;
+ }
+ $code .= $this->subtrees[$key]->to_smarty_php();
+ }
+ return $code;
+ }
+
+}
+
+/**
+ * template text
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_text extends _smarty_parsetree {
+
+
+ /**
+ * Create template text buffer
+ *
+ * @param object $parser parser object
+ * @param string $data text
+ */
+ public function __construct($parser, $data)
+ {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return buffer content
+ *
+ * @return strint text
+ */
+ public function to_smarty_php()
+ {
+ return $this->data;
+ }
+
+}
+
+/**
+ * template linebreaks
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @ignore
+ */
+class _smarty_linebreak extends _smarty_parsetree {
+
+ /**
+ * Create buffer with linebreak content
+ *
+ * @param object $parser parser object
+ * @param string $data linebreak string
+ */
+ public function __construct($parser, $data)
+ {
+ $this->parser = $parser;
+ $this->data = $data;
+ }
+
+ /**
+ * Return linebrak
+ *
+ * @return string linebreak
+ */
+ public function to_smarty_php()
+ {
+ return $this->data;
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_eval.php b/include/smarty/libs/sysplugins/smarty_internal_resource_eval.php new file mode 100644 index 000000000..cf2ec3e1c --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_eval.php @@ -0,0 +1,94 @@ +<?php
+/**
+ * Smarty Internal Plugin Resource Eval
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ * @author Uwe Tews
+ * @author Rodney Rehm
+ */
+
+/**
+ * Smarty Internal Plugin Resource Eval
+ *
+ * Implements the strings as resource for Smarty template
+ *
+ * {@internal unlike string-resources the compiled state of eval-resources is NOT saved for subsequent access}}
+ *
+ * @package Smarty
+ * @subpackage TemplateResources
+ */
+class Smarty_Internal_Resource_Eval extends Smarty_Resource_Recompiled {
+
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ * @return void
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
+ {
+ $source->uid = $source->filepath = sha1($source->name);
+ $source->timestamp = false;
+ $source->exists = true;
+ }
+
+ /**
+ * Load template's source from $resource_name into current template object
+ *
+ * @uses decode() to decode base64 and urlencoded template_resources
+ * @param Smarty_Template_Source $source source object
+ * @return string template source
+ */
+ public function getContent(Smarty_Template_Source $source)
+ {
+ return $this->decode($source->name);
+ }
+
+ /**
+ * decode base64 and urlencode
+ *
+ * @param string $string template_resource to decode
+ * @return string decoded template_resource
+ */
+ protected function decode($string)
+ {
+ // decode if specified
+ if (($pos = strpos($string, ':')) !== false) {
+ if (!strncmp($string, 'base64', 6)) {
+ return base64_decode(substr($string, 7));
+ } elseif (!strncmp($string, 'urlencode', 9)) {
+ return urldecode(substr($string, 10));
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ * @return string unique resource name
+ */
+ protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
+ {
+ return get_class($this) . '#' .$this->decode($resource_name);
+ }
+
+ /**
+ * Determine basename for compiled filename
+ *
+ * @param Smarty_Template_Source $source source object
+ * @return string resource's basename
+ */
+ protected function getBasename(Smarty_Template_Source $source)
+ {
+ return '';
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_extends.php b/include/smarty/libs/sysplugins/smarty_internal_resource_extends.php new file mode 100644 index 000000000..29734ae05 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_extends.php @@ -0,0 +1,162 @@ +<?php +/** +* Smarty Internal Plugin Resource Extends +* +* @package Smarty +* @subpackage TemplateResources +* @author Uwe Tews +* @author Rodney Rehm +*/ + +/** +* Smarty Internal Plugin Resource Extends +* +* Implements the file system as resource for Smarty which {extend}s a chain of template files templates +* +* @package Smarty +* @subpackage TemplateResources +*/ +class Smarty_Internal_Resource_Extends extends Smarty_Resource { + + /** + * mbstring.overload flag + * + * @var int + */ + public $mbstring_overload = 0; + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $uid = ''; + $sources = array(); + $components = explode('|', $source->name); + $exists = true; + foreach ($components as $component) { + $s = Smarty_Resource::source(null, $source->smarty, $component); + if ($s->type == 'php') { + throw new SmartyException("Resource type {$s->type} cannot be used with the extends resource type"); + } + $sources[$s->uid] = $s; + $uid .= $s->filepath; + if ($_template && $_template->smarty->compile_check) { + $exists = $exists && $s->exists; + } + } + $source->components = $sources; + $source->filepath = $s->filepath; + $source->uid = sha1($uid); + if ($_template && $_template->smarty->compile_check) { + $source->timestamp = $s->timestamp; + $source->exists = $exists; + } + // need the template at getContent() + $source->template = $_template; + } + + /** + * populate Source Object with timestamp and exists from Resource + * + * @param Smarty_Template_Source $source source object + */ + public function populateTimestamp(Smarty_Template_Source $source) + { + $source->exists = true; + foreach ($source->components as $s) { + $source->exists = $source->exists && $s->exists; + } + $source->timestamp = $s->timestamp; + } + + /** + * Load template's source from files into current template object + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public function getContent(Smarty_Template_Source $source) + { + if (!$source->exists) { + throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); + } + + $this->mbstring_overload = ini_get('mbstring.func_overload') & 2; + $_rdl = preg_quote($source->smarty->right_delimiter); + $_ldl = preg_quote($source->smarty->left_delimiter); + if (!$source->smarty->auto_literal) { + $al = '\s*'; + } else { + $al = ''; + } + $_components = array_reverse($source->components); + $_first = reset($_components); + $_last = end($_components); + + foreach ($_components as $_component) { + // register dependency + if ($_component != $_first) { + $source->template->properties['file_dependency'][$_component->uid] = array($_component->filepath, $_component->timestamp, $_component->type); + } + + // read content + $source->filepath = $_component->filepath; + $_content = $_component->content; + + // extend sources + if ($_component != $_last) { + if (preg_match_all("!({$_ldl}{$al}block\s(.+?)\s*{$_rdl})!", $_content, $_open) != + preg_match_all("!({$_ldl}{$al}/block\s*{$_rdl})!", $_content, $_close)) { + throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'"); + } + preg_match_all("!{$_ldl}{$al}block\s(.+?)\s*{$_rdl}|{$_ldl}{$al}/block\s*{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); + $_result_count = count($_result[0]); + $_start = 0; + while ($_start+1 < $_result_count) { + $_end = 0; + $_level = 1; + if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') { + $_start++; + continue; + } + while ($_level != 0) { + $_end++; + if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') { + continue; + } + if (!strpos($_result[0][$_start + $_end][0], '/')) { + $_level++; + } else { + $_level--; + } + } + $_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', + ($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])))); + Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $source->template, $_component->filepath); + $_start = $_start + $_end + 1; + } + } else { + return $_content; + } + } + } + + /** + * Determine basename for compiled filename + * + * @param Smarty_Template_Source $source source object + * @return string resource's basename + */ + public function getBasename(Smarty_Template_Source $source) + { + return str_replace(':', '.', basename($source->filepath)); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_file.php b/include/smarty/libs/sysplugins/smarty_internal_resource_file.php new file mode 100644 index 000000000..48b391d20 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_file.php @@ -0,0 +1,90 @@ +<?php +/** + * Smarty Internal Plugin Resource File + * + * @package Smarty + * @subpackage TemplateResources + * @author Uwe Tews + * @author Rodney Rehm + */ + +/** + * Smarty Internal Plugin Resource File + * + * Implements the file system as resource for Smarty templates + * + * @package Smarty + * @subpackage TemplateResources + */ +class Smarty_Internal_Resource_File extends Smarty_Resource { + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $source->filepath = $this->buildFilepath($source, $_template); + + if ($source->filepath !== false) { + if (is_object($source->smarty->security_policy)) { + $source->smarty->security_policy->isTrustedResourceDir($source->filepath); + } + + $source->uid = sha1($source->filepath); + if ($source->smarty->compile_check && !isset($source->timestamp)) { + $source->timestamp = @filemtime($source->filepath); + $source->exists = !!$source->timestamp; + } + } + } + + /** + * populate Source Object with timestamp and exists from Resource + * + * @param Smarty_Template_Source $source source object + */ + public function populateTimestamp(Smarty_Template_Source $source) + { + $source->timestamp = @filemtime($source->filepath); + $source->exists = !!$source->timestamp; + } + + /** + * Load template's source from file into current template object + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public function getContent(Smarty_Template_Source $source) + { + if ($source->timestamp) { + return file_get_contents($source->filepath); + } + if ($source instanceof Smarty_Config_Source) { + throw new SmartyException("Unable to read config {$source->type} '{$source->name}'"); + } + throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); + } + + /** + * Determine basename for compiled filename + * + * @param Smarty_Template_Source $source source object + * @return string resource's basename + */ + public function getBasename(Smarty_Template_Source $source) + { + $_file = $source->name; + if (($_pos = strpos($_file, ']')) !== false) { + $_file = substr($_file, $_pos + 1); + } + return basename($_file); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_php.php b/include/smarty/libs/sysplugins/smarty_internal_resource_php.php new file mode 100644 index 000000000..7cd8baeec --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_php.php @@ -0,0 +1,114 @@ +<?php + +/** + * Smarty Internal Plugin Resource PHP + * + * Implements the file system as resource for PHP templates + * + * @package Smarty + * @subpackage TemplateResources + * @author Uwe Tews + * @author Rodney Rehm + */ +class Smarty_Internal_Resource_PHP extends Smarty_Resource_Uncompiled { + /** + * container for short_open_tag directive's value before executing PHP templates + * @var string + */ + protected $short_open_tag; + + /** + * Create a new PHP Resource + * + */ + public function __construct() + { + $this->short_open_tag = ini_get( 'short_open_tag' ); + } + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $source->filepath = $this->buildFilepath($source, $_template); + + if ($source->filepath !== false) { + if (is_object($source->smarty->security_policy)) { + $source->smarty->security_policy->isTrustedResourceDir($source->filepath); + } + + $source->uid = sha1($source->filepath); + if ($source->smarty->compile_check) { + $source->timestamp = @filemtime($source->filepath); + $source->exists = !!$source->timestamp; + } + } + } + + /** + * populate Source Object with timestamp and exists from Resource + * + * @param Smarty_Template_Source $source source object + * @return void + */ + public function populateTimestamp(Smarty_Template_Source $source) + { + $source->timestamp = @filemtime($source->filepath); + $source->exists = !!$source->timestamp; + } + + /** + * Load template's source from file into current template object + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public function getContent(Smarty_Template_Source $source) + { + if ($source->timestamp) { + return ''; + } + throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); + } + + /** + * Render and output the template (without using the compiler) + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @return void + * @throws SmartyException if template cannot be loaded or allow_php_templates is disabled + */ + public function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template) + { + $_smarty_template = $_template; + + if (!$source->smarty->allow_php_templates) { + throw new SmartyException("PHP templates are disabled"); + } + if (!$source->exists) { + if ($_template->parent instanceof Smarty_Internal_Template) { + $parent_resource = " in '{$_template->parent->template_resource}'"; + } else { + $parent_resource = ''; + } + throw new SmartyException("Unable to load template {$source->type} '{$source->name}'{$parent_resource}"); + } + + // prepare variables + extract($_template->getTemplateVars()); + + // include PHP template with short open tags enabled + ini_set( 'short_open_tag', '1' ); + include($source->filepath); + ini_set( 'short_open_tag', $this->short_open_tag ); + } +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_registered.php b/include/smarty/libs/sysplugins/smarty_internal_resource_registered.php new file mode 100644 index 000000000..44497b922 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_registered.php @@ -0,0 +1,95 @@ +<?php +/** + * Smarty Internal Plugin Resource Registered + * + * @package Smarty + * @subpackage TemplateResources + * @author Uwe Tews + * @author Rodney Rehm + */ + +/** + * Smarty Internal Plugin Resource Registered + * + * Implements the registered resource for Smarty template + * + * @package Smarty + * @subpackage TemplateResources + * @deprecated + */ +class Smarty_Internal_Resource_Registered extends Smarty_Resource { + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $source->filepath = $source->type . ':' . $source->name; + $source->uid = sha1($source->filepath); + if ($source->smarty->compile_check) { + $source->timestamp = $this->getTemplateTimestamp($source); + $source->exists = !!$source->timestamp; + } + } + + /** + * populate Source Object with timestamp and exists from Resource + * + * @param Smarty_Template_Source $source source object + * @return void + */ + public function populateTimestamp(Smarty_Template_Source $source) + { + $source->timestamp = $this->getTemplateTimestamp($source); + $source->exists = !!$source->timestamp; + } + + /** + * Get timestamp (epoch) the template source was modified + * + * @param Smarty_Template_Source $source source object + * @return integer|boolean timestamp (epoch) the template was modified, false if resources has no timestamp + */ + public function getTemplateTimestamp(Smarty_Template_Source $source) + { + // return timestamp + $time_stamp = false; + call_user_func_array($source->smarty->registered_resources[$source->type][0][1], array($source->name, &$time_stamp, $source->smarty)); + return is_numeric($time_stamp) ? (int) $time_stamp : $time_stamp; + } + + /** + * Load template's source by invoking the registered callback into current template object + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public function getContent(Smarty_Template_Source $source) + { + // return template string + $t = call_user_func_array($source->smarty->registered_resources[$source->type][0][0], array($source->name, &$source->content, $source->smarty)); + if (is_bool($t) && !$t) { + throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); + } + return $source->content; + } + + /** + * Determine basename for compiled filename + * + * @param Smarty_Template_Source $source source object + * @return string resource's basename + */ + protected function getBasename(Smarty_Template_Source $source) + { + return basename($source->name); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_stream.php b/include/smarty/libs/sysplugins/smarty_internal_resource_stream.php new file mode 100644 index 000000000..58086c179 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_stream.php @@ -0,0 +1,78 @@ +<?php +/** +* Smarty Internal Plugin Resource Stream +* +* Implements the streams as resource for Smarty template +* +* @package Smarty +* @subpackage TemplateResources +* @author Uwe Tews +* @author Rodney Rehm +*/ + +/** +* Smarty Internal Plugin Resource Stream +* +* Implements the streams as resource for Smarty template +* +* @link http://php.net/streams +* @package Smarty +* @subpackage TemplateResources +*/ +class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled { + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + if(strpos($source->resource, '://') !== false) { + $source->filepath = $source->resource; + } else { + $source->filepath = str_replace(':', '://', $source->resource); + } + $source->uid = false; + $source->content = $this->getContent($source); + $source->timestamp = false; + $source->exists = !!$source->content; + } + + /** + * Load template's source from stream into current template object + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public function getContent(Smarty_Template_Source $source) + { + $t = ''; + // the availability of the stream has already been checked in Smarty_Resource::fetch() + $fp = fopen($source->filepath, 'r+'); + if ($fp) { + while (!feof($fp) && ($current_line = fgets($fp)) !== false) { + $t .= $current_line; + } + fclose($fp); + return $t; + } else { + return false; + } + } + + /** + * modify resource_name according to resource handlers specifications + * + * @param Smarty $smarty Smarty instance + * @param string $resource_name resource_name to make unique + * @return string unique resource name + */ + protected function buildUniqueResourceName(Smarty $smarty, $resource_name) + { + return get_class($this) . '#' . $resource_name; + } +} diff --git a/include/smarty/libs/sysplugins/smarty_internal_resource_string.php b/include/smarty/libs/sysplugins/smarty_internal_resource_string.php new file mode 100644 index 000000000..9571337b0 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_resource_string.php @@ -0,0 +1,96 @@ +<?php +/** + * Smarty Internal Plugin Resource String + * + * @package Smarty + * @subpackage TemplateResources + * @author Uwe Tews + * @author Rodney Rehm + */ + +/** + * Smarty Internal Plugin Resource String + * + * Implements the strings as resource for Smarty template + * + * {@internal unlike eval-resources the compiled state of string-resources is saved for subsequent access}} + * + * @package Smarty + * @subpackage TemplateResources + */ +class Smarty_Internal_Resource_String extends Smarty_Resource { + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $source->uid = $source->filepath = sha1($source->name); + $source->timestamp = 0; + $source->exists = true; + } + + /** + * Load template's source from $resource_name into current template object + * + * @uses decode() to decode base64 and urlencoded template_resources + * @param Smarty_Template_Source $source source object + * @return string template source + */ + public function getContent(Smarty_Template_Source $source) + { + return $this->decode($source->name); + } + + /** + * decode base64 and urlencode + * + * @param string $string template_resource to decode + * @return string decoded template_resource + */ + protected function decode($string) + { + // decode if specified + if (($pos = strpos($string, ':')) !== false) { + if (!strncmp($string, 'base64', 6)) { + return base64_decode(substr($string, 7)); + } elseif (!strncmp($string, 'urlencode', 9)) { + return urldecode(substr($string, 10)); + } + } + + return $string; + } + + /** + * modify resource_name according to resource handlers specifications + * + * @param Smarty $smarty Smarty instance + * @param string $resource_name resource_name to make unique + * @return string unique resource name + */ + protected function buildUniqueResourceName(Smarty $smarty, $resource_name) + { + return get_class($this) . '#' .$this->decode($resource_name); + } + + /** + * Determine basename for compiled filename + * + * Always returns an empty string. + * + * @param Smarty_Template_Source $source source object + * @return string resource's basename + */ + protected function getBasename(Smarty_Template_Source $source) + { + return ''; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_smartytemplatecompiler.php b/include/smarty/libs/sysplugins/smarty_internal_smartytemplatecompiler.php new file mode 100644 index 000000000..1ec1aa430 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_smartytemplatecompiler.php @@ -0,0 +1,127 @@ +<?php +/** + * Smarty Internal Plugin Smarty Template Compiler Base + * + * This file contains the basic classes and methodes for compiling Smarty templates with lexer/parser + * + * @package Smarty + * @subpackage Compiler + * @author Uwe Tews + */ + +/** + * @ignore + */ +include ("smarty_internal_parsetree.php"); + +/** + * Class SmartyTemplateCompiler + * + * @package Smarty + * @subpackage Compiler + */ +class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCompilerBase { + + /** + * Lexer class name + * + * @var string + */ + public $lexer_class; + + /** + * Parser class name + * + * @var string + */ + public $parser_class; + + /** + * Lexer object + * + * @var object + */ + public $lex; + + /** + * Parser object + * + * @var object + */ + public $parser; + + /** + * Smarty object + * + * @var object + */ + public $smarty; + + /** + * array of vars which can be compiled in local scope + * + * @var array + */ + public $local_var = array(); + + /** + * Initialize compiler + * + * @param string $lexer_class class name + * @param string $parser_class class name + * @param Smarty $smarty global instance + */ + public function __construct($lexer_class, $parser_class, $smarty) + { + $this->smarty = $smarty; + parent::__construct(); + // get required plugins + $this->lexer_class = $lexer_class; + $this->parser_class = $parser_class; + } + + /** + * Methode to compile a Smarty template + * + * @param mixed $_content template source + * @return bool true if compiling succeeded, false if it failed + */ + protected function doCompile($_content) + { + /* here is where the compiling takes place. Smarty + tags in the templates are replaces with PHP code, + then written to compiled files. */ + // init the lexer/parser to compile the template + $this->lex = new $this->lexer_class($_content, $this); + $this->parser = new $this->parser_class($this->lex, $this); + if ($this->smarty->_parserdebug) + $this->parser->PrintTrace(); + // get tokens from lexer and parse them + while ($this->lex->yylex() && !$this->abort_and_recompile) { + if ($this->smarty->_parserdebug) { + echo "<pre>Line {$this->lex->line} Parsing {$this->parser->yyTokenName[$this->lex->token]} Token " . + htmlentities($this->lex->value) . "</pre>"; + } + $this->parser->doParse($this->lex->token, $this->lex->value); + } + + if ($this->abort_and_recompile) { + // exit here on abort + return false; + } + // finish parsing process + $this->parser->doParse(0, 0); + // check for unclosed tags + if (count($this->_tag_stack) > 0) { + // get stacked info + list($openTag, $_data) = array_pop($this->_tag_stack); + $this->trigger_template_error("unclosed {" . $openTag . "} tag"); + } + // return compiled code + // return str_replace(array("? >\n<?php","? ><?php"), array('',''), $this->parser->retvalue); + return $this->parser->retvalue; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_template.php b/include/smarty/libs/sysplugins/smarty_internal_template.php new file mode 100644 index 000000000..29017edbb --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_template.php @@ -0,0 +1,692 @@ +<?php +/** + * Smarty Internal Plugin Template + * + * This file contains the Smarty template engine + * + * @package Smarty + * @subpackage Template + * @author Uwe Tews + */ + +/** + * Main class with template data structures and methods + * + * @package Smarty + * @subpackage Template + * + * @property Smarty_Template_Source $source + * @property Smarty_Template_Compiled $compiled + * @property Smarty_Template_Cached $cached + */ +class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { + + /** + * cache_id + * @var string + */ + public $cache_id = null; + /** + * $compile_id + * @var string + */ + public $compile_id = null; + /** + * caching enabled + * @var boolean + */ + public $caching = null; + /** + * cache lifetime in seconds + * @var integer + */ + public $cache_lifetime = null; + /** + * Template resource + * @var string + */ + public $template_resource = null; + /** + * flag if compiled template is invalid and must be (re)compiled + * @var bool + */ + public $mustCompile = null; + /** + * flag if template does contain nocache code sections + * @var bool + */ + public $has_nocache_code = false; + /** + * special compiled and cached template properties + * @var array + */ + public $properties = array('file_dependency' => array(), + 'nocache_hash' => '', + 'function' => array()); + /** + * required plugins + * @var array + */ + public $required_plugins = array('compiled' => array(), 'nocache' => array()); + /** + * Global smarty instance + * @var Smarty + */ + public $smarty = null; + /** + * blocks for template inheritance + * @var array + */ + public $block_data = array(); + /** + * variable filters + * @var array + */ + public $variable_filters = array(); + /** + * optional log of tag/attributes + * @var array + */ + public $used_tags = array(); + /** + * internal flag to allow relative path in child template blocks + * @var bool + */ + public $allow_relative_path = false; + /** + * internal capture runtime stack + * @var array + */ + public $_capture_stack = array(0 => array()); + + /** + * Create template data object + * + * Some of the global Smarty settings copied to template scope + * It load the required template resources and cacher plugins + * + * @param string $template_resource template resource string + * @param Smarty $smarty Smarty instance + * @param Smarty_Internal_Template $_parent back pointer to parent object with variables or null + * @param mixed $_cache_id cache id or null + * @param mixed $_compile_id compile id or null + * @param bool $_caching use caching? + * @param int $_cache_lifetime cache life-time in seconds + */ + public function __construct($template_resource, $smarty, $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null) + { + $this->smarty = &$smarty; + // Smarty parameter + $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id; + $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id; + $this->caching = $_caching === null ? $this->smarty->caching : $_caching; + if ($this->caching === true) + $this->caching = Smarty::CACHING_LIFETIME_CURRENT; + $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime; + $this->parent = $_parent; + // Template resource + $this->template_resource = $template_resource; + // copy block data of template inheritance + if ($this->parent instanceof Smarty_Internal_Template) { + $this->block_data = $this->parent->block_data; + } + } + + /** + * Returns if the current template must be compiled by the Smarty compiler + * + * It does compare the timestamps of template source and the compiled templates and checks the force compile configuration + * + * @return boolean true if the template must be compiled + */ + public function mustCompile() + { + if (!$this->source->exists) { + if ($this->parent instanceof Smarty_Internal_Template) { + $parent_resource = " in '$this->parent->template_resource}'"; + } else { + $parent_resource = ''; + } + throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}"); + } + if ($this->mustCompile === null) { + $this->mustCompile = (!$this->source->uncompiled && ($this->smarty->force_compile || $this->source->recompiled || $this->compiled->timestamp === false || + ($this->smarty->compile_check && $this->compiled->timestamp < $this->source->timestamp))); + } + return $this->mustCompile; + } + + /** + * Compiles the template + * + * If the template is not evaluated the compiled template is saved on disk + */ + public function compileTemplateSource() + { + if (!$this->source->recompiled) { + $this->properties['file_dependency'] = array(); + if ($this->source->components) { + // uses real resource for file dependency + $source = end($this->source->components); + $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $source->type); + } else { + $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type); + } + } + if ($this->smarty->debugging) { + Smarty_Internal_Debug::start_compile($this); + } + // compile locking + if ($this->smarty->compile_locking && !$this->source->recompiled) { + if ($saved_timestamp = $this->compiled->timestamp) { + touch($this->compiled->filepath); + } + } + // call compiler + try { + $code = $this->compiler->compileTemplate($this); + } catch (Exception $e) { + // restore old timestamp in case of error + if ($this->smarty->compile_locking && !$this->source->recompiled && $saved_timestamp) { + touch($this->compiled->filepath, $saved_timestamp); + } + throw $e; + } + // compiling succeded + if (!$this->source->recompiled && $this->compiler->write_compiled_code) { + // write compiled template + $_filepath = $this->compiled->filepath; + if ($_filepath === false) + throw new SmartyException('getCompiledFilepath() did not return a destination to save the compiled template to'); + Smarty_Internal_Write_File::writeFile($_filepath, $code, $this->smarty); + $this->compiled->exists = true; + $this->compiled->isCompiled = true; + } + if ($this->smarty->debugging) { + Smarty_Internal_Debug::end_compile($this); + } + // release compiler object to free memory + unset($this->compiler); + } + + /** + * Writes the cached template output + * + * @return bool + */ + public function writeCachedContent($content) + { + if ($this->source->recompiled || !($this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED)) { + // don't write cache file + return false; + } + $this->properties['cache_lifetime'] = $this->cache_lifetime; + $this->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true)); + $content = $this->createTemplateCodeFrame($content, true); + $_smarty_tpl = $this; + eval("?>" . $content); + $this->cached->valid = true; + $this->cached->processed = true; + return $this->cached->write($this, $content); + } + + /** + * Template code runtime function to get subtemplate content + * + * @param string $template the resource handle of the template file + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param integer $caching cache mode + * @param integer $cache_lifetime life time of cache data + * @param array $vars optional variables to assign + * @param int $parent_scope scope in which {include} should execute + * @returns string template content + */ + public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope) + { + // already in template cache? + if ($this->smarty->allow_ambiguous_resources) { + $_templateId = Smarty_Resource::getUniqueTemplateName($this->smarty, $template) . $cache_id . $compile_id; + } else { + $_templateId = $this->smarty->joined_template_dir . '#' . $template . $cache_id . $compile_id; + } + + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); + } + if (isset($this->smarty->template_objects[$_templateId])) { + // clone cached template object because of possible recursive call + $tpl = clone $this->smarty->template_objects[$_templateId]; + $tpl->parent = $this; + $tpl->caching = $caching; + $tpl->cache_lifetime = $cache_lifetime; + } else { + $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime); + } + // get variables from calling scope + if ($parent_scope == Smarty::SCOPE_LOCAL) { + $tpl->tpl_vars = $this->tpl_vars; + $tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty']; + } elseif ($parent_scope == Smarty::SCOPE_PARENT) { + $tpl->tpl_vars = &$this->tpl_vars; + } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { + $tpl->tpl_vars = &Smarty::$global_tpl_vars; + } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) { + $tpl->tpl_vars = &$this->tpl_vars; + } else { + $tpl->tpl_vars = &$scope_ptr->tpl_vars; + } + $tpl->config_vars = $this->config_vars; + if (!empty($data)) { + // set up variable values + foreach ($data as $_key => $_val) { + $tpl->tpl_vars[$_key] = new Smarty_variable($_val); + } + } + return $tpl->fetch(null, null, null, null, false, false, true); + } + + /** + * Template code runtime function to set up an inline subtemplate + * + * @param string $template the resource handle of the template file + * @param mixed $cache_id cache id to be used with this template + * @param mixed $compile_id compile id to be used with this template + * @param integer $caching cache mode + * @param integer $cache_lifetime life time of cache data + * @param array $vars optional variables to assign + * @param int $parent_scope scope in which {include} should execute + * @param string $hash nocache hash code + * @returns string template content + */ + public function setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash) + { + $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime); + $tpl->properties['nocache_hash'] = $hash; + // get variables from calling scope + if ($parent_scope == Smarty::SCOPE_LOCAL ) { + $tpl->tpl_vars = $this->tpl_vars; + $tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty']; + } elseif ($parent_scope == Smarty::SCOPE_PARENT) { + $tpl->tpl_vars = &$this->tpl_vars; + } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { + $tpl->tpl_vars = &Smarty::$global_tpl_vars; + } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) { + $tpl->tpl_vars = &$this->tpl_vars; + } else { + $tpl->tpl_vars = &$scope_ptr->tpl_vars; + } + $tpl->config_vars = $this->config_vars; + if (!empty($data)) { + // set up variable values + foreach ($data as $_key => $_val) { + $tpl->tpl_vars[$_key] = new Smarty_variable($_val); + } + } + return $tpl; + } + + + /** + * Create code frame for compiled and cached templates + * + * @param string $content optional template content + * @param bool $cache flag for cache file + * @return string + */ + public function createTemplateCodeFrame($content = '', $cache = false) + { + $plugins_string = ''; + // include code for plugins + if (!$cache) { + if (!empty($this->required_plugins['compiled'])) { + $plugins_string = '<?php '; + foreach ($this->required_plugins['compiled'] as $tmp) { + foreach ($tmp as $data) { + $file = addslashes($data['file']); + if (is_Array($data['function'])){ + $plugins_string .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n"; + } else { + $plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n"; + } + } + } + $plugins_string .= '?>'; + } + if (!empty($this->required_plugins['nocache'])) { + $this->has_nocache_code = true; + $plugins_string .= "<?php echo '/*%%SmartyNocache:{$this->properties['nocache_hash']}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; "; + foreach ($this->required_plugins['nocache'] as $tmp) { + foreach ($tmp as $data) { + $file = addslashes($data['file']); + if (is_Array($data['function'])){ + $plugins_string .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n"); + } else { + $plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n"); + } + } + } + $plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n"; + } + } + // build property code + $this->properties['has_nocache_code'] = $this->has_nocache_code; + $output = ''; + if (!$this->source->recompiled) { + $output = "<?php /*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/"; + if ($this->smarty->direct_access_security) { + $output .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n"; + } + } + if ($cache) { + // remove compiled code of{function} definition + unset($this->properties['function']); + if (!empty($this->smarty->template_functions)) { + // copy code of {function} tags called in nocache mode + foreach ($this->smarty->template_functions as $name => $function_data) { + if (isset($function_data['called_nocache'])) { + foreach ($function_data['called_functions'] as $func_name) { + $this->smarty->template_functions[$func_name]['called_nocache'] = true; + } + } + } + foreach ($this->smarty->template_functions as $name => $function_data) { + if (isset($function_data['called_nocache'])) { + unset($function_data['called_nocache'], $function_data['called_functions'], $this->smarty->template_functions[$name]['called_nocache']); + $this->properties['function'][$name] = $function_data; + } + } + } + } + $this->properties['version'] = Smarty::SMARTY_VERSION; + if (!isset($this->properties['unifunc'])) { + $this->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true)); + } + if (!$this->source->recompiled) { + $output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . ',' . ($cache ? 'true' : 'false') . "); /*/%%SmartyHeaderCode%%*/?>\n"; + $output .= '<?php if ($_valid && !is_callable(\'' . $this->properties['unifunc'] . '\')) {function ' . $this->properties['unifunc'] . '($_smarty_tpl) {?>'; + } + $output .= $plugins_string; + $output .= $content; + if (!$this->source->recompiled) { + $output .= '<?php }} ?>'; + } + return $output; + } + + /** + * This function is executed automatically when a compiled or cached template file is included + * + * - Decode saved properties from compiled template and cache files + * - Check if compiled or cache file is valid + * + * @param array $properties special template properties + * @param bool $cache flag if called from cache file + * @return bool flag if compiled or cache file is valid + */ + public function decodeProperties($properties, $cache = false) + { + $this->has_nocache_code = $properties['has_nocache_code']; + $this->properties['nocache_hash'] = $properties['nocache_hash']; + if (isset($properties['cache_lifetime'])) { + $this->properties['cache_lifetime'] = $properties['cache_lifetime']; + } + if (isset($properties['file_dependency'])) { + $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']); + } + if (!empty($properties['function'])) { + $this->properties['function'] = array_merge($this->properties['function'], $properties['function']); + $this->smarty->template_functions = array_merge($this->smarty->template_functions, $properties['function']); + } + $this->properties['version'] = (isset($properties['version'])) ? $properties['version'] : ''; + $this->properties['unifunc'] = $properties['unifunc']; + // check file dependencies at compiled code + $is_valid = true; + if ($this->properties['version'] != Smarty::SMARTY_VERSION) { + $is_valid = false; + } else if (((!$cache && $this->smarty->compile_check && empty($this->compiled->_properties) && !$this->compiled->isCompiled) || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($this->properties['file_dependency'])) { + foreach ($this->properties['file_dependency'] as $_file_to_check) { + if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') { + if ($this->source->filepath == $_file_to_check[0] && isset($this->source->timestamp)) { + // do not recheck current template + $mtime = $this->source->timestamp; + } else { + // file and php types can be checked without loading the respective resource handlers + $mtime = @filemtime($_file_to_check[0]); + } + } elseif ($_file_to_check[2] == 'string') { + continue; + } else { + $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]); + $mtime = $source->timestamp; + } + if (!$mtime || $mtime > $_file_to_check[1]) { + $is_valid = false; + break; + } + } + } + if ($cache) { + $this->cached->valid = $is_valid; + } else { + $this->mustCompile = !$is_valid; + } + // store data in reusable Smarty_Template_Compiled + if (!$cache) { + $this->compiled->_properties = $properties; + } + return $is_valid; + } + + /** + * Template code runtime function to create a local Smarty variable for array assignments + * + * @param string $tpl_var tempate variable name + * @param bool $nocache cache mode of variable + * @param int $scope scope of variable + */ + public function createLocalArrayVariable($tpl_var, $nocache = false, $scope = Smarty::SCOPE_LOCAL) + { + if (!isset($this->tpl_vars[$tpl_var])) { + $this->tpl_vars[$tpl_var] = new Smarty_variable(array(), $nocache, $scope); + } else { + $this->tpl_vars[$tpl_var] = clone $this->tpl_vars[$tpl_var]; + if ($scope != Smarty::SCOPE_LOCAL) { + $this->tpl_vars[$tpl_var]->scope = $scope; + } + if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) { + settype($this->tpl_vars[$tpl_var]->value, 'array'); + } + } + } + + /** + * Template code runtime function to get pointer to template variable array of requested scope + * + * @param int $scope requested variable scope + * @return array array of template variables + */ + public function &getScope($scope) + { + if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) { + return $this->parent->tpl_vars; + } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) { + $ptr = $this->parent; + while (!empty($ptr->parent)) { + $ptr = $ptr->parent; + } + return $ptr->tpl_vars; + } elseif ($scope == Smarty::SCOPE_GLOBAL) { + return Smarty::$global_tpl_vars; + } + $null = null; + return $null; + } + + /** + * Get parent or root of template parent chain + * + * @param int $scope pqrent or root scope + * @return mixed object + */ + public function getScopePointer($scope) + { + if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) { + return $this->parent; + } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) { + $ptr = $this->parent; + while (!empty($ptr->parent)) { + $ptr = $ptr->parent; + } + return $ptr; + } + return null; + } + + /** + * [util function] counts an array, arrayaccess/traversable or PDOStatement object + * + * @param mixed $value + * @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0 for empty elements + */ + public function _count($value) + { + if (is_array($value) === true || $value instanceof Countable) { + return count($value); + } elseif ($value instanceof IteratorAggregate) { + // Note: getIterator() returns a Traversable, not an Iterator + // thus rewind() and valid() methods may not be present + return iterator_count($value->getIterator()); + } elseif ($value instanceof Iterator) { + return iterator_count($value); + } elseif ($value instanceof PDOStatement) { + return $value->rowCount(); + } elseif ($value instanceof Traversable) { + return iterator_count($value); + } elseif ($value instanceof ArrayAccess) { + if ($value->offsetExists(0)) { + return 1; + } + } elseif (is_object($value)) { + return count($value); + } + return 0; + } + + /** + * runtime error not matching capture tags + * + */ + public function capture_error() + { + throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\""); + } + + /** + * Empty cache for this template + * + * @param integer $exp_time expiration time + * @return integer number of cache files deleted + */ + public function clearCache($exp_time=null) + { + Smarty_CacheResource::invalidLoadedCache($this->smarty); + return $this->cached->handler->clear($this->smarty, $this->template_name, $this->cache_id, $this->compile_id, $exp_time); + } + + /** + * set Smarty property in template context + * + * @param string $property_name property name + * @param mixed $value value + */ + public function __set($property_name, $value) + { + switch ($property_name) { + case 'source': + case 'compiled': + case 'cached': + case 'compiler': + $this->$property_name = $value; + return; + + // FIXME: routing of template -> smarty attributes + default: + if (property_exists($this->smarty, $property_name)) { + $this->smarty->$property_name = $value; + return; + } + } + + throw new SmartyException("invalid template property '$property_name'."); + } + + /** + * get Smarty property in template context + * + * @param string $property_name property name + */ + public function __get($property_name) + { + switch ($property_name) { + case 'source': + if (strlen($this->template_resource) == 0) { + throw new SmartyException('Missing template name'); + } + $this->source = Smarty_Resource::source($this); + // cache template object under a unique ID + // do not cache eval resources + if ($this->source->type != 'eval') { + if ($this->smarty->allow_ambiguous_resources) { + $_templateId = $this->source->unique_resource . $this->cache_id . $this->compile_id; + } else { + $_templateId = $this->smarty->joined_template_dir . '#' . $this->template_resource . $this->cache_id . $this->compile_id; + } + + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); + } + $this->smarty->template_objects[$_templateId] = $this; + } + return $this->source; + + case 'compiled': + $this->compiled = $this->source->getCompiled($this); + return $this->compiled; + + case 'cached': + if (!class_exists('Smarty_Template_Cached')) { + include SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php'; + } + $this->cached = new Smarty_Template_Cached($this); + return $this->cached; + + case 'compiler': + $this->smarty->loadPlugin($this->source->compiler_class); + $this->compiler = new $this->source->compiler_class($this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty); + return $this->compiler; + + // FIXME: routing of template -> smarty attributes + default: + if (property_exists($this->smarty, $property_name)) { + return $this->smarty->$property_name; + } + } + + throw new SmartyException("template property '$property_name' does not exist."); + } + + /** + * Template data object destrutor + * + */ + public function __destruct() + { + if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) { + $this->cached->handler->releaseLock($this->smarty, $this->cached); + } + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_templatebase.php b/include/smarty/libs/sysplugins/smarty_internal_templatebase.php new file mode 100644 index 000000000..abd48b799 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_templatebase.php @@ -0,0 +1,811 @@ +<?php
+/**
+ * Smarty Internal Plugin Smarty Template Base
+ *
+ * This file contains the basic shared methodes for template handling
+ *
+ * @package Smarty
+ * @subpackage Template
+ * @author Uwe Tews
+ */
+
+/**
+ * Class with shared template methodes
+ *
+ * @package Smarty
+ * @subpackage Template
+ */
+abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
+
+ /**
+ * fetches a rendered Smarty template
+ *
+ * @param string $template the resource handle of the template file or template object
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ * @param bool $display true: display, false: fetch
+ * @param bool $merge_tpl_vars if true parent template variables merged in to local scope
+ * @param bool $no_output_filter if true do not run output filter
+ * @return string rendered template output
+ */
+ public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
+ {
+ if ($template === null && $this instanceof $this->template_class) {
+ $template = $this;
+ }
+ if (!empty($cache_id) && is_object($cache_id)) {
+ $parent = $cache_id;
+ $cache_id = null;
+ }
+ if ($parent === null && ($this instanceof Smarty || is_string($template))) {
+ $parent = $this;
+ }
+ // create template object if necessary
+ $_template = ($template instanceof $this->template_class)
+ ? $template
+ : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
+ // if called by Smarty object make sure we use current caching status
+ if ($this instanceof Smarty) {
+ $_template->caching = $this->caching;
+ }
+ // merge all variable scopes into template
+ if ($merge_tpl_vars) {
+ // save local variables
+ $save_tpl_vars = $_template->tpl_vars;
+ $save_config_vars = $_template->config_vars;
+ $ptr_array = array($_template);
+ $ptr = $_template;
+ while (isset($ptr->parent)) {
+ $ptr_array[] = $ptr = $ptr->parent;
+ }
+ $ptr_array = array_reverse($ptr_array);
+ $parent_ptr = reset($ptr_array);
+ $tpl_vars = $parent_ptr->tpl_vars;
+ $config_vars = $parent_ptr->config_vars;
+ while ($parent_ptr = next($ptr_array)) {
+ if (!empty($parent_ptr->tpl_vars)) {
+ $tpl_vars = array_merge($tpl_vars, $parent_ptr->tpl_vars);
+ }
+ if (!empty($parent_ptr->config_vars)) {
+ $config_vars = array_merge($config_vars, $parent_ptr->config_vars);
+ }
+ }
+ if (!empty(Smarty::$global_tpl_vars)) {
+ $tpl_vars = array_merge(Smarty::$global_tpl_vars, $tpl_vars);
+ }
+ $_template->tpl_vars = $tpl_vars;
+ $_template->config_vars = $config_vars;
+ }
+ // dummy local smarty variable
+ if (!isset($_template->tpl_vars['smarty'])) {
+ $_template->tpl_vars['smarty'] = new Smarty_Variable;
+ }
+ if (isset($this->smarty->error_reporting)) {
+ $_smarty_old_error_level = error_reporting($this->smarty->error_reporting);
+ }
+ // check URL debugging control
+ if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
+ if (isset($_SERVER['QUERY_STRING'])) {
+ $_query_string = $_SERVER['QUERY_STRING'];
+ } else {
+ $_query_string = '';
+ }
+ if (false !== strpos($_query_string, $this->smarty->smarty_debug_id)) {
+ if (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=on')) {
+ // enable debugging for this browser session
+ setcookie('SMARTY_DEBUG', true);
+ $this->smarty->debugging = true;
+ } elseif (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=off')) {
+ // disable debugging for this browser session
+ setcookie('SMARTY_DEBUG', false);
+ $this->smarty->debugging = false;
+ } else {
+ // enable debugging for this page
+ $this->smarty->debugging = true;
+ }
+ } else {
+ if (isset($_COOKIE['SMARTY_DEBUG'])) {
+ $this->smarty->debugging = true;
+ }
+ }
+ }
+ // must reset merge template date
+ $_template->smarty->merged_templates_func = array();
+ // get rendered template
+ // disable caching for evaluated code
+ if ($_template->source->recompiled) {
+ $_template->caching = false;
+ }
+ // checks if template exists
+ if (!$_template->source->exists) {
+ if ($_template->parent instanceof Smarty_Internal_Template) {
+ $parent_resource = " in '{$_template->parent->template_resource}'";
+ } else {
+ $parent_resource = '';
+ }
+ throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}");
+ }
+ // read from cache or render
+ if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) {
+ // render template (not loaded and not in cache)
+ if (!$_template->source->uncompiled) {
+ $_smarty_tpl = $_template;
+ if ($_template->source->recompiled) {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_compile($_template);
+ }
+ $code = $_template->compiler->compileTemplate($_template);
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_compile($_template);
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_render($_template);
+ }
+ try {
+ ob_start();
+ eval("?>" . $code);
+ unset($code);
+ } catch (Exception $e) {
+ ob_get_clean();
+ throw $e;
+ }
+ } else {
+ if (!$_template->compiled->exists || ($_template->smarty->force_compile && !$_template->compiled->isCompiled)) {
+ $_template->compileTemplateSource();
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_render($_template);
+ }
+ if (!$_template->compiled->loaded) {
+ include($_template->compiled->filepath);
+ if ($_template->mustCompile) {
+ // recompile and load again
+ $_template->compileTemplateSource();
+ include($_template->compiled->filepath);
+ }
+ $_template->compiled->loaded = true;
+ } else {
+ $_template->decodeProperties($_template->compiled->_properties, false);
+ }
+ try {
+ ob_start();
+ if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) {
+ throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'");
+ }
+ array_unshift($_template->_capture_stack,array());
+ //
+ // render compiled template
+ //
+ $_template->properties['unifunc']($_template);
+ // any unclosed {capture} tags ?
+ if (isset($_template->_capture_stack[0][0])) {
+ $_template->capture_error();
+ }
+ array_shift($_template->_capture_stack);
+ } catch (Exception $e) {
+ ob_get_clean();
+ throw $e;
+ }
+ }
+ } else {
+ if ($_template->source->uncompiled) {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_render($_template);
+ }
+ try {
+ ob_start();
+ $_template->source->renderUncompiled($_template);
+ } catch (Exception $e) {
+ ob_get_clean();
+ throw $e;
+ }
+ } else {
+ throw new SmartyException("Resource '$_template->source->type' must have 'renderUncompiled' method");
+ }
+ }
+ $_output = ob_get_clean();
+ if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) {
+ $_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
+ }
+ if ($_template->parent instanceof Smarty_Internal_Template) {
+ $_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']);
+ foreach ($_template->required_plugins as $code => $tmp1) {
+ foreach ($tmp1 as $name => $tmp) {
+ foreach ($tmp as $type => $data) {
+ $_template->parent->required_plugins[$code][$name][$type] = $data;
+ }
+ }
+ }
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_render($_template);
+ }
+ // write to cache when nessecary
+ if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_cache($_template);
+ }
+ $_template->properties['has_nocache_code'] = false;
+ // get text between non-cached items
+ $cache_split = preg_split("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output);
+ // get non-cached items
+ preg_match_all("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output, $cache_parts);
+ $output = '';
+ // loop over items, stitch back together
+ foreach ($cache_split as $curr_idx => $curr_split) {
+ // escape PHP tags in template content
+ $output .= preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php echo \'$1\'; ?>', $curr_split);
+ if (isset($cache_parts[0][$curr_idx])) {
+ $_template->properties['has_nocache_code'] = true;
+ // remove nocache tags from cache output
+ $output .= preg_replace("!/\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]);
+ }
+ }
+ if (!$no_output_filter && !$_template->has_nocache_code && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
+ $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template);
+ }
+ // rendering (must be done before writing cache file because of {function} nocache handling)
+ $_smarty_tpl = $_template;
+ try {
+ ob_start();
+ eval("?>" . $output);
+ $_output = ob_get_clean();
+ } catch (Exception $e) {
+ ob_get_clean();
+ throw $e;
+ }
+ // write cache file content
+ $_template->writeCachedContent($output);
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_cache($_template);
+ }
+ } else {
+ // var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output);
+ if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) {
+ // replace nocache_hash
+ $_output = str_replace("{$_template->properties['nocache_hash']}", $_template->parent->properties['nocache_hash'], $_output);
+ $_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code;
+ }
+ }
+ } else {
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::start_cache($_template);
+ }
+ try {
+ ob_start();
+ array_unshift($_template->_capture_stack,array());
+ //
+ // render cached template
+ //
+ $_template->properties['unifunc']($_template);
+ // any unclosed {capture} tags ?
+ if (isset($_template->_capture_stack[0][0])) {
+ $_template->capture_error();
+ }
+ array_shift($_template->_capture_stack);
+ $_output = ob_get_clean();
+ } catch (Exception $e) {
+ ob_get_clean();
+ throw $e;
+ }
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::end_cache($_template);
+ }
+ }
+ if ((!$this->caching || $_template->has_nocache_code || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
+ $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template);
+ }
+ if (isset($this->error_reporting)) {
+ error_reporting($_smarty_old_error_level);
+ }
+ // display or fetch
+ if ($display) {
+ if ($this->caching && $this->cache_modified_check) {
+ $_isCached = $_template->isCached() && !$_template->has_nocache_code;
+ $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+ if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) {
+ switch (PHP_SAPI) {
+ case 'cgi': // php-cgi < 5.3
+ case 'cgi-fcgi': // php-cgi >= 5.3
+ case 'fpm-fcgi': // php-fpm >= 5.3.3
+ header('Status: 304 Not Modified');
+ break;
+
+ case 'cli':
+ if (/* ^phpunit */!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])/* phpunit$ */) {
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified';
+ }
+ break;
+
+ default:
+ header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
+ break;
+ }
+ } else {
+ switch (PHP_SAPI) {
+ case 'cli':
+ if (/* ^phpunit */!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])/* phpunit$ */) {
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT';
+ }
+ break;
+
+ default:
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT');
+ break;
+ }
+ echo $_output;
+ }
+ } else {
+ echo $_output;
+ }
+ // debug output
+ if ($this->smarty->debugging) {
+ Smarty_Internal_Debug::display_debug($this);
+ }
+ if ($merge_tpl_vars) {
+ // restore local variables
+ $_template->tpl_vars = $save_tpl_vars;
+ $_template->config_vars = $save_config_vars;
+ }
+ return;
+ } else {
+ if ($merge_tpl_vars) {
+ // restore local variables
+ $_template->tpl_vars = $save_tpl_vars;
+ $_template->config_vars = $save_config_vars;
+ }
+ // return fetched content
+ return $_output;
+ }
+ }
+
+ /**
+ * displays a Smarty template
+ *
+ * @param string $template the resource handle of the template file or template object
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ */
+ public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
+ {
+ // display template
+ $this->fetch($template, $cache_id, $compile_id, $parent, true);
+ }
+
+ /**
+ * test if cache is valid
+ *
+ * @param string|object $template the resource handle of the template file or template object
+ * @param mixed $cache_id cache id to be used with this template
+ * @param mixed $compile_id compile id to be used with this template
+ * @param object $parent next higher level of Smarty variables
+ * @return boolean cache status
+ */
+ public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
+ {
+ if ($template === null && $this instanceof $this->template_class) {
+ return $this->cached->valid;
+ }
+ if (!($template instanceof $this->template_class)) {
+ if ($parent === null) {
+ $parent = $this;
+ }
+ $template = $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
+ }
+ // return cache status of template
+ return $template->cached->valid;
+ }
+
+ /**
+ * creates a data object
+ *
+ * @param object $parent next higher level of Smarty variables
+ * @returns Smarty_Data data object
+ */
+ public function createData($parent = null)
+ {
+ return new Smarty_Data($parent, $this);
+ }
+
+ /**
+ * Registers plugin to be used in templates
+ *
+ * @param string $type plugin type
+ * @param string $tag name of template tag
+ * @param callback $callback PHP callback to register
+ * @param boolean $cacheable if true (default) this fuction is cachable
+ * @param array $cache_attr caching attributes if any
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException when the plugin tag is invalid
+ */
+ public function registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = null)
+ {
+ if (isset($this->smarty->registered_plugins[$type][$tag])) {
+ throw new SmartyException("Plugin tag \"{$tag}\" already registered");
+ } elseif (!is_callable($callback)) {
+ throw new SmartyException("Plugin \"{$tag}\" not callable");
+ } else {
+ $this->smarty->registered_plugins[$type][$tag] = array($callback, (bool) $cacheable, (array) $cache_attr);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Unregister Plugin
+ *
+ * @param string $type of plugin
+ * @param string $tag name of plugin
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterPlugin($type, $tag)
+ {
+ if (isset($this->smarty->registered_plugins[$type][$tag])) {
+ unset($this->smarty->registered_plugins[$type][$tag]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a resource to fetch a template
+ *
+ * @param string $type name of resource type
+ * @param Smarty_Resource|array $callback or instance of Smarty_Resource, or array of callbacks to handle resource (deprecated)
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function registerResource($type, $callback)
+ {
+ $this->smarty->registered_resources[$type] = $callback instanceof Smarty_Resource ? $callback : array($callback, false);
+ return $this;
+ }
+
+ /**
+ * Unregisters a resource
+ *
+ * @param string $type name of resource type
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterResource($type)
+ {
+ if (isset($this->smarty->registered_resources[$type])) {
+ unset($this->smarty->registered_resources[$type]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a cache resource to cache a template's output
+ *
+ * @param string $type name of cache resource type
+ * @param Smarty_CacheResource $callback instance of Smarty_CacheResource to handle output caching
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function registerCacheResource($type, Smarty_CacheResource $callback)
+ {
+ $this->smarty->registered_cache_resources[$type] = $callback;
+ return $this;
+ }
+
+ /**
+ * Unregisters a cache resource
+ *
+ * @param string $type name of cache resource type
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterCacheResource($type)
+ {
+ if (isset($this->smarty->registered_cache_resources[$type])) {
+ unset($this->smarty->registered_cache_resources[$type]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers object to be used in templates
+ *
+ * @param string $object name of template object
+ * @param object $object_impl the referenced PHP object to register
+ * @param array $allowed list of allowed methods (empty = all)
+ * @param boolean $smarty_args smarty argument format, else traditional
+ * @param array $block_methods list of block-methods
+ * @param array $block_functs list of methods that are block format
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if any of the methods in $allowed or $block_methods are invalid
+ */
+ public function registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+ {
+ // test if allowed methodes callable
+ if (!empty($allowed)) {
+ foreach ((array) $allowed as $method) {
+ if (!is_callable(array($object_impl, $method))) {
+ throw new SmartyException("Undefined method '$method' in registered object");
+ }
+ }
+ }
+ // test if block methodes callable
+ if (!empty($block_methods)) {
+ foreach ((array) $block_methods as $method) {
+ if (!is_callable(array($object_impl, $method))) {
+ throw new SmartyException("Undefined method '$method' in registered object");
+ }
+ }
+ }
+ // register the object
+ $this->smarty->registered_objects[$object_name] =
+ array($object_impl, (array) $allowed, (boolean) $smarty_args, (array) $block_methods);
+ return $this;
+ }
+
+ /**
+ * return a reference to a registered object
+ *
+ * @param string $name object name
+ * @return object
+ * @throws SmartyException if no such object is found
+ */
+ public function getRegisteredObject($name)
+ {
+ if (!isset($this->smarty->registered_objects[$name])) {
+ throw new SmartyException("'$name' is not a registered object");
+ }
+ if (!is_object($this->smarty->registered_objects[$name][0])) {
+ throw new SmartyException("registered '$name' is not an object");
+ }
+ return $this->smarty->registered_objects[$name][0];
+ }
+
+ /**
+ * unregister an object
+ *
+ * @param string $name object name
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterObject($name)
+ {
+ if (isset($this->smarty->registered_objects[$name])) {
+ unset($this->smarty->registered_objects[$name]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers static classes to be used in templates
+ *
+ * @param string $class name of template class
+ * @param string $class_impl the referenced PHP class to register
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $class_impl does not refer to an existing class
+ */
+ public function registerClass($class_name, $class_impl)
+ {
+ // test if exists
+ if (!class_exists($class_impl)) {
+ throw new SmartyException("Undefined class '$class_impl' in register template class");
+ }
+ // register the class
+ $this->smarty->registered_classes[$class_name] = $class_impl;
+ return $this;
+ }
+
+ /**
+ * Registers a default plugin handler
+ *
+ * @param callable $callback class/method name
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $callback is not callable
+ */
+ public function registerDefaultPluginHandler($callback)
+ {
+ if (is_callable($callback)) {
+ $this->smarty->default_plugin_handler_func = $callback;
+ } else {
+ throw new SmartyException("Default plugin handler '$callback' not callable");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a default template handler
+ *
+ * @param callable $callback class/method name
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $callback is not callable
+ */
+ public function registerDefaultTemplateHandler($callback)
+ {
+ if (is_callable($callback)) {
+ $this->smarty->default_template_handler_func = $callback;
+ } else {
+ throw new SmartyException("Default template handler '$callback' not callable");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a default template handler
+ *
+ * @param callable $callback class/method name
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ * @throws SmartyException if $callback is not callable
+ */
+ public function registerDefaultConfigHandler($callback)
+ {
+ if (is_callable($callback)) {
+ $this->smarty->default_config_handler_func = $callback;
+ } else {
+ throw new SmartyException("Default config handler '$callback' not callable");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Registers a filter function
+ *
+ * @param string $type filter type
+ * @param callback $callback
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function registerFilter($type, $callback)
+ {
+ $this->smarty->registered_filters[$type][$this->_get_filter_name($callback)] = $callback;
+ return $this;
+ }
+
+ /**
+ * Unregisters a filter function
+ *
+ * @param string $type filter type
+ * @param callback $callback
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function unregisterFilter($type, $callback)
+ {
+ $name = $this->_get_filter_name($callback);
+ if (isset($this->smarty->registered_filters[$type][$name])) {
+ unset($this->smarty->registered_filters[$type][$name]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Return internal filter name
+ *
+ * @param callback $function_name
+ * @return string internal filter name
+ */
+ public function _get_filter_name($function_name)
+ {
+ if (is_array($function_name)) {
+ $_class_name = (is_object($function_name[0]) ?
+ get_class($function_name[0]) : $function_name[0]);
+ return $_class_name . '_' . $function_name[1];
+ } else {
+ return $function_name;
+ }
+ }
+
+ /**
+ * load a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ * @throws SmartyException if filter could not be loaded
+ */
+ public function loadFilter($type, $name)
+ {
+ $_plugin = "smarty_{$type}filter_{$name}";
+ $_filter_name = $_plugin;
+ if ($this->smarty->loadPlugin($_plugin)) {
+ if (class_exists($_plugin, false)) {
+ $_plugin = array($_plugin, 'execute');
+ }
+ if (is_callable($_plugin)) {
+ $this->smarty->registered_filters[$type][$_filter_name] = $_plugin;
+ return true;
+ }
+ }
+ throw new SmartyException("{$type}filter \"{$name}\" not callable");
+ }
+
+ /**
+ * unload a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining
+ */
+ public function unloadFilter($type, $name)
+ {
+ $_filter_name = "smarty_{$type}filter_{$name}";
+ if (isset($this->smarty->registered_filters[$type][$_filter_name])) {
+ unset ($this->smarty->registered_filters[$type][$_filter_name]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * preg_replace callback to convert camelcase getter/setter to underscore property names
+ *
+ * @param string $match match string
+ * @return string replacemant
+ */
+ private function replaceCamelcase($match) {
+ return "_" . strtolower($match[1]);
+ }
+
+ /**
+ * Handle unknown class methods
+ *
+ * @param string $name unknown method-name
+ * @param array $args argument array
+ */
+ public function __call($name, $args)
+ {
+ static $_prefixes = array('set' => true, 'get' => true);
+ static $_resolved_property_name = array();
+ static $_resolved_property_source = array();
+
+ // method of Smarty object?
+ if (method_exists($this->smarty, $name)) {
+ return call_user_func_array(array($this->smarty, $name), $args);
+ }
+ // see if this is a set/get for a property
+ $first3 = strtolower(substr($name, 0, 3));
+ if (isset($_prefixes[$first3]) && isset($name[3]) && $name[3] !== '_') {
+ if (isset($_resolved_property_name[$name])) {
+ $property_name = $_resolved_property_name[$name];
+ } else {
+ // try to keep case correct for future PHP 6.0 case-sensitive class methods
+ // lcfirst() not available < PHP 5.3.0, so improvise
+ $property_name = strtolower(substr($name, 3, 1)) . substr($name, 4);
+ // convert camel case to underscored name
+ $property_name = preg_replace_callback('/([A-Z])/', array($this,'replaceCamelcase'), $property_name);
+ $_resolved_property_name[$name] = $property_name;
+ }
+ if (isset($_resolved_property_source[$property_name])) {
+ $_is_this = $_resolved_property_source[$property_name];
+ } else {
+ $_is_this = null;
+ if (property_exists($this, $property_name)) {
+ $_is_this = true;
+ } else if (property_exists($this->smarty, $property_name)) {
+ $_is_this = false;
+ }
+ $_resolved_property_source[$property_name] = $_is_this;
+ }
+ if ($_is_this) {
+ if ($first3 == 'get')
+ return $this->$property_name;
+ else
+ return $this->$property_name = $args[0];
+ } else if ($_is_this === false) {
+ if ($first3 == 'get')
+ return $this->smarty->$property_name;
+ else
+ return $this->smarty->$property_name = $args[0];
+ } else {
+ throw new SmartyException("property '$property_name' does not exist.");
+ return false;
+ }
+ }
+ if ($name == 'Smarty') {
+ throw new SmartyException("PHP5 requires you to call __construct() instead of Smarty()");
+ }
+ // must be unknown
+ throw new SmartyException("Call of unknown method '$name'.");
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_templatecompilerbase.php b/include/smarty/libs/sysplugins/smarty_internal_templatecompilerbase.php new file mode 100644 index 000000000..11fc2144d --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_templatecompilerbase.php @@ -0,0 +1,670 @@ +<?php
+
+/**
+ * Smarty Internal Plugin Smarty Template Compiler Base
+ *
+ * This file contains the basic classes and methodes for compiling Smarty templates with lexer/parser
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Main abstract compiler class
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ */
+abstract class Smarty_Internal_TemplateCompilerBase {
+
+ /**
+ * hash for nocache sections
+ *
+ * @var mixed
+ */
+ private $nocache_hash = null;
+
+ /**
+ * suppress generation of nocache code
+ *
+ * @var bool
+ */
+ public $suppressNocacheProcessing = false;
+
+ /**
+ * suppress generation of merged template code
+ *
+ * @var bool
+ */
+ public $suppressMergedTemplates = false;
+
+ /**
+ * compile tag objects
+ *
+ * @var array
+ */
+ public static $_tag_objects = array();
+
+ /**
+ * tag stack
+ *
+ * @var array
+ */
+ public $_tag_stack = array();
+
+ /**
+ * current template
+ *
+ * @var Smarty_Internal_Template
+ */
+ public $template = null;
+
+ /**
+ * merged templates
+ *
+ * @var array
+ */
+ public $merged_templates = array();
+
+ /**
+ * flag when compiling {block}
+ *
+ * @var bool
+ */
+ public $inheritance = false;
+
+ /**
+ * plugins loaded by default plugin handler
+ *
+ * @var array
+ */
+ public $default_handler_plugins = array();
+
+ /**
+ * saved preprocessed modifier list
+ *
+ * @var mixed
+ */
+ public $default_modifier_list = null;
+
+ /**
+ * force compilation of complete template as nocache
+ * @var boolean
+ */
+ public $forceNocache = false;
+
+ /**
+ * suppress Smarty header code in compiled template
+ * @var bool
+ */
+ public $suppressHeader = false;
+
+ /**
+ * suppress template property header code in compiled template
+ * @var bool
+ */
+ public $suppressTemplatePropertyHeader = false;
+
+ /**
+ * flag if compiled template file shall we written
+ * @var bool
+ */
+ public $write_compiled_code = true;
+
+ /**
+ * flag if currently a template function is compiled
+ * @var bool
+ */
+ public $compiles_template_function = false;
+
+ /**
+ * called subfuntions from template function
+ * @var array
+ */
+ public $called_functions = array();
+
+ /**
+ * flags for used modifier plugins
+ * @var array
+ */
+ public $modifier_plugins = array();
+
+ /**
+ * type of already compiled modifier
+ * @var array
+ */
+ public $known_modifier_type = array();
+
+ /**
+ * Methode to compile a Smarty template
+ *
+ * @param mixed $_content template source
+ * @return bool true if compiling succeeded, false if it failed
+ */
+ abstract protected function doCompile($_content);
+
+ /**
+ * Initialize compiler
+ */
+ public function __construct() {
+ $this->nocache_hash = str_replace('.', '-', uniqid(rand(), true));
+ }
+
+ /**
+ * Method to compile a Smarty template
+ *
+ * @param Smarty_Internal_Template $template template object to compile
+ * @return bool true if compiling succeeded, false if it failed
+ */
+ public function compileTemplate(Smarty_Internal_Template $template) {
+ if (empty($template->properties['nocache_hash'])) {
+ $template->properties['nocache_hash'] = $this->nocache_hash;
+ } else {
+ $this->nocache_hash = $template->properties['nocache_hash'];
+ }
+ // flag for nochache sections
+ $this->nocache = false;
+ $this->tag_nocache = false;
+ // save template object in compiler class
+ $this->template = $template;
+ // reset has noche code flag
+ $this->template->has_nocache_code = false;
+ $this->smarty->_current_file = $saved_filepath = $this->template->source->filepath;
+ // template header code
+ $template_header = '';
+ if (!$this->suppressHeader) {
+ $template_header .= "<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") . "\n";
+ $template_header .= " compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
+ }
+
+ do {
+ // flag for aborting current and start recompile
+ $this->abort_and_recompile = false;
+ // get template source
+ $_content = $template->source->content;
+ // run prefilter if required
+ if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) {
+ $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
+ }
+ // on empty template just return header
+ if ($_content == '') {
+ if ($this->suppressTemplatePropertyHeader) {
+ $code = '';
+ } else {
+ $code = $template_header . $template->createTemplateCodeFrame();
+ }
+ return $code;
+ }
+ // call compiler
+ $_compiled_code = $this->doCompile($_content);
+ } while ($this->abort_and_recompile);
+ $this->template->source->filepath = $saved_filepath;
+ // free memory
+ unset($this->parser->root_buffer, $this->parser->current_buffer, $this->parser, $this->lex, $this->template);
+ self::$_tag_objects = array();
+ // return compiled code to template object
+ $merged_code = '';
+ if (!$this->suppressMergedTemplates && !empty($this->merged_templates)) {
+ foreach ($this->merged_templates as $code) {
+ $merged_code .= $code;
+ }
+ // run postfilter if required on merged code
+ if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
+ $merged_code = Smarty_Internal_Filter_Handler::runFilter('post', $merged_code, $template);
+ }
+ }
+ // run postfilter if required on compiled template code
+ if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
+ $_compiled_code = Smarty_Internal_Filter_Handler::runFilter('post', $_compiled_code, $template);
+ }
+ if ($this->suppressTemplatePropertyHeader) {
+ $code = $_compiled_code . $merged_code;
+ } else {
+ $code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
+ }
+ // unset content because template inheritance could have replace source with parent code
+ unset ($template->source->content);
+ return $code;
+ }
+
+ /**
+ * Compile Tag
+ *
+ * This is a call back from the lexer/parser
+ * It executes the required compile plugin for the Smarty tag
+ *
+ * @param string $tag tag name
+ * @param array $args array with tag attributes
+ * @param array $parameter array with compilation parameter
+ * @return string compiled code
+ */
+ public function compileTag($tag, $args, $parameter = array()) {
+ // $args contains the attributes parsed and compiled by the lexer/parser
+ // assume that tag does compile into code, but creates no HTML output
+ $this->has_code = true;
+ $this->has_output = false;
+ // log tag/attributes
+ if (isset($this->smarty->get_used_tags) && $this->smarty->get_used_tags) {
+ $this->template->used_tags[] = array($tag, $args);
+ }
+ // check nocache option flag
+ if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args)
+ || in_array(array('nocache' => '"true"'), $args) || in_array(array('nocache' => "'true'"), $args)) {
+ $this->tag_nocache = true;
+ }
+ // compile the smarty tag (required compile classes to compile the tag are autoloaded)
+ if (($_output = $this->callTagCompiler($tag, $args, $parameter)) === false) {
+ if (isset($this->smarty->template_functions[$tag])) {
+ // template defined by {template} tag
+ $args['_attr']['name'] = "'" . $tag . "'";
+ $_output = $this->callTagCompiler('call', $args, $parameter);
+ }
+ }
+ if ($_output !== false) {
+ if ($_output !== true) {
+ // did we get compiled code
+ if ($this->has_code) {
+ // Does it create output?
+ if ($this->has_output) {
+ $_output .= "\n";
+ }
+ // return compiled code
+ return $_output;
+ }
+ }
+ // tag did not produce compiled code
+ return '';
+ } else {
+ // map_named attributes
+ if (isset($args['_attr'])) {
+ foreach ($args['_attr'] as $key => $attribute) {
+ if (is_array($attribute)) {
+ $args = array_merge($args, $attribute);
+ }
+ }
+ }
+ // not an internal compiler tag
+ if (strlen($tag) < 6 || substr($tag, -5) != 'close') {
+ // check if tag is a registered object
+ if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) {
+ $methode = $parameter['object_methode'];
+ if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) &&
+ (empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) {
+ return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode);
+ } elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
+ return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
+ } else {
+ return $this->trigger_template_error('unallowed methode "' . $methode . '" in registered object "' . $tag . '"', $this->lex->taglineno);
+ }
+ }
+ // check if tag is registered
+ foreach (array(Smarty::PLUGIN_COMPILER, Smarty::PLUGIN_FUNCTION, Smarty::PLUGIN_BLOCK) as $plugin_type) {
+ if (isset($this->smarty->registered_plugins[$plugin_type][$tag])) {
+ // if compiler function plugin call it now
+ if ($plugin_type == Smarty::PLUGIN_COMPILER) {
+ $new_args = array();
+ foreach ($args as $key => $mixed) {
+ if (is_array($mixed)) {
+ $new_args = array_merge($new_args, $mixed);
+ } else {
+ $new_args[$key] = $mixed;
+ }
+ }
+ if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) {
+ $this->tag_nocache = true;
+ }
+ $function = $this->smarty->registered_plugins[$plugin_type][$tag][0];
+ if (!is_array($function)) {
+ return $function($new_args, $this);
+ } else if (is_object($function[0])) {
+ return $this->smarty->registered_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args, $this);
+ } else {
+ return call_user_func_array($function, array($new_args, $this));
+ }
+ }
+ // compile registered function or block function
+ if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) {
+ return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
+ }
+ }
+ }
+ // check plugins from plugins folder
+ foreach ($this->smarty->plugin_search_order as $plugin_type) {
+ if ($plugin_type == Smarty::PLUGIN_BLOCK && $this->smarty->loadPlugin('smarty_compiler_' . $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))) {
+ $plugin = 'smarty_compiler_' . $tag;
+ if (is_callable($plugin)) {
+ // convert arguments format for old compiler plugins
+ $new_args = array();
+ foreach ($args as $key => $mixed) {
+ if (is_array($mixed)) {
+ $new_args = array_merge($new_args, $mixed);
+ } else {
+ $new_args[$key] = $mixed;
+ }
+ }
+ return $plugin($new_args, $this->smarty);
+ }
+ if (class_exists($plugin, false)) {
+ $plugin_object = new $plugin;
+ if (method_exists($plugin_object, 'compile')) {
+ return $plugin_object->compile($args, $this);
+ }
+ }
+ throw new SmartyException("Plugin \"{$tag}\" not callable");
+ } else {
+ if ($function = $this->getPlugin($tag, $plugin_type)) {
+ if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
+ return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function);
+ }
+ }
+ }
+ }
+ if (is_callable($this->smarty->default_plugin_handler_func)) {
+ $found = false;
+ // look for already resolved tags
+ foreach ($this->smarty->plugin_search_order as $plugin_type) {
+ if (isset($this->default_handler_plugins[$plugin_type][$tag])) {
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ // call default handler
+ foreach ($this->smarty->plugin_search_order as $plugin_type) {
+ if ($this->getPluginFromDefaultHandler($tag, $plugin_type)) {
+ $found = true;
+ break;
+ }
+ }
+ }
+ if ($found) {
+ // if compiler function plugin call it now
+ if ($plugin_type == Smarty::PLUGIN_COMPILER) {
+ $new_args = array();
+ foreach ($args as $mixed) {
+ $new_args = array_merge($new_args, $mixed);
+ }
+ $function = $this->default_handler_plugins[$plugin_type][$tag][0];
+ if (!is_array($function)) {
+ return $function($new_args, $this);
+ } else if (is_object($function[0])) {
+ return $this->default_handler_plugins[$plugin_type][$tag][0][0]->$function[1]($new_args, $this);
+ } else {
+ return call_user_func_array($function, array($new_args, $this));
+ }
+ } else {
+ return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
+ }
+ }
+ }
+ } else {
+ // compile closing tag of block function
+ $base_tag = substr($tag, 0, -5);
+ // check if closing tag is a registered object
+ if (isset($this->smarty->registered_objects[$base_tag]) && isset($parameter['object_methode'])) {
+ $methode = $parameter['object_methode'];
+ if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) {
+ return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
+ } else {
+ return $this->trigger_template_error('unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"', $this->lex->taglineno);
+ }
+ }
+ // registered block tag ?
+ if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK][$base_tag]) || isset($this->default_handler_plugins[Smarty::PLUGIN_BLOCK][$base_tag])) {
+ return $this->callTagCompiler('private_registered_block', $args, $parameter, $tag);
+ }
+ // block plugin?
+ if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
+ return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function);
+ }
+ // registered compiler plugin ?
+ if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag])) {
+ // if compiler function plugin call it now
+ $args = array();
+ if (!$this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][1]) {
+ $this->tag_nocache = true;
+ }
+ $function = $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0];
+ if (!is_array($function)) {
+ return $function($args, $this);
+ } else if (is_object($function[0])) {
+ return $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0][0]->$function[1]($args, $this);
+ } else {
+ return call_user_func_array($function, array($args, $this));
+ }
+ }
+ if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) {
+ $plugin = 'smarty_compiler_' . $tag;
+ if (is_callable($plugin)) {
+ return $plugin($args, $this->smarty);
+ }
+ if (class_exists($plugin, false)) {
+ $plugin_object = new $plugin;
+ if (method_exists($plugin_object, 'compile')) {
+ return $plugin_object->compile($args, $this);
+ }
+ }
+ throw new SmartyException("Plugin \"{$tag}\" not callable");
+ }
+ }
+ $this->trigger_template_error("unknown tag \"" . $tag . "\"", $this->lex->taglineno);
+ }
+ }
+
+ /**
+ * lazy loads internal compile plugin for tag and calls the compile methode
+ *
+ * compile objects cached for reuse.
+ * class name format: Smarty_Internal_Compile_TagName
+ * plugin filename format: Smarty_Internal_Tagname.php
+ *
+ * @param string $tag tag name
+ * @param array $args list of tag attributes
+ * @param mixed $param1 optional parameter
+ * @param mixed $param2 optional parameter
+ * @param mixed $param3 optional parameter
+ * @return string compiled code
+ */
+ public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null) {
+ // re-use object if already exists
+ if (isset(self::$_tag_objects[$tag])) {
+ // compile this tag
+ return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
+ }
+ // lazy load internal compiler plugin
+ $class_name = 'Smarty_Internal_Compile_' . $tag;
+ if ($this->smarty->loadPlugin($class_name)) {
+ // check if tag allowed by security
+ if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
+ // use plugin if found
+ self::$_tag_objects[$tag] = new $class_name;
+ // compile this tag
+ return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
+ }
+ }
+ // no internal compile plugin for this tag
+ return false;
+ }
+
+ /**
+ * Check for plugins and return function name
+ *
+ * @param string $pugin_name name of plugin or function
+ * @param string $plugin_type type of plugin
+ * @return string call name of function
+ */
+ public function getPlugin($plugin_name, $plugin_type) {
+ $function = null;
+ if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+ if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
+ $function = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
+ } else if (isset($this->template->required_plugins['compiled'][$plugin_name][$plugin_type])) {
+ $this->template->required_plugins['nocache'][$plugin_name][$plugin_type] = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type];
+ $function = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'];
+ }
+ } else {
+ if (isset($this->template->required_plugins['compiled'][$plugin_name][$plugin_type])) {
+ $function = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
+ } else if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
+ $this->template->required_plugins['compiled'][$plugin_name][$plugin_type] = $this->template->required_plugins['nocache'][$plugin_name][$plugin_type];
+ $function = $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'];
+ }
+ }
+ if (isset($function)) {
+ if ($plugin_type == 'modifier') {
+ $this->modifier_plugins[$plugin_name] = true;
+ }
+ return $function;
+ }
+ // loop through plugin dirs and find the plugin
+ $function = 'smarty_' . $plugin_type . '_' . $plugin_name;
+ $file = $this->smarty->loadPlugin($function, false);
+
+ if (is_string($file)) {
+ if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+ $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['file'] = $file;
+ $this->template->required_plugins['nocache'][$plugin_name][$plugin_type]['function'] = $function;
+ } else {
+ $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['file'] = $file;
+ $this->template->required_plugins['compiled'][$plugin_name][$plugin_type]['function'] = $function;
+ }
+ if ($plugin_type == 'modifier') {
+ $this->modifier_plugins[$plugin_name] = true;
+ }
+ return $function;
+ }
+ if (is_callable($function)) {
+ // plugin function is defined in the script
+ return $function;
+ }
+ return false;
+ }
+
+ /**
+ * Check for plugins by default plugin handler
+ *
+ * @param string $tag name of tag
+ * @param string $plugin_type type of plugin
+ * @return boolean true if found
+ */
+ public function getPluginFromDefaultHandler($tag, $plugin_type) {
+ $callback = null;
+ $script = null;
+ $cacheable = true;
+ $result = call_user_func_array(
+ $this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
+ );
+ if ($result) {
+ $this->tag_nocache = $this->tag_nocache || !$cacheable;
+ if ($script !== null) {
+ if (is_file($script)) {
+ if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
+ $this->template->required_plugins['nocache'][$tag][$plugin_type]['file'] = $script;
+ $this->template->required_plugins['nocache'][$tag][$plugin_type]['function'] = $callback;
+ } else {
+ $this->template->required_plugins['compiled'][$tag][$plugin_type]['file'] = $script;
+ $this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback;
+ }
+ include_once $script;
+ } else {
+ $this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
+ }
+ }
+ if (!is_string($callback) && !(is_array($callback) && is_string($callback[0]) && is_string($callback[1]))) {
+ $this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" must be a static function name or array of class and function name");
+ }
+ if (is_callable($callback)) {
+ $this->default_handler_plugins[$plugin_type][$tag] = array($callback, true, array());
+ return true;
+ } else {
+ $this->trigger_template_error("Default plugin handler: Returned callback for \"{$tag}\" not callable");
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Inject inline code for nocache template sections
+ *
+ * This method gets the content of each template element from the parser.
+ * If the content is compiled code and it should be not cached the code is injected
+ * into the rendered output.
+ *
+ * @param string $content content of template element
+ * @param boolean $is_code true if content is compiled code
+ * @return string content
+ */
+ public function processNocacheCode($content, $is_code) {
+ // If the template is not evaluated and we have a nocache section and or a nocache tag
+ if ($is_code && !empty($content)) {
+ // generate replacement code
+ if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing &&
+ ($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) {
+ $this->template->has_nocache_code = true;
+ $_output = addcslashes($content,'\'\\');
+ $_output = str_replace("^#^", "'", $_output);
+ $_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
+ // make sure we include modifer plugins for nocache code
+ foreach ($this->modifier_plugins as $plugin_name => $dummy) {
+ if (isset($this->template->required_plugins['compiled'][$plugin_name]['modifier'])) {
+ $this->template->required_plugins['nocache'][$plugin_name]['modifier'] = $this->template->required_plugins['compiled'][$plugin_name]['modifier'];
+ }
+ }
+ } else {
+ $_output = $content;
+ }
+ } else {
+ $_output = $content;
+ }
+ $this->modifier_plugins = array();
+ $this->suppressNocacheProcessing = false;
+ $this->tag_nocache = false;
+ return $_output;
+ }
+
+ /**
+ * display compiler error messages without dying
+ *
+ * If parameter $args is empty it is a parser detected syntax error.
+ * In this case the parser is called to obtain information about expected tokens.
+ *
+ * If parameter $args contains a string this is used as error message
+ *
+ * @param string $args individual error message or null
+ * @param string $line line-number
+ * @throws SmartyCompilerException when an unexpected token is found
+ */
+ public function trigger_template_error($args = null, $line = null) {
+ // get template source line which has error
+ if (!isset($line)) {
+ $line = $this->lex->line;
+ }
+ $match = preg_split("/\n/", $this->lex->data);
+ $error_text = 'Syntax Error in template "' . $this->template->source->filepath . '" on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]))) . '" ';
+ if (isset($args)) {
+ // individual error message
+ $error_text .= $args;
+ } else {
+ // expected token from parser
+ $error_text .= ' - Unexpected "' . $this->lex->value . '"';
+ if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
+ foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
+ $exp_token = $this->parser->yyTokenName[$token];
+ if (isset($this->lex->smarty_token_names[$exp_token])) {
+ // token type from lexer
+ $expect[] = '"' . $this->lex->smarty_token_names[$exp_token] . '"';
+ } else {
+ // otherwise internal token name
+ $expect[] = $this->parser->yyTokenName[$token];
+ }
+ }
+ $error_text .= ', expected one of: ' . implode(' , ', $expect);
+ }
+ }
+ throw new SmartyCompilerException($error_text);
+ }
+
+}
+
+?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_templatelexer.php b/include/smarty/libs/sysplugins/smarty_internal_templatelexer.php new file mode 100644 index 000000000..a7d5fa9a5 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_templatelexer.php @@ -0,0 +1,1203 @@ +<?php +/** +* Smarty Internal Plugin Templatelexer +* +* This is the lexer to break the template source into tokens +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ +/** +* Smarty Internal Plugin Templatelexer +*/ +class Smarty_Internal_Templatelexer +{ + public $data; + public $counter; + public $token; + public $value; + public $node; + public $line; + public $taglineno; + public $state = 1; + private $heredoc_id_stack = Array(); + public $smarty_token_names = array ( // Text for parser error messages + 'IDENTITY' => '===', + 'NONEIDENTITY' => '!==', + 'EQUALS' => '==', + 'NOTEQUALS' => '!=', + 'GREATEREQUAL' => '(>=,ge)', + 'LESSEQUAL' => '(<=,le)', + 'GREATERTHAN' => '(>,gt)', + 'LESSTHAN' => '(<,lt)', + 'MOD' => '(%,mod)', + 'NOT' => '(!,not)', + 'LAND' => '(&&,and)', + 'LOR' => '(||,or)', + 'LXOR' => 'xor', + 'OPENP' => '(', + 'CLOSEP' => ')', + 'OPENB' => '[', + 'CLOSEB' => ']', + 'PTR' => '->', + 'APTR' => '=>', + 'EQUAL' => '=', + 'NUMBER' => 'number', + 'UNIMATH' => '+" , "-', + 'MATH' => '*" , "/" , "%', + 'INCDEC' => '++" , "--', + 'SPACE' => ' ', + 'DOLLAR' => '$', + 'SEMICOLON' => ';', + 'COLON' => ':', + 'DOUBLECOLON' => '::', + 'AT' => '@', + 'HATCH' => '#', + 'QUOTE' => '"', + 'BACKTICK' => '`', + 'VERT' => '|', + 'DOT' => '.', + 'COMMA' => '","', + 'ANDSYM' => '"&"', + 'QMARK' => '"?"', + 'ID' => 'identifier', + 'TEXT' => 'text', + 'FAKEPHPSTARTTAG' => 'Fake PHP start tag', + 'PHPSTARTTAG' => 'PHP start tag', + 'PHPENDTAG' => 'PHP end tag', + 'LITERALSTART' => 'Literal start', + 'LITERALEND' => 'Literal end', + 'LDELSLASH' => 'closing tag', + 'COMMENT' => 'comment', + 'AS' => 'as', + 'TO' => 'to', + ); + + + function __construct($data,$compiler) + { +// $this->data = preg_replace("/(\r\n|\r|\n)/", "\n", $data); + $this->data = $data; + $this->counter = 0; + $this->line = 1; + $this->smarty = $compiler->smarty; + $this->compiler = $compiler; + $this->ldel = preg_quote($this->smarty->left_delimiter,'/'); + $this->ldel_length = strlen($this->smarty->left_delimiter); + $this->rdel = preg_quote($this->smarty->right_delimiter,'/'); + $this->rdel_length = strlen($this->smarty->right_delimiter); + $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter; + $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter; + $this->mbstring_overload = ini_get('mbstring.func_overload') & 2; + } + + + private $_yy_state = 1; + private $_yy_stack = array(); + + function yylex() + { + return $this->{'yylex' . $this->_yy_state}(); + } + + function yypushstate($state) + { + array_push($this->_yy_stack, $this->_yy_state); + $this->_yy_state = $state; + } + + function yypopstate() + { + $this->_yy_state = array_pop($this->_yy_stack); + } + + function yybegin($state) + { + $this->_yy_state = $state; + } + + + + function yylex1() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + 3 => 1, + 5 => 0, + 6 => 0, + 7 => 0, + 8 => 0, + 9 => 0, + 10 => 0, + 11 => 1, + 13 => 0, + 14 => 0, + 15 => 0, + 16 => 0, + 17 => 0, + 18 => 0, + 19 => 0, + 20 => 0, + 21 => 0, + 22 => 0, + 23 => 0, + 24 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G(".$this->ldel."[$]smarty\\.block\\.child".$this->rdel.")|\G(\\{\\})|\G(".$this->ldel."\\*([\S\s]*?)\\*".$this->rdel.")|\G(".$this->ldel."strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s*setfilter\\s+)|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(".$this->rdel.")|\G(<%)|\G(%>)|\G([\S\s])/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state TEXT'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r1_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const TEXT = 1; + function yy_r1_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILD; + } + function yy_r1_2($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + function yy_r1_3($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_COMMENT; + } + function yy_r1_5($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_STRIPON; + } + function yy_r1_6($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_STRIPON; + } + } + function yy_r1_7($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF; + } + function yy_r1_8($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF; + } + } + function yy_r1_9($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART; + $this->yypushstate(self::LITERAL); + } + function yy_r1_10($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r1_11($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELIF; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r1_13($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOR; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r1_14($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r1_15($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r1_16($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r1_17($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r1_18($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r1_19($yy_subpatterns) + { + + if (in_array($this->value, Array('<?', '<?=', '<?php'))) { + $this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG; + } elseif ($this->value == '<?xml') { + $this->token = Smarty_Internal_Templateparser::TP_XMLTAG; + } else { + $this->token = Smarty_Internal_Templateparser::TP_FAKEPHPSTARTTAG; + $this->value = substr($this->value, 0, 2); + } + } + function yy_r1_20($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_PHPENDTAG; + } + function yy_r1_21($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + function yy_r1_22($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG; + } + function yy_r1_23($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG; + } + function yy_r1_24($yy_subpatterns) + { + + if ($this->mbstring_overload) { + $to = mb_strlen($this->data,'latin1'); + } else { + $to = strlen($this->data); + } + preg_match("/{$this->ldel}|<\?|\?>|<%|%>/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } + if ($this->mbstring_overload) { + $this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1'); + } else { + $this->value = substr($this->data,$this->counter,$to-$this->counter); + } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + + + function yylex2() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + 3 => 1, + 5 => 0, + 6 => 0, + 7 => 0, + 8 => 0, + 9 => 0, + 10 => 0, + 11 => 0, + 12 => 0, + 13 => 0, + 14 => 0, + 15 => 0, + 16 => 0, + 17 => 0, + 18 => 0, + 19 => 0, + 20 => 1, + 22 => 1, + 24 => 1, + 26 => 0, + 27 => 0, + 28 => 0, + 29 => 0, + 30 => 0, + 31 => 0, + 32 => 0, + 33 => 0, + 34 => 0, + 35 => 0, + 36 => 0, + 37 => 0, + 38 => 0, + 39 => 0, + 40 => 0, + 41 => 0, + 42 => 0, + 43 => 3, + 47 => 0, + 48 => 0, + 49 => 0, + 50 => 0, + 51 => 0, + 52 => 0, + 53 => 0, + 54 => 0, + 55 => 1, + 57 => 1, + 59 => 0, + 60 => 0, + 61 => 0, + 62 => 0, + 63 => 0, + 64 => 0, + 65 => 0, + 66 => 0, + 67 => 0, + 68 => 0, + 69 => 0, + 70 => 0, + 71 => 0, + 72 => 0, + 73 => 0, + 74 => 0, + 75 => 0, + 76 => 0, + 77 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(".$this->rdel.")|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*===\\s*)|\G(\\s*!==\\s*)|\G(\\s*==\\s*|\\s+eq\\s+)|\G(\\s*!=\\s*|\\s*<>\\s*|\\s+(ne|neq)\\s+)|\G(\\s*>=\\s*|\\s+(ge|gte)\\s+)|\G(\\s*<=\\s*|\\s+(le|lte)\\s+)|\G(\\s*>\\s*|\\s+gt\\s+)|\G(\\s*<\\s*|\\s+lt\\s+)|\G(\\s+mod\\s+)|\G(!\\s*|not\\s+)|\G(\\s*&&\\s*|\\s*and\\s+)|\G(\\s*\\|\\|\\s*|\\s*or\\s+)|\G(\\s*xor\\s+)|\G(\\s+is\\s+odd\\s+by\\s+)|\G(\\s+is\\s+not\\s+odd\\s+by\\s+)|\G(\\s+is\\s+odd)|\G(\\s+is\\s+not\\s+odd)|\G(\\s+is\\s+even\\s+by\\s+)|\G(\\s+is\\s+not\\s+even\\s+by\\s+)|\G(\\s+is\\s+even)|\G(\\s+is\\s+not\\s+even)|\G(\\s+is\\s+div\\s+by\\s+)|\G(\\s+is\\s+not\\s+div\\s+by\\s+)|\G(\\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\\)\\s*)|\G(\\s*\\(\\s*)|\G(\\s*\\))|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*->\\s*)|\G(\\s*=>\\s*)|\G(\\s*=\\s*)|\G(\\+\\+|--)|\G(\\s*(\\+|-)\\s*)|\G(\\s*(\\*|\/|%)\\s*)|\G(\\$)|\G(\\s*;)|\G(::)|\G(\\s*:\\s*)|\G(@)|\G(#)|\G(\")|\G(`)|\G(\\|)|\G(\\.)|\G(\\s*,\\s*)|\G(\\s*&\\s*)|\G(\\s*\\?\\s*)|\G(0[xX][0-9a-fA-F]+)|\G(\\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\\s*=\\s*)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G(\\s+)|\G([\S\s])/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state SMARTY'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r2_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const SMARTY = 2; + function yy_r2_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING; + } + function yy_r2_2($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r2_3($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELIF; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r2_5($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOR; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r2_6($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r2_7($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r2_8($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_RDEL; + $this->yypopstate(); + } + function yy_r2_9($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r2_10($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r2_11($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_RDEL; + $this->yypopstate(); + } + function yy_r2_12($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISIN; + } + function yy_r2_13($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_AS; + } + function yy_r2_14($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TO; + } + function yy_r2_15($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_STEP; + } + function yy_r2_16($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF; + } + function yy_r2_17($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_IDENTITY; + } + function yy_r2_18($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_NONEIDENTITY; + } + function yy_r2_19($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_EQUALS; + } + function yy_r2_20($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_NOTEQUALS; + } + function yy_r2_22($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_GREATEREQUAL; + } + function yy_r2_24($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LESSEQUAL; + } + function yy_r2_26($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_GREATERTHAN; + } + function yy_r2_27($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LESSTHAN; + } + function yy_r2_28($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_MOD; + } + function yy_r2_29($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_NOT; + } + function yy_r2_30($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LAND; + } + function yy_r2_31($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LOR; + } + function yy_r2_32($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LXOR; + } + function yy_r2_33($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISODDBY; + } + function yy_r2_34($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISNOTODDBY; + } + function yy_r2_35($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISODD; + } + function yy_r2_36($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISNOTODD; + } + function yy_r2_37($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISEVENBY; + } + function yy_r2_38($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISNOTEVENBY; + } + function yy_r2_39($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISEVEN; + } + function yy_r2_40($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISNOTEVEN; + } + function yy_r2_41($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISDIVBY; + } + function yy_r2_42($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ISNOTDIVBY; + } + function yy_r2_43($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TYPECAST; + } + function yy_r2_47($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_OPENP; + } + function yy_r2_48($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_CLOSEP; + } + function yy_r2_49($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_OPENB; + } + function yy_r2_50($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_CLOSEB; + } + function yy_r2_51($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_PTR; + } + function yy_r2_52($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_APTR; + } + function yy_r2_53($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_EQUAL; + } + function yy_r2_54($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_INCDEC; + } + function yy_r2_55($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_UNIMATH; + } + function yy_r2_57($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_MATH; + } + function yy_r2_59($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_DOLLAR; + } + function yy_r2_60($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON; + } + function yy_r2_61($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON; + } + function yy_r2_62($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_COLON; + } + function yy_r2_63($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_AT; + } + function yy_r2_64($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_HATCH; + } + function yy_r2_65($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; + $this->yypushstate(self::DOUBLEQUOTEDSTRING); + } + function yy_r2_66($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; + $this->yypopstate(); + } + function yy_r2_67($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_VERT; + } + function yy_r2_68($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_DOT; + } + function yy_r2_69($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_COMMA; + } + function yy_r2_70($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ANDSYM; + } + function yy_r2_71($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_QMARK; + } + function yy_r2_72($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_HEX; + } + function yy_r2_73($yy_subpatterns) + { + + // resolve conflicts with shorttag and right_delimiter starting with '=' + if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) { + preg_match("/\s+/",$this->value,$match); + $this->value = $match[0]; + $this->token = Smarty_Internal_Templateparser::TP_SPACE; + } else { + $this->token = Smarty_Internal_Templateparser::TP_ATTR; + } + } + function yy_r2_74($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ID; + } + function yy_r2_75($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_INTEGER; + } + function yy_r2_76($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_SPACE; + } + function yy_r2_77($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + + + + function yylex3() + { + $tokenMap = array ( + 1 => 0, + 2 => 0, + 3 => 0, + 4 => 0, + 5 => 0, + 6 => 0, + 7 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s*\/literal\\s*".$this->rdel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(<%)|\G(%>)|\G([\S\s])/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state LITERAL'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r3_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const LITERAL = 3; + function yy_r3_1($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART; + $this->yypushstate(self::LITERAL); + } + function yy_r3_2($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LITERALEND; + $this->yypopstate(); + } + function yy_r3_3($yy_subpatterns) + { + + if (in_array($this->value, Array('<?', '<?=', '<?php'))) { + $this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG; + } else { + $this->token = Smarty_Internal_Templateparser::TP_FAKEPHPSTARTTAG; + $this->value = substr($this->value, 0, 2); + } + } + function yy_r3_4($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_PHPENDTAG; + } + function yy_r3_5($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG; + } + function yy_r3_6($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG; + } + function yy_r3_7($yy_subpatterns) + { + + if ($this->mbstring_overload) { + $to = mb_strlen($this->data,'latin1'); + } else { + $to = strlen($this->data); + } + preg_match("/{$this->ldel}\/?literal{$this->rdel}|<\?|<%|\?>|%>/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1]; + } else { + $this->compiler->trigger_template_error ("missing or misspelled literal closing tag"); + } + if ($this->mbstring_overload) { + $this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1'); + } else { + $this->value = substr($this->data,$this->counter,$to-$this->counter); + } + $this->token = Smarty_Internal_Templateparser::TP_LITERAL; + } + + + function yylex4() + { + $tokenMap = array ( + 1 => 0, + 2 => 1, + 4 => 0, + 5 => 0, + 6 => 0, + 7 => 0, + 8 => 0, + 9 => 0, + 10 => 0, + 11 => 0, + 12 => 0, + 13 => 3, + 17 => 0, + ); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + $yy_global_pattern = "/\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(\")|\G(`\\$)|\G(\\$[0-9]*[a-zA-Z_]\\w*)|\G(\\$)|\G(([^\"\\\\]*?)((?:\\\\.[^\"\\\\]*?)*?)(?=(".$this->ldel."|\\$|`\\$|\")))|\G([\S\s])/iS"; + + do { + if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { + $yysubmatches = $yymatches; + $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns + if (!count($yymatches)) { + throw new Exception('Error: lexing failed because a rule matched' . + ' an empty string. Input "' . substr($this->data, + $this->counter, 5) . '... state DOUBLEQUOTEDSTRING'); + } + next($yymatches); // skip global match + $this->token = key($yymatches); // token number + if ($tokenMap[$this->token]) { + // extract sub-patterns for passing to lex function + $yysubmatches = array_slice($yysubmatches, $this->token + 1, + $tokenMap[$this->token]); + } else { + $yysubmatches = array(); + } + $this->value = current($yymatches); // token value + $r = $this->{'yy_r4_' . $this->token}($yysubmatches); + if ($r === null) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + // accept this token + return true; + } elseif ($r === true) { + // we have changed state + // process this token in the new state + return $this->yylex(); + } elseif ($r === false) { + $this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value)); + $this->line += substr_count($this->value, "\n"); + if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { + return false; // end of input + } + // skip this token + continue; + } } else { + throw new Exception('Unexpected input at line' . $this->line . + ': ' . $this->data[$this->counter]); + } + break; + } while (true); + + } // end function + + + const DOUBLEQUOTEDSTRING = 4; + function yy_r4_1($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r4_2($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELIF; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r4_4($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOR; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r4_5($yy_subpatterns) + { + + if ($this->smarty->auto_literal && trim(substr($this->value,$this->ldel_length,1)) == '') { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r4_6($yy_subpatterns) + { + + if ($this->smarty->auto_literal) { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } else { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + } + function yy_r4_7($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r4_8($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r4_9($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; + $this->yypopstate(); + } + function yy_r4_10($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; + $this->value = substr($this->value,0,-1); + $this->yypushstate(self::SMARTY); + $this->taglineno = $this->line; + } + function yy_r4_11($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; + } + function yy_r4_12($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + function yy_r4_13($yy_subpatterns) + { + + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + function yy_r4_17($yy_subpatterns) + { + + if ($this->mbstring_overload) { + $to = mb_strlen($this->data,'latin1'); + } else { + $to = strlen($this->data); + } + if ($this->mbstring_overload) { + $this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1'); + } else { + $this->value = substr($this->data,$this->counter,$to-$this->counter); + } + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + +} diff --git a/include/smarty/libs/sysplugins/smarty_internal_templateparser.php b/include/smarty/libs/sysplugins/smarty_internal_templateparser.php new file mode 100644 index 000000000..d67be6e6f --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_templateparser.php @@ -0,0 +1,3254 @@ +<?php +/** +* Smarty Internal Plugin Templateparser +* +* This is the template parser. +* It is generated from the internal.templateparser.y file +* @package Smarty +* @subpackage Compiler +* @author Uwe Tews +*/ + +class TP_yyToken implements ArrayAccess +{ + public $string = ''; + public $metadata = array(); + + function __construct($s, $m = array()) + { + if ($s instanceof TP_yyToken) { + $this->string = $s->string; + $this->metadata = $s->metadata; + } else { + $this->string = (string) $s; + if ($m instanceof TP_yyToken) { + $this->metadata = $m->metadata; + } elseif (is_array($m)) { + $this->metadata = $m; + } + } + } + + function __toString() + { + return $this->_string; + } + + function offsetExists($offset) + { + return isset($this->metadata[$offset]); + } + + function offsetGet($offset) + { + return $this->metadata[$offset]; + } + + function offsetSet($offset, $value) + { + if ($offset === null) { + if (isset($value[0])) { + $x = ($value instanceof TP_yyToken) ? + $value->metadata : $value; + $this->metadata = array_merge($this->metadata, $x); + return; + } + $offset = count($this->metadata); + } + if ($value === null) { + return; + } + if ($value instanceof TP_yyToken) { + if ($value->metadata) { + $this->metadata[$offset] = $value->metadata; + } + } elseif ($value) { + $this->metadata[$offset] = $value; + } + } + + function offsetUnset($offset) + { + unset($this->metadata[$offset]); + } +} + +class TP_yyStackEntry +{ + public $stateno; /* The state-number */ + public $major; /* The major token value. This is the code + ** number for the token at this stack level */ + public $minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; + + +#line 12 "smarty_internal_templateparser.y" +class Smarty_Internal_Templateparser#line 79 "smarty_internal_templateparser.php" +{ +#line 14 "smarty_internal_templateparser.y" + + const Err1 = "Security error: Call to private object member not allowed"; + const Err2 = "Security error: Call to dynamic object member not allowed"; + const Err3 = "PHP in template not allowed. Use SmartyBC to enable it"; + // states whether the parse was successful or not + public $successful = true; + public $retvalue = 0; + private $lex; + private $internalError = false; + private $strip = false; + + function __construct($lex, $compiler) { + $this->lex = $lex; + $this->compiler = $compiler; + $this->smarty = $this->compiler->smarty; + $this->template = $this->compiler->template; + $this->compiler->has_variable_string = false; + $this->compiler->prefix_code = array(); + $this->prefix_number = 0; + $this->block_nesting_level = 0; + if ($this->security = isset($this->smarty->security_policy)) { + $this->php_handling = $this->smarty->security_policy->php_handling; + } else { + $this->php_handling = $this->smarty->php_handling; + } + $this->is_xml = false; + $this->asp_tags = (ini_get('asp_tags') != '0'); + $this->current_buffer = $this->root_buffer = new _smarty_template_buffer($this); + } + + public static function escape_start_tag($tag_text) { + $tag = preg_replace('/\A<\?(.*)\z/', '<<?php ?>?\1', $tag_text, -1 , $count); //Escape tag + return $tag; + } + + public static function escape_end_tag($tag_text) { + return '?<?php ?>>'; + } + + public function compileVariable($variable) { + if (strpos($variable,'(') == 0) { + // not a variable variable + $var = trim($variable,'\''); + $this->compiler->tag_nocache=$this->compiler->tag_nocache|$this->template->getVariable($var, null, true, false)->nocache; + $this->template->properties['variables'][$var] = $this->compiler->tag_nocache|$this->compiler->nocache; + } +// return '(isset($_smarty_tpl->tpl_vars['. $variable .'])?$_smarty_tpl->tpl_vars['. $variable .']->value:$_smarty_tpl->getVariable('. $variable .')->value)'; + return '$_smarty_tpl->tpl_vars['. $variable .']->value'; + } +#line 132 "smarty_internal_templateparser.php" + + const TP_VERT = 1; + const TP_COLON = 2; + const TP_COMMENT = 3; + const TP_PHPSTARTTAG = 4; + const TP_PHPENDTAG = 5; + const TP_ASPSTARTTAG = 6; + const TP_ASPENDTAG = 7; + const TP_FAKEPHPSTARTTAG = 8; + const TP_XMLTAG = 9; + const TP_TEXT = 10; + const TP_STRIPON = 11; + const TP_STRIPOFF = 12; + const TP_LITERALSTART = 13; + const TP_LITERALEND = 14; + const TP_LITERAL = 15; + const TP_LDEL = 16; + const TP_RDEL = 17; + const TP_DOLLAR = 18; + const TP_ID = 19; + const TP_EQUAL = 20; + const TP_PTR = 21; + const TP_LDELIF = 22; + const TP_LDELFOR = 23; + const TP_SEMICOLON = 24; + const TP_INCDEC = 25; + const TP_TO = 26; + const TP_STEP = 27; + const TP_LDELFOREACH = 28; + const TP_SPACE = 29; + const TP_AS = 30; + const TP_APTR = 31; + const TP_LDELSETFILTER = 32; + const TP_SMARTYBLOCKCHILD = 33; + const TP_LDELSLASH = 34; + const TP_ATTR = 35; + const TP_INTEGER = 36; + const TP_COMMA = 37; + const TP_OPENP = 38; + const TP_CLOSEP = 39; + const TP_MATH = 40; + const TP_UNIMATH = 41; + const TP_ANDSYM = 42; + const TP_ISIN = 43; + const TP_ISDIVBY = 44; + const TP_ISNOTDIVBY = 45; + const TP_ISEVEN = 46; + const TP_ISNOTEVEN = 47; + const TP_ISEVENBY = 48; + const TP_ISNOTEVENBY = 49; + const TP_ISODD = 50; + const TP_ISNOTODD = 51; + const TP_ISODDBY = 52; + const TP_ISNOTODDBY = 53; + const TP_INSTANCEOF = 54; + const TP_QMARK = 55; + const TP_NOT = 56; + const TP_TYPECAST = 57; + const TP_HEX = 58; + const TP_DOT = 59; + const TP_SINGLEQUOTESTRING = 60; + const TP_DOUBLECOLON = 61; + const TP_AT = 62; + const TP_HATCH = 63; + const TP_OPENB = 64; + const TP_CLOSEB = 65; + const TP_EQUALS = 66; + const TP_NOTEQUALS = 67; + const TP_GREATERTHAN = 68; + const TP_LESSTHAN = 69; + const TP_GREATEREQUAL = 70; + const TP_LESSEQUAL = 71; + const TP_IDENTITY = 72; + const TP_NONEIDENTITY = 73; + const TP_MOD = 74; + const TP_LAND = 75; + const TP_LOR = 76; + const TP_LXOR = 77; + const TP_QUOTE = 78; + const TP_BACKTICK = 79; + const TP_DOLLARID = 80; + const YY_NO_ACTION = 597; + const YY_ACCEPT_ACTION = 596; + const YY_ERROR_ACTION = 595; + + const YY_SZ_ACTTAB = 2383; +static public $yy_action = array( + /* 0 */ 225, 275, 263, 276, 259, 257, 260, 390, 356, 359, + /* 10 */ 353, 193, 18, 127, 42, 317, 381, 351, 196, 350, + /* 20 */ 6, 108, 24, 98, 128, 190, 134, 318, 41, 41, + /* 30 */ 249, 329, 231, 18, 43, 43, 317, 26, 298, 50, + /* 40 */ 47, 48, 44, 10, 13, 305, 306, 12, 11, 340, + /* 50 */ 341, 40, 20, 387, 308, 307, 309, 374, 254, 248, + /* 60 */ 252, 217, 193, 385, 291, 375, 376, 377, 373, 372, + /* 70 */ 368, 367, 369, 370, 371, 378, 379, 225, 312, 255, + /* 80 */ 225, 225, 118, 2, 207, 76, 135, 596, 95, 281, + /* 90 */ 271, 264, 2, 366, 315, 386, 461, 383, 232, 294, + /* 100 */ 303, 388, 313, 389, 227, 41, 144, 225, 461, 245, + /* 110 */ 282, 43, 218, 358, 461, 144, 50, 47, 48, 44, + /* 120 */ 10, 13, 305, 306, 12, 11, 340, 341, 40, 20, + /* 130 */ 105, 177, 522, 46, 46, 41, 19, 522, 143, 297, + /* 140 */ 325, 43, 375, 376, 377, 373, 372, 368, 367, 369, + /* 150 */ 370, 371, 378, 379, 225, 312, 293, 206, 225, 141, + /* 160 */ 124, 225, 54, 119, 123, 225, 459, 38, 173, 246, + /* 170 */ 319, 315, 386, 347, 455, 232, 294, 303, 459, 313, + /* 180 */ 139, 321, 41, 31, 459, 41, 41, 2, 43, 188, + /* 190 */ 2, 43, 43, 50, 47, 48, 44, 10, 13, 305, + /* 200 */ 306, 12, 11, 340, 341, 40, 20, 225, 136, 301, + /* 210 */ 144, 194, 350, 144, 46, 202, 206, 328, 198, 375, + /* 220 */ 376, 377, 373, 372, 368, 367, 369, 370, 371, 378, + /* 230 */ 379, 21, 9, 28, 185, 41, 318, 225, 265, 271, + /* 240 */ 264, 43, 206, 27, 173, 206, 50, 47, 48, 44, + /* 250 */ 10, 13, 305, 306, 12, 11, 340, 341, 40, 20, + /* 260 */ 225, 178, 18, 212, 330, 317, 17, 32, 8, 14, + /* 270 */ 325, 267, 375, 376, 377, 373, 372, 368, 367, 369, + /* 280 */ 370, 371, 378, 379, 136, 363, 363, 207, 41, 4, + /* 290 */ 46, 5, 131, 233, 43, 25, 186, 289, 318, 50, + /* 300 */ 47, 48, 44, 10, 13, 305, 306, 12, 11, 340, + /* 310 */ 341, 40, 20, 225, 100, 161, 18, 355, 361, 317, + /* 320 */ 26, 109, 360, 346, 325, 375, 376, 377, 373, 372, + /* 330 */ 368, 367, 369, 370, 371, 378, 379, 106, 201, 172, + /* 340 */ 25, 206, 288, 25, 18, 261, 181, 317, 325, 45, + /* 350 */ 339, 129, 50, 47, 48, 44, 10, 13, 305, 306, + /* 360 */ 12, 11, 340, 341, 40, 20, 225, 104, 162, 18, + /* 370 */ 16, 205, 317, 206, 248, 238, 43, 325, 375, 376, + /* 380 */ 377, 373, 372, 368, 367, 369, 370, 371, 378, 379, + /* 390 */ 255, 354, 243, 229, 206, 342, 18, 239, 242, 241, + /* 400 */ 248, 266, 300, 330, 240, 50, 47, 48, 44, 10, + /* 410 */ 13, 305, 306, 12, 11, 340, 341, 40, 20, 225, + /* 420 */ 165, 176, 184, 18, 18, 18, 253, 215, 251, 325, + /* 430 */ 325, 375, 376, 377, 373, 372, 368, 367, 369, 370, + /* 440 */ 371, 378, 379, 304, 268, 159, 207, 207, 247, 206, + /* 450 */ 148, 41, 195, 350, 325, 27, 33, 43, 50, 47, + /* 460 */ 48, 44, 10, 13, 305, 306, 12, 11, 340, 341, + /* 470 */ 40, 20, 163, 225, 328, 199, 133, 29, 187, 23, + /* 480 */ 250, 325, 101, 225, 375, 376, 377, 373, 372, 368, + /* 490 */ 367, 369, 370, 371, 378, 379, 225, 298, 207, 334, + /* 500 */ 225, 45, 312, 103, 299, 192, 154, 364, 18, 302, + /* 510 */ 135, 317, 285, 35, 173, 203, 320, 3, 236, 6, + /* 520 */ 108, 41, 232, 294, 303, 134, 313, 43, 130, 249, + /* 530 */ 329, 231, 250, 225, 280, 50, 47, 48, 44, 10, + /* 540 */ 13, 305, 306, 12, 11, 340, 341, 40, 20, 336, + /* 550 */ 36, 166, 212, 230, 332, 228, 338, 8, 132, 330, + /* 560 */ 325, 375, 376, 377, 373, 372, 368, 367, 369, 370, + /* 570 */ 371, 378, 379, 225, 312, 345, 37, 362, 141, 312, + /* 580 */ 94, 77, 135, 156, 236, 182, 173, 135, 122, 204, + /* 590 */ 315, 386, 365, 225, 232, 294, 303, 137, 313, 232, + /* 600 */ 294, 303, 125, 313, 41, 222, 333, 180, 277, 337, + /* 610 */ 43, 225, 50, 47, 48, 44, 10, 13, 305, 306, + /* 620 */ 12, 11, 340, 341, 40, 20, 136, 335, 316, 5, + /* 630 */ 22, 197, 269, 34, 173, 148, 126, 116, 375, 376, + /* 640 */ 377, 373, 372, 368, 367, 369, 370, 371, 378, 379, + /* 650 */ 225, 312, 298, 225, 292, 141, 312, 258, 77, 135, + /* 660 */ 153, 183, 318, 301, 135, 175, 284, 315, 386, 461, + /* 670 */ 117, 232, 294, 303, 325, 313, 232, 294, 303, 382, + /* 680 */ 313, 461, 220, 110, 329, 298, 318, 461, 329, 50, + /* 690 */ 47, 48, 44, 10, 13, 305, 306, 12, 11, 340, + /* 700 */ 341, 40, 20, 225, 30, 191, 46, 189, 314, 107, + /* 710 */ 329, 329, 146, 97, 102, 375, 376, 377, 373, 372, + /* 720 */ 368, 367, 369, 370, 371, 378, 379, 298, 298, 298, + /* 730 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + /* 740 */ 329, 329, 50, 47, 48, 44, 10, 13, 305, 306, + /* 750 */ 12, 11, 340, 341, 40, 20, 225, 329, 329, 329, + /* 760 */ 329, 329, 329, 329, 329, 114, 160, 115, 375, 376, + /* 770 */ 377, 373, 372, 368, 367, 369, 370, 371, 378, 379, + /* 780 */ 298, 298, 298, 329, 329, 329, 329, 329, 329, 329, + /* 790 */ 329, 329, 329, 329, 283, 50, 47, 48, 44, 10, + /* 800 */ 13, 305, 306, 12, 11, 340, 341, 40, 20, 329, + /* 810 */ 225, 329, 329, 329, 329, 329, 329, 329, 329, 329, + /* 820 */ 329, 375, 376, 377, 373, 372, 368, 367, 369, 370, + /* 830 */ 371, 378, 379, 200, 329, 329, 329, 329, 329, 329, + /* 840 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 50, + /* 850 */ 47, 48, 44, 10, 13, 305, 306, 12, 11, 340, + /* 860 */ 341, 40, 20, 225, 329, 329, 329, 329, 329, 329, + /* 870 */ 329, 329, 329, 329, 329, 375, 376, 377, 373, 372, + /* 880 */ 368, 367, 369, 370, 371, 378, 379, 329, 329, 329, + /* 890 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + /* 900 */ 329, 329, 50, 47, 48, 44, 10, 13, 305, 306, + /* 910 */ 12, 11, 340, 341, 40, 20, 329, 329, 329, 329, + /* 920 */ 329, 329, 329, 329, 329, 329, 329, 290, 375, 376, + /* 930 */ 377, 373, 372, 368, 367, 369, 370, 371, 378, 379, + /* 940 */ 225, 312, 329, 225, 329, 141, 312, 329, 77, 135, + /* 950 */ 152, 329, 329, 329, 135, 158, 208, 315, 386, 458, + /* 960 */ 329, 232, 294, 303, 325, 313, 232, 294, 303, 329, + /* 970 */ 313, 458, 223, 329, 329, 329, 318, 458, 329, 50, + /* 980 */ 47, 48, 44, 10, 13, 305, 306, 12, 11, 340, + /* 990 */ 341, 40, 20, 225, 329, 329, 46, 329, 329, 329, + /* 1000 */ 329, 329, 329, 329, 329, 375, 376, 377, 373, 372, + /* 1010 */ 368, 367, 369, 370, 371, 378, 379, 329, 329, 329, + /* 1020 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + /* 1030 */ 329, 329, 50, 47, 48, 44, 10, 13, 305, 306, + /* 1040 */ 12, 11, 340, 341, 40, 20, 329, 329, 329, 329, + /* 1050 */ 329, 329, 329, 329, 329, 329, 329, 329, 375, 376, + /* 1060 */ 377, 373, 372, 368, 367, 369, 370, 371, 378, 379, + /* 1070 */ 329, 329, 329, 50, 47, 48, 44, 10, 13, 305, + /* 1080 */ 306, 12, 11, 340, 341, 40, 20, 329, 329, 329, + /* 1090 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 375, + /* 1100 */ 376, 377, 373, 372, 368, 367, 369, 370, 371, 378, + /* 1110 */ 379, 329, 329, 329, 329, 329, 42, 329, 145, 211, + /* 1120 */ 329, 329, 6, 108, 329, 279, 329, 312, 134, 329, + /* 1130 */ 329, 150, 249, 329, 231, 135, 235, 41, 39, 329, + /* 1140 */ 329, 52, 329, 43, 311, 329, 312, 232, 294, 303, + /* 1150 */ 147, 313, 329, 170, 135, 329, 51, 49, 331, 237, + /* 1160 */ 296, 329, 325, 106, 1, 278, 232, 294, 303, 329, + /* 1170 */ 313, 155, 329, 42, 318, 145, 216, 329, 96, 6, + /* 1180 */ 108, 18, 329, 226, 317, 134, 329, 313, 329, 249, + /* 1190 */ 329, 231, 329, 235, 41, 39, 256, 329, 52, 329, + /* 1200 */ 43, 329, 312, 329, 329, 329, 141, 329, 329, 66, + /* 1210 */ 119, 238, 329, 51, 49, 331, 237, 296, 315, 386, + /* 1220 */ 106, 1, 232, 294, 303, 329, 313, 270, 329, 329, + /* 1230 */ 42, 329, 140, 92, 329, 96, 6, 108, 18, 41, + /* 1240 */ 169, 317, 134, 329, 273, 43, 249, 329, 231, 325, + /* 1250 */ 235, 41, 39, 244, 329, 52, 41, 43, 329, 312, + /* 1260 */ 329, 318, 43, 141, 329, 329, 67, 135, 225, 329, + /* 1270 */ 51, 49, 331, 237, 296, 315, 386, 106, 1, 224, + /* 1280 */ 294, 303, 329, 313, 310, 329, 329, 42, 329, 145, + /* 1290 */ 213, 329, 96, 6, 108, 329, 41, 329, 329, 134, + /* 1300 */ 329, 323, 43, 249, 329, 231, 329, 235, 329, 39, + /* 1310 */ 329, 329, 52, 41, 329, 329, 312, 329, 329, 43, + /* 1320 */ 141, 46, 329, 86, 135, 329, 329, 51, 49, 331, + /* 1330 */ 237, 296, 315, 386, 106, 1, 232, 294, 303, 329, + /* 1340 */ 313, 274, 329, 329, 42, 329, 142, 216, 329, 96, + /* 1350 */ 6, 108, 329, 41, 329, 329, 134, 329, 348, 43, + /* 1360 */ 249, 329, 231, 329, 235, 329, 7, 329, 329, 52, + /* 1370 */ 41, 329, 329, 312, 329, 329, 43, 141, 329, 329, + /* 1380 */ 90, 135, 329, 329, 51, 49, 331, 237, 296, 315, + /* 1390 */ 386, 106, 1, 232, 294, 303, 329, 313, 295, 329, + /* 1400 */ 329, 42, 329, 138, 216, 329, 96, 6, 108, 329, + /* 1410 */ 41, 329, 329, 134, 329, 322, 43, 249, 329, 231, + /* 1420 */ 329, 235, 329, 39, 329, 329, 52, 41, 329, 329, + /* 1430 */ 312, 329, 329, 43, 141, 329, 329, 87, 135, 329, + /* 1440 */ 329, 51, 49, 331, 237, 296, 315, 386, 106, 1, + /* 1450 */ 232, 294, 303, 329, 313, 384, 329, 329, 42, 329, + /* 1460 */ 131, 216, 329, 96, 6, 108, 329, 41, 329, 329, + /* 1470 */ 134, 329, 380, 43, 249, 329, 231, 329, 235, 329, + /* 1480 */ 15, 329, 329, 52, 41, 329, 329, 312, 329, 329, + /* 1490 */ 43, 141, 329, 329, 79, 135, 329, 329, 51, 49, + /* 1500 */ 331, 237, 296, 315, 386, 106, 1, 232, 294, 303, + /* 1510 */ 329, 313, 272, 329, 329, 42, 329, 145, 210, 329, + /* 1520 */ 96, 6, 108, 329, 41, 329, 329, 134, 329, 349, + /* 1530 */ 43, 249, 329, 231, 329, 221, 329, 39, 329, 329, + /* 1540 */ 52, 41, 329, 329, 312, 329, 329, 43, 141, 329, + /* 1550 */ 329, 70, 135, 329, 329, 51, 49, 331, 237, 296, + /* 1560 */ 315, 386, 106, 1, 232, 294, 303, 329, 313, 324, + /* 1570 */ 329, 329, 42, 329, 145, 209, 329, 96, 6, 108, + /* 1580 */ 329, 41, 329, 329, 134, 329, 326, 43, 249, 329, + /* 1590 */ 231, 329, 235, 329, 39, 329, 329, 52, 41, 329, + /* 1600 */ 329, 312, 329, 329, 43, 141, 329, 329, 74, 135, + /* 1610 */ 329, 329, 51, 49, 331, 237, 296, 315, 386, 106, + /* 1620 */ 1, 232, 294, 303, 329, 313, 262, 329, 329, 42, + /* 1630 */ 329, 131, 214, 329, 96, 6, 108, 329, 41, 329, + /* 1640 */ 329, 134, 329, 327, 43, 249, 329, 231, 329, 235, + /* 1650 */ 329, 15, 329, 329, 52, 41, 329, 329, 312, 329, + /* 1660 */ 329, 43, 141, 329, 329, 53, 135, 329, 329, 51, + /* 1670 */ 49, 331, 237, 296, 315, 386, 106, 329, 232, 294, + /* 1680 */ 303, 329, 313, 286, 329, 329, 42, 329, 131, 216, + /* 1690 */ 329, 96, 6, 108, 329, 41, 329, 329, 134, 329, + /* 1700 */ 343, 43, 249, 329, 231, 329, 235, 329, 15, 329, + /* 1710 */ 329, 52, 41, 329, 329, 312, 329, 329, 43, 118, + /* 1720 */ 329, 329, 76, 135, 329, 329, 51, 49, 331, 237, + /* 1730 */ 296, 315, 386, 106, 329, 232, 294, 303, 329, 313, + /* 1740 */ 329, 329, 329, 329, 504, 329, 329, 329, 96, 329, + /* 1750 */ 357, 504, 329, 504, 504, 364, 504, 504, 329, 329, + /* 1760 */ 329, 35, 504, 329, 504, 2, 504, 6, 108, 329, + /* 1770 */ 198, 174, 329, 134, 329, 329, 329, 249, 329, 231, + /* 1780 */ 325, 504, 329, 21, 9, 329, 329, 329, 144, 329, + /* 1790 */ 329, 329, 504, 329, 312, 99, 179, 206, 141, 329, + /* 1800 */ 329, 58, 135, 329, 329, 325, 504, 329, 21, 9, + /* 1810 */ 315, 386, 329, 312, 232, 294, 303, 141, 313, 329, + /* 1820 */ 71, 135, 206, 344, 37, 362, 329, 329, 329, 315, + /* 1830 */ 386, 329, 329, 232, 294, 303, 312, 313, 329, 329, + /* 1840 */ 141, 329, 329, 72, 135, 329, 329, 312, 329, 329, + /* 1850 */ 329, 141, 315, 386, 65, 135, 232, 294, 303, 329, + /* 1860 */ 313, 329, 329, 315, 386, 329, 329, 232, 294, 303, + /* 1870 */ 329, 313, 329, 329, 312, 198, 167, 329, 141, 329, + /* 1880 */ 329, 69, 135, 329, 329, 325, 329, 329, 21, 9, + /* 1890 */ 315, 386, 329, 329, 232, 294, 303, 312, 313, 329, + /* 1900 */ 329, 141, 206, 329, 85, 135, 329, 312, 329, 329, + /* 1910 */ 329, 149, 329, 315, 386, 135, 312, 232, 294, 303, + /* 1920 */ 141, 313, 329, 81, 135, 329, 329, 232, 294, 303, + /* 1930 */ 329, 313, 315, 386, 329, 329, 232, 294, 303, 312, + /* 1940 */ 313, 329, 329, 141, 329, 329, 82, 135, 329, 329, + /* 1950 */ 312, 329, 329, 329, 141, 315, 386, 63, 135, 232, + /* 1960 */ 294, 303, 329, 313, 329, 329, 315, 386, 329, 329, + /* 1970 */ 232, 294, 303, 329, 313, 329, 312, 329, 329, 329, + /* 1980 */ 141, 329, 329, 73, 135, 329, 329, 312, 329, 329, + /* 1990 */ 329, 141, 315, 386, 83, 135, 232, 294, 303, 329, + /* 2000 */ 313, 329, 329, 315, 386, 329, 312, 232, 294, 303, + /* 2010 */ 141, 313, 329, 89, 135, 329, 329, 329, 329, 329, + /* 2020 */ 329, 329, 315, 386, 329, 312, 232, 294, 303, 111, + /* 2030 */ 313, 329, 68, 135, 329, 329, 312, 329, 329, 329, + /* 2040 */ 141, 315, 386, 62, 135, 232, 294, 303, 329, 313, + /* 2050 */ 329, 329, 315, 386, 329, 329, 232, 294, 303, 329, + /* 2060 */ 313, 329, 312, 329, 329, 329, 141, 329, 329, 61, + /* 2070 */ 135, 329, 329, 312, 329, 329, 329, 141, 315, 386, + /* 2080 */ 91, 135, 232, 294, 303, 329, 313, 329, 329, 315, + /* 2090 */ 386, 329, 312, 232, 294, 303, 141, 313, 329, 78, + /* 2100 */ 135, 329, 329, 329, 329, 329, 329, 329, 315, 386, + /* 2110 */ 329, 312, 232, 294, 303, 141, 313, 329, 66, 135, + /* 2120 */ 329, 329, 312, 329, 329, 329, 141, 315, 386, 80, + /* 2130 */ 135, 232, 294, 303, 329, 313, 329, 329, 315, 386, + /* 2140 */ 329, 329, 232, 294, 303, 329, 313, 329, 312, 329, + /* 2150 */ 329, 329, 113, 329, 329, 88, 135, 329, 329, 312, + /* 2160 */ 329, 329, 329, 112, 315, 386, 84, 135, 232, 294, + /* 2170 */ 303, 329, 313, 329, 329, 315, 386, 329, 312, 232, + /* 2180 */ 294, 303, 141, 313, 329, 57, 135, 329, 329, 329, + /* 2190 */ 329, 329, 329, 329, 315, 386, 329, 312, 232, 294, + /* 2200 */ 303, 93, 313, 329, 59, 121, 329, 329, 312, 329, + /* 2210 */ 329, 329, 141, 315, 386, 75, 135, 232, 294, 303, + /* 2220 */ 329, 313, 329, 329, 315, 386, 329, 329, 232, 294, + /* 2230 */ 303, 329, 313, 329, 312, 329, 329, 329, 141, 329, + /* 2240 */ 329, 60, 135, 329, 329, 312, 329, 329, 329, 141, + /* 2250 */ 315, 386, 64, 135, 232, 294, 303, 329, 313, 329, + /* 2260 */ 329, 315, 386, 329, 312, 232, 294, 303, 120, 313, + /* 2270 */ 329, 55, 135, 329, 329, 329, 329, 329, 329, 329, + /* 2280 */ 315, 386, 329, 312, 232, 294, 303, 93, 313, 329, + /* 2290 */ 56, 121, 225, 329, 312, 329, 198, 164, 157, 315, + /* 2300 */ 386, 329, 135, 219, 294, 303, 325, 313, 352, 21, + /* 2310 */ 9, 287, 234, 329, 232, 294, 303, 329, 313, 329, + /* 2320 */ 41, 329, 329, 206, 312, 329, 43, 329, 151, 2, + /* 2330 */ 329, 329, 135, 329, 329, 329, 329, 329, 329, 329, + /* 2340 */ 198, 168, 329, 329, 232, 294, 303, 329, 313, 329, + /* 2350 */ 325, 329, 144, 21, 9, 198, 171, 329, 329, 329, + /* 2360 */ 329, 329, 329, 329, 329, 325, 329, 206, 21, 9, + /* 2370 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + /* 2380 */ 329, 329, 206, + ); + static public $yy_lookahead = array( + /* 0 */ 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, + /* 10 */ 12, 13, 16, 98, 16, 19, 17, 17, 113, 114, + /* 20 */ 22, 23, 16, 97, 18, 19, 28, 112, 29, 29, + /* 30 */ 32, 33, 34, 16, 35, 35, 19, 20, 112, 40, + /* 40 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + /* 50 */ 51, 52, 53, 4, 5, 6, 7, 8, 62, 93, + /* 60 */ 94, 95, 13, 14, 15, 66, 67, 68, 69, 70, + /* 70 */ 71, 72, 73, 74, 75, 76, 77, 1, 85, 62, + /* 80 */ 1, 1, 89, 38, 117, 92, 93, 82, 83, 84, + /* 90 */ 85, 86, 38, 17, 101, 102, 17, 17, 105, 106, + /* 100 */ 107, 86, 109, 88, 59, 29, 61, 1, 29, 30, + /* 110 */ 65, 35, 119, 120, 35, 61, 40, 41, 42, 43, + /* 120 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 130 */ 90, 91, 59, 54, 54, 29, 16, 64, 18, 19, + /* 140 */ 100, 35, 66, 67, 68, 69, 70, 71, 72, 73, + /* 150 */ 74, 75, 76, 77, 1, 85, 36, 117, 1, 89, + /* 160 */ 18, 1, 92, 93, 94, 1, 17, 20, 21, 20, + /* 170 */ 17, 101, 102, 17, 17, 105, 106, 107, 29, 109, + /* 180 */ 38, 17, 29, 31, 35, 29, 29, 38, 35, 90, + /* 190 */ 38, 35, 35, 40, 41, 42, 43, 44, 45, 46, + /* 200 */ 47, 48, 49, 50, 51, 52, 53, 1, 61, 111, + /* 210 */ 61, 113, 114, 61, 54, 90, 117, 118, 90, 66, + /* 220 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 230 */ 77, 103, 104, 27, 110, 29, 112, 1, 84, 85, + /* 240 */ 86, 35, 117, 20, 21, 117, 40, 41, 42, 43, + /* 250 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 260 */ 1, 91, 16, 59, 25, 19, 20, 31, 64, 16, + /* 270 */ 100, 25, 66, 67, 68, 69, 70, 71, 72, 73, + /* 280 */ 74, 75, 76, 77, 61, 85, 85, 117, 29, 37, + /* 290 */ 54, 38, 18, 19, 35, 37, 110, 39, 112, 40, + /* 300 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + /* 310 */ 51, 52, 53, 1, 90, 91, 16, 65, 79, 19, + /* 320 */ 20, 121, 122, 122, 100, 66, 67, 68, 69, 70, + /* 330 */ 71, 72, 73, 74, 75, 76, 77, 63, 24, 91, + /* 340 */ 37, 117, 39, 37, 16, 39, 90, 19, 100, 2, + /* 350 */ 19, 37, 40, 41, 42, 43, 44, 45, 46, 47, + /* 360 */ 48, 49, 50, 51, 52, 53, 1, 90, 91, 16, + /* 370 */ 29, 19, 19, 117, 93, 94, 35, 100, 66, 67, + /* 380 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 390 */ 62, 79, 96, 62, 117, 17, 16, 18, 19, 19, + /* 400 */ 93, 94, 19, 25, 39, 40, 41, 42, 43, 44, + /* 410 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 1, + /* 420 */ 91, 91, 90, 16, 16, 16, 19, 19, 19, 100, + /* 430 */ 100, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 440 */ 75, 76, 77, 108, 29, 91, 117, 117, 30, 117, + /* 450 */ 115, 29, 113, 114, 100, 20, 96, 35, 40, 41, + /* 460 */ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 470 */ 52, 53, 91, 1, 118, 99, 18, 26, 110, 20, + /* 480 */ 2, 100, 97, 1, 66, 67, 68, 69, 70, 71, + /* 490 */ 72, 73, 74, 75, 76, 77, 1, 112, 117, 17, + /* 500 */ 1, 2, 85, 99, 19, 110, 89, 10, 16, 19, + /* 510 */ 93, 19, 17, 16, 21, 99, 17, 38, 59, 22, + /* 520 */ 23, 29, 105, 106, 107, 28, 109, 35, 18, 32, + /* 530 */ 33, 34, 2, 1, 65, 40, 41, 42, 43, 44, + /* 540 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 17, + /* 550 */ 20, 91, 59, 21, 36, 19, 19, 64, 19, 25, + /* 560 */ 100, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 570 */ 75, 76, 77, 1, 85, 78, 79, 80, 89, 85, + /* 580 */ 19, 92, 93, 89, 59, 63, 21, 93, 19, 17, + /* 590 */ 101, 102, 17, 1, 105, 106, 107, 18, 109, 105, + /* 600 */ 106, 107, 18, 109, 29, 116, 36, 63, 19, 17, + /* 610 */ 35, 1, 40, 41, 42, 43, 44, 45, 46, 47, + /* 620 */ 48, 49, 50, 51, 52, 53, 61, 17, 108, 38, + /* 630 */ 2, 19, 39, 55, 21, 115, 18, 97, 66, 67, + /* 640 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 650 */ 1, 85, 112, 1, 100, 89, 85, 115, 92, 93, + /* 660 */ 89, 110, 112, 111, 93, 91, 17, 101, 102, 17, + /* 670 */ 97, 105, 106, 107, 100, 109, 105, 106, 107, 14, + /* 680 */ 109, 29, 116, 87, 123, 112, 112, 35, 123, 40, + /* 690 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + /* 700 */ 51, 52, 53, 1, 2, 110, 54, 110, 114, 110, + /* 710 */ 123, 123, 97, 97, 97, 66, 67, 68, 69, 70, + /* 720 */ 71, 72, 73, 74, 75, 76, 77, 112, 112, 112, + /* 730 */ 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + /* 740 */ 123, 123, 40, 41, 42, 43, 44, 45, 46, 47, + /* 750 */ 48, 49, 50, 51, 52, 53, 1, 123, 123, 123, + /* 760 */ 123, 123, 123, 123, 123, 97, 97, 97, 66, 67, + /* 770 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 780 */ 112, 112, 112, 123, 123, 123, 123, 123, 123, 123, + /* 790 */ 123, 123, 123, 123, 39, 40, 41, 42, 43, 44, + /* 800 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 123, + /* 810 */ 1, 123, 123, 123, 123, 123, 123, 123, 123, 123, + /* 820 */ 123, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 830 */ 75, 76, 77, 24, 123, 123, 123, 123, 123, 123, + /* 840 */ 123, 123, 123, 123, 123, 123, 123, 123, 123, 40, + /* 850 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + /* 860 */ 51, 52, 53, 1, 123, 123, 123, 123, 123, 123, + /* 870 */ 123, 123, 123, 123, 123, 66, 67, 68, 69, 70, + /* 880 */ 71, 72, 73, 74, 75, 76, 77, 123, 123, 123, + /* 890 */ 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + /* 900 */ 123, 123, 40, 41, 42, 43, 44, 45, 46, 47, + /* 910 */ 48, 49, 50, 51, 52, 53, 123, 123, 123, 123, + /* 920 */ 123, 123, 123, 123, 123, 123, 123, 65, 66, 67, + /* 930 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 940 */ 1, 85, 123, 1, 123, 89, 85, 123, 92, 93, + /* 950 */ 89, 123, 123, 123, 93, 91, 17, 101, 102, 17, + /* 960 */ 123, 105, 106, 107, 100, 109, 105, 106, 107, 123, + /* 970 */ 109, 29, 116, 123, 123, 123, 112, 35, 123, 40, + /* 980 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + /* 990 */ 51, 52, 53, 1, 123, 123, 54, 123, 123, 123, + /* 1000 */ 123, 123, 123, 123, 123, 66, 67, 68, 69, 70, + /* 1010 */ 71, 72, 73, 74, 75, 76, 77, 123, 123, 123, + /* 1020 */ 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + /* 1030 */ 123, 123, 40, 41, 42, 43, 44, 45, 46, 47, + /* 1040 */ 48, 49, 50, 51, 52, 53, 123, 123, 123, 123, + /* 1050 */ 123, 123, 123, 123, 123, 123, 123, 123, 66, 67, + /* 1060 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + /* 1070 */ 123, 123, 123, 40, 41, 42, 43, 44, 45, 46, + /* 1080 */ 47, 48, 49, 50, 51, 52, 53, 123, 123, 123, + /* 1090 */ 123, 123, 123, 123, 123, 123, 123, 123, 123, 66, + /* 1100 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 1110 */ 77, 123, 123, 123, 123, 123, 16, 123, 18, 19, + /* 1120 */ 123, 123, 22, 23, 123, 17, 123, 85, 28, 123, + /* 1130 */ 123, 89, 32, 33, 34, 93, 36, 29, 38, 123, + /* 1140 */ 123, 41, 123, 35, 102, 123, 85, 105, 106, 107, + /* 1150 */ 89, 109, 123, 91, 93, 123, 56, 57, 58, 59, + /* 1160 */ 60, 123, 100, 63, 64, 65, 105, 106, 107, 123, + /* 1170 */ 109, 93, 123, 16, 112, 18, 19, 123, 78, 22, + /* 1180 */ 23, 16, 123, 105, 19, 28, 123, 109, 123, 32, + /* 1190 */ 33, 34, 123, 36, 29, 38, 31, 123, 41, 123, + /* 1200 */ 35, 123, 85, 123, 123, 123, 89, 123, 123, 92, + /* 1210 */ 93, 94, 123, 56, 57, 58, 59, 60, 101, 102, + /* 1220 */ 63, 64, 105, 106, 107, 123, 109, 17, 123, 123, + /* 1230 */ 16, 123, 18, 19, 123, 78, 22, 23, 16, 29, + /* 1240 */ 91, 19, 28, 123, 17, 35, 32, 33, 34, 100, + /* 1250 */ 36, 29, 38, 31, 123, 41, 29, 35, 123, 85, + /* 1260 */ 123, 112, 35, 89, 123, 123, 92, 93, 1, 123, + /* 1270 */ 56, 57, 58, 59, 60, 101, 102, 63, 64, 105, + /* 1280 */ 106, 107, 123, 109, 17, 123, 123, 16, 123, 18, + /* 1290 */ 19, 123, 78, 22, 23, 123, 29, 123, 123, 28, + /* 1300 */ 123, 17, 35, 32, 33, 34, 123, 36, 123, 38, + /* 1310 */ 123, 123, 41, 29, 123, 123, 85, 123, 123, 35, + /* 1320 */ 89, 54, 123, 92, 93, 123, 123, 56, 57, 58, + /* 1330 */ 59, 60, 101, 102, 63, 64, 105, 106, 107, 123, + /* 1340 */ 109, 17, 123, 123, 16, 123, 18, 19, 123, 78, + /* 1350 */ 22, 23, 123, 29, 123, 123, 28, 123, 17, 35, + /* 1360 */ 32, 33, 34, 123, 36, 123, 38, 123, 123, 41, + /* 1370 */ 29, 123, 123, 85, 123, 123, 35, 89, 123, 123, + /* 1380 */ 92, 93, 123, 123, 56, 57, 58, 59, 60, 101, + /* 1390 */ 102, 63, 64, 105, 106, 107, 123, 109, 17, 123, + /* 1400 */ 123, 16, 123, 18, 19, 123, 78, 22, 23, 123, + /* 1410 */ 29, 123, 123, 28, 123, 17, 35, 32, 33, 34, + /* 1420 */ 123, 36, 123, 38, 123, 123, 41, 29, 123, 123, + /* 1430 */ 85, 123, 123, 35, 89, 123, 123, 92, 93, 123, + /* 1440 */ 123, 56, 57, 58, 59, 60, 101, 102, 63, 64, + /* 1450 */ 105, 106, 107, 123, 109, 17, 123, 123, 16, 123, + /* 1460 */ 18, 19, 123, 78, 22, 23, 123, 29, 123, 123, + /* 1470 */ 28, 123, 17, 35, 32, 33, 34, 123, 36, 123, + /* 1480 */ 38, 123, 123, 41, 29, 123, 123, 85, 123, 123, + /* 1490 */ 35, 89, 123, 123, 92, 93, 123, 123, 56, 57, + /* 1500 */ 58, 59, 60, 101, 102, 63, 64, 105, 106, 107, + /* 1510 */ 123, 109, 17, 123, 123, 16, 123, 18, 19, 123, + /* 1520 */ 78, 22, 23, 123, 29, 123, 123, 28, 123, 17, + /* 1530 */ 35, 32, 33, 34, 123, 36, 123, 38, 123, 123, + /* 1540 */ 41, 29, 123, 123, 85, 123, 123, 35, 89, 123, + /* 1550 */ 123, 92, 93, 123, 123, 56, 57, 58, 59, 60, + /* 1560 */ 101, 102, 63, 64, 105, 106, 107, 123, 109, 17, + /* 1570 */ 123, 123, 16, 123, 18, 19, 123, 78, 22, 23, + /* 1580 */ 123, 29, 123, 123, 28, 123, 17, 35, 32, 33, + /* 1590 */ 34, 123, 36, 123, 38, 123, 123, 41, 29, 123, + /* 1600 */ 123, 85, 123, 123, 35, 89, 123, 123, 92, 93, + /* 1610 */ 123, 123, 56, 57, 58, 59, 60, 101, 102, 63, + /* 1620 */ 64, 105, 106, 107, 123, 109, 17, 123, 123, 16, + /* 1630 */ 123, 18, 19, 123, 78, 22, 23, 123, 29, 123, + /* 1640 */ 123, 28, 123, 17, 35, 32, 33, 34, 123, 36, + /* 1650 */ 123, 38, 123, 123, 41, 29, 123, 123, 85, 123, + /* 1660 */ 123, 35, 89, 123, 123, 92, 93, 123, 123, 56, + /* 1670 */ 57, 58, 59, 60, 101, 102, 63, 123, 105, 106, + /* 1680 */ 107, 123, 109, 17, 123, 123, 16, 123, 18, 19, + /* 1690 */ 123, 78, 22, 23, 123, 29, 123, 123, 28, 123, + /* 1700 */ 17, 35, 32, 33, 34, 123, 36, 123, 38, 123, + /* 1710 */ 123, 41, 29, 123, 123, 85, 123, 123, 35, 89, + /* 1720 */ 123, 123, 92, 93, 123, 123, 56, 57, 58, 59, + /* 1730 */ 60, 101, 102, 63, 123, 105, 106, 107, 123, 109, + /* 1740 */ 123, 123, 123, 123, 17, 123, 123, 123, 78, 123, + /* 1750 */ 120, 24, 123, 26, 27, 10, 29, 30, 123, 123, + /* 1760 */ 123, 16, 35, 123, 37, 38, 39, 22, 23, 123, + /* 1770 */ 90, 91, 123, 28, 123, 123, 123, 32, 33, 34, + /* 1780 */ 100, 54, 123, 103, 104, 123, 123, 123, 61, 123, + /* 1790 */ 123, 123, 65, 123, 85, 90, 91, 117, 89, 123, + /* 1800 */ 123, 92, 93, 123, 123, 100, 79, 123, 103, 104, + /* 1810 */ 101, 102, 123, 85, 105, 106, 107, 89, 109, 123, + /* 1820 */ 92, 93, 117, 78, 79, 80, 123, 123, 123, 101, + /* 1830 */ 102, 123, 123, 105, 106, 107, 85, 109, 123, 123, + /* 1840 */ 89, 123, 123, 92, 93, 123, 123, 85, 123, 123, + /* 1850 */ 123, 89, 101, 102, 92, 93, 105, 106, 107, 123, + /* 1860 */ 109, 123, 123, 101, 102, 123, 123, 105, 106, 107, + /* 1870 */ 123, 109, 123, 123, 85, 90, 91, 123, 89, 123, + /* 1880 */ 123, 92, 93, 123, 123, 100, 123, 123, 103, 104, + /* 1890 */ 101, 102, 123, 123, 105, 106, 107, 85, 109, 123, + /* 1900 */ 123, 89, 117, 123, 92, 93, 123, 85, 123, 123, + /* 1910 */ 123, 89, 123, 101, 102, 93, 85, 105, 106, 107, + /* 1920 */ 89, 109, 123, 92, 93, 123, 123, 105, 106, 107, + /* 1930 */ 123, 109, 101, 102, 123, 123, 105, 106, 107, 85, + /* 1940 */ 109, 123, 123, 89, 123, 123, 92, 93, 123, 123, + /* 1950 */ 85, 123, 123, 123, 89, 101, 102, 92, 93, 105, + /* 1960 */ 106, 107, 123, 109, 123, 123, 101, 102, 123, 123, + /* 1970 */ 105, 106, 107, 123, 109, 123, 85, 123, 123, 123, + /* 1980 */ 89, 123, 123, 92, 93, 123, 123, 85, 123, 123, + /* 1990 */ 123, 89, 101, 102, 92, 93, 105, 106, 107, 123, + /* 2000 */ 109, 123, 123, 101, 102, 123, 85, 105, 106, 107, + /* 2010 */ 89, 109, 123, 92, 93, 123, 123, 123, 123, 123, + /* 2020 */ 123, 123, 101, 102, 123, 85, 105, 106, 107, 89, + /* 2030 */ 109, 123, 92, 93, 123, 123, 85, 123, 123, 123, + /* 2040 */ 89, 101, 102, 92, 93, 105, 106, 107, 123, 109, + /* 2050 */ 123, 123, 101, 102, 123, 123, 105, 106, 107, 123, + /* 2060 */ 109, 123, 85, 123, 123, 123, 89, 123, 123, 92, + /* 2070 */ 93, 123, 123, 85, 123, 123, 123, 89, 101, 102, + /* 2080 */ 92, 93, 105, 106, 107, 123, 109, 123, 123, 101, + /* 2090 */ 102, 123, 85, 105, 106, 107, 89, 109, 123, 92, + /* 2100 */ 93, 123, 123, 123, 123, 123, 123, 123, 101, 102, + /* 2110 */ 123, 85, 105, 106, 107, 89, 109, 123, 92, 93, + /* 2120 */ 123, 123, 85, 123, 123, 123, 89, 101, 102, 92, + /* 2130 */ 93, 105, 106, 107, 123, 109, 123, 123, 101, 102, + /* 2140 */ 123, 123, 105, 106, 107, 123, 109, 123, 85, 123, + /* 2150 */ 123, 123, 89, 123, 123, 92, 93, 123, 123, 85, + /* 2160 */ 123, 123, 123, 89, 101, 102, 92, 93, 105, 106, + /* 2170 */ 107, 123, 109, 123, 123, 101, 102, 123, 85, 105, + /* 2180 */ 106, 107, 89, 109, 123, 92, 93, 123, 123, 123, + /* 2190 */ 123, 123, 123, 123, 101, 102, 123, 85, 105, 106, + /* 2200 */ 107, 89, 109, 123, 92, 93, 123, 123, 85, 123, + /* 2210 */ 123, 123, 89, 101, 102, 92, 93, 105, 106, 107, + /* 2220 */ 123, 109, 123, 123, 101, 102, 123, 123, 105, 106, + /* 2230 */ 107, 123, 109, 123, 85, 123, 123, 123, 89, 123, + /* 2240 */ 123, 92, 93, 123, 123, 85, 123, 123, 123, 89, + /* 2250 */ 101, 102, 92, 93, 105, 106, 107, 123, 109, 123, + /* 2260 */ 123, 101, 102, 123, 85, 105, 106, 107, 89, 109, + /* 2270 */ 123, 92, 93, 123, 123, 123, 123, 123, 123, 123, + /* 2280 */ 101, 102, 123, 85, 105, 106, 107, 89, 109, 123, + /* 2290 */ 92, 93, 1, 123, 85, 123, 90, 91, 89, 101, + /* 2300 */ 102, 123, 93, 105, 106, 107, 100, 109, 17, 103, + /* 2310 */ 104, 102, 21, 123, 105, 106, 107, 123, 109, 123, + /* 2320 */ 29, 123, 123, 117, 85, 123, 35, 123, 89, 38, + /* 2330 */ 123, 123, 93, 123, 123, 123, 123, 123, 123, 123, + /* 2340 */ 90, 91, 123, 123, 105, 106, 107, 123, 109, 123, + /* 2350 */ 100, 123, 61, 103, 104, 90, 91, 123, 123, 123, + /* 2360 */ 123, 123, 123, 123, 123, 100, 123, 117, 103, 104, + /* 2370 */ 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + /* 2380 */ 123, 123, 117, +); + const YY_SHIFT_USE_DFLT = -5; + const YY_SHIFT_MAX = 256; + static public $yy_shift_ofst = array( + /* 0 */ -2, 1271, 1157, 1157, 1271, 1157, 1328, 1328, 1100, 1157, + /* 10 */ 1157, 1157, 1157, 1157, 1157, 1157, 1499, 1157, 1157, 1157, + /* 20 */ 1157, 1157, 1556, 1157, 1157, 1157, 1157, 1157, 1157, 1157, + /* 30 */ 1157, 1157, 1157, 1157, 1385, 1214, 1157, 1157, 1157, 1157, + /* 40 */ 1157, 1499, 1214, 1157, 1442, 1442, 1613, 1670, 1670, 1670, + /* 50 */ 1670, 1670, 1670, 206, 153, 76, -1, 259, 259, 259, + /* 60 */ 809, 939, 755, 862, 702, 649, 365, 312, 418, 495, + /* 70 */ 572, 992, 992, 992, 992, 992, 992, 992, 992, 992, + /* 80 */ 992, 992, 992, 992, 992, 992, 992, 992, 992, 992, + /* 90 */ 1033, 1033, 2291, 1267, 106, -2, 1745, 1222, 1165, 157, + /* 100 */ 157, 492, 492, 499, 106, 106, 274, 493, 142, 497, + /* 110 */ 49, 79, 942, 652, 246, 17, 328, 300, 236, 223, + /* 120 */ 80, 147, 532, 1227, 353, 353, 353, 422, 407, 142, + /* 130 */ 353, 353, 610, 353, 341, 565, 379, 353, 380, 142, + /* 140 */ 408, 160, 409, 353, 379, 409, 353, 472, 613, 472, + /* 150 */ 472, 472, 472, 472, 472, 613, 472, -5, 1284, 1210, + /* 160 */ -4, 1108, 0, 156, 575, 1683, 1552, 1512, 1569, 1609, + /* 170 */ 1666, 1324, 1626, 6, 1495, 1398, 1381, 1341, 1438, 1455, + /* 180 */ 73, 482, 73, 204, 592, 204, 204, 204, 164, 204, + /* 190 */ 253, 204, 204, 665, 613, 613, 613, 479, 472, 347, + /* 200 */ 415, 415, 472, 347, -5, -5, -5, -5, -5, 1727, + /* 210 */ 149, 45, 120, 152, 54, 530, 54, 314, 252, 378, + /* 220 */ 306, 459, 258, 303, 239, 331, 522, 536, 469, 537, + /* 230 */ 539, 569, 534, 544, 561, 525, 518, 570, 593, 612, + /* 240 */ 578, 628, 591, 579, 510, 584, 589, 458, 435, 352, + /* 250 */ 485, 478, 451, 479, 490, 383, 618, +); + const YY_REDUCE_USE_DFLT = -96; + const YY_REDUCE_MAX = 208; + static public $yy_reduce_ofst = array( + /* 0 */ 5, -7, 489, 566, 1630, 856, 70, 1117, 1865, 1854, + /* 10 */ 1831, 1812, 1891, 1902, 1977, 1951, 1940, 1921, 1789, 1762, + /* 20 */ 1402, 1345, 1288, 1231, 1459, 1516, 1751, 1728, 1709, 1573, + /* 30 */ 1988, 2007, 2123, 2149, 2160, 2198, 2179, 1174, 2093, 2026, + /* 40 */ 2037, 2063, 2112, 2074, 1042, 2209, 1822, 2239, 1061, 861, + /* 50 */ 494, 417, 571, 2265, 2250, 2206, 1705, 1785, 1680, 1705, + /* 60 */ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + /* 70 */ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + /* 80 */ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + /* 90 */ 128, 128, 277, 224, 40, 154, 200, 864, 1062, 170, + /* 100 */ 330, 574, 1149, 99, 329, 381, 1078, 98, -34, 201, + /* 110 */ 15, 125, 125, 125, -85, 124, 124, 124, 125, -95, + /* 120 */ 125, -95, 332, 354, 573, 616, 617, 460, 615, 307, + /* 130 */ 385, 540, 256, -74, 248, -95, 335, 668, 540, 281, + /* 140 */ 540, 125, 670, 669, 520, 540, 186, 125, 339, 125, + /* 150 */ 125, 125, 125, 125, 125, -95, 125, 125, 554, 554, + /* 160 */ 550, 554, 554, 554, 554, 554, 554, 554, 554, 554, + /* 170 */ 554, 554, 554, 542, 554, 554, 554, 554, 554, 554, + /* 180 */ 595, -33, 551, 552, -33, 552, 552, 552, -33, 552, + /* 190 */ 597, 552, 552, 596, 594, 594, 594, 599, -33, 356, + /* 200 */ 296, 360, -33, 356, 395, 404, 376, 416, 368, +); + static public $yyExpectedTokens = array( + /* 0 */ array(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 22, 23, 28, 32, 33, 34, ), + /* 1 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 2 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 3 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 4 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 5 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 6 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 7 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 8 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 65, 78, ), + /* 9 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 10 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 11 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 12 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 13 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 14 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 15 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 16 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 17 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 18 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 19 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 20 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 21 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 22 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 23 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 24 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 25 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 26 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 27 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 28 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 29 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 30 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 31 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 32 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 33 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 34 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 35 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 36 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 37 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 38 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 39 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 40 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 41 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 42 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 43 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 44 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 45 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 64, 78, ), + /* 46 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 47 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 48 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 49 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 50 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 51 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 52 */ array(16, 18, 19, 22, 23, 28, 32, 33, 34, 36, 38, 41, 56, 57, 58, 59, 60, 63, 78, ), + /* 53 */ array(1, 27, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 54 */ array(1, 17, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 55 */ array(1, 17, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 56 */ array(1, 17, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 57 */ array(1, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 58 */ array(1, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 59 */ array(1, 29, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 60 */ array(1, 24, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 61 */ array(1, 17, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 62 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 63 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 64 */ array(1, 2, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 65 */ array(1, 17, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 66 */ array(1, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 67 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, ), + /* 68 */ array(1, 30, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 69 */ array(1, 17, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 70 */ array(1, 17, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 71 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 72 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 73 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 74 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 75 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 76 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 77 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 78 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 79 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 80 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 81 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 82 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 83 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 84 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 85 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 86 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 87 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 88 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 89 */ array(1, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 90 */ array(40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 91 */ array(40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, ), + /* 92 */ array(1, 17, 21, 29, 35, 38, 61, ), + /* 93 */ array(1, 17, 29, 35, 54, ), + /* 94 */ array(1, 29, 35, ), + /* 95 */ array(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 22, 23, 28, 32, 33, 34, ), + /* 96 */ array(10, 16, 22, 23, 28, 32, 33, 34, 78, 79, 80, ), + /* 97 */ array(16, 19, 29, 31, 35, ), + /* 98 */ array(16, 19, 29, 31, 35, ), + /* 99 */ array(1, 17, 29, 35, ), + /* 100 */ array(1, 17, 29, 35, ), + /* 101 */ array(16, 19, 29, 35, ), + /* 102 */ array(16, 19, 29, 35, ), + /* 103 */ array(1, 2, 17, ), + /* 104 */ array(1, 29, 35, ), + /* 105 */ array(1, 29, 35, ), + /* 106 */ array(18, 19, 63, ), + /* 107 */ array(21, 59, 64, ), + /* 108 */ array(18, 38, ), + /* 109 */ array(10, 16, 22, 23, 28, 32, 33, 34, 78, 79, 80, ), + /* 110 */ array(4, 5, 6, 7, 8, 13, 14, 15, ), + /* 111 */ array(1, 17, 29, 30, 35, 54, ), + /* 112 */ array(1, 17, 29, 35, 54, ), + /* 113 */ array(1, 17, 29, 35, 54, ), + /* 114 */ array(16, 19, 20, 25, ), + /* 115 */ array(16, 19, 20, 62, ), + /* 116 */ array(16, 19, 62, ), + /* 117 */ array(16, 19, 20, ), + /* 118 */ array(1, 31, 54, ), + /* 119 */ array(20, 21, 61, ), + /* 120 */ array(1, 17, 54, ), + /* 121 */ array(20, 21, 61, ), + /* 122 */ array(1, 17, 21, ), + /* 123 */ array(17, 29, 35, ), + /* 124 */ array(16, 19, ), + /* 125 */ array(16, 19, ), + /* 126 */ array(16, 19, ), + /* 127 */ array(29, 35, ), + /* 128 */ array(16, 19, ), + /* 129 */ array(18, 38, ), + /* 130 */ array(16, 19, ), + /* 131 */ array(16, 19, ), + /* 132 */ array(1, 17, ), + /* 133 */ array(16, 19, ), + /* 134 */ array(29, 35, ), + /* 135 */ array(21, 61, ), + /* 136 */ array(18, 19, ), + /* 137 */ array(16, 19, ), + /* 138 */ array(16, 19, ), + /* 139 */ array(18, 38, ), + /* 140 */ array(16, 19, ), + /* 141 */ array(1, 54, ), + /* 142 */ array(16, 19, ), + /* 143 */ array(16, 19, ), + /* 144 */ array(18, 19, ), + /* 145 */ array(16, 19, ), + /* 146 */ array(16, 19, ), + /* 147 */ array(1, ), + /* 148 */ array(21, ), + /* 149 */ array(1, ), + /* 150 */ array(1, ), + /* 151 */ array(1, ), + /* 152 */ array(1, ), + /* 153 */ array(1, ), + /* 154 */ array(1, ), + /* 155 */ array(21, ), + /* 156 */ array(1, ), + /* 157 */ array(), + /* 158 */ array(17, 29, 35, ), + /* 159 */ array(17, 29, 35, ), + /* 160 */ array(16, 19, 62, ), + /* 161 */ array(17, 29, 35, ), + /* 162 */ array(17, 29, 35, ), + /* 163 */ array(17, 29, 35, ), + /* 164 */ array(17, 29, 35, ), + /* 165 */ array(17, 29, 35, ), + /* 166 */ array(17, 29, 35, ), + /* 167 */ array(17, 29, 35, ), + /* 168 */ array(17, 29, 35, ), + /* 169 */ array(17, 29, 35, ), + /* 170 */ array(17, 29, 35, ), + /* 171 */ array(17, 29, 35, ), + /* 172 */ array(17, 29, 35, ), + /* 173 */ array(16, 18, 19, ), + /* 174 */ array(17, 29, 35, ), + /* 175 */ array(17, 29, 35, ), + /* 176 */ array(17, 29, 35, ), + /* 177 */ array(17, 29, 35, ), + /* 178 */ array(17, 29, 35, ), + /* 179 */ array(17, 29, 35, ), + /* 180 */ array(59, 64, ), + /* 181 */ array(1, 17, ), + /* 182 */ array(59, 64, ), + /* 183 */ array(59, 64, ), + /* 184 */ array(1, 17, ), + /* 185 */ array(59, 64, ), + /* 186 */ array(59, 64, ), + /* 187 */ array(59, 64, ), + /* 188 */ array(1, 17, ), + /* 189 */ array(59, 64, ), + /* 190 */ array(16, 38, ), + /* 191 */ array(59, 64, ), + /* 192 */ array(59, 64, ), + /* 193 */ array(14, ), + /* 194 */ array(21, ), + /* 195 */ array(21, ), + /* 196 */ array(21, ), + /* 197 */ array(38, ), + /* 198 */ array(1, ), + /* 199 */ array(2, ), + /* 200 */ array(29, ), + /* 201 */ array(29, ), + /* 202 */ array(1, ), + /* 203 */ array(2, ), + /* 204 */ array(), + /* 205 */ array(), + /* 206 */ array(), + /* 207 */ array(), + /* 208 */ array(), + /* 209 */ array(17, 24, 26, 27, 29, 30, 35, 37, 38, 39, 54, 61, 65, 79, ), + /* 210 */ array(17, 20, 29, 35, 38, 61, ), + /* 211 */ array(38, 59, 61, 65, ), + /* 212 */ array(16, 18, 19, 36, ), + /* 213 */ array(31, 38, 61, ), + /* 214 */ array(38, 61, ), + /* 215 */ array(2, 20, ), + /* 216 */ array(38, 61, ), + /* 217 */ array(24, 37, ), + /* 218 */ array(37, 65, ), + /* 219 */ array(17, 25, ), + /* 220 */ array(37, 39, ), + /* 221 */ array(20, 59, ), + /* 222 */ array(37, 39, ), + /* 223 */ array(37, 39, ), + /* 224 */ array(25, 79, ), + /* 225 */ array(19, 62, ), + /* 226 */ array(63, ), + /* 227 */ array(19, ), + /* 228 */ array(65, ), + /* 229 */ array(19, ), + /* 230 */ array(19, ), + /* 231 */ array(19, ), + /* 232 */ array(25, ), + /* 233 */ array(63, ), + /* 234 */ array(19, ), + /* 235 */ array(59, ), + /* 236 */ array(36, ), + /* 237 */ array(36, ), + /* 238 */ array(39, ), + /* 239 */ array(19, ), + /* 240 */ array(55, ), + /* 241 */ array(2, ), + /* 242 */ array(38, ), + /* 243 */ array(18, ), + /* 244 */ array(18, ), + /* 245 */ array(18, ), + /* 246 */ array(19, ), + /* 247 */ array(18, ), + /* 248 */ array(20, ), + /* 249 */ array(19, ), + /* 250 */ array(19, ), + /* 251 */ array(2, ), + /* 252 */ array(26, ), + /* 253 */ array(38, ), + /* 254 */ array(19, ), + /* 255 */ array(19, ), + /* 256 */ array(18, ), + /* 257 */ array(), + /* 258 */ array(), + /* 259 */ array(), + /* 260 */ array(), + /* 261 */ array(), + /* 262 */ array(), + /* 263 */ array(), + /* 264 */ array(), + /* 265 */ array(), + /* 266 */ array(), + /* 267 */ array(), + /* 268 */ array(), + /* 269 */ array(), + /* 270 */ array(), + /* 271 */ array(), + /* 272 */ array(), + /* 273 */ array(), + /* 274 */ array(), + /* 275 */ array(), + /* 276 */ array(), + /* 277 */ array(), + /* 278 */ array(), + /* 279 */ array(), + /* 280 */ array(), + /* 281 */ array(), + /* 282 */ array(), + /* 283 */ array(), + /* 284 */ array(), + /* 285 */ array(), + /* 286 */ array(), + /* 287 */ array(), + /* 288 */ array(), + /* 289 */ array(), + /* 290 */ array(), + /* 291 */ array(), + /* 292 */ array(), + /* 293 */ array(), + /* 294 */ array(), + /* 295 */ array(), + /* 296 */ array(), + /* 297 */ array(), + /* 298 */ array(), + /* 299 */ array(), + /* 300 */ array(), + /* 301 */ array(), + /* 302 */ array(), + /* 303 */ array(), + /* 304 */ array(), + /* 305 */ array(), + /* 306 */ array(), + /* 307 */ array(), + /* 308 */ array(), + /* 309 */ array(), + /* 310 */ array(), + /* 311 */ array(), + /* 312 */ array(), + /* 313 */ array(), + /* 314 */ array(), + /* 315 */ array(), + /* 316 */ array(), + /* 317 */ array(), + /* 318 */ array(), + /* 319 */ array(), + /* 320 */ array(), + /* 321 */ array(), + /* 322 */ array(), + /* 323 */ array(), + /* 324 */ array(), + /* 325 */ array(), + /* 326 */ array(), + /* 327 */ array(), + /* 328 */ array(), + /* 329 */ array(), + /* 330 */ array(), + /* 331 */ array(), + /* 332 */ array(), + /* 333 */ array(), + /* 334 */ array(), + /* 335 */ array(), + /* 336 */ array(), + /* 337 */ array(), + /* 338 */ array(), + /* 339 */ array(), + /* 340 */ array(), + /* 341 */ array(), + /* 342 */ array(), + /* 343 */ array(), + /* 344 */ array(), + /* 345 */ array(), + /* 346 */ array(), + /* 347 */ array(), + /* 348 */ array(), + /* 349 */ array(), + /* 350 */ array(), + /* 351 */ array(), + /* 352 */ array(), + /* 353 */ array(), + /* 354 */ array(), + /* 355 */ array(), + /* 356 */ array(), + /* 357 */ array(), + /* 358 */ array(), + /* 359 */ array(), + /* 360 */ array(), + /* 361 */ array(), + /* 362 */ array(), + /* 363 */ array(), + /* 364 */ array(), + /* 365 */ array(), + /* 366 */ array(), + /* 367 */ array(), + /* 368 */ array(), + /* 369 */ array(), + /* 370 */ array(), + /* 371 */ array(), + /* 372 */ array(), + /* 373 */ array(), + /* 374 */ array(), + /* 375 */ array(), + /* 376 */ array(), + /* 377 */ array(), + /* 378 */ array(), + /* 379 */ array(), + /* 380 */ array(), + /* 381 */ array(), + /* 382 */ array(), + /* 383 */ array(), + /* 384 */ array(), + /* 385 */ array(), + /* 386 */ array(), + /* 387 */ array(), + /* 388 */ array(), + /* 389 */ array(), + /* 390 */ array(), +); + static public $yy_default = array( + /* 0 */ 394, 578, 549, 549, 595, 549, 595, 595, 595, 595, + /* 10 */ 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + /* 20 */ 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + /* 30 */ 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + /* 40 */ 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + /* 50 */ 595, 595, 595, 455, 595, 595, 595, 455, 455, 455, + /* 60 */ 595, 595, 595, 595, 595, 595, 595, 595, 460, 595, + /* 70 */ 595, 466, 465, 484, 547, 579, 581, 548, 580, 489, + /* 80 */ 488, 480, 479, 481, 457, 485, 462, 476, 460, 437, + /* 90 */ 492, 493, 504, 468, 455, 391, 595, 455, 455, 475, + /* 100 */ 512, 455, 455, 595, 455, 455, 595, 561, 595, 595, + /* 110 */ 595, 468, 468, 468, 595, 522, 522, 522, 468, 513, + /* 120 */ 468, 513, 595, 595, 595, 595, 595, 455, 595, 595, + /* 130 */ 595, 595, 595, 595, 455, 513, 595, 595, 595, 595, + /* 140 */ 595, 468, 595, 595, 595, 595, 522, 473, 558, 491, + /* 150 */ 478, 472, 497, 495, 496, 513, 471, 556, 595, 595, + /* 160 */ 523, 595, 595, 595, 595, 595, 595, 595, 595, 595, + /* 170 */ 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + /* 180 */ 516, 595, 518, 519, 595, 520, 540, 542, 595, 539, + /* 190 */ 522, 517, 541, 410, 562, 559, 536, 522, 475, 551, + /* 200 */ 594, 594, 512, 550, 522, 555, 555, 555, 522, 470, + /* 210 */ 504, 504, 595, 504, 490, 534, 504, 595, 595, 494, + /* 220 */ 595, 500, 595, 595, 494, 595, 595, 595, 595, 595, + /* 230 */ 595, 595, 494, 595, 595, 500, 502, 595, 595, 595, + /* 240 */ 506, 534, 560, 595, 595, 595, 595, 595, 595, 595, + /* 250 */ 595, 534, 463, 534, 595, 595, 595, 401, 543, 400, + /* 260 */ 402, 546, 445, 398, 397, 393, 464, 438, 593, 467, + /* 270 */ 435, 395, 440, 434, 439, 396, 399, 456, 531, 420, + /* 280 */ 529, 392, 528, 506, 527, 535, 444, 557, 545, 544, + /* 290 */ 530, 412, 453, 526, 505, 419, 507, 525, 532, 470, + /* 300 */ 514, 521, 524, 508, 510, 482, 483, 416, 415, 417, + /* 310 */ 418, 477, 511, 515, 538, 469, 509, 534, 533, 432, + /* 320 */ 446, 447, 443, 442, 436, 454, 433, 441, 554, 448, + /* 330 */ 498, 499, 501, 503, 452, 451, 449, 450, 552, 553, + /* 340 */ 486, 487, 589, 430, 582, 583, 584, 431, 429, 426, + /* 350 */ 537, 427, 428, 406, 587, 575, 404, 577, 576, 405, + /* 360 */ 585, 586, 588, 591, 592, 425, 424, 569, 568, 570, + /* 370 */ 571, 572, 567, 566, 414, 563, 564, 565, 573, 574, + /* 380 */ 422, 590, 407, 423, 421, 408, 474, 413, 411, 409, + /* 390 */ 403, +); + const YYNOCODE = 124; + const YYSTACKDEPTH = 100; + const YYNSTATE = 391; + const YYNRULE = 204; + const YYERRORSYMBOL = 81; + const YYERRSYMDT = 'yy0'; + const YYFALLBACK = 0; + static public $yyFallback = array( + ); + static function Trace($TraceFILE, $zTracePrompt) + { + if (!$TraceFILE) { + $zTracePrompt = 0; + } elseif (!$zTracePrompt) { + $TraceFILE = 0; + } + self::$yyTraceFILE = $TraceFILE; + self::$yyTracePrompt = $zTracePrompt; + } + + static function PrintTrace() + { + self::$yyTraceFILE = fopen('php://output', 'w'); + self::$yyTracePrompt = '<br>'; + } + + static public $yyTraceFILE; + static public $yyTracePrompt; + public $yyidx; /* Index of top element in stack */ + public $yyerrcnt; /* Shifts left before out of the error */ + public $yystack = array(); /* The parser's stack */ + + public $yyTokenName = array( + '$', 'VERT', 'COLON', 'COMMENT', + 'PHPSTARTTAG', 'PHPENDTAG', 'ASPSTARTTAG', 'ASPENDTAG', + 'FAKEPHPSTARTTAG', 'XMLTAG', 'TEXT', 'STRIPON', + 'STRIPOFF', 'LITERALSTART', 'LITERALEND', 'LITERAL', + 'LDEL', 'RDEL', 'DOLLAR', 'ID', + 'EQUAL', 'PTR', 'LDELIF', 'LDELFOR', + 'SEMICOLON', 'INCDEC', 'TO', 'STEP', + 'LDELFOREACH', 'SPACE', 'AS', 'APTR', + 'LDELSETFILTER', 'SMARTYBLOCKCHILD', 'LDELSLASH', 'ATTR', + 'INTEGER', 'COMMA', 'OPENP', 'CLOSEP', + 'MATH', 'UNIMATH', 'ANDSYM', 'ISIN', + 'ISDIVBY', 'ISNOTDIVBY', 'ISEVEN', 'ISNOTEVEN', + 'ISEVENBY', 'ISNOTEVENBY', 'ISODD', 'ISNOTODD', + 'ISODDBY', 'ISNOTODDBY', 'INSTANCEOF', 'QMARK', + 'NOT', 'TYPECAST', 'HEX', 'DOT', + 'SINGLEQUOTESTRING', 'DOUBLECOLON', 'AT', 'HATCH', + 'OPENB', 'CLOSEB', 'EQUALS', 'NOTEQUALS', + 'GREATERTHAN', 'LESSTHAN', 'GREATEREQUAL', 'LESSEQUAL', + 'IDENTITY', 'NONEIDENTITY', 'MOD', 'LAND', + 'LOR', 'LXOR', 'QUOTE', 'BACKTICK', + 'DOLLARID', 'error', 'start', 'template', + 'template_element', 'smartytag', 'literal', 'literal_elements', + 'literal_element', 'value', 'modifierlist', 'attributes', + 'expr', 'varindexed', 'statement', 'statements', + 'optspace', 'varvar', 'foraction', 'modparameters', + 'attribute', 'ternary', 'array', 'ifcond', + 'lop', 'variable', 'function', 'doublequoted_with_quotes', + 'static_class_access', 'object', 'arrayindex', 'indexdef', + 'varvarele', 'objectchain', 'objectelement', 'method', + 'params', 'modifier', 'modparameter', 'arrayelements', + 'arrayelement', 'doublequoted', 'doublequotedcontent', + ); + + static public $yyRuleName = array( + /* 0 */ "start ::= template", + /* 1 */ "template ::= template_element", + /* 2 */ "template ::= template template_element", + /* 3 */ "template ::=", + /* 4 */ "template_element ::= smartytag", + /* 5 */ "template_element ::= COMMENT", + /* 6 */ "template_element ::= literal", + /* 7 */ "template_element ::= PHPSTARTTAG", + /* 8 */ "template_element ::= PHPENDTAG", + /* 9 */ "template_element ::= ASPSTARTTAG", + /* 10 */ "template_element ::= ASPENDTAG", + /* 11 */ "template_element ::= FAKEPHPSTARTTAG", + /* 12 */ "template_element ::= XMLTAG", + /* 13 */ "template_element ::= TEXT", + /* 14 */ "template_element ::= STRIPON", + /* 15 */ "template_element ::= STRIPOFF", + /* 16 */ "literal ::= LITERALSTART LITERALEND", + /* 17 */ "literal ::= LITERALSTART literal_elements LITERALEND", + /* 18 */ "literal_elements ::= literal_elements literal_element", + /* 19 */ "literal_elements ::=", + /* 20 */ "literal_element ::= literal", + /* 21 */ "literal_element ::= LITERAL", + /* 22 */ "literal_element ::= PHPSTARTTAG", + /* 23 */ "literal_element ::= FAKEPHPSTARTTAG", + /* 24 */ "literal_element ::= PHPENDTAG", + /* 25 */ "literal_element ::= ASPSTARTTAG", + /* 26 */ "literal_element ::= ASPENDTAG", + /* 27 */ "smartytag ::= LDEL value RDEL", + /* 28 */ "smartytag ::= LDEL value modifierlist attributes RDEL", + /* 29 */ "smartytag ::= LDEL value attributes RDEL", + /* 30 */ "smartytag ::= LDEL expr modifierlist attributes RDEL", + /* 31 */ "smartytag ::= LDEL expr attributes RDEL", + /* 32 */ "smartytag ::= LDEL DOLLAR ID EQUAL value RDEL", + /* 33 */ "smartytag ::= LDEL DOLLAR ID EQUAL expr RDEL", + /* 34 */ "smartytag ::= LDEL DOLLAR ID EQUAL expr attributes RDEL", + /* 35 */ "smartytag ::= LDEL varindexed EQUAL expr attributes RDEL", + /* 36 */ "smartytag ::= LDEL ID attributes RDEL", + /* 37 */ "smartytag ::= LDEL ID RDEL", + /* 38 */ "smartytag ::= LDEL ID PTR ID attributes RDEL", + /* 39 */ "smartytag ::= LDEL ID modifierlist attributes RDEL", + /* 40 */ "smartytag ::= LDEL ID PTR ID modifierlist attributes RDEL", + /* 41 */ "smartytag ::= LDELIF expr RDEL", + /* 42 */ "smartytag ::= LDELIF expr attributes RDEL", + /* 43 */ "smartytag ::= LDELIF statement RDEL", + /* 44 */ "smartytag ::= LDELIF statement attributes RDEL", + /* 45 */ "smartytag ::= LDELFOR statements SEMICOLON optspace expr SEMICOLON optspace DOLLAR varvar foraction attributes RDEL", + /* 46 */ "foraction ::= EQUAL expr", + /* 47 */ "foraction ::= INCDEC", + /* 48 */ "smartytag ::= LDELFOR statement TO expr attributes RDEL", + /* 49 */ "smartytag ::= LDELFOR statement TO expr STEP expr attributes RDEL", + /* 50 */ "smartytag ::= LDELFOREACH attributes RDEL", + /* 51 */ "smartytag ::= LDELFOREACH SPACE value AS DOLLAR varvar attributes RDEL", + /* 52 */ "smartytag ::= LDELFOREACH SPACE value AS DOLLAR varvar APTR DOLLAR varvar attributes RDEL", + /* 53 */ "smartytag ::= LDELFOREACH SPACE expr AS DOLLAR varvar attributes RDEL", + /* 54 */ "smartytag ::= LDELFOREACH SPACE expr AS DOLLAR varvar APTR DOLLAR varvar attributes RDEL", + /* 55 */ "smartytag ::= LDELSETFILTER ID modparameters RDEL", + /* 56 */ "smartytag ::= LDELSETFILTER ID modparameters modifierlist RDEL", + /* 57 */ "smartytag ::= SMARTYBLOCKCHILD", + /* 58 */ "smartytag ::= LDELSLASH ID RDEL", + /* 59 */ "smartytag ::= LDELSLASH ID modifierlist RDEL", + /* 60 */ "smartytag ::= LDELSLASH ID PTR ID RDEL", + /* 61 */ "smartytag ::= LDELSLASH ID PTR ID modifierlist RDEL", + /* 62 */ "attributes ::= attributes attribute", + /* 63 */ "attributes ::= attribute", + /* 64 */ "attributes ::=", + /* 65 */ "attribute ::= SPACE ID EQUAL ID", + /* 66 */ "attribute ::= ATTR expr", + /* 67 */ "attribute ::= ATTR value", + /* 68 */ "attribute ::= SPACE ID", + /* 69 */ "attribute ::= SPACE expr", + /* 70 */ "attribute ::= SPACE value", + /* 71 */ "attribute ::= SPACE INTEGER EQUAL expr", + /* 72 */ "statements ::= statement", + /* 73 */ "statements ::= statements COMMA statement", + /* 74 */ "statement ::= DOLLAR varvar EQUAL expr", + /* 75 */ "statement ::= varindexed EQUAL expr", + /* 76 */ "statement ::= OPENP statement CLOSEP", + /* 77 */ "expr ::= value", + /* 78 */ "expr ::= ternary", + /* 79 */ "expr ::= DOLLAR ID COLON ID", + /* 80 */ "expr ::= expr MATH value", + /* 81 */ "expr ::= expr UNIMATH value", + /* 82 */ "expr ::= expr ANDSYM value", + /* 83 */ "expr ::= array", + /* 84 */ "expr ::= expr modifierlist", + /* 85 */ "expr ::= expr ifcond expr", + /* 86 */ "expr ::= expr ISIN array", + /* 87 */ "expr ::= expr ISIN value", + /* 88 */ "expr ::= expr lop expr", + /* 89 */ "expr ::= expr ISDIVBY expr", + /* 90 */ "expr ::= expr ISNOTDIVBY expr", + /* 91 */ "expr ::= expr ISEVEN", + /* 92 */ "expr ::= expr ISNOTEVEN", + /* 93 */ "expr ::= expr ISEVENBY expr", + /* 94 */ "expr ::= expr ISNOTEVENBY expr", + /* 95 */ "expr ::= expr ISODD", + /* 96 */ "expr ::= expr ISNOTODD", + /* 97 */ "expr ::= expr ISODDBY expr", + /* 98 */ "expr ::= expr ISNOTODDBY expr", + /* 99 */ "expr ::= value INSTANCEOF ID", + /* 100 */ "expr ::= value INSTANCEOF value", + /* 101 */ "ternary ::= OPENP expr CLOSEP QMARK DOLLAR ID COLON expr", + /* 102 */ "ternary ::= OPENP expr CLOSEP QMARK expr COLON expr", + /* 103 */ "value ::= variable", + /* 104 */ "value ::= UNIMATH value", + /* 105 */ "value ::= NOT value", + /* 106 */ "value ::= TYPECAST value", + /* 107 */ "value ::= variable INCDEC", + /* 108 */ "value ::= HEX", + /* 109 */ "value ::= INTEGER", + /* 110 */ "value ::= INTEGER DOT INTEGER", + /* 111 */ "value ::= INTEGER DOT", + /* 112 */ "value ::= DOT INTEGER", + /* 113 */ "value ::= ID", + /* 114 */ "value ::= function", + /* 115 */ "value ::= OPENP expr CLOSEP", + /* 116 */ "value ::= SINGLEQUOTESTRING", + /* 117 */ "value ::= doublequoted_with_quotes", + /* 118 */ "value ::= ID DOUBLECOLON static_class_access", + /* 119 */ "value ::= varindexed DOUBLECOLON static_class_access", + /* 120 */ "value ::= smartytag", + /* 121 */ "value ::= value modifierlist", + /* 122 */ "variable ::= varindexed", + /* 123 */ "variable ::= DOLLAR varvar AT ID", + /* 124 */ "variable ::= object", + /* 125 */ "variable ::= HATCH ID HATCH", + /* 126 */ "variable ::= HATCH ID HATCH arrayindex", + /* 127 */ "variable ::= HATCH variable HATCH", + /* 128 */ "variable ::= HATCH variable HATCH arrayindex", + /* 129 */ "varindexed ::= DOLLAR varvar arrayindex", + /* 130 */ "arrayindex ::= arrayindex indexdef", + /* 131 */ "arrayindex ::=", + /* 132 */ "indexdef ::= DOT DOLLAR varvar", + /* 133 */ "indexdef ::= DOT DOLLAR varvar AT ID", + /* 134 */ "indexdef ::= DOT ID", + /* 135 */ "indexdef ::= DOT INTEGER", + /* 136 */ "indexdef ::= DOT LDEL expr RDEL", + /* 137 */ "indexdef ::= OPENB ID CLOSEB", + /* 138 */ "indexdef ::= OPENB ID DOT ID CLOSEB", + /* 139 */ "indexdef ::= OPENB expr CLOSEB", + /* 140 */ "indexdef ::= OPENB CLOSEB", + /* 141 */ "varvar ::= varvarele", + /* 142 */ "varvar ::= varvar varvarele", + /* 143 */ "varvarele ::= ID", + /* 144 */ "varvarele ::= LDEL expr RDEL", + /* 145 */ "object ::= varindexed objectchain", + /* 146 */ "objectchain ::= objectelement", + /* 147 */ "objectchain ::= objectchain objectelement", + /* 148 */ "objectelement ::= PTR ID arrayindex", + /* 149 */ "objectelement ::= PTR DOLLAR varvar arrayindex", + /* 150 */ "objectelement ::= PTR LDEL expr RDEL arrayindex", + /* 151 */ "objectelement ::= PTR ID LDEL expr RDEL arrayindex", + /* 152 */ "objectelement ::= PTR method", + /* 153 */ "function ::= ID OPENP params CLOSEP", + /* 154 */ "method ::= ID OPENP params CLOSEP", + /* 155 */ "method ::= DOLLAR ID OPENP params CLOSEP", + /* 156 */ "params ::= params COMMA expr", + /* 157 */ "params ::= expr", + /* 158 */ "params ::=", + /* 159 */ "modifierlist ::= modifierlist modifier modparameters", + /* 160 */ "modifierlist ::= modifier modparameters", + /* 161 */ "modifier ::= VERT AT ID", + /* 162 */ "modifier ::= VERT ID", + /* 163 */ "modparameters ::= modparameters modparameter", + /* 164 */ "modparameters ::=", + /* 165 */ "modparameter ::= COLON value", + /* 166 */ "modparameter ::= COLON array", + /* 167 */ "static_class_access ::= method", + /* 168 */ "static_class_access ::= method objectchain", + /* 169 */ "static_class_access ::= ID", + /* 170 */ "static_class_access ::= DOLLAR ID arrayindex", + /* 171 */ "static_class_access ::= DOLLAR ID arrayindex objectchain", + /* 172 */ "ifcond ::= EQUALS", + /* 173 */ "ifcond ::= NOTEQUALS", + /* 174 */ "ifcond ::= GREATERTHAN", + /* 175 */ "ifcond ::= LESSTHAN", + /* 176 */ "ifcond ::= GREATEREQUAL", + /* 177 */ "ifcond ::= LESSEQUAL", + /* 178 */ "ifcond ::= IDENTITY", + /* 179 */ "ifcond ::= NONEIDENTITY", + /* 180 */ "ifcond ::= MOD", + /* 181 */ "lop ::= LAND", + /* 182 */ "lop ::= LOR", + /* 183 */ "lop ::= LXOR", + /* 184 */ "array ::= OPENB arrayelements CLOSEB", + /* 185 */ "arrayelements ::= arrayelement", + /* 186 */ "arrayelements ::= arrayelements COMMA arrayelement", + /* 187 */ "arrayelements ::=", + /* 188 */ "arrayelement ::= value APTR expr", + /* 189 */ "arrayelement ::= ID APTR expr", + /* 190 */ "arrayelement ::= expr", + /* 191 */ "doublequoted_with_quotes ::= QUOTE QUOTE", + /* 192 */ "doublequoted_with_quotes ::= QUOTE doublequoted QUOTE", + /* 193 */ "doublequoted ::= doublequoted doublequotedcontent", + /* 194 */ "doublequoted ::= doublequotedcontent", + /* 195 */ "doublequotedcontent ::= BACKTICK variable BACKTICK", + /* 196 */ "doublequotedcontent ::= BACKTICK expr BACKTICK", + /* 197 */ "doublequotedcontent ::= DOLLARID", + /* 198 */ "doublequotedcontent ::= LDEL variable RDEL", + /* 199 */ "doublequotedcontent ::= LDEL expr RDEL", + /* 200 */ "doublequotedcontent ::= smartytag", + /* 201 */ "doublequotedcontent ::= TEXT", + /* 202 */ "optspace ::= SPACE", + /* 203 */ "optspace ::=", + ); + + function tokenName($tokenType) + { + if ($tokenType === 0) { + return 'End of Input'; + } + if ($tokenType > 0 && $tokenType < count($this->yyTokenName)) { + return $this->yyTokenName[$tokenType]; + } else { + return "Unknown"; + } + } + + static function yy_destructor($yymajor, $yypminor) + { + switch ($yymajor) { + default: break; /* If no destructor action specified: do nothing */ + } + } + + function yy_pop_parser_stack() + { + if (!count($this->yystack)) { + return; + } + $yytos = array_pop($this->yystack); + if (self::$yyTraceFILE && $this->yyidx >= 0) { + fwrite(self::$yyTraceFILE, + self::$yyTracePrompt . 'Popping ' . $this->yyTokenName[$yytos->major] . + "\n"); + } + $yymajor = $yytos->major; + self::yy_destructor($yymajor, $yytos->minor); + $this->yyidx--; + return $yymajor; + } + + function __destruct() + { + while ($this->yystack !== Array()) { + $this->yy_pop_parser_stack(); + } + if (is_resource(self::$yyTraceFILE)) { + fclose(self::$yyTraceFILE); + } + } + + function yy_get_expected_tokens($token) + { + $state = $this->yystack[$this->yyidx]->stateno; + $expected = self::$yyExpectedTokens[$state]; + if (in_array($token, self::$yyExpectedTokens[$state], true)) { + return $expected; + } + $stack = $this->yystack; + $yyidx = $this->yyidx; + do { + $yyact = $this->yy_find_shift_action($token); + if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) { + // reduce action + $done = 0; + do { + if ($done++ == 100) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // too much recursion prevents proper detection + // so give up + return array_unique($expected); + } + $yyruleno = $yyact - self::YYNSTATE; + $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs']; + $nextstate = $this->yy_find_reduce_action( + $this->yystack[$this->yyidx]->stateno, + self::$yyRuleInfo[$yyruleno]['lhs']); + if (isset(self::$yyExpectedTokens[$nextstate])) { + $expected = array_merge($expected, self::$yyExpectedTokens[$nextstate]); + if (in_array($token, + self::$yyExpectedTokens[$nextstate], true)) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + return array_unique($expected); + } + } + if ($nextstate < self::YYNSTATE) { + // we need to shift a non-terminal + $this->yyidx++; + $x = new TP_yyStackEntry; + $x->stateno = $nextstate; + $x->major = self::$yyRuleInfo[$yyruleno]['lhs']; + $this->yystack[$this->yyidx] = $x; + continue 2; + } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // the last token was just ignored, we can't accept + // by ignoring input, this is in essence ignoring a + // syntax error! + return array_unique($expected); + } elseif ($nextstate === self::YY_NO_ACTION) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // input accepted, but not shifted (I guess) + return $expected; + } else { + $yyact = $nextstate; + } + } while (true); + } + break; + } while (true); + $this->yyidx = $yyidx; + $this->yystack = $stack; + return array_unique($expected); + } + + function yy_is_expected_token($token) + { + if ($token === 0) { + return true; // 0 is not part of this + } + $state = $this->yystack[$this->yyidx]->stateno; + if (in_array($token, self::$yyExpectedTokens[$state], true)) { + return true; + } + $stack = $this->yystack; + $yyidx = $this->yyidx; + do { + $yyact = $this->yy_find_shift_action($token); + if ($yyact >= self::YYNSTATE && $yyact < self::YYNSTATE + self::YYNRULE) { + // reduce action + $done = 0; + do { + if ($done++ == 100) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // too much recursion prevents proper detection + // so give up + return true; + } + $yyruleno = $yyact - self::YYNSTATE; + $this->yyidx -= self::$yyRuleInfo[$yyruleno]['rhs']; + $nextstate = $this->yy_find_reduce_action( + $this->yystack[$this->yyidx]->stateno, + self::$yyRuleInfo[$yyruleno]['lhs']); + if (isset(self::$yyExpectedTokens[$nextstate]) && + in_array($token, self::$yyExpectedTokens[$nextstate], true)) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + return true; + } + if ($nextstate < self::YYNSTATE) { + // we need to shift a non-terminal + $this->yyidx++; + $x = new TP_yyStackEntry; + $x->stateno = $nextstate; + $x->major = self::$yyRuleInfo[$yyruleno]['lhs']; + $this->yystack[$this->yyidx] = $x; + continue 2; + } elseif ($nextstate == self::YYNSTATE + self::YYNRULE + 1) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + if (!$token) { + // end of input: this is valid + return true; + } + // the last token was just ignored, we can't accept + // by ignoring input, this is in essence ignoring a + // syntax error! + return false; + } elseif ($nextstate === self::YY_NO_ACTION) { + $this->yyidx = $yyidx; + $this->yystack = $stack; + // input accepted, but not shifted (I guess) + return true; + } else { + $yyact = $nextstate; + } + } while (true); + } + break; + } while (true); + $this->yyidx = $yyidx; + $this->yystack = $stack; + return true; + } + + function yy_find_shift_action($iLookAhead) + { + $stateno = $this->yystack[$this->yyidx]->stateno; + + /* if ($this->yyidx < 0) return self::YY_NO_ACTION; */ + if (!isset(self::$yy_shift_ofst[$stateno])) { + // no shift actions + return self::$yy_default[$stateno]; + } + $i = self::$yy_shift_ofst[$stateno]; + if ($i === self::YY_SHIFT_USE_DFLT) { + return self::$yy_default[$stateno]; + } + if ($iLookAhead == self::YYNOCODE) { + return self::YY_NO_ACTION; + } + $i += $iLookAhead; + if ($i < 0 || $i >= self::YY_SZ_ACTTAB || + self::$yy_lookahead[$i] != $iLookAhead) { + if (count(self::$yyFallback) && $iLookAhead < count(self::$yyFallback) + && ($iFallback = self::$yyFallback[$iLookAhead]) != 0) { + if (self::$yyTraceFILE) { + fwrite(self::$yyTraceFILE, self::$yyTracePrompt . "FALLBACK " . + $this->yyTokenName[$iLookAhead] . " => " . + $this->yyTokenName[$iFallback] . "\n"); + } + return $this->yy_find_shift_action($iFallback); + } + return self::$yy_default[$stateno]; + } else { + return self::$yy_action[$i]; + } + } + + function yy_find_reduce_action($stateno, $iLookAhead) + { + /* $stateno = $this->yystack[$this->yyidx]->stateno; */ + + if (!isset(self::$yy_reduce_ofst[$stateno])) { + return self::$yy_default[$stateno]; + } + $i = self::$yy_reduce_ofst[$stateno]; + if ($i == self::YY_REDUCE_USE_DFLT) { + return self::$yy_default[$stateno]; + } + if ($iLookAhead == self::YYNOCODE) { + return self::YY_NO_ACTION; + } + $i += $iLookAhead; + if ($i < 0 || $i >= self::YY_SZ_ACTTAB || + self::$yy_lookahead[$i] != $iLookAhead) { + return self::$yy_default[$stateno]; + } else { + return self::$yy_action[$i]; + } + } + + function yy_shift($yyNewState, $yyMajor, $yypMinor) + { + $this->yyidx++; + if ($this->yyidx >= self::YYSTACKDEPTH) { + $this->yyidx--; + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sStack Overflow!\n", self::$yyTracePrompt); + } + while ($this->yyidx >= 0) { + $this->yy_pop_parser_stack(); + } +#line 84 "smarty_internal_templateparser.y" + + $this->internalError = true; + $this->compiler->trigger_template_error("Stack overflow in template parser"); +#line 1724 "smarty_internal_templateparser.php" + return; + } + $yytos = new TP_yyStackEntry; + $yytos->stateno = $yyNewState; + $yytos->major = $yyMajor; + $yytos->minor = $yypMinor; + array_push($this->yystack, $yytos); + if (self::$yyTraceFILE && $this->yyidx > 0) { + fprintf(self::$yyTraceFILE, "%sShift %d\n", self::$yyTracePrompt, + $yyNewState); + fprintf(self::$yyTraceFILE, "%sStack:", self::$yyTracePrompt); + for($i = 1; $i <= $this->yyidx; $i++) { + fprintf(self::$yyTraceFILE, " %s", + $this->yyTokenName[$this->yystack[$i]->major]); + } + fwrite(self::$yyTraceFILE,"\n"); + } + } + + static public $yyRuleInfo = array( + array( 'lhs' => 82, 'rhs' => 1 ), + array( 'lhs' => 83, 'rhs' => 1 ), + array( 'lhs' => 83, 'rhs' => 2 ), + array( 'lhs' => 83, 'rhs' => 0 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 86, 'rhs' => 2 ), + array( 'lhs' => 86, 'rhs' => 3 ), + array( 'lhs' => 87, 'rhs' => 2 ), + array( 'lhs' => 87, 'rhs' => 0 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 88, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 3 ), + array( 'lhs' => 85, 'rhs' => 5 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 5 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 6 ), + array( 'lhs' => 85, 'rhs' => 6 ), + array( 'lhs' => 85, 'rhs' => 7 ), + array( 'lhs' => 85, 'rhs' => 6 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 3 ), + array( 'lhs' => 85, 'rhs' => 6 ), + array( 'lhs' => 85, 'rhs' => 5 ), + array( 'lhs' => 85, 'rhs' => 7 ), + array( 'lhs' => 85, 'rhs' => 3 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 3 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 12 ), + array( 'lhs' => 98, 'rhs' => 2 ), + array( 'lhs' => 98, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 6 ), + array( 'lhs' => 85, 'rhs' => 8 ), + array( 'lhs' => 85, 'rhs' => 3 ), + array( 'lhs' => 85, 'rhs' => 8 ), + array( 'lhs' => 85, 'rhs' => 11 ), + array( 'lhs' => 85, 'rhs' => 8 ), + array( 'lhs' => 85, 'rhs' => 11 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 5 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 3 ), + array( 'lhs' => 85, 'rhs' => 4 ), + array( 'lhs' => 85, 'rhs' => 5 ), + array( 'lhs' => 85, 'rhs' => 6 ), + array( 'lhs' => 91, 'rhs' => 2 ), + array( 'lhs' => 91, 'rhs' => 1 ), + array( 'lhs' => 91, 'rhs' => 0 ), + array( 'lhs' => 100, 'rhs' => 4 ), + array( 'lhs' => 100, 'rhs' => 2 ), + array( 'lhs' => 100, 'rhs' => 2 ), + array( 'lhs' => 100, 'rhs' => 2 ), + array( 'lhs' => 100, 'rhs' => 2 ), + array( 'lhs' => 100, 'rhs' => 2 ), + array( 'lhs' => 100, 'rhs' => 4 ), + array( 'lhs' => 95, 'rhs' => 1 ), + array( 'lhs' => 95, 'rhs' => 3 ), + array( 'lhs' => 94, 'rhs' => 4 ), + array( 'lhs' => 94, 'rhs' => 3 ), + array( 'lhs' => 94, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 1 ), + array( 'lhs' => 92, 'rhs' => 1 ), + array( 'lhs' => 92, 'rhs' => 4 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 1 ), + array( 'lhs' => 92, 'rhs' => 2 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 2 ), + array( 'lhs' => 92, 'rhs' => 2 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 2 ), + array( 'lhs' => 92, 'rhs' => 2 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 92, 'rhs' => 3 ), + array( 'lhs' => 101, 'rhs' => 8 ), + array( 'lhs' => 101, 'rhs' => 7 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 3 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 3 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 3 ), + array( 'lhs' => 89, 'rhs' => 3 ), + array( 'lhs' => 89, 'rhs' => 1 ), + array( 'lhs' => 89, 'rhs' => 2 ), + array( 'lhs' => 105, 'rhs' => 1 ), + array( 'lhs' => 105, 'rhs' => 4 ), + array( 'lhs' => 105, 'rhs' => 1 ), + array( 'lhs' => 105, 'rhs' => 3 ), + array( 'lhs' => 105, 'rhs' => 4 ), + array( 'lhs' => 105, 'rhs' => 3 ), + array( 'lhs' => 105, 'rhs' => 4 ), + array( 'lhs' => 93, 'rhs' => 3 ), + array( 'lhs' => 110, 'rhs' => 2 ), + array( 'lhs' => 110, 'rhs' => 0 ), + array( 'lhs' => 111, 'rhs' => 3 ), + array( 'lhs' => 111, 'rhs' => 5 ), + array( 'lhs' => 111, 'rhs' => 2 ), + array( 'lhs' => 111, 'rhs' => 2 ), + array( 'lhs' => 111, 'rhs' => 4 ), + array( 'lhs' => 111, 'rhs' => 3 ), + array( 'lhs' => 111, 'rhs' => 5 ), + array( 'lhs' => 111, 'rhs' => 3 ), + array( 'lhs' => 111, 'rhs' => 2 ), + array( 'lhs' => 97, 'rhs' => 1 ), + array( 'lhs' => 97, 'rhs' => 2 ), + array( 'lhs' => 112, 'rhs' => 1 ), + array( 'lhs' => 112, 'rhs' => 3 ), + array( 'lhs' => 109, 'rhs' => 2 ), + array( 'lhs' => 113, 'rhs' => 1 ), + array( 'lhs' => 113, 'rhs' => 2 ), + array( 'lhs' => 114, 'rhs' => 3 ), + array( 'lhs' => 114, 'rhs' => 4 ), + array( 'lhs' => 114, 'rhs' => 5 ), + array( 'lhs' => 114, 'rhs' => 6 ), + array( 'lhs' => 114, 'rhs' => 2 ), + array( 'lhs' => 106, 'rhs' => 4 ), + array( 'lhs' => 115, 'rhs' => 4 ), + array( 'lhs' => 115, 'rhs' => 5 ), + array( 'lhs' => 116, 'rhs' => 3 ), + array( 'lhs' => 116, 'rhs' => 1 ), + array( 'lhs' => 116, 'rhs' => 0 ), + array( 'lhs' => 90, 'rhs' => 3 ), + array( 'lhs' => 90, 'rhs' => 2 ), + array( 'lhs' => 117, 'rhs' => 3 ), + array( 'lhs' => 117, 'rhs' => 2 ), + array( 'lhs' => 99, 'rhs' => 2 ), + array( 'lhs' => 99, 'rhs' => 0 ), + array( 'lhs' => 118, 'rhs' => 2 ), + array( 'lhs' => 118, 'rhs' => 2 ), + array( 'lhs' => 108, 'rhs' => 1 ), + array( 'lhs' => 108, 'rhs' => 2 ), + array( 'lhs' => 108, 'rhs' => 1 ), + array( 'lhs' => 108, 'rhs' => 3 ), + array( 'lhs' => 108, 'rhs' => 4 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 103, 'rhs' => 1 ), + array( 'lhs' => 104, 'rhs' => 1 ), + array( 'lhs' => 104, 'rhs' => 1 ), + array( 'lhs' => 104, 'rhs' => 1 ), + array( 'lhs' => 102, 'rhs' => 3 ), + array( 'lhs' => 119, 'rhs' => 1 ), + array( 'lhs' => 119, 'rhs' => 3 ), + array( 'lhs' => 119, 'rhs' => 0 ), + array( 'lhs' => 120, 'rhs' => 3 ), + array( 'lhs' => 120, 'rhs' => 3 ), + array( 'lhs' => 120, 'rhs' => 1 ), + array( 'lhs' => 107, 'rhs' => 2 ), + array( 'lhs' => 107, 'rhs' => 3 ), + array( 'lhs' => 121, 'rhs' => 2 ), + array( 'lhs' => 121, 'rhs' => 1 ), + array( 'lhs' => 122, 'rhs' => 3 ), + array( 'lhs' => 122, 'rhs' => 3 ), + array( 'lhs' => 122, 'rhs' => 1 ), + array( 'lhs' => 122, 'rhs' => 3 ), + array( 'lhs' => 122, 'rhs' => 3 ), + array( 'lhs' => 122, 'rhs' => 1 ), + array( 'lhs' => 122, 'rhs' => 1 ), + array( 'lhs' => 96, 'rhs' => 1 ), + array( 'lhs' => 96, 'rhs' => 0 ), + ); + + static public $yyReduceMap = array( + 0 => 0, + 1 => 1, + 2 => 1, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + 9 => 9, + 10 => 10, + 11 => 11, + 12 => 12, + 13 => 13, + 14 => 14, + 15 => 15, + 16 => 16, + 19 => 16, + 203 => 16, + 17 => 17, + 76 => 17, + 18 => 18, + 104 => 18, + 106 => 18, + 107 => 18, + 130 => 18, + 168 => 18, + 20 => 20, + 21 => 20, + 47 => 20, + 69 => 20, + 70 => 20, + 77 => 20, + 78 => 20, + 83 => 20, + 103 => 20, + 108 => 20, + 109 => 20, + 114 => 20, + 116 => 20, + 117 => 20, + 124 => 20, + 141 => 20, + 167 => 20, + 169 => 20, + 185 => 20, + 190 => 20, + 202 => 20, + 22 => 22, + 23 => 22, + 24 => 24, + 25 => 25, + 26 => 26, + 27 => 27, + 28 => 28, + 29 => 29, + 31 => 29, + 30 => 30, + 32 => 32, + 33 => 32, + 34 => 34, + 35 => 35, + 36 => 36, + 37 => 37, + 38 => 38, + 39 => 39, + 40 => 40, + 41 => 41, + 42 => 42, + 44 => 42, + 43 => 43, + 45 => 45, + 46 => 46, + 48 => 48, + 49 => 49, + 50 => 50, + 51 => 51, + 52 => 52, + 53 => 53, + 54 => 54, + 55 => 55, + 56 => 56, + 57 => 57, + 58 => 58, + 59 => 59, + 60 => 60, + 61 => 61, + 62 => 62, + 63 => 63, + 72 => 63, + 157 => 63, + 161 => 63, + 165 => 63, + 166 => 63, + 64 => 64, + 158 => 64, + 164 => 64, + 65 => 65, + 66 => 66, + 67 => 66, + 68 => 68, + 71 => 71, + 73 => 73, + 74 => 74, + 75 => 74, + 79 => 79, + 80 => 80, + 81 => 80, + 82 => 80, + 84 => 84, + 121 => 84, + 85 => 85, + 88 => 85, + 99 => 85, + 86 => 86, + 87 => 87, + 89 => 89, + 90 => 90, + 91 => 91, + 96 => 91, + 92 => 92, + 95 => 92, + 93 => 93, + 98 => 93, + 94 => 94, + 97 => 94, + 100 => 100, + 101 => 101, + 102 => 102, + 105 => 105, + 110 => 110, + 111 => 111, + 112 => 112, + 113 => 113, + 115 => 115, + 118 => 118, + 119 => 119, + 120 => 120, + 122 => 122, + 123 => 123, + 125 => 125, + 126 => 126, + 127 => 127, + 128 => 128, + 129 => 129, + 131 => 131, + 187 => 131, + 132 => 132, + 133 => 133, + 134 => 134, + 135 => 135, + 136 => 136, + 139 => 136, + 137 => 137, + 138 => 138, + 140 => 140, + 142 => 142, + 143 => 143, + 144 => 144, + 145 => 145, + 146 => 146, + 147 => 147, + 148 => 148, + 149 => 149, + 150 => 150, + 151 => 151, + 152 => 152, + 153 => 153, + 154 => 154, + 155 => 155, + 156 => 156, + 159 => 159, + 160 => 160, + 162 => 162, + 163 => 163, + 170 => 170, + 171 => 171, + 172 => 172, + 173 => 173, + 174 => 174, + 175 => 175, + 176 => 176, + 177 => 177, + 178 => 178, + 179 => 179, + 180 => 180, + 181 => 181, + 182 => 182, + 183 => 183, + 184 => 184, + 186 => 186, + 188 => 188, + 189 => 189, + 191 => 191, + 192 => 192, + 193 => 193, + 194 => 194, + 195 => 195, + 196 => 195, + 198 => 195, + 197 => 197, + 199 => 199, + 200 => 200, + 201 => 201, + ); +#line 95 "smarty_internal_templateparser.y" + function yy_r0(){ + $this->_retvalue = $this->root_buffer->to_smarty_php(); + } +#line 2160 "smarty_internal_templateparser.php" +#line 103 "smarty_internal_templateparser.y" + function yy_r1(){ + $this->current_buffer->append_subtree($this->yystack[$this->yyidx + 0]->minor); + } +#line 2165 "smarty_internal_templateparser.php" +#line 119 "smarty_internal_templateparser.y" + function yy_r4(){ + if ($this->compiler->has_code) { + $tmp =''; foreach ($this->compiler->prefix_code as $code) {$tmp.=$code;} $this->compiler->prefix_code=array(); + $this->_retvalue = new _smarty_tag($this, $this->compiler->processNocacheCode($tmp.$this->yystack[$this->yyidx + 0]->minor,true)); + } else { + $this->_retvalue = new _smarty_tag($this, $this->yystack[$this->yyidx + 0]->minor); + } + $this->compiler->has_variable_string = false; + $this->block_nesting_level = count($this->compiler->_tag_stack); + } +#line 2177 "smarty_internal_templateparser.php" +#line 131 "smarty_internal_templateparser.y" + function yy_r5(){ + $this->_retvalue = new _smarty_tag($this, ''); + } +#line 2182 "smarty_internal_templateparser.php" +#line 136 "smarty_internal_templateparser.y" + function yy_r6(){ + $this->_retvalue = new _smarty_text($this, $this->yystack[$this->yyidx + 0]->minor); + } +#line 2187 "smarty_internal_templateparser.php" +#line 141 "smarty_internal_templateparser.y" + function yy_r7(){ + if ($this->php_handling == Smarty::PHP_PASSTHRU) { + $this->_retvalue = new _smarty_text($this, self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor)); + } elseif ($this->php_handling == Smarty::PHP_QUOTE) { + $this->_retvalue = new _smarty_text($this, htmlspecialchars($this->yystack[$this->yyidx + 0]->minor, ENT_QUOTES)); + } elseif ($this->php_handling == Smarty::PHP_ALLOW) { + if (!($this->smarty instanceof SmartyBC)) { + $this->compiler->trigger_template_error (self::Err3); + } + $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('<?php', true)); + } elseif ($this->php_handling == Smarty::PHP_REMOVE) { + $this->_retvalue = new _smarty_text($this, ''); + } + } +#line 2203 "smarty_internal_templateparser.php" +#line 157 "smarty_internal_templateparser.y" + function yy_r8(){ + if ($this->is_xml) { + $this->compiler->tag_nocache = true; + $this->is_xml = false; + $save = $this->template->has_nocache_code; + $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode("<?php echo '?>';?>\n", $this->compiler, true)); + $this->template->has_nocache_code = $save; + } elseif ($this->php_handling == Smarty::PHP_PASSTHRU) { + $this->_retvalue = new _smarty_text($this, '?<?php ?>>'); + } elseif ($this->php_handling == Smarty::PHP_QUOTE) { + $this->_retvalue = new _smarty_text($this, htmlspecialchars('?>', ENT_QUOTES)); + } elseif ($this->php_handling == Smarty::PHP_ALLOW) { + $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('?>', true)); + } elseif ($this->php_handling == Smarty::PHP_REMOVE) { + $this->_retvalue = new _smarty_text($this, ''); + } + } +#line 2222 "smarty_internal_templateparser.php" +#line 176 "smarty_internal_templateparser.y" + function yy_r9(){ + if ($this->php_handling == Smarty::PHP_PASSTHRU) { + $this->_retvalue = new _smarty_text($this, '<<?php ?>%'); + } elseif ($this->php_handling == Smarty::PHP_QUOTE) { + $this->_retvalue = new _smarty_text($this, htmlspecialchars($this->yystack[$this->yyidx + 0]->minor, ENT_QUOTES)); + } elseif ($this->php_handling == Smarty::PHP_ALLOW) { + if ($this->asp_tags) { + if (!($this->smarty instanceof SmartyBC)) { + $this->compiler->trigger_template_error (self::Err3); + } + $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('<%', true)); + } else { + $this->_retvalue = new _smarty_text($this, '<<?php ?>%'); + } + } elseif ($this->php_handling == Smarty::PHP_REMOVE) { + if ($this->asp_tags) { + $this->_retvalue = new _smarty_text($this, ''); + } else { + $this->_retvalue = new _smarty_text($this, '<<?php ?>%'); + } + } + } +#line 2246 "smarty_internal_templateparser.php" +#line 200 "smarty_internal_templateparser.y" + function yy_r10(){ + if ($this->php_handling == Smarty::PHP_PASSTHRU) { + $this->_retvalue = new _smarty_text($this, '%<?php ?>>'); + } elseif ($this->php_handling == Smarty::PHP_QUOTE) { + $this->_retvalue = new _smarty_text($this, htmlspecialchars('%>', ENT_QUOTES)); + } elseif ($this->php_handling == Smarty::PHP_ALLOW) { + if ($this->asp_tags) { + $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode('%>', true)); + } else { + $this->_retvalue = new _smarty_text($this, '%<?php ?>>'); + } + } elseif ($this->php_handling == Smarty::PHP_REMOVE) { + if ($this->asp_tags) { + $this->_retvalue = new _smarty_text($this, ''); + } else { + $this->_retvalue = new _smarty_text($this, '%<?php ?>>'); + } + } + } +#line 2267 "smarty_internal_templateparser.php" +#line 220 "smarty_internal_templateparser.y" + function yy_r11(){ + if ($this->strip) { + $this->_retvalue = new _smarty_text($this, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor))); + } else { + $this->_retvalue = new _smarty_text($this, self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor)); + } + } +#line 2276 "smarty_internal_templateparser.php" +#line 229 "smarty_internal_templateparser.y" + function yy_r12(){ + $this->compiler->tag_nocache = true; + $this->is_xml = true; + $save = $this->template->has_nocache_code; + $this->_retvalue = new _smarty_text($this, $this->compiler->processNocacheCode("<?php echo '<?xml';?>", $this->compiler, true)); + $this->template->has_nocache_code = $save; + } +#line 2285 "smarty_internal_templateparser.php" +#line 238 "smarty_internal_templateparser.y" + function yy_r13(){ + if ($this->strip) { + $this->_retvalue = new _smarty_text($this, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $this->yystack[$this->yyidx + 0]->minor)); + } else { + $this->_retvalue = new _smarty_text($this, $this->yystack[$this->yyidx + 0]->minor); + } + } +#line 2294 "smarty_internal_templateparser.php" +#line 247 "smarty_internal_templateparser.y" + function yy_r14(){ + $this->strip = true; + $this->_retvalue = new _smarty_text($this, ''); + } +#line 2300 "smarty_internal_templateparser.php" +#line 252 "smarty_internal_templateparser.y" + function yy_r15(){ + $this->strip = false; + $this->_retvalue = new _smarty_text($this, ''); + } +#line 2306 "smarty_internal_templateparser.php" +#line 258 "smarty_internal_templateparser.y" + function yy_r16(){ + $this->_retvalue = ''; + } +#line 2311 "smarty_internal_templateparser.php" +#line 262 "smarty_internal_templateparser.y" + function yy_r17(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + } +#line 2316 "smarty_internal_templateparser.php" +#line 266 "smarty_internal_templateparser.y" + function yy_r18(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2321 "smarty_internal_templateparser.php" +#line 274 "smarty_internal_templateparser.y" + function yy_r20(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; + } +#line 2326 "smarty_internal_templateparser.php" +#line 282 "smarty_internal_templateparser.y" + function yy_r22(){ + $this->_retvalue = self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor); + } +#line 2331 "smarty_internal_templateparser.php" +#line 290 "smarty_internal_templateparser.y" + function yy_r24(){ + $this->_retvalue = self::escape_end_tag($this->yystack[$this->yyidx + 0]->minor); + } +#line 2336 "smarty_internal_templateparser.php" +#line 294 "smarty_internal_templateparser.y" + function yy_r25(){ + $this->_retvalue = '<<?php ?>%'; + } +#line 2341 "smarty_internal_templateparser.php" +#line 298 "smarty_internal_templateparser.y" + function yy_r26(){ + $this->_retvalue = '%<?php ?>>'; + } +#line 2346 "smarty_internal_templateparser.php" +#line 307 "smarty_internal_templateparser.y" + function yy_r27(){ + $this->_retvalue = $this->compiler->compileTag('private_print_expression',array(),array('value'=>$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2351 "smarty_internal_templateparser.php" +#line 311 "smarty_internal_templateparser.y" + function yy_r28(){ + $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + -1]->minor,array('value'=>$this->yystack[$this->yyidx + -3]->minor, 'modifierlist'=>$this->yystack[$this->yyidx + -2]->minor)); + } +#line 2356 "smarty_internal_templateparser.php" +#line 315 "smarty_internal_templateparser.y" + function yy_r29(){ + $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + -1]->minor,array('value'=>$this->yystack[$this->yyidx + -2]->minor)); + } +#line 2361 "smarty_internal_templateparser.php" +#line 319 "smarty_internal_templateparser.y" + function yy_r30(){ + $this->_retvalue = $this->compiler->compileTag('private_print_expression',$this->yystack[$this->yyidx + -1]->minor,array('value'=>$this->yystack[$this->yyidx + -3]->minor,'modifierlist'=>$this->yystack[$this->yyidx + -2]->minor)); + } +#line 2366 "smarty_internal_templateparser.php" +#line 332 "smarty_internal_templateparser.y" + function yy_r32(){ + $this->_retvalue = $this->compiler->compileTag('assign',array(array('value'=>$this->yystack[$this->yyidx + -1]->minor),array('var'=>"'".$this->yystack[$this->yyidx + -3]->minor."'"))); + } +#line 2371 "smarty_internal_templateparser.php" +#line 340 "smarty_internal_templateparser.y" + function yy_r34(){ + $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + -2]->minor),array('var'=>"'".$this->yystack[$this->yyidx + -4]->minor."'")),$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2376 "smarty_internal_templateparser.php" +#line 344 "smarty_internal_templateparser.y" + function yy_r35(){ + $this->_retvalue = $this->compiler->compileTag('assign',array_merge(array(array('value'=>$this->yystack[$this->yyidx + -2]->minor),array('var'=>$this->yystack[$this->yyidx + -4]->minor['var'])),$this->yystack[$this->yyidx + -1]->minor),array('smarty_internal_index'=>$this->yystack[$this->yyidx + -4]->minor['smarty_internal_index'])); + } +#line 2381 "smarty_internal_templateparser.php" +#line 349 "smarty_internal_templateparser.y" + function yy_r36(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor,$this->yystack[$this->yyidx + -1]->minor); + } +#line 2386 "smarty_internal_templateparser.php" +#line 353 "smarty_internal_templateparser.y" + function yy_r37(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor,array()); + } +#line 2391 "smarty_internal_templateparser.php" +#line 358 "smarty_internal_templateparser.y" + function yy_r38(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor,$this->yystack[$this->yyidx + -1]->minor,array('object_methode'=>$this->yystack[$this->yyidx + -2]->minor)); + } +#line 2396 "smarty_internal_templateparser.php" +#line 363 "smarty_internal_templateparser.y" + function yy_r39(){ + $this->_retvalue = '<?php ob_start();?>'.$this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor,$this->yystack[$this->yyidx + -1]->minor).'<?php echo '; + $this->_retvalue .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>$this->yystack[$this->yyidx + -2]->minor,'value'=>'ob_get_clean()')).'?>'; + } +#line 2402 "smarty_internal_templateparser.php" +#line 369 "smarty_internal_templateparser.y" + function yy_r40(){ + $this->_retvalue = '<?php ob_start();?>'.$this->compiler->compileTag($this->yystack[$this->yyidx + -5]->minor,$this->yystack[$this->yyidx + -1]->minor,array('object_methode'=>$this->yystack[$this->yyidx + -3]->minor)).'<?php echo '; + $this->_retvalue .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>$this->yystack[$this->yyidx + -2]->minor,'value'=>'ob_get_clean()')).'?>'; + } +#line 2408 "smarty_internal_templateparser.php" +#line 375 "smarty_internal_templateparser.y" + function yy_r41(){ + $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor,$this->lex->ldel_length)); + $this->_retvalue = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2414 "smarty_internal_templateparser.php" +#line 380 "smarty_internal_templateparser.y" + function yy_r42(){ + $tag = trim(substr($this->yystack[$this->yyidx + -3]->minor,$this->lex->ldel_length)); + $this->_retvalue = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,$this->yystack[$this->yyidx + -1]->minor,array('if condition'=>$this->yystack[$this->yyidx + -2]->minor)); + } +#line 2420 "smarty_internal_templateparser.php" +#line 385 "smarty_internal_templateparser.y" + function yy_r43(){ + $tag = trim(substr($this->yystack[$this->yyidx + -2]->minor,$this->lex->ldel_length)); + $this->_retvalue = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2426 "smarty_internal_templateparser.php" +#line 396 "smarty_internal_templateparser.y" + function yy_r45(){ + $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('start'=>$this->yystack[$this->yyidx + -10]->minor),array('ifexp'=>$this->yystack[$this->yyidx + -7]->minor),array('var'=>$this->yystack[$this->yyidx + -3]->minor),array('step'=>$this->yystack[$this->yyidx + -2]->minor))),1); + } +#line 2431 "smarty_internal_templateparser.php" +#line 400 "smarty_internal_templateparser.y" + function yy_r46(){ + $this->_retvalue = '='.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2436 "smarty_internal_templateparser.php" +#line 408 "smarty_internal_templateparser.y" + function yy_r48(){ + $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('start'=>$this->yystack[$this->yyidx + -4]->minor),array('to'=>$this->yystack[$this->yyidx + -2]->minor))),0); + } +#line 2441 "smarty_internal_templateparser.php" +#line 412 "smarty_internal_templateparser.y" + function yy_r49(){ + $this->_retvalue = $this->compiler->compileTag('for',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('start'=>$this->yystack[$this->yyidx + -6]->minor),array('to'=>$this->yystack[$this->yyidx + -4]->minor),array('step'=>$this->yystack[$this->yyidx + -2]->minor))),0); + } +#line 2446 "smarty_internal_templateparser.php" +#line 417 "smarty_internal_templateparser.y" + function yy_r50(){ + $this->_retvalue = $this->compiler->compileTag('foreach',$this->yystack[$this->yyidx + -1]->minor); + } +#line 2451 "smarty_internal_templateparser.php" +#line 422 "smarty_internal_templateparser.y" + function yy_r51(){ + $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -5]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor)))); + } +#line 2456 "smarty_internal_templateparser.php" +#line 426 "smarty_internal_templateparser.y" + function yy_r52(){ + $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -8]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor),array('key'=>$this->yystack[$this->yyidx + -5]->minor)))); + } +#line 2461 "smarty_internal_templateparser.php" +#line 430 "smarty_internal_templateparser.y" + function yy_r53(){ + $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -5]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor)))); + } +#line 2466 "smarty_internal_templateparser.php" +#line 434 "smarty_internal_templateparser.y" + function yy_r54(){ + $this->_retvalue = $this->compiler->compileTag('foreach',array_merge($this->yystack[$this->yyidx + -1]->minor,array(array('from'=>$this->yystack[$this->yyidx + -8]->minor),array('item'=>$this->yystack[$this->yyidx + -2]->minor),array('key'=>$this->yystack[$this->yyidx + -5]->minor)))); + } +#line 2471 "smarty_internal_templateparser.php" +#line 439 "smarty_internal_templateparser.y" + function yy_r55(){ + $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array($this->yystack[$this->yyidx + -2]->minor),$this->yystack[$this->yyidx + -1]->minor)))); + } +#line 2476 "smarty_internal_templateparser.php" +#line 443 "smarty_internal_templateparser.y" + function yy_r56(){ + $this->_retvalue = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array($this->yystack[$this->yyidx + -3]->minor),$this->yystack[$this->yyidx + -2]->minor)),$this->yystack[$this->yyidx + -1]->minor))); + } +#line 2481 "smarty_internal_templateparser.php" +#line 448 "smarty_internal_templateparser.y" + function yy_r57(){ + $this->_retvalue = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler); + } +#line 2486 "smarty_internal_templateparser.php" +#line 454 "smarty_internal_templateparser.y" + function yy_r58(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -1]->minor.'close',array()); + } +#line 2491 "smarty_internal_templateparser.php" +#line 458 "smarty_internal_templateparser.y" + function yy_r59(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -2]->minor.'close',array(),array('modifier_list'=>$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2496 "smarty_internal_templateparser.php" +#line 463 "smarty_internal_templateparser.y" + function yy_r60(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -3]->minor.'close',array(),array('object_methode'=>$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2501 "smarty_internal_templateparser.php" +#line 467 "smarty_internal_templateparser.y" + function yy_r61(){ + $this->_retvalue = $this->compiler->compileTag($this->yystack[$this->yyidx + -4]->minor.'close',array(),array('object_methode'=>$this->yystack[$this->yyidx + -2]->minor, 'modifier_list'=>$this->yystack[$this->yyidx + -1]->minor)); + } +#line 2506 "smarty_internal_templateparser.php" +#line 475 "smarty_internal_templateparser.y" + function yy_r62(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + $this->_retvalue[] = $this->yystack[$this->yyidx + 0]->minor; + } +#line 2512 "smarty_internal_templateparser.php" +#line 481 "smarty_internal_templateparser.y" + function yy_r63(){ + $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); + } +#line 2517 "smarty_internal_templateparser.php" +#line 486 "smarty_internal_templateparser.y" + function yy_r64(){ + $this->_retvalue = array(); + } +#line 2522 "smarty_internal_templateparser.php" +#line 491 "smarty_internal_templateparser.y" + function yy_r65(){ + if (preg_match('~^true$~i', $this->yystack[$this->yyidx + 0]->minor)) { + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'true'); + } elseif (preg_match('~^false$~i', $this->yystack[$this->yyidx + 0]->minor)) { + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'false'); + } elseif (preg_match('~^null$~i', $this->yystack[$this->yyidx + 0]->minor)) { + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>'null'); + } else { + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>"'".$this->yystack[$this->yyidx + 0]->minor."'"); + } + } +#line 2535 "smarty_internal_templateparser.php" +#line 503 "smarty_internal_templateparser.y" + function yy_r66(){ + $this->_retvalue = array(trim($this->yystack[$this->yyidx + -1]->minor," =\n\r\t")=>$this->yystack[$this->yyidx + 0]->minor); + } +#line 2540 "smarty_internal_templateparser.php" +#line 511 "smarty_internal_templateparser.y" + function yy_r68(){ + $this->_retvalue = "'".$this->yystack[$this->yyidx + 0]->minor."'"; + } +#line 2545 "smarty_internal_templateparser.php" +#line 523 "smarty_internal_templateparser.y" + function yy_r71(){ + $this->_retvalue = array($this->yystack[$this->yyidx + -2]->minor=>$this->yystack[$this->yyidx + 0]->minor); + } +#line 2550 "smarty_internal_templateparser.php" +#line 536 "smarty_internal_templateparser.y" + function yy_r73(){ + $this->yystack[$this->yyidx + -2]->minor[]=$this->yystack[$this->yyidx + 0]->minor; + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor; + } +#line 2556 "smarty_internal_templateparser.php" +#line 541 "smarty_internal_templateparser.y" + function yy_r74(){ + $this->_retvalue = array('var' => $this->yystack[$this->yyidx + -2]->minor, 'value'=>$this->yystack[$this->yyidx + 0]->minor); + } +#line 2561 "smarty_internal_templateparser.php" +#line 569 "smarty_internal_templateparser.y" + function yy_r79(){ + $this->_retvalue = '$_smarty_tpl->getStreamVariable(\''. $this->yystack[$this->yyidx + -2]->minor .'://'. $this->yystack[$this->yyidx + 0]->minor . '\')'; + } +#line 2566 "smarty_internal_templateparser.php" +#line 574 "smarty_internal_templateparser.y" + function yy_r80(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor . trim($this->yystack[$this->yyidx + -1]->minor) . $this->yystack[$this->yyidx + 0]->minor; + } +#line 2571 "smarty_internal_templateparser.php" +#line 593 "smarty_internal_templateparser.y" + function yy_r84(){ + $this->_retvalue = $this->compiler->compileTag('private_modifier',array(),array('value'=>$this->yystack[$this->yyidx + -1]->minor,'modifierlist'=>$this->yystack[$this->yyidx + 0]->minor)); + } +#line 2576 "smarty_internal_templateparser.php" +#line 599 "smarty_internal_templateparser.y" + function yy_r85(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2581 "smarty_internal_templateparser.php" +#line 603 "smarty_internal_templateparser.y" + function yy_r86(){ + $this->_retvalue = 'in_array('.$this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor.')'; + } +#line 2586 "smarty_internal_templateparser.php" +#line 607 "smarty_internal_templateparser.y" + function yy_r87(){ + $this->_retvalue = 'in_array('.$this->yystack[$this->yyidx + -2]->minor.',(array)'.$this->yystack[$this->yyidx + 0]->minor.')'; + } +#line 2591 "smarty_internal_templateparser.php" +#line 615 "smarty_internal_templateparser.y" + function yy_r89(){ + $this->_retvalue = '!('.$this->yystack[$this->yyidx + -2]->minor.' % '.$this->yystack[$this->yyidx + 0]->minor.')'; + } +#line 2596 "smarty_internal_templateparser.php" +#line 619 "smarty_internal_templateparser.y" + function yy_r90(){ + $this->_retvalue = '('.$this->yystack[$this->yyidx + -2]->minor.' % '.$this->yystack[$this->yyidx + 0]->minor.')'; + } +#line 2601 "smarty_internal_templateparser.php" +#line 623 "smarty_internal_templateparser.y" + function yy_r91(){ + $this->_retvalue = '!(1 & '.$this->yystack[$this->yyidx + -1]->minor.')'; + } +#line 2606 "smarty_internal_templateparser.php" +#line 627 "smarty_internal_templateparser.y" + function yy_r92(){ + $this->_retvalue = '(1 & '.$this->yystack[$this->yyidx + -1]->minor.')'; + } +#line 2611 "smarty_internal_templateparser.php" +#line 631 "smarty_internal_templateparser.y" + function yy_r93(){ + $this->_retvalue = '!(1 & '.$this->yystack[$this->yyidx + -2]->minor.' / '.$this->yystack[$this->yyidx + 0]->minor.')'; + } +#line 2616 "smarty_internal_templateparser.php" +#line 635 "smarty_internal_templateparser.y" + function yy_r94(){ + $this->_retvalue = '(1 & '.$this->yystack[$this->yyidx + -2]->minor.' / '.$this->yystack[$this->yyidx + 0]->minor.')'; + } +#line 2621 "smarty_internal_templateparser.php" +#line 659 "smarty_internal_templateparser.y" + function yy_r100(){ + $this->prefix_number++; + $this->compiler->prefix_code[] = '<?php $_tmp'.$this->prefix_number.'='.$this->yystack[$this->yyidx + 0]->minor.';?>'; + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.'$_tmp'.$this->prefix_number; + } +#line 2628 "smarty_internal_templateparser.php" +#line 668 "smarty_internal_templateparser.y" + function yy_r101(){ + $this->_retvalue = $this->yystack[$this->yyidx + -6]->minor.' ? '. $this->compileVariable("'".$this->yystack[$this->yyidx + -2]->minor."'") . ' : '.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2633 "smarty_internal_templateparser.php" +#line 672 "smarty_internal_templateparser.y" + function yy_r102(){ + $this->_retvalue = $this->yystack[$this->yyidx + -5]->minor.' ? '.$this->yystack[$this->yyidx + -2]->minor.' : '.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2638 "smarty_internal_templateparser.php" +#line 687 "smarty_internal_templateparser.y" + function yy_r105(){ + $this->_retvalue = '!'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2643 "smarty_internal_templateparser.php" +#line 708 "smarty_internal_templateparser.y" + function yy_r110(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2648 "smarty_internal_templateparser.php" +#line 712 "smarty_internal_templateparser.y" + function yy_r111(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'; + } +#line 2653 "smarty_internal_templateparser.php" +#line 716 "smarty_internal_templateparser.y" + function yy_r112(){ + $this->_retvalue = '.'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2658 "smarty_internal_templateparser.php" +#line 721 "smarty_internal_templateparser.y" + function yy_r113(){ + if (preg_match('~^true$~i', $this->yystack[$this->yyidx + 0]->minor)) { + $this->_retvalue = 'true'; + } elseif (preg_match('~^false$~i', $this->yystack[$this->yyidx + 0]->minor)) { + $this->_retvalue = 'false'; + } elseif (preg_match('~^null$~i', $this->yystack[$this->yyidx + 0]->minor)) { + $this->_retvalue = 'null'; + } else { + $this->_retvalue = "'".$this->yystack[$this->yyidx + 0]->minor."'"; + } + } +#line 2671 "smarty_internal_templateparser.php" +#line 739 "smarty_internal_templateparser.y" + function yy_r115(){ + $this->_retvalue = "(". $this->yystack[$this->yyidx + -1]->minor .")"; + } +#line 2676 "smarty_internal_templateparser.php" +#line 754 "smarty_internal_templateparser.y" + function yy_r118(){ + if (!$this->security || isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor]) || $this->smarty->security_policy->isTrustedStaticClass($this->yystack[$this->yyidx + -2]->minor, $this->compiler)) { + if (isset($this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor])) { + $this->_retvalue = $this->smarty->registered_classes[$this->yystack[$this->yyidx + -2]->minor].'::'.$this->yystack[$this->yyidx + 0]->minor; + } else { + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'::'.$this->yystack[$this->yyidx + 0]->minor; + } + } else { + $this->compiler->trigger_template_error ("static class '".$this->yystack[$this->yyidx + -2]->minor."' is undefined or not allowed by security setting"); + } + } +#line 2689 "smarty_internal_templateparser.php" +#line 766 "smarty_internal_templateparser.y" + function yy_r119(){ + if ($this->yystack[$this->yyidx + -2]->minor['var'] == '\'smarty\'') { + $this->_retvalue = $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index']).'::'.$this->yystack[$this->yyidx + 0]->minor; + } else { + $this->_retvalue = $this->compileVariable($this->yystack[$this->yyidx + -2]->minor['var']).$this->yystack[$this->yyidx + -2]->minor['smarty_internal_index'].'::'.$this->yystack[$this->yyidx + 0]->minor; + } + } +#line 2698 "smarty_internal_templateparser.php" +#line 775 "smarty_internal_templateparser.y" + function yy_r120(){ + $this->prefix_number++; + $this->compiler->prefix_code[] = '<?php ob_start();?>'.$this->yystack[$this->yyidx + 0]->minor.'<?php $_tmp'.$this->prefix_number.'=ob_get_clean();?>'; + $this->_retvalue = '$_tmp'.$this->prefix_number; + } +#line 2705 "smarty_internal_templateparser.php" +#line 790 "smarty_internal_templateparser.y" + function yy_r122(){ + if ($this->yystack[$this->yyidx + 0]->minor['var'] == '\'smarty\'') { + $smarty_var = $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']); + $this->_retvalue = $smarty_var; + } else { + // used for array reset,next,prev,end,current + $this->last_variable = $this->yystack[$this->yyidx + 0]->minor['var']; + $this->last_index = $this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']; + $this->_retvalue = $this->compileVariable($this->yystack[$this->yyidx + 0]->minor['var']).$this->yystack[$this->yyidx + 0]->minor['smarty_internal_index']; + } + } +#line 2718 "smarty_internal_templateparser.php" +#line 803 "smarty_internal_templateparser.y" + function yy_r123(){ + $this->_retvalue = '$_smarty_tpl->tpl_vars['. $this->yystack[$this->yyidx + -2]->minor .']->'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2723 "smarty_internal_templateparser.php" +#line 813 "smarty_internal_templateparser.y" + function yy_r125(){ + $this->_retvalue = '$_smarty_tpl->getConfigVariable(\''. $this->yystack[$this->yyidx + -1]->minor .'\')'; + } +#line 2728 "smarty_internal_templateparser.php" +#line 817 "smarty_internal_templateparser.y" + function yy_r126(){ + $this->_retvalue = '(is_array($tmp = $_smarty_tpl->getConfigVariable(\''. $this->yystack[$this->yyidx + -2]->minor .'\')) ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' :null)'; + } +#line 2733 "smarty_internal_templateparser.php" +#line 821 "smarty_internal_templateparser.y" + function yy_r127(){ + $this->_retvalue = '$_smarty_tpl->getConfigVariable('. $this->yystack[$this->yyidx + -1]->minor .')'; + } +#line 2738 "smarty_internal_templateparser.php" +#line 825 "smarty_internal_templateparser.y" + function yy_r128(){ + $this->_retvalue = '(is_array($tmp = $_smarty_tpl->getConfigVariable('. $this->yystack[$this->yyidx + -2]->minor .')) ? $tmp'.$this->yystack[$this->yyidx + 0]->minor.' : null)'; + } +#line 2743 "smarty_internal_templateparser.php" +#line 829 "smarty_internal_templateparser.y" + function yy_r129(){ + $this->_retvalue = array('var'=>$this->yystack[$this->yyidx + -1]->minor, 'smarty_internal_index'=>$this->yystack[$this->yyidx + 0]->minor); + } +#line 2748 "smarty_internal_templateparser.php" +#line 842 "smarty_internal_templateparser.y" + function yy_r131(){ + return; + } +#line 2753 "smarty_internal_templateparser.php" +#line 848 "smarty_internal_templateparser.y" + function yy_r132(){ + $this->_retvalue = '['.$this->compileVariable($this->yystack[$this->yyidx + 0]->minor).']'; + } +#line 2758 "smarty_internal_templateparser.php" +#line 852 "smarty_internal_templateparser.y" + function yy_r133(){ + $this->_retvalue = '['.$this->compileVariable($this->yystack[$this->yyidx + -2]->minor).'->'.$this->yystack[$this->yyidx + 0]->minor.']'; + } +#line 2763 "smarty_internal_templateparser.php" +#line 856 "smarty_internal_templateparser.y" + function yy_r134(){ + $this->_retvalue = "['". $this->yystack[$this->yyidx + 0]->minor ."']"; + } +#line 2768 "smarty_internal_templateparser.php" +#line 860 "smarty_internal_templateparser.y" + function yy_r135(){ + $this->_retvalue = "[". $this->yystack[$this->yyidx + 0]->minor ."]"; + } +#line 2773 "smarty_internal_templateparser.php" +#line 864 "smarty_internal_templateparser.y" + function yy_r136(){ + $this->_retvalue = "[". $this->yystack[$this->yyidx + -1]->minor ."]"; + } +#line 2778 "smarty_internal_templateparser.php" +#line 869 "smarty_internal_templateparser.y" + function yy_r137(){ + $this->_retvalue = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\'][\'index\']').']'; + } +#line 2783 "smarty_internal_templateparser.php" +#line 873 "smarty_internal_templateparser.y" + function yy_r138(){ + $this->_retvalue = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.$this->yystack[$this->yyidx + -3]->minor.'\'][\''.$this->yystack[$this->yyidx + -1]->minor.'\']').']'; + } +#line 2788 "smarty_internal_templateparser.php" +#line 883 "smarty_internal_templateparser.y" + function yy_r140(){ + $this->_retvalue = '[]'; + } +#line 2793 "smarty_internal_templateparser.php" +#line 896 "smarty_internal_templateparser.y" + function yy_r142(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.'.'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2798 "smarty_internal_templateparser.php" +#line 901 "smarty_internal_templateparser.y" + function yy_r143(){ + $this->_retvalue = '\''.$this->yystack[$this->yyidx + 0]->minor.'\''; + } +#line 2803 "smarty_internal_templateparser.php" +#line 906 "smarty_internal_templateparser.y" + function yy_r144(){ + $this->_retvalue = '('.$this->yystack[$this->yyidx + -1]->minor.')'; + } +#line 2808 "smarty_internal_templateparser.php" +#line 913 "smarty_internal_templateparser.y" + function yy_r145(){ + if ($this->yystack[$this->yyidx + -1]->minor['var'] == '\'smarty\'') { + $this->_retvalue = $this->compiler->compileTag('private_special_variable',array(),$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index']).$this->yystack[$this->yyidx + 0]->minor; + } else { + $this->_retvalue = $this->compileVariable($this->yystack[$this->yyidx + -1]->minor['var']).$this->yystack[$this->yyidx + -1]->minor['smarty_internal_index'].$this->yystack[$this->yyidx + 0]->minor; + } + } +#line 2817 "smarty_internal_templateparser.php" +#line 922 "smarty_internal_templateparser.y" + function yy_r146(){ + $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; + } +#line 2822 "smarty_internal_templateparser.php" +#line 927 "smarty_internal_templateparser.y" + function yy_r147(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2827 "smarty_internal_templateparser.php" +#line 932 "smarty_internal_templateparser.y" + function yy_r148(){ + if ($this->security && substr($this->yystack[$this->yyidx + -1]->minor,0,1) == '_') { + $this->compiler->trigger_template_error (self::Err1); + } + $this->_retvalue = '->'.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2835 "smarty_internal_templateparser.php" +#line 939 "smarty_internal_templateparser.y" + function yy_r149(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + $this->_retvalue = '->{'.$this->compileVariable($this->yystack[$this->yyidx + -1]->minor).$this->yystack[$this->yyidx + 0]->minor.'}'; + } +#line 2843 "smarty_internal_templateparser.php" +#line 946 "smarty_internal_templateparser.y" + function yy_r150(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + $this->_retvalue = '->{'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}'; + } +#line 2851 "smarty_internal_templateparser.php" +#line 953 "smarty_internal_templateparser.y" + function yy_r151(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + $this->_retvalue = '->{\''.$this->yystack[$this->yyidx + -4]->minor.'\'.'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + 0]->minor.'}'; + } +#line 2859 "smarty_internal_templateparser.php" +#line 961 "smarty_internal_templateparser.y" + function yy_r152(){ + $this->_retvalue = '->'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2864 "smarty_internal_templateparser.php" +#line 969 "smarty_internal_templateparser.y" + function yy_r153(){ + if (!$this->security || $this->smarty->security_policy->isTrustedPhpFunction($this->yystack[$this->yyidx + -3]->minor, $this->compiler)) { + if (strcasecmp($this->yystack[$this->yyidx + -3]->minor,'isset') === 0 || strcasecmp($this->yystack[$this->yyidx + -3]->minor,'empty') === 0 || strcasecmp($this->yystack[$this->yyidx + -3]->minor,'array') === 0 || is_callable($this->yystack[$this->yyidx + -3]->minor)) { + $func_name = strtolower($this->yystack[$this->yyidx + -3]->minor); + if ($func_name == 'isset') { + if (count($this->yystack[$this->yyidx + -1]->minor) == 0) { + $this->compiler->trigger_template_error ('Illegal number of paramer in "isset()"'); + } + $par = implode(',',$this->yystack[$this->yyidx + -1]->minor); + if (strncasecmp($par,'$_smarty_tpl->getConfigVariable',strlen('$_smarty_tpl->getConfigVariable')) === 0) { + $this->prefix_number++; + $this->compiler->prefix_code[] = '<?php $_tmp'.$this->prefix_number.'='.str_replace(')',', false)',$par).';?>'; + $isset_par = '$_tmp'.$this->prefix_number; + } else { + $isset_par=str_replace("')->value","',null,true,false)->value",$par); + } + $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(". $isset_par .")"; + } elseif (in_array($func_name,array('empty','reset','current','end','prev','next'))){ + if (count($this->yystack[$this->yyidx + -1]->minor) != 1) { + $this->compiler->trigger_template_error ('Illegal number of paramer in "empty()"'); + } + if ($func_name == 'empty') { + $this->_retvalue = $func_name.'('.str_replace("')->value","',null,true,false)->value",$this->yystack[$this->yyidx + -1]->minor[0]).')'; + } else { + $this->_retvalue = $func_name.'('.$this->yystack[$this->yyidx + -1]->minor[0].')'; + } + } else { + $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(". implode(',',$this->yystack[$this->yyidx + -1]->minor) .")"; + } + } else { + $this->compiler->trigger_template_error ("unknown function \"" . $this->yystack[$this->yyidx + -3]->minor . "\""); + } + } + } +#line 2900 "smarty_internal_templateparser.php" +#line 1007 "smarty_internal_templateparser.y" + function yy_r154(){ + if ($this->security && substr($this->yystack[$this->yyidx + -3]->minor,0,1) == '_') { + $this->compiler->trigger_template_error (self::Err1); + } + $this->_retvalue = $this->yystack[$this->yyidx + -3]->minor . "(". implode(',',$this->yystack[$this->yyidx + -1]->minor) .")"; + } +#line 2908 "smarty_internal_templateparser.php" +#line 1014 "smarty_internal_templateparser.y" + function yy_r155(){ + if ($this->security) { + $this->compiler->trigger_template_error (self::Err2); + } + $this->prefix_number++; + $this->compiler->prefix_code[] = '<?php $_tmp'.$this->prefix_number.'='.$this->compileVariable("'".$this->yystack[$this->yyidx + -3]->minor."'").';?>'; + $this->_retvalue = '$_tmp'.$this->prefix_number.'('. implode(',',$this->yystack[$this->yyidx + -1]->minor) .')'; + } +#line 2918 "smarty_internal_templateparser.php" +#line 1025 "smarty_internal_templateparser.y" + function yy_r156(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array($this->yystack[$this->yyidx + 0]->minor)); + } +#line 2923 "smarty_internal_templateparser.php" +#line 1042 "smarty_internal_templateparser.y" + function yy_r159(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -2]->minor,array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor))); + } +#line 2928 "smarty_internal_templateparser.php" +#line 1046 "smarty_internal_templateparser.y" + function yy_r160(){ + $this->_retvalue = array(array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor)); + } +#line 2933 "smarty_internal_templateparser.php" +#line 1054 "smarty_internal_templateparser.y" + function yy_r162(){ + $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); + } +#line 2938 "smarty_internal_templateparser.php" +#line 1062 "smarty_internal_templateparser.y" + function yy_r163(){ + $this->_retvalue = array_merge($this->yystack[$this->yyidx + -1]->minor,$this->yystack[$this->yyidx + 0]->minor); + } +#line 2943 "smarty_internal_templateparser.php" +#line 1096 "smarty_internal_templateparser.y" + function yy_r170(){ + $this->_retvalue = '$'.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2948 "smarty_internal_templateparser.php" +#line 1101 "smarty_internal_templateparser.y" + function yy_r171(){ + $this->_retvalue = '$'.$this->yystack[$this->yyidx + -2]->minor.$this->yystack[$this->yyidx + -1]->minor.$this->yystack[$this->yyidx + 0]->minor; + } +#line 2953 "smarty_internal_templateparser.php" +#line 1107 "smarty_internal_templateparser.y" + function yy_r172(){ + $this->_retvalue = '=='; + } +#line 2958 "smarty_internal_templateparser.php" +#line 1111 "smarty_internal_templateparser.y" + function yy_r173(){ + $this->_retvalue = '!='; + } +#line 2963 "smarty_internal_templateparser.php" +#line 1115 "smarty_internal_templateparser.y" + function yy_r174(){ + $this->_retvalue = '>'; + } +#line 2968 "smarty_internal_templateparser.php" +#line 1119 "smarty_internal_templateparser.y" + function yy_r175(){ + $this->_retvalue = '<'; + } +#line 2973 "smarty_internal_templateparser.php" +#line 1123 "smarty_internal_templateparser.y" + function yy_r176(){ + $this->_retvalue = '>='; + } +#line 2978 "smarty_internal_templateparser.php" +#line 1127 "smarty_internal_templateparser.y" + function yy_r177(){ + $this->_retvalue = '<='; + } +#line 2983 "smarty_internal_templateparser.php" +#line 1131 "smarty_internal_templateparser.y" + function yy_r178(){ + $this->_retvalue = '==='; + } +#line 2988 "smarty_internal_templateparser.php" +#line 1135 "smarty_internal_templateparser.y" + function yy_r179(){ + $this->_retvalue = '!=='; + } +#line 2993 "smarty_internal_templateparser.php" +#line 1139 "smarty_internal_templateparser.y" + function yy_r180(){ + $this->_retvalue = '%'; + } +#line 2998 "smarty_internal_templateparser.php" +#line 1143 "smarty_internal_templateparser.y" + function yy_r181(){ + $this->_retvalue = '&&'; + } +#line 3003 "smarty_internal_templateparser.php" +#line 1147 "smarty_internal_templateparser.y" + function yy_r182(){ + $this->_retvalue = '||'; + } +#line 3008 "smarty_internal_templateparser.php" +#line 1151 "smarty_internal_templateparser.y" + function yy_r183(){ + $this->_retvalue = ' XOR '; + } +#line 3013 "smarty_internal_templateparser.php" +#line 1158 "smarty_internal_templateparser.y" + function yy_r184(){ + $this->_retvalue = 'array('.$this->yystack[$this->yyidx + -1]->minor.')'; + } +#line 3018 "smarty_internal_templateparser.php" +#line 1166 "smarty_internal_templateparser.y" + function yy_r186(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.','.$this->yystack[$this->yyidx + 0]->minor; + } +#line 3023 "smarty_internal_templateparser.php" +#line 1174 "smarty_internal_templateparser.y" + function yy_r188(){ + $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor.'=>'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 3028 "smarty_internal_templateparser.php" +#line 1178 "smarty_internal_templateparser.y" + function yy_r189(){ + $this->_retvalue = '\''.$this->yystack[$this->yyidx + -2]->minor.'\'=>'.$this->yystack[$this->yyidx + 0]->minor; + } +#line 3033 "smarty_internal_templateparser.php" +#line 1190 "smarty_internal_templateparser.y" + function yy_r191(){ + $this->_retvalue = "''"; + } +#line 3038 "smarty_internal_templateparser.php" +#line 1194 "smarty_internal_templateparser.y" + function yy_r192(){ + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor->to_smarty_php(); + } +#line 3043 "smarty_internal_templateparser.php" +#line 1199 "smarty_internal_templateparser.y" + function yy_r193(){ + $this->yystack[$this->yyidx + -1]->minor->append_subtree($this->yystack[$this->yyidx + 0]->minor); + $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; + } +#line 3049 "smarty_internal_templateparser.php" +#line 1204 "smarty_internal_templateparser.y" + function yy_r194(){ + $this->_retvalue = new _smarty_doublequoted($this, $this->yystack[$this->yyidx + 0]->minor); + } +#line 3054 "smarty_internal_templateparser.php" +#line 1208 "smarty_internal_templateparser.y" + function yy_r195(){ + $this->_retvalue = new _smarty_code($this, '(string)'.$this->yystack[$this->yyidx + -1]->minor); + } +#line 3059 "smarty_internal_templateparser.php" +#line 1216 "smarty_internal_templateparser.y" + function yy_r197(){ + $this->_retvalue = new _smarty_code($this, '(string)$_smarty_tpl->tpl_vars[\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\']->value'); + } +#line 3064 "smarty_internal_templateparser.php" +#line 1224 "smarty_internal_templateparser.y" + function yy_r199(){ + $this->_retvalue = new _smarty_code($this, '(string)('.$this->yystack[$this->yyidx + -1]->minor.')'); + } +#line 3069 "smarty_internal_templateparser.php" +#line 1228 "smarty_internal_templateparser.y" + function yy_r200(){ + $this->_retvalue = new _smarty_tag($this, $this->yystack[$this->yyidx + 0]->minor); + } +#line 3074 "smarty_internal_templateparser.php" +#line 1232 "smarty_internal_templateparser.y" + function yy_r201(){ + $this->_retvalue = new _smarty_dq_content($this, $this->yystack[$this->yyidx + 0]->minor); + } +#line 3079 "smarty_internal_templateparser.php" + + private $_retvalue; + + function yy_reduce($yyruleno) + { + $yymsp = $this->yystack[$this->yyidx]; + if (self::$yyTraceFILE && $yyruleno >= 0 + && $yyruleno < count(self::$yyRuleName)) { + fprintf(self::$yyTraceFILE, "%sReduce (%d) [%s].\n", + self::$yyTracePrompt, $yyruleno, + self::$yyRuleName[$yyruleno]); + } + + $this->_retvalue = $yy_lefthand_side = null; + if (array_key_exists($yyruleno, self::$yyReduceMap)) { + // call the action + $this->_retvalue = null; + $this->{'yy_r' . self::$yyReduceMap[$yyruleno]}(); + $yy_lefthand_side = $this->_retvalue; + } + $yygoto = self::$yyRuleInfo[$yyruleno]['lhs']; + $yysize = self::$yyRuleInfo[$yyruleno]['rhs']; + $this->yyidx -= $yysize; + for($i = $yysize; $i; $i--) { + // pop all of the right-hand side parameters + array_pop($this->yystack); + } + $yyact = $this->yy_find_reduce_action($this->yystack[$this->yyidx]->stateno, $yygoto); + if ($yyact < self::YYNSTATE) { + if (!self::$yyTraceFILE && $yysize) { + $this->yyidx++; + $x = new TP_yyStackEntry; + $x->stateno = $yyact; + $x->major = $yygoto; + $x->minor = $yy_lefthand_side; + $this->yystack[$this->yyidx] = $x; + } else { + $this->yy_shift($yyact, $yygoto, $yy_lefthand_side); + } + } elseif ($yyact == self::YYNSTATE + self::YYNRULE + 1) { + $this->yy_accept(); + } + } + + function yy_parse_failed() + { + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sFail!\n", self::$yyTracePrompt); + } + while ($this->yyidx >= 0) { + $this->yy_pop_parser_stack(); + } + } + + function yy_syntax_error($yymajor, $TOKEN) + { +#line 77 "smarty_internal_templateparser.y" + + $this->internalError = true; + $this->yymajor = $yymajor; + $this->compiler->trigger_template_error(); +#line 3142 "smarty_internal_templateparser.php" + } + + function yy_accept() + { + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sAccept!\n", self::$yyTracePrompt); + } + while ($this->yyidx >= 0) { + $stack = $this->yy_pop_parser_stack(); + } +#line 69 "smarty_internal_templateparser.y" + + $this->successful = !$this->internalError; + $this->internalError = false; + $this->retvalue = $this->_retvalue; + //echo $this->retvalue."\n\n"; +#line 3160 "smarty_internal_templateparser.php" + } + + function doParse($yymajor, $yytokenvalue) + { + $yyerrorhit = 0; /* True if yymajor has invoked an error */ + + if ($this->yyidx === null || $this->yyidx < 0) { + $this->yyidx = 0; + $this->yyerrcnt = -1; + $x = new TP_yyStackEntry; + $x->stateno = 0; + $x->major = 0; + $this->yystack = array(); + array_push($this->yystack, $x); + } + $yyendofinput = ($yymajor==0); + + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sInput %s\n", + self::$yyTracePrompt, $this->yyTokenName[$yymajor]); + } + + do { + $yyact = $this->yy_find_shift_action($yymajor); + if ($yymajor < self::YYERRORSYMBOL && + !$this->yy_is_expected_token($yymajor)) { + // force a syntax error + $yyact = self::YY_ERROR_ACTION; + } + if ($yyact < self::YYNSTATE) { + $this->yy_shift($yyact, $yymajor, $yytokenvalue); + $this->yyerrcnt--; + if ($yyendofinput && $this->yyidx >= 0) { + $yymajor = 0; + } else { + $yymajor = self::YYNOCODE; + } + } elseif ($yyact < self::YYNSTATE + self::YYNRULE) { + $this->yy_reduce($yyact - self::YYNSTATE); + } elseif ($yyact == self::YY_ERROR_ACTION) { + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sSyntax Error!\n", + self::$yyTracePrompt); + } + if (self::YYERRORSYMBOL) { + if ($this->yyerrcnt < 0) { + $this->yy_syntax_error($yymajor, $yytokenvalue); + } + $yymx = $this->yystack[$this->yyidx]->major; + if ($yymx == self::YYERRORSYMBOL || $yyerrorhit ){ + if (self::$yyTraceFILE) { + fprintf(self::$yyTraceFILE, "%sDiscard input token %s\n", + self::$yyTracePrompt, $this->yyTokenName[$yymajor]); + } + $this->yy_destructor($yymajor, $yytokenvalue); + $yymajor = self::YYNOCODE; + } else { + while ($this->yyidx >= 0 && + $yymx != self::YYERRORSYMBOL && + ($yyact = $this->yy_find_shift_action(self::YYERRORSYMBOL)) >= self::YYNSTATE + ){ + $this->yy_pop_parser_stack(); + } + if ($this->yyidx < 0 || $yymajor==0) { + $this->yy_destructor($yymajor, $yytokenvalue); + $this->yy_parse_failed(); + $yymajor = self::YYNOCODE; + } elseif ($yymx != self::YYERRORSYMBOL) { + $u2 = 0; + $this->yy_shift($yyact, self::YYERRORSYMBOL, $u2); + } + } + $this->yyerrcnt = 3; + $yyerrorhit = 1; + } else { + if ($this->yyerrcnt <= 0) { + $this->yy_syntax_error($yymajor, $yytokenvalue); + } + $this->yyerrcnt = 3; + $this->yy_destructor($yymajor, $yytokenvalue); + if ($yyendofinput) { + $this->yy_parse_failed(); + } + $yymajor = self::YYNOCODE; + } + } else { + $this->yy_accept(); + $yymajor = self::YYNOCODE; + } + } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0); + } +} diff --git a/include/smarty/libs/sysplugins/smarty_internal_utility.php b/include/smarty/libs/sysplugins/smarty_internal_utility.php new file mode 100644 index 000000000..f19ca01f8 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_utility.php @@ -0,0 +1,830 @@ +<?php +/** + * Project: Smarty: the PHP compiling template engine + * File: smarty_internal_utility.php + * SVN: $Id: $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For questions, help, comments, discussion, etc., please join the + * Smarty mailing list. Send a blank e-mail to + * smarty-discussion-subscribe@googlegroups.com + * + * @link http://www.smarty.net/ + * @copyright 2008 New Digital Group, Inc. + * @author Monte Ohrt <monte at ohrt dot com> + * @author Uwe Tews + * @package Smarty + * @subpackage PluginsInternal + * @version 3-SVN$Rev: 3286 $ + */ + + +/** + * Utility class + * + * @package Smarty + * @subpackage Security + */ +class Smarty_Internal_Utility { + + /** + * private constructor to prevent calls creation of new instances + */ + private final function __construct() + { + // intentionally left blank + } + + /** + * Compile all template files + * + * @param string $extension template file name extension + * @param bool $force_compile force all to recompile + * @param int $time_limit set maximum execution time + * @param int $max_errors set maximum allowed errors + * @param Smarty $smarty Smarty instance + * @return integer number of template files compiled + */ + public static function compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, Smarty $smarty) + { + // switch off time limit + if (function_exists('set_time_limit')) { + @set_time_limit($time_limit); + } + $smarty->force_compile = $force_compile; + $_count = 0; + $_error_count = 0; + // loop over array of template directories + foreach($smarty->getTemplateDir() as $_dir) { + $_compileDirs = new RecursiveDirectoryIterator($_dir); + $_compile = new RecursiveIteratorIterator($_compileDirs); + foreach ($_compile as $_fileinfo) { + $_file = $_fileinfo->getFilename(); + if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue; + if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue; + if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { + $_template_file = $_file; + } else { + $_template_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file; + } + echo '<br>', $_dir, '---', $_template_file; + flush(); + $_start_time = microtime(true); + try { + $_tpl = $smarty->createTemplate($_template_file,null,null,null,false); + if ($_tpl->mustCompile()) { + $_tpl->compileTemplateSource(); + $_count++; + echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; + flush(); + } else { + echo ' is up to date'; + flush(); + } + } + catch (Exception $e) { + echo 'Error: ', $e->getMessage(), "<br><br>"; + $_error_count++; + } + // free memory + $smarty->template_objects = array(); + $_tpl->smarty->template_objects = array(); + $_tpl = null; + if ($max_errors !== null && $_error_count == $max_errors) { + echo '<br><br>too many errors'; + exit(); + } + } + } + return $_count; + } + + /** + * Compile all config files + * + * @param string $extension config file name extension + * @param bool $force_compile force all to recompile + * @param int $time_limit set maximum execution time + * @param int $max_errors set maximum allowed errors + * @param Smarty $smarty Smarty instance + * @return integer number of config files compiled + */ + public static function compileAllConfig($extention, $force_compile, $time_limit, $max_errors, Smarty $smarty) + { + // switch off time limit + if (function_exists('set_time_limit')) { + @set_time_limit($time_limit); + } + $smarty->force_compile = $force_compile; + $_count = 0; + $_error_count = 0; + // loop over array of template directories + foreach($smarty->getConfigDir() as $_dir) { + $_compileDirs = new RecursiveDirectoryIterator($_dir); + $_compile = new RecursiveIteratorIterator($_compileDirs); + foreach ($_compile as $_fileinfo) { + $_file = $_fileinfo->getFilename(); + if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue; + if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue; + if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { + $_config_file = $_file; + } else { + $_config_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file; + } + echo '<br>', $_dir, '---', $_config_file; + flush(); + $_start_time = microtime(true); + try { + $_config = new Smarty_Internal_Config($_config_file, $smarty); + if ($_config->mustCompile()) { + $_config->compileConfigSource(); + $_count++; + echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; + flush(); + } else { + echo ' is up to date'; + flush(); + } + } + catch (Exception $e) { + echo 'Error: ', $e->getMessage(), "<br><br>"; + $_error_count++; + } + if ($max_errors !== null && $_error_count == $max_errors) { + echo '<br><br>too many errors'; + exit(); + } + } + } + return $_count; + } + + /** + * Delete compiled template file + * + * @param string $resource_name template name + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @param Smarty $smarty Smarty instance + * @return integer number of template files deleted + */ + public static function clearCompiledTemplate($resource_name, $compile_id, $exp_time, Smarty $smarty) + { + $_compile_dir = $smarty->getCompileDir(); + $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null; + $_dir_sep = $smarty->use_sub_dirs ? DS : '^'; + if (isset($resource_name)) { + $_save_stat = $smarty->caching; + $smarty->caching = false; + $tpl = new $smarty->template_class($resource_name, $smarty); + $smarty->caching = $_save_stat; + + // remove from template cache + $tpl->source; // have the template registered before unset() + if ($smarty->allow_ambiguous_resources) { + $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id; + } else { + $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id; + } + if (isset($_templateId[150])) { + $_templateId = sha1($_templateId); + } + unset($smarty->template_objects[$_templateId]); + + if ($tpl->source->exists) { + $_resource_part_1 = basename(str_replace('^', '/', $tpl->compiled->filepath)); + $_resource_part_1_length = strlen($_resource_part_1); + } else { + return 0; + } + + $_resource_part_2 = str_replace('.php','.cache.php',$_resource_part_1); + $_resource_part_2_length = strlen($_resource_part_2); + } + $_dir = $_compile_dir; + if ($smarty->use_sub_dirs && isset($_compile_id)) { + $_dir .= $_compile_id . $_dir_sep; + } + if (isset($_compile_id)) { + $_compile_id_part = $_compile_dir . $_compile_id . $_dir_sep; + $_compile_id_part_length = strlen($_compile_id_part); + } + $_count = 0; + try { + $_compileDirs = new RecursiveDirectoryIterator($_dir); + // NOTE: UnexpectedValueException thrown for PHP >= 5.3 + } catch (Exception $e) { + return 0; + } + $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); + foreach ($_compile as $_file) { + if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) + continue; + + $_filepath = (string) $_file; + + if ($_file->isDir()) { + if (!$_compile->isDot()) { + // delete folder if empty + @rmdir($_file->getPathname()); + } + } else { + $unlink = false; + if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) && !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length))) + && (!isset($resource_name) + || (isset($_filepath[$_resource_part_1_length]) + && substr_compare($_filepath, $_resource_part_1, -$_resource_part_1_length, $_resource_part_1_length) == 0) + || (isset($_filepath[$_resource_part_2_length]) + && substr_compare($_filepath, $_resource_part_2, -$_resource_part_2_length, $_resource_part_2_length) == 0))) { + if (isset($exp_time)) { + if (time() - @filemtime($_filepath) >= $exp_time) { + $unlink = true; + } + } else { + $unlink = true; + } + } + + if ($unlink && @unlink($_filepath)) { + $_count++; + } + } + } + // clear compiled cache + Smarty_Resource::$sources = array(); + Smarty_Resource::$compileds = array(); + return $_count; + } + + /** + * Return array of tag/attributes of all tags used by an template + * + * @param Smarty_Internal_Template $templae template object + * @return array of tag/attributes + */ + public static function getTags(Smarty_Internal_Template $template) + { + $template->smarty->get_used_tags = true; + $template->compileTemplateSource(); + return $template->used_tags; + } + + + /** + * diagnose Smarty setup + * + * If $errors is secified, the diagnostic report will be appended to the array, rather than being output. + * + * @param Smarty $smarty Smarty instance to test + * @param array $errors array to push results into rather than outputting them + * @return bool status, true if everything is fine, false else + */ + public static function testInstall(Smarty $smarty, &$errors=null) + { + $status = true; + + if ($errors === null) { + echo "<PRE>\n"; + echo "Smarty Installation test...\n"; + echo "Testing template directory...\n"; + } + + $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); + + // test if all registered template_dir are accessible + foreach($smarty->getTemplateDir() as $template_dir) { + $_template_dir = $template_dir; + $template_dir = realpath($template_dir); + // resolve include_path or fail existance + if (!$template_dir) { + if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $template_dir = stream_resolve_include_path($_template_dir); + } else { + $template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir); + } + + if ($template_dir !== false) { + if ($errors === null) { + echo "$template_dir is OK.\n"; + } + + continue; + } else { + $status = false; + $message = "FAILED: $_template_dir does not exist (and couldn't be found in include_path either)"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['template_dir'] = $message; + } + + continue; + } + } else { + $status = false; + $message = "FAILED: $_template_dir does not exist"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['template_dir'] = $message; + } + + continue; + } + } + + if (!is_dir($template_dir)) { + $status = false; + $message = "FAILED: $template_dir is not a directory"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['template_dir'] = $message; + } + } elseif (!is_readable($template_dir)) { + $status = false; + $message = "FAILED: $template_dir is not readable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['template_dir'] = $message; + } + } else { + if ($errors === null) { + echo "$template_dir is OK.\n"; + } + } + } + + + if ($errors === null) { + echo "Testing compile directory...\n"; + } + + // test if registered compile_dir is accessible + $__compile_dir = $smarty->getCompileDir(); + $_compile_dir = realpath($__compile_dir); + if (!$_compile_dir) { + $status = false; + $message = "FAILED: {$__compile_dir} does not exist"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['compile_dir'] = $message; + } + } elseif (!is_dir($_compile_dir)) { + $status = false; + $message = "FAILED: {$_compile_dir} is not a directory"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['compile_dir'] = $message; + } + } elseif (!is_readable($_compile_dir)) { + $status = false; + $message = "FAILED: {$_compile_dir} is not readable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['compile_dir'] = $message; + } + } elseif (!is_writable($_compile_dir)) { + $status = false; + $message = "FAILED: {$_compile_dir} is not writable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['compile_dir'] = $message; + } + } else { + if ($errors === null) { + echo "{$_compile_dir} is OK.\n"; + } + } + + + if ($errors === null) { + echo "Testing plugins directory...\n"; + } + + // test if all registered plugins_dir are accessible + // and if core plugins directory is still registered + $_core_plugins_dir = realpath(dirname(__FILE__) .'/../plugins'); + $_core_plugins_available = false; + foreach($smarty->getPluginsDir() as $plugin_dir) { + $_plugin_dir = $plugin_dir; + $plugin_dir = realpath($plugin_dir); + // resolve include_path or fail existance + if (!$plugin_dir) { + if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $plugin_dir = stream_resolve_include_path($_plugin_dir); + } else { + $plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir); + } + + if ($plugin_dir !== false) { + if ($errors === null) { + echo "$plugin_dir is OK.\n"; + } + + continue; + } else { + $status = false; + $message = "FAILED: $_plugin_dir does not exist (and couldn't be found in include_path either)"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['plugins_dir'] = $message; + } + + continue; + } + } else { + $status = false; + $message = "FAILED: $_plugin_dir does not exist"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['plugins_dir'] = $message; + } + + continue; + } + } + + if (!is_dir($plugin_dir)) { + $status = false; + $message = "FAILED: $plugin_dir is not a directory"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['plugins_dir'] = $message; + } + } elseif (!is_readable($plugin_dir)) { + $status = false; + $message = "FAILED: $plugin_dir is not readable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['plugins_dir'] = $message; + } + } elseif ($_core_plugins_dir && $_core_plugins_dir == realpath($plugin_dir)) { + $_core_plugins_available = true; + if ($errors === null) { + echo "$plugin_dir is OK.\n"; + } + } else { + if ($errors === null) { + echo "$plugin_dir is OK.\n"; + } + } + } + if (!$_core_plugins_available) { + $status = false; + $message = "WARNING: Smarty's own libs/plugins is not available"; + if ($errors === null) { + echo $message . ".\n"; + } elseif (!isset($errors['plugins_dir'])) { + $errors['plugins_dir'] = $message; + } + } + + if ($errors === null) { + echo "Testing cache directory...\n"; + } + + + // test if all registered cache_dir is accessible + $__cache_dir = $smarty->getCacheDir(); + $_cache_dir = realpath($__cache_dir); + if (!$_cache_dir) { + $status = false; + $message = "FAILED: {$__cache_dir} does not exist"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['cache_dir'] = $message; + } + } elseif (!is_dir($_cache_dir)) { + $status = false; + $message = "FAILED: {$_cache_dir} is not a directory"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['cache_dir'] = $message; + } + } elseif (!is_readable($_cache_dir)) { + $status = false; + $message = "FAILED: {$_cache_dir} is not readable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['cache_dir'] = $message; + } + } elseif (!is_writable($_cache_dir)) { + $status = false; + $message = "FAILED: {$_cache_dir} is not writable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['cache_dir'] = $message; + } + } else { + if ($errors === null) { + echo "{$_cache_dir} is OK.\n"; + } + } + + + if ($errors === null) { + echo "Testing configs directory...\n"; + } + + // test if all registered config_dir are accessible + foreach($smarty->getConfigDir() as $config_dir) { + $_config_dir = $config_dir; + $config_dir = realpath($config_dir); + // resolve include_path or fail existance + if (!$config_dir) { + if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $config_dir = stream_resolve_include_path($_config_dir); + } else { + $config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir); + } + + if ($config_dir !== false) { + if ($errors === null) { + echo "$config_dir is OK.\n"; + } + + continue; + } else { + $status = false; + $message = "FAILED: $_config_dir does not exist (and couldn't be found in include_path either)"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['config_dir'] = $message; + } + + continue; + } + } else { + $status = false; + $message = "FAILED: $_config_dir does not exist"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['config_dir'] = $message; + } + + continue; + } + } + + if (!is_dir($config_dir)) { + $status = false; + $message = "FAILED: $config_dir is not a directory"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['config_dir'] = $message; + } + } elseif (!is_readable($config_dir)) { + $status = false; + $message = "FAILED: $config_dir is not readable"; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['config_dir'] = $message; + } + } else { + if ($errors === null) { + echo "$config_dir is OK.\n"; + } + } + } + + + if ($errors === null) { + echo "Testing sysplugin files...\n"; + } + // test if sysplugins are available + $source = SMARTY_SYSPLUGINS_DIR; + if (is_dir($source)) { + $expected = array( + "smarty_cacheresource.php" => true, + "smarty_cacheresource_custom.php" => true, + "smarty_cacheresource_keyvaluestore.php" => true, + "smarty_config_source.php" => true, + "smarty_internal_cacheresource_file.php" => true, + "smarty_internal_compile_append.php" => true, + "smarty_internal_compile_assign.php" => true, + "smarty_internal_compile_block.php" => true, + "smarty_internal_compile_break.php" => true, + "smarty_internal_compile_call.php" => true, + "smarty_internal_compile_capture.php" => true, + "smarty_internal_compile_config_load.php" => true, + "smarty_internal_compile_continue.php" => true, + "smarty_internal_compile_debug.php" => true, + "smarty_internal_compile_eval.php" => true, + "smarty_internal_compile_extends.php" => true, + "smarty_internal_compile_for.php" => true, + "smarty_internal_compile_foreach.php" => true, + "smarty_internal_compile_function.php" => true, + "smarty_internal_compile_if.php" => true, + "smarty_internal_compile_include.php" => true, + "smarty_internal_compile_include_php.php" => true, + "smarty_internal_compile_insert.php" => true, + "smarty_internal_compile_ldelim.php" => true, + "smarty_internal_compile_nocache.php" => true, + "smarty_internal_compile_private_block_plugin.php" => true, + "smarty_internal_compile_private_function_plugin.php" => true, + "smarty_internal_compile_private_modifier.php" => true, + "smarty_internal_compile_private_object_block_function.php" => true, + "smarty_internal_compile_private_object_function.php" => true, + "smarty_internal_compile_private_print_expression.php" => true, + "smarty_internal_compile_private_registered_block.php" => true, + "smarty_internal_compile_private_registered_function.php" => true, + "smarty_internal_compile_private_special_variable.php" => true, + "smarty_internal_compile_rdelim.php" => true, + "smarty_internal_compile_section.php" => true, + "smarty_internal_compile_setfilter.php" => true, + "smarty_internal_compile_while.php" => true, + "smarty_internal_compilebase.php" => true, + "smarty_internal_config.php" => true, + "smarty_internal_config_file_compiler.php" => true, + "smarty_internal_configfilelexer.php" => true, + "smarty_internal_configfileparser.php" => true, + "smarty_internal_data.php" => true, + "smarty_internal_debug.php" => true, + "smarty_internal_filter_handler.php" => true, + "smarty_internal_function_call_handler.php" => true, + "smarty_internal_get_include_path.php" => true, + "smarty_internal_nocache_insert.php" => true, + "smarty_internal_parsetree.php" => true, + "smarty_internal_resource_eval.php" => true, + "smarty_internal_resource_extends.php" => true, + "smarty_internal_resource_file.php" => true, + "smarty_internal_resource_registered.php" => true, + "smarty_internal_resource_stream.php" => true, + "smarty_internal_resource_string.php" => true, + "smarty_internal_smartytemplatecompiler.php" => true, + "smarty_internal_template.php" => true, + "smarty_internal_templatebase.php" => true, + "smarty_internal_templatecompilerbase.php" => true, + "smarty_internal_templatelexer.php" => true, + "smarty_internal_templateparser.php" => true, + "smarty_internal_utility.php" => true, + "smarty_internal_write_file.php" => true, + "smarty_resource.php" => true, + "smarty_resource_custom.php" => true, + "smarty_resource_recompiled.php" => true, + "smarty_resource_uncompiled.php" => true, + "smarty_security.php" => true, + ); + $iterator = new DirectoryIterator($source); + foreach ($iterator as $file) { + if (!$file->isDot()) { + $filename = $file->getFilename(); + if (isset($expected[$filename])) { + unset($expected[$filename]); + } + } + } + if ($expected) { + $status = false; + $message = "FAILED: files missing from libs/sysplugins: ". join(', ', array_keys($expected)); + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['sysplugins'] = $message; + } + } elseif ($errors === null) { + echo "... OK\n"; + } + } else { + $status = false; + $message = "FAILED: ". SMARTY_SYSPLUGINS_DIR .' is not a directory'; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['sysplugins_dir_constant'] = $message; + } + } + + if ($errors === null) { + echo "Testing plugin files...\n"; + } + // test if core plugins are available + $source = SMARTY_PLUGINS_DIR; + if (is_dir($source)) { + $expected = array( + "block.textformat.php" => true, + "function.counter.php" => true, + "function.cycle.php" => true, + "function.fetch.php" => true, + "function.html_checkboxes.php" => true, + "function.html_image.php" => true, + "function.html_options.php" => true, + "function.html_radios.php" => true, + "function.html_select_date.php" => true, + "function.html_select_time.php" => true, + "function.html_table.php" => true, + "function.mailto.php" => true, + "function.math.php" => true, + "modifier.capitalize.php" => true, + "modifier.date_format.php" => true, + "modifier.debug_print_var.php" => true, + "modifier.escape.php" => true, + "modifier.regex_replace.php" => true, + "modifier.replace.php" => true, + "modifier.spacify.php" => true, + "modifier.truncate.php" => true, + "modifiercompiler.cat.php" => true, + "modifiercompiler.count_characters.php" => true, + "modifiercompiler.count_paragraphs.php" => true, + "modifiercompiler.count_sentences.php" => true, + "modifiercompiler.count_words.php" => true, + "modifiercompiler.default.php" => true, + "modifiercompiler.escape.php" => true, + "modifiercompiler.from_charset.php" => true, + "modifiercompiler.indent.php" => true, + "modifiercompiler.lower.php" => true, + "modifiercompiler.noprint.php" => true, + "modifiercompiler.string_format.php" => true, + "modifiercompiler.strip.php" => true, + "modifiercompiler.strip_tags.php" => true, + "modifiercompiler.to_charset.php" => true, + "modifiercompiler.unescape.php" => true, + "modifiercompiler.upper.php" => true, + "modifiercompiler.wordwrap.php" => true, + "outputfilter.trimwhitespace.php" => true, + "shared.escape_special_chars.php" => true, + "shared.literal_compiler_param.php" => true, + "shared.make_timestamp.php" => true, + "shared.mb_str_replace.php" => true, + "shared.mb_unicode.php" => true, + "shared.mb_wordwrap.php" => true, + "variablefilter.htmlspecialchars.php" => true, + ); + $iterator = new DirectoryIterator($source); + foreach ($iterator as $file) { + if (!$file->isDot()) { + $filename = $file->getFilename(); + if (isset($expected[$filename])) { + unset($expected[$filename]); + } + } + } + if ($expected) { + $status = false; + $message = "FAILED: files missing from libs/plugins: ". join(', ', array_keys($expected)); + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['plugins'] = $message; + } + } elseif ($errors === null) { + echo "... OK\n"; + } + } else { + $status = false; + $message = "FAILED: ". SMARTY_PLUGINS_DIR .' is not a directory'; + if ($errors === null) { + echo $message . ".\n"; + } else { + $errors['plugins_dir_constant'] = $message; + } + } + + if ($errors === null) { + echo "Tests complete.\n"; + echo "</PRE>\n"; + } + + return $status; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_internal_write_file.php b/include/smarty/libs/sysplugins/smarty_internal_write_file.php new file mode 100644 index 000000000..e5d19ce8d --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_internal_write_file.php @@ -0,0 +1,88 @@ +<?php +/** + * Smarty write file plugin + * + * @package Smarty + * @subpackage PluginsInternal + * @author Monte Ohrt + */ + +/** + * Smarty Internal Write File Class + * + * @package Smarty + * @subpackage PluginsInternal + */ +class Smarty_Internal_Write_File { + + /** + * Writes file in a safe way to disk + * + * @param string $_filepath complete filepath + * @param string $_contents file content + * @param Smarty $smarty smarty instance + * @return boolean true + */ + public static function writeFile($_filepath, $_contents, Smarty $smarty) + { + $_error_reporting = error_reporting(); + error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING); + if ($smarty->_file_perms !== null) { + $old_umask = umask(0); + } + + $_dirpath = dirname($_filepath); + // if subdirs, create dir structure + if ($_dirpath !== '.' && !file_exists($_dirpath)) { + mkdir($_dirpath, $smarty->_dir_perms === null ? 0777 : $smarty->_dir_perms, true); + } + + // write to tmp file, then move to overt file lock race condition + $_tmp_file = $_dirpath . DS . uniqid('wrt', true); + if (!file_put_contents($_tmp_file, $_contents)) { + error_reporting($_error_reporting); + throw new SmartyException("unable to write file {$_tmp_file}"); + return false; + } + + /* + * Windows' rename() fails if the destination exists, + * Linux' rename() properly handles the overwrite. + * Simply unlink()ing a file might cause other processes + * currently reading that file to fail, but linux' rename() + * seems to be smart enough to handle that for us. + */ + if (Smarty::$_IS_WINDOWS) { + // remove original file + @unlink($_filepath); + // rename tmp file + $success = @rename($_tmp_file, $_filepath); + } else { + // rename tmp file + $success = @rename($_tmp_file, $_filepath); + if (!$success) { + // remove original file + @unlink($_filepath); + // rename tmp file + $success = @rename($_tmp_file, $_filepath); + } + } + + if (!$success) { + error_reporting($_error_reporting); + throw new SmartyException("unable to write file {$_filepath}"); + return false; + } + + if ($smarty->_file_perms !== null) { + // set file permissions + chmod($_filepath, $smarty->_file_perms); + umask($old_umask); + } + error_reporting($_error_reporting); + return true; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_resource.php b/include/smarty/libs/sysplugins/smarty_resource.php new file mode 100644 index 000000000..55f1497fb --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_resource.php @@ -0,0 +1,857 @@ +<?php +/** + * Smarty Resource Plugin + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + */ + +/** + * Smarty Resource Plugin + * + * Base implementation for resource plugins + * + * @package Smarty + * @subpackage TemplateResources + */ +abstract class Smarty_Resource { + /** + * cache for Smarty_Template_Source instances + * @var array + */ + public static $sources = array(); + /** + * cache for Smarty_Template_Compiled instances + * @var array + */ + public static $compileds = array(); + /** + * cache for Smarty_Resource instances + * @var array + */ + public static $resources = array(); + /** + * resource types provided by the core + * @var array + */ + protected static $sysplugins = array( + 'file' => true, + 'string' => true, + 'extends' => true, + 'stream' => true, + 'eval' => true, + 'php' => true + ); + + /** + * Name of the Class to compile this resource's contents with + * @var string + */ + public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler'; + + /** + * Name of the Class to tokenize this resource's contents with + * @var string + */ + public $template_lexer_class = 'Smarty_Internal_Templatelexer'; + + /** + * Name of the Class to parse this resource's contents with + * @var string + */ + public $template_parser_class = 'Smarty_Internal_Templateparser'; + + /** + * Load template's source into current template object + * + * {@internal The loaded source is assigned to $_template->source->content directly.}} + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public abstract function getContent(Smarty_Template_Source $source); + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + */ + public abstract function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null); + + /** + * populate Source Object with timestamp and exists from Resource + * + * @param Smarty_Template_Source $source source object + */ + public function populateTimestamp(Smarty_Template_Source $source) + { + // intentionally left blank + } + + + /** + * modify resource_name according to resource handlers specifications + * + * @param Smarty $smarty Smarty instance + * @param string $resource_name resource_name to make unique + * @return string unique resource name + */ + protected function buildUniqueResourceName(Smarty $smarty, $resource_name) + { + return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name; + } + + /** + * populate Compiled Object with compiled filepath + * + * @param Smarty_Template_Compiled $compiled compiled object + * @param Smarty_Internal_Template $_template template object + */ + public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) + { + $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null; + $_filepath = $compiled->source->uid; + // if use_sub_dirs, break file into directories + if ($_template->smarty->use_sub_dirs) { + $_filepath = substr($_filepath, 0, 2) . DS + . substr($_filepath, 2, 2) . DS + . substr($_filepath, 4, 2) . DS + . $_filepath; + } + $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^'; + if (isset($_compile_id)) { + $_filepath = $_compile_id . $_compile_dir_sep . $_filepath; + } + // caching token + if ($_template->caching) { + $_cache = '.cache'; + } else { + $_cache = ''; + } + $_compile_dir = $_template->smarty->getCompileDir(); + // set basename if not specified + $_basename = $this->getBasename($compiled->source); + if ($_basename === null) { + $_basename = basename( preg_replace('![^\w\/]+!', '_', $compiled->source->name) ); + } + // separate (optional) basename by dot + if ($_basename) { + $_basename = '.' . $_basename; + } + + $compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php'; + } + + /** + * Normalize Paths "foo/../bar" to "bar" + * + * @param string $_path path to normalize + * @param boolean $ds respect windows directory separator + * @return string normalized path + */ + protected function normalizePath($_path, $ds=true) + { + if ($ds) { + // don't we all just love windows? + $_path = str_replace('\\', '/', $_path); + } + + $offset = 0; + + // resolve simples + $_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path); + // resolve parents + while (true) { + $_parent = strpos($_path, '/../', $offset); + if (!$_parent) { + break; + } else if ($_path[$_parent - 1] === '.') { + $offset = $_parent + 3; + continue; + } + + $_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1); + if ($_pos === false) { + // don't we all just love windows? + $_pos = $_parent; + } + + $_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos); + } + + if ($ds && DS != '/') { + // don't we all just love windows? + $_path = str_replace('/', '\\', $_path); + } + + return $_path; + } + + /** + * build template filepath by traversing the template_dir array + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @return string fully qualified filepath + * @throws SmartyException if default template handler is registered but not callable + */ + protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $file = $source->name; + if ($source instanceof Smarty_Config_Source) { + $_directories = $source->smarty->getConfigDir(); + $_default_handler = $source->smarty->default_config_handler_func; + } else { + $_directories = $source->smarty->getTemplateDir(); + $_default_handler = $source->smarty->default_template_handler_func; + } + + // go relative to a given template? + $_file_is_dotted = $file[0] == '.' && ($file[1] == '.' || $file[1] == '/' || $file[1] == "\\"); + if ($_template && $_template->parent instanceof Smarty_Internal_Template && $_file_is_dotted) { + if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) { + throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'"); + } + $file = dirname($_template->parent->source->filepath) . DS . $file; + $_file_exact_match = true; + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { + // the path gained from the parent template is relative to the current working directory + // as expansions (like include_path) have already been done + $file = getcwd() . DS . $file; + } + } + + // resolve relative path + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { + // don't we all just love windows? + $_path = str_replace('\\', '/', $file); + $_path = DS . trim($file, '/'); + $_was_relative = true; + } else { + // don't we all just love windows? + $_path = str_replace('\\', '/', $file); + } + $_path = $this->normalizePath($_path, false); + if (DS != '/') { + // don't we all just love windows? + $_path = str_replace('/', '\\', $_path); + } + // revert to relative + if (isset($_was_relative)) { + $_path = substr($_path, 1); + } + + // this is only required for directories + $file = rtrim($_path, '/\\'); + + // files relative to a template only get one shot + if (isset($_file_exact_match)) { + return $this->fileExists($source, $file) ? $file : false; + } + + // template_dir index? + if (preg_match('#^\[(?P<key>[^\]]+)\](?P<file>.+)$#', $file, $match)) { + $_directory = null; + // try string indexes + if (isset($_directories[$match['key']])) { + $_directory = $_directories[$match['key']]; + } else if (is_numeric($match['key'])) { + // try numeric index + $match['key'] = (int) $match['key']; + if (isset($_directories[$match['key']])) { + $_directory = $_directories[$match['key']]; + } else { + // try at location index + $keys = array_keys($_directories); + $_directory = $_directories[$keys[$match['key']]]; + } + } + + if ($_directory) { + $_file = substr($file, strpos($file, ']') + 1); + $_filepath = $_directory . $_file; + if ($this->fileExists($source, $_filepath)) { + return $_filepath; + } + } + } + + $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); + + // relative file name? + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { + foreach ($_directories as $_directory) { + $_filepath = $_directory . $file; + if ($this->fileExists($source, $_filepath)) { + return $this->normalizePath($_filepath); + } + if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) { + // try PHP include_path + if ($_stream_resolve_include_path) { + $_filepath = stream_resolve_include_path($_filepath); + } else { + $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath); + } + + if ($_filepath !== false) { + if ($this->fileExists($source, $_filepath)) { + return $this->normalizePath($_filepath); + } + } + } + } + } + + // try absolute filepath + if ($this->fileExists($source, $file)) { + return $file; + } + + // no tpl file found + if ($_default_handler) { + if (!is_callable($_default_handler)) { + if ($source instanceof Smarty_Config_Source) { + throw new SmartyException("Default config handler not callable"); + } else { + throw new SmartyException("Default template handler not callable"); + } + } + $_return = call_user_func_array($_default_handler, + array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty)); + if (is_string($_return)) { + $source->timestamp = @filemtime($_return); + $source->exists = !!$source->timestamp; + return $_return; + } elseif ($_return === true) { + $source->content = $_content; + $source->timestamp = $_timestamp; + $source->exists = true; + return $_filepath; + } + } + + // give up + return false; + } + + /** + * test is file exists and save timestamp + * + * @param Smarty_Template_Source $source source object + * @param string $file file name + * @return bool true if file exists + */ + protected function fileExists(Smarty_Template_Source $source, $file) + { + $source->timestamp = @filemtime($file); + return $source->exists = !!$source->timestamp; + + } + + /** + * Determine basename for compiled filename + * + * @param Smarty_Template_Source $source source object + * @return string resource's basename + */ + protected function getBasename(Smarty_Template_Source $source) + { + return null; + } + + /** + * Load Resource Handler + * + * @param Smarty $smarty smarty object + * @param string $type name of the resource + * @return Smarty_Resource Resource Handler + */ + public static function load(Smarty $smarty, $type) + { + // try smarty's cache + if (isset($smarty->_resource_handlers[$type])) { + return $smarty->_resource_handlers[$type]; + } + + // try registered resource + if (isset($smarty->registered_resources[$type])) { + if ($smarty->registered_resources[$type] instanceof Smarty_Resource) { + $smarty->_resource_handlers[$type] = $smarty->registered_resources[$type]; + // note registered to smarty is not kept unique! + return $smarty->_resource_handlers[$type]; + } + + if (!isset(self::$resources['registered'])) { + self::$resources['registered'] = new Smarty_Internal_Resource_Registered(); + } + if (!isset($smarty->_resource_handlers[$type])) { + $smarty->_resource_handlers[$type] = self::$resources['registered']; + } + + return $smarty->_resource_handlers[$type]; + } + + // try sysplugins dir + if (isset(self::$sysplugins[$type])) { + if (!isset(self::$resources[$type])) { + $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type); + self::$resources[$type] = new $_resource_class(); + } + return $smarty->_resource_handlers[$type] = self::$resources[$type]; + } + + // try plugins dir + $_resource_class = 'Smarty_Resource_' . ucfirst($type); + if ($smarty->loadPlugin($_resource_class)) { + if (isset(self::$resources[$type])) { + return $smarty->_resource_handlers[$type] = self::$resources[$type]; + } + + if (class_exists($_resource_class, false)) { + self::$resources[$type] = new $_resource_class(); + return $smarty->_resource_handlers[$type] = self::$resources[$type]; + } else { + $smarty->registerResource($type, array( + "smarty_resource_{$type}_source", + "smarty_resource_{$type}_timestamp", + "smarty_resource_{$type}_secure", + "smarty_resource_{$type}_trusted" + )); + + // give it another try, now that the resource is registered properly + return self::load($smarty, $type); + } + } + + // try streams + $_known_stream = stream_get_wrappers(); + if (in_array($type, $_known_stream)) { + // is known stream + if (is_object($smarty->security_policy)) { + $smarty->security_policy->isTrustedStream($type); + } + if (!isset(self::$resources['stream'])) { + self::$resources['stream'] = new Smarty_Internal_Resource_Stream(); + } + return $smarty->_resource_handlers[$type] = self::$resources['stream']; + } + + // TODO: try default_(template|config)_handler + + // give up + throw new SmartyException("Unkown resource type '{$type}'"); + } + + /** + * extract resource_type and resource_name from template_resource and config_resource + * + * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including). + * @param string $resource_name template_resource or config_resource to parse + * @param string $default_resource the default resource_type defined in $smarty + * @param string &$name the parsed resource name + * @param string &$type the parsed resource type + * @return void + */ + protected static function parseResourceName($resource_name, $default_resource, &$name, &$type) + { + $parts = explode(':', $resource_name, 2); + if (!isset($parts[1]) || !isset($parts[0][1])) { + // no resource given, use default + // or single character before the colon is not a resource type, but part of the filepath + $type = $default_resource; + $name = $resource_name; + } else { + $type = $parts[0]; + $name = $parts[1]; + } + } + + + /** + * modify resource_name according to resource handlers specifications + * + * @param Smarty $smarty Smarty instance + * @param string $resource_name resource_name to make unique + * @return string unique resource name + */ + + /** + * modify template_resource according to resource handlers specifications + * + * @param string $smarty Smarty instance + * @param string $template_resource template_resource to extracate resource handler and name of + * @return string unique resource name + */ + public static function getUniqueTemplateName($smarty, $template_resource) + { + self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type); + // TODO: optimize for Smarty's internal resource types + $resource = Smarty_Resource::load($smarty, $type); + return $resource->buildUniqueResourceName($smarty, $name); + } + + /** + * initialize Source Object for given resource + * + * Either [$_template] or [$smarty, $template_resource] must be specified + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty $smarty smarty object + * @param string $template_resource resource identifier + * @return Smarty_Template_Source Source Object + */ + public static function source(Smarty_Internal_Template $_template=null, Smarty $smarty=null, $template_resource=null) + { + if ($_template) { + $smarty = $_template->smarty; + $template_resource = $_template->template_resource; + } + + // parse resource_name, load resource handler, identify unique resource name + self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type); + $resource = Smarty_Resource::load($smarty, $type); + $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name); + + // check runtime cache + $_cache_key = 'template|' . $unique_resource_name; + if ($smarty->compile_id) { + $_cache_key .= '|'.$smarty->compile_id; + } + if (isset(self::$sources[$_cache_key])) { + return self::$sources[$_cache_key]; + } + + // create source + $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name, $unique_resource_name); + $resource->populate($source, $_template); + + // runtime cache + self::$sources[$_cache_key] = $source; + return $source; + } + + /** + * initialize Config Source Object for given resource + * + * @param Smarty_Internal_Config $_config config object + * @return Smarty_Config_Source Source Object + */ + public static function config(Smarty_Internal_Config $_config) + { + static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true); + $config_resource = $_config->config_resource; + $smarty = $_config->smarty; + + // parse resource_name + self::parseResourceName($config_resource, $smarty->default_config_type, $name, $type); + + // make sure configs are not loaded via anything smarty can't handle + if (isset($_incompatible_resources[$type])) { + throw new SmartyException ("Unable to use resource '{$type}' for config"); + } + + // load resource handler, identify unique resource name + $resource = Smarty_Resource::load($smarty, $type); + $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name); + + // check runtime cache + $_cache_key = 'config|' . $unique_resource_name; + if (isset(self::$sources[$_cache_key])) { + return self::$sources[$_cache_key]; + } + + // create source + $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name); + $resource->populate($source, null); + + // runtime cache + self::$sources[$_cache_key] = $source; + return $source; + } + +} + +/** + * Smarty Resource Data Object + * + * Meta Data Container for Template Files + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + * + * @property integer $timestamp Source Timestamp + * @property boolean $exists Source Existance + * @property boolean $template Extended Template reference + * @property string $content Source Content + */ +class Smarty_Template_Source { + + /** + * Name of the Class to compile this resource's contents with + * @var string + */ + public $compiler_class = null; + + /** + * Name of the Class to tokenize this resource's contents with + * @var string + */ + public $template_lexer_class = null; + + /** + * Name of the Class to parse this resource's contents with + * @var string + */ + public $template_parser_class = null; + + /** + * Unique Template ID + * @var string + */ + public $uid = null; + + /** + * Template Resource (Smarty_Internal_Template::$template_resource) + * @var string + */ + public $resource = null; + + /** + * Resource Type + * @var string + */ + public $type = null; + + /** + * Resource Name + * @var string + */ + public $name = null; + + /** + * Unique Resource Name + * @var string + */ + public $unique_resource = null; + + /** + * Source Filepath + * @var string + */ + public $filepath = null; + + /** + * Source is bypassing compiler + * @var boolean + */ + public $uncompiled = null; + + /** + * Source must be recompiled on every occasion + * @var boolean + */ + public $recompiled = null; + + /** + * The Components an extended template is made of + * @var array + */ + public $components = null; + + /** + * Resource Handler + * @var Smarty_Resource + */ + public $handler = null; + + /** + * Smarty instance + * @var Smarty + */ + public $smarty = null; + + /** + * create Source Object container + * + * @param Smarty_Resource $handler Resource Handler this source object communicates with + * @param Smarty $smarty Smarty instance this source object belongs to + * @param string $resource full template_resource + * @param string $type type of resource + * @param string $name resource name + * @param string $unique_resource unqiue resource name + */ + public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource) + { + $this->handler = $handler; // Note: prone to circular references + + $this->compiler_class = $handler->compiler_class; + $this->template_lexer_class = $handler->template_lexer_class; + $this->template_parser_class = $handler->template_parser_class; + $this->uncompiled = $this->handler instanceof Smarty_Resource_Uncompiled; + $this->recompiled = $this->handler instanceof Smarty_Resource_Recompiled; + + $this->smarty = $smarty; + $this->resource = $resource; + $this->type = $type; + $this->name = $name; + $this->unique_resource = $unique_resource; + } + + /** + * get a Compiled Object of this source + * + * @param Smarty_Internal_Template $_template template objet + * @return Smarty_Template_Compiled compiled object + */ + public function getCompiled(Smarty_Internal_Template $_template) + { + // check runtime cache + $_cache_key = $this->unique_resource . '#' . $_template->compile_id; + if (isset(Smarty_Resource::$compileds[$_cache_key])) { + return Smarty_Resource::$compileds[$_cache_key]; + } + + $compiled = new Smarty_Template_Compiled($this); + $this->handler->populateCompiledFilepath($compiled, $_template); + $compiled->timestamp = @filemtime($compiled->filepath); + $compiled->exists = !!$compiled->timestamp; + + // runtime cache + Smarty_Resource::$compileds[$_cache_key] = $compiled; + + return $compiled; + } + + /** + * render the uncompiled source + * + * @param Smarty_Internal_Template $_template template object + */ + public function renderUncompiled(Smarty_Internal_Template $_template) + { + return $this->handler->renderUncompiled($this, $_template); + } + + /** + * <<magic>> Generic Setter. + * + * @param string $property_name valid: timestamp, exists, content, template + * @param mixed $value new value (is not checked) + * @throws SmartyException if $property_name is not valid + */ + public function __set($property_name, $value) + { + switch ($property_name) { + // regular attributes + case 'timestamp': + case 'exists': + case 'content': + // required for extends: only + case 'template': + $this->$property_name = $value; + break; + + default: + throw new SmartyException("invalid source property '$property_name'."); + } + } + + /** + * <<magic>> Generic getter. + * + * @param string $property_name valid: timestamp, exists, content + * @return mixed + * @throws SmartyException if $property_name is not valid + */ + public function __get($property_name) + { + switch ($property_name) { + case 'timestamp': + case 'exists': + $this->handler->populateTimestamp($this); + return $this->$property_name; + + case 'content': + return $this->content = $this->handler->getContent($this); + + default: + throw new SmartyException("source property '$property_name' does not exist."); + } + } + +} + +/** + * Smarty Resource Data Object + * + * Meta Data Container for Template Files + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + * + * @property string $content compiled content + */ +class Smarty_Template_Compiled { + + /** + * Compiled Filepath + * @var string + */ + public $filepath = null; + + /** + * Compiled Timestamp + * @var integer + */ + public $timestamp = null; + + /** + * Compiled Existance + * @var boolean + */ + public $exists = false; + + /** + * Compiled Content Loaded + * @var boolean + */ + public $loaded = false; + + /** + * Template was compiled + * @var boolean + */ + public $isCompiled = false; + + /** + * Source Object + * @var Smarty_Template_Source + */ + public $source = null; + + /** + * Metadata properties + * + * populated by Smarty_Internal_Template::decodeProperties() + * @var array + */ + public $_properties = null; + + /** + * create Compiled Object container + * + * @param Smarty_Template_Source $source source object this compiled object belongs to + */ + public function __construct(Smarty_Template_Source $source) + { + $this->source = $source; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_resource_custom.php b/include/smarty/libs/sysplugins/smarty_resource_custom.php new file mode 100644 index 000000000..9ec1f356b --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_resource_custom.php @@ -0,0 +1,96 @@ +<?php +/** + * Smarty Resource Plugin + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + */ + +/** + * Smarty Resource Plugin + * + * Wrapper Implementation for custom resource plugins + * + * @package Smarty + * @subpackage TemplateResources + */ +abstract class Smarty_Resource_Custom extends Smarty_Resource { + + /** + * fetch template and its modification time from data source + * + * @param string $name template name + * @param string &$source template source + * @param integer &$mtime template modification timestamp (epoch) + */ + protected abstract function fetch($name, &$source, &$mtime); + + /** + * Fetch template's modification timestamp from data source + * + * {@internal implementing this method is optional. + * Only implement it if modification times can be accessed faster than loading the complete template source.}} + * + * @param string $name template name + * @return integer|boolean timestamp (epoch) the template was modified, or false if not found + */ + protected function fetchTimestamp($name) + { + return null; + } + + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) + { + $source->filepath = strtolower($source->type . ':' . $source->name); + $source->uid = sha1($source->type . ':' . $source->name); + + $mtime = $this->fetchTimestamp($source->name); + if ($mtime !== null) { + $source->timestamp = $mtime; + } else { + $this->fetch($source->name, $content, $timestamp); + $source->timestamp = isset($timestamp) ? $timestamp : false; + if( isset($content) ) + $source->content = $content; + } + $source->exists = !!$source->timestamp; + } + + /** + * Load template's source into current template object + * + * @param Smarty_Template_Source $source source object + * @return string template source + * @throws SmartyException if source cannot be loaded + */ + public function getContent(Smarty_Template_Source $source) + { + $this->fetch($source->name, $content, $timestamp); + if (isset($content)) { + return $content; + } + + throw new SmartyException("Unable to read template {$source->type} '{$source->name}'"); + } + + /** + * Determine basename for compiled filename + * + * @param Smarty_Template_Source $source source object + * @return string resource's basename + */ + protected function getBasename(Smarty_Template_Source $source) + { + return basename($source->name); + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_resource_recompiled.php b/include/smarty/libs/sysplugins/smarty_resource_recompiled.php new file mode 100644 index 000000000..ab55b93a6 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_resource_recompiled.php @@ -0,0 +1,36 @@ +<?php +/** + * Smarty Resource Plugin + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + */ + +/** + * Smarty Resource Plugin + * + * Base implementation for resource plugins that don't compile cache + * + * @package Smarty + * @subpackage TemplateResources + */ +abstract class Smarty_Resource_Recompiled extends Smarty_Resource { + + /** + * populate Compiled Object with compiled filepath + * + * @param Smarty_Template_Compiled $compiled compiled object + * @param Smarty_Internal_Template $_template template object + * @return void + */ + public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) + { + $compiled->filepath = false; + $compiled->timestamp = false; + $compiled->exists = false; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_resource_uncompiled.php b/include/smarty/libs/sysplugins/smarty_resource_uncompiled.php new file mode 100644 index 000000000..ea8023507 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_resource_uncompiled.php @@ -0,0 +1,44 @@ +<?php +/** + * Smarty Resource Plugin + * + * @package Smarty + * @subpackage TemplateResources + * @author Rodney Rehm + */ + +/** + * Smarty Resource Plugin + * + * Base implementation for resource plugins that don't use the compiler + * + * @package Smarty + * @subpackage TemplateResources + */ +abstract class Smarty_Resource_Uncompiled extends Smarty_Resource { + + /** + * Render and output the template (without using the compiler) + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * @throws SmartyException on failure + */ + public abstract function renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template); + + /** + * populate compiled object with compiled filepath + * + * @param Smarty_Template_Compiled $compiled compiled object + * @param Smarty_Internal_Template $_template template object (is ignored) + */ + public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) + { + $compiled->filepath = false; + $compiled->timestamp = false; + $compiled->exists = false; + } + +} + +?>
\ No newline at end of file diff --git a/include/smarty/libs/sysplugins/smarty_security.php b/include/smarty/libs/sysplugins/smarty_security.php new file mode 100644 index 000000000..f8b31d963 --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_security.php @@ -0,0 +1,459 @@ +<?php +/** + * Smarty plugin + * + * @package Smarty + * @subpackage Security + * @author Uwe Tews + */ + +/* + * FIXME: Smarty_Security API + * - getter and setter instead of public properties would allow cultivating an internal cache properly + * - current implementation of isTrustedResourceDir() assumes that Smarty::$template_dir and Smarty::$config_dir are immutable + * the cache is killed every time either of the variables change. That means that two distinct Smarty objects with differing + * $template_dir or $config_dir should NOT share the same Smarty_Security instance, + * as this would lead to (severe) performance penalty! how should this be handled? + */ + +/** + * This class does contain the security settings + */ +class Smarty_Security { + + /** + * This determines how Smarty handles "<?php ... ?>" tags in templates. + * possible values: + * <ul> + * <li>Smarty::PHP_PASSTHRU -> echo PHP tags as they are</li> + * <li>Smarty::PHP_QUOTE -> escape tags as entities</li> + * <li>Smarty::PHP_REMOVE -> remove php tags</li> + * <li>Smarty::PHP_ALLOW -> execute php tags</li> + * </ul> + * + * @var integer + */ + public $php_handling = Smarty::PHP_PASSTHRU; + /** + * This is the list of template directories that are considered secure. + * $template_dir is in this list implicitly. + * + * @var array + */ + public $secure_dir = array(); + /** + * This is an array of directories where trusted php scripts reside. + * {@link $security} is disabled during their inclusion/execution. + * + * @var array + */ + public $trusted_dir = array(); + /** + * List of regular expressions (PCRE) that include trusted URIs + * + * @var array + */ + public $trusted_uri = array(); + /** + * This is an array of trusted static classes. + * + * If empty access to all static classes is allowed. + * If set to 'none' none is allowed. + * @var array + */ + public $static_classes = array(); + /** + * This is an array of trusted PHP functions. + * + * If empty all functions are allowed. + * To disable all PHP functions set $php_functions = null. + * @var array + */ + public $php_functions = array( + 'isset', 'empty', + 'count', 'sizeof', + 'in_array', 'is_array', + 'time', + 'nl2br', + ); + /** + * This is an array of trusted PHP modifers. + * + * If empty all modifiers are allowed. + * To disable all modifier set $modifiers = null. + * @var array + */ + public $php_modifiers = array( + 'escape', + 'count' + ); + /** + * This is an array of allowed tags. + * + * If empty no restriction by allowed_tags. + * @var array + */ + public $allowed_tags = array(); + /** + * This is an array of disabled tags. + * + * If empty no restriction by disabled_tags. + * @var array + */ + public $disabled_tags = array(); + /** + * This is an array of allowed modifier plugins. + * + * If empty no restriction by allowed_modifiers. + * @var array + */ + public $allowed_modifiers = array(); + /** + * This is an array of disabled modifier plugins. + * + * If empty no restriction by disabled_modifiers. + * @var array + */ + public $disabled_modifiers = array(); + /** + * This is an array of trusted streams. + * + * If empty all streams are allowed. + * To disable all streams set $streams = null. + * @var array + */ + public $streams = array('file'); + /** + * + flag if constants can be accessed from template + * @var boolean + */ + public $allow_constants = true; + /** + * + flag if super globals can be accessed from template + * @var boolean + */ + public $allow_super_globals = true; + + /** + * Cache for $resource_dir lookups + * @var array + */ + protected $_resource_dir = null; + /** + * Cache for $template_dir lookups + * @var array + */ + protected $_template_dir = null; + /** + * Cache for $config_dir lookups + * @var array + */ + protected $_config_dir = null; + /** + * Cache for $secure_dir lookups + * @var array + */ + protected $_secure_dir = null; + /** + * Cache for $php_resource_dir lookups + * @var array + */ + protected $_php_resource_dir = null; + /** + * Cache for $trusted_dir lookups + * @var array + */ + protected $_trusted_dir = null; + + + /** + * @param Smarty $smarty + */ + public function __construct($smarty) + { + $this->smarty = $smarty; + } + + /** + * Check if PHP function is trusted. + * + * @param string $function_name + * @param object $compiler compiler object + * @return boolean true if function is trusted + * @throws SmartyCompilerException if php function is not trusted + */ + public function isTrustedPhpFunction($function_name, $compiler) + { + if (isset($this->php_functions) && (empty($this->php_functions) || in_array($function_name, $this->php_functions))) { + return true; + } + + $compiler->trigger_template_error("PHP function '{$function_name}' not allowed by security setting"); + return false; // should not, but who knows what happens to the compiler in the future? + } + + /** + * Check if static class is trusted. + * + * @param string $class_name + * @param object $compiler compiler object + * @return boolean true if class is trusted + * @throws SmartyCompilerException if static class is not trusted + */ + public function isTrustedStaticClass($class_name, $compiler) + { + if (isset($this->static_classes) && (empty($this->static_classes) || in_array($class_name, $this->static_classes))) { + return true; + } + + $compiler->trigger_template_error("access to static class '{$class_name}' not allowed by security setting"); + return false; // should not, but who knows what happens to the compiler in the future? + } + + /** + * Check if PHP modifier is trusted. + * + * @param string $modifier_name + * @param object $compiler compiler object + * @return boolean true if modifier is trusted + * @throws SmartyCompilerException if modifier is not trusted + */ + public function isTrustedPhpModifier($modifier_name, $compiler) + { + if (isset($this->php_modifiers) && (empty($this->php_modifiers) || in_array($modifier_name, $this->php_modifiers))) { + return true; + } + + $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting"); + return false; // should not, but who knows what happens to the compiler in the future? + } + + /** + * Check if tag is trusted. + * + * @param string $tag_name + * @param object $compiler compiler object + * @return boolean true if tag is trusted + * @throws SmartyCompilerException if modifier is not trusted + */ + public function isTrustedTag($tag_name, $compiler) + { + // check for internal always required tags + if (in_array($tag_name, array('assign', 'call', 'private_filter', 'private_block_plugin', 'private_function_plugin', 'private_object_block_function', + 'private_object_function', 'private_registered_function', 'private_registered_block', 'private_special_variable', 'private_print_expression', 'private_modifier'))) { + return true; + } + // check security settings + if (empty($this->allowed_tags)) { + if (empty($this->disabled_tags) || !in_array($tag_name, $this->disabled_tags)) { + return true; + } else { + $compiler->trigger_template_error("tag '{$tag_name}' disabled by security setting", $compiler->lex->taglineno); + } + } else if (in_array($tag_name, $this->allowed_tags) && !in_array($tag_name, $this->disabled_tags)) { + return true; + } else { + $compiler->trigger_template_error("tag '{$tag_name}' not allowed by security setting", $compiler->lex->taglineno); + } + return false; // should not, but who knows what happens to the compiler in the future? + } + + /** + * Check if modifier plugin is trusted. + * + * @param string $modifier_name + * @param object $compiler compiler object + * @return boolean true if tag is trusted + * @throws SmartyCompilerException if modifier is not trusted + */ + public function isTrustedModifier($modifier_name, $compiler) + { + // check for internal always allowed modifier + if (in_array($modifier_name, array('default'))) { + return true; + } + // check security settings + if (empty($this->allowed_modifiers)) { + if (empty($this->disabled_modifiers) || !in_array($modifier_name, $this->disabled_modifiers)) { + return true; + } else { + $compiler->trigger_template_error("modifier '{$modifier_name}' disabled by security setting", $compiler->lex->taglineno); + } + } else if (in_array($modifier_name, $this->allowed_modifiers) && !in_array($modifier_name, $this->disabled_modifiers)) { + return true; + } else { + $compiler->trigger_template_error("modifier '{$modifier_name}' not allowed by security setting", $compiler->lex->taglineno); + } + return false; // should not, but who knows what happens to the compiler in the future? + } + + /** + * Check if stream is trusted. + * + * @param string $stream_name + * @return boolean true if stream is trusted + * @throws SmartyException if stream is not trusted + */ + public function isTrustedStream($stream_name) + { + if (isset($this->streams) && (empty($this->streams) || in_array($stream_name, $this->streams))) { + return true; + } + + throw new SmartyException("stream '{$stream_name}' not allowed by security setting"); + } + + /** + * Check if directory of file resource is trusted. + * + * @param string $filepath + * @return boolean true if directory is trusted + * @throws SmartyException if directory is not trusted + */ + public function isTrustedResourceDir($filepath) + { + $_template = false; + $_config = false; + $_secure = false; + + $_template_dir = $this->smarty->getTemplateDir(); + $_config_dir = $this->smarty->getConfigDir(); + + // check if index is outdated + if ((!$this->_template_dir || $this->_template_dir !== $_template_dir) + || (!$this->_config_dir || $this->_config_dir !== $_config_dir) + || (!empty($this->secure_dir) && (!$this->_secure_dir || $this->_secure_dir !== $this->secure_dir)) + ) { + $this->_resource_dir = array(); + $_template = true; + $_config = true; + $_secure = !empty($this->secure_dir); + } + + // rebuild template dir index + if ($_template) { + $this->_template_dir = $_template_dir; + foreach ($_template_dir as $directory) { + $directory = realpath($directory); + $this->_resource_dir[$directory] = true; + } + } + + // rebuild config dir index + if ($_config) { + $this->_config_dir = $_config_dir; + foreach ($_config_dir as $directory) { + $directory = realpath($directory); + $this->_resource_dir[$directory] = true; + } + } + + // rebuild secure dir index + if ($_secure) { + $this->_secure_dir = $this->secure_dir; + foreach ((array) $this->secure_dir as $directory) { + $directory = realpath($directory); + $this->_resource_dir[$directory] = true; + } + } + + $_filepath = realpath($filepath); + $directory = dirname($_filepath); + $_directory = array(); + while (true) { + // remember the directory to add it to _resource_dir in case we're successful + $_directory[$directory] = true; + // test if the directory is trusted + if (isset($this->_resource_dir[$directory])) { + // merge sub directories of current $directory into _resource_dir to speed up subsequent lookups + $this->_resource_dir = array_merge($this->_resource_dir, $_directory); + return true; + } + // abort if we've reached root + if (($pos = strrpos($directory, DS)) === false || !isset($directory[1])) { + break; + } + // bubble up one level + $directory = substr($directory, 0, $pos); + } + + // give up + throw new SmartyException("directory '{$_filepath}' not allowed by security setting"); + } + + /** + * Check if URI (e.g. {fetch} or {html_image}) is trusted + * + * To simplify things, isTrustedUri() resolves all input to "{$PROTOCOL}://{$HOSTNAME}". + * So "http://username:password@hello.world.example.org:8080/some-path?some=query-string" + * is reduced to "http://hello.world.example.org" prior to applying the patters from {@link $trusted_uri}. + * @param string $uri + * @return boolean true if URI is trusted + * @throws SmartyException if URI is not trusted + * @uses $trusted_uri for list of patterns to match against $uri + */ + public function isTrustedUri($uri) + { + $_uri = parse_url($uri); + if (!empty($_uri['scheme']) && !empty($_uri['host'])) { + $_uri = $_uri['scheme'] . '://' . $_uri['host']; + foreach ($this->trusted_uri as $pattern) { + if (preg_match($pattern, $_uri)) { + return true; + } + } + } + + throw new SmartyException("URI '{$uri}' not allowed by security setting"); + } + + /** + * Check if directory of file resource is trusted. + * + * @param string $filepath + * @return boolean true if directory is trusted + * @throws SmartyException if PHP directory is not trusted + */ + public function isTrustedPHPDir($filepath) + { + if (empty($this->trusted_dir)) { + throw new SmartyException("directory '{$filepath}' not allowed by security setting (no trusted_dir specified)"); + } + + // check if index is outdated + if (!$this->_trusted_dir || $this->_trusted_dir !== $this->trusted_dir) { + $this->_php_resource_dir = array(); + + $this->_trusted_dir = $this->trusted_dir; + foreach ((array) $this->trusted_dir as $directory) { + $directory = realpath($directory); + $this->_php_resource_dir[$directory] = true; + } + } + + $_filepath = realpath($filepath); + $directory = dirname($_filepath); + $_directory = array(); + while (true) { + // remember the directory to add it to _resource_dir in case we're successful + $_directory[] = $directory; + // test if the directory is trusted + if (isset($this->_php_resource_dir[$directory])) { + // merge sub directories of current $directory into _resource_dir to speed up subsequent lookups + $this->_php_resource_dir = array_merge($this->_php_resource_dir, $_directory); + return true; + } + // abort if we've reached root + if (($pos = strrpos($directory, DS)) === false || !isset($directory[2])) { + break; + } + // bubble up one level + $directory = substr($directory, 0, $pos); + } + + throw new SmartyException("directory '{$_filepath}' not allowed by security setting"); + } + +} + +?>
\ No newline at end of file |