From: Davide Franco Date: Tue, 22 Mar 2011 13:26:32 +0000 (+0100) Subject: bacula-web: Moved external_packages folder to classes/external X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=31a88954edb80eda62cd37af27f7e9f776b9cfb6;p=bacula%2Fbacula bacula-web: Moved external_packages folder to classes/external - Changed path in config.inc.php --- diff --git a/gui/bacula-web/classes/external/phplot/COPYING b/gui/bacula-web/classes/external/phplot/COPYING new file mode 100644 index 0000000000..602bfc9463 --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + 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 + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/gui/bacula-web/classes/external/phplot/ChangeLog b/gui/bacula-web/classes/external/phplot/ChangeLog new file mode 100644 index 0000000000..af66bd1cf8 --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/ChangeLog @@ -0,0 +1,1364 @@ +This is the Change Log for PHPlot. +The project home page is http://sourceforge.net/projects/phplot/ +----------------------------------------------------------------------------- + +2011-01-15 (lbayuk) ===== Released as 5.3.1 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + +2011-01-09 + * Fixed some style / indent errors, and 1 redundant test. + +2011-01-03 + * For bug 3143586 "Multiple plots per image - fixes & docs": + Make sure there is a documented way to reset PHPlot feature + settings, especially those for which the default settings result + in automatic calculated values. Where possible, calling a Set*() + function with no arguments should reset the feature to defaults. + + + Changed SetLegendPixels() arguments to be optional with default + NULL meaning reset to automatic positioning. + + + Fixed SetXAxisPosition() and SetYAxisPosition() to accept empty + string '' to mean reset to default automatic positioning. + Make arguments optional, defaulting to empty string. + + + Changed SetNumXTicks() and SetNumYTicks() arguments to be + optional with default empty string '' meaning reset to + of automatic calculation. + + * Changed SetPointShapes() to use CheckOptionArray(). This + simplifies the function with no change in operation. + + * Extend copyright years to 2011. + +2010-12-30 + * Fix for bug 3147397 "Data colors missing with multiple plots": + + Do not truncate the data_colors and related arrays, so the full + set of colors will be available for subsequent plots on the image. + (Color indexes are still allocated in the image only as needed.) + + New internal functions GetColorIndexArray() and + GetDarkColorIndexArray(), replacing previous use of array_map(). + + Removed internal function truncate_array() - no longer used. + + Changed SetColorIndexes(), NeedDataDarkColors(), and + NeedErrorBarColors() to only allocate the color indexes that will + be needed (instead of allocating all colors in the truncated color + descriptor arrays). + +2010-12-28 + * Instead of throwing an error, SetLegend(NULL) now clears the legend + array. This can be useful with multiple plots on an image. Before + this change, only SetLegend(array()) did that (possibly by accident). + +2010-12-27 + * Do not have SetDefaultStyles() call deprecated SetLabelColor(). + + * Fixes for bug 3143586 "Multiple plots per image - fixes & docs": + + Fix DrawLegend so it doesn't forget that the legend position + was specified in world coordinates. This fixes the legend + position for plots after the first. + + Don't draw the image border more than once (although this would + probably have no impact on the resulting image). This parallels + the behavior for the main plot title and the image background. + Replaced member variables background_done and title_done with a new + member array done[] which will track when these elements were done. + +2010-12-06 + * Fix comments above CalcPlotAreaWorld(). Deleted incorrect information + from before data-data-yx existed, and before DecodeDataType rewrite. + +2010-12-04 (lbayuk) ===== Released as 5.3.0 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + +2010-12-03 + * Feature request 3127005 "Ability to suppress X/Y axis lines": + Added SetDrawXAxis() and SetDrawYAxis() to control flags which + will suppress drawing the X or Y axis lines. (These lines were + probably the only PHPlot elements that could not be turned off.) + Changed DrawXAxis() and DrawYAxis() to conditionally draw the + axis lines. + +2010-11-28 + * Feature request 3117873 "Data value labels in more plot types": + Implemented Data Value Labels for plot types points, lines, + linepoints, and squared. Added 2 class variables which can be + set to control the distance and angle of the labels from points. + New internal function CheckDataValueLabels() calculates position + and text alignment for these labels. + + * Updated comments for Set[XY]DataLabelPos to match the text in + the manual, which was rewritten to clarify label types. + +2010-11-23 + * Code cleanup. Moved some functions around to group "plot drawing + helpers" separately from "plot drawing". No changes to operation. + +2010-11-21 + * Feature request 3111166 "Control legend colorbox width": + Added a class variable legend_colorbox_width which can be changed + to make the colorboxes wider or narrower. + +2010-11-16 + * Feature request 3093483 "Investing support chart types": + Added 3 new plot types: Basic OHLC (Open/High/Low/Close), Candlesticks, + and Filled Candlesticks. Implemented with one new function to handle the + 3 new plot types: ohlc, candlesticks, and candlesticks2. + +2010-11-11 + * Moved information about plot types into a new static member array + plots[]. (This is an internal change with no impact on usage, but will + make it easier to add new plot types.) SetPlotType() no longer needs a + list of plot types to check, FindDataLimits() does not need to check for + specific plot types to to process the data array, and DrawGraph() uses + data from the array rather than knowing about all the plot types. + +2010-10-31 + * Changed internal CalcBarWidths() to take two arguments which indicate + how it should calculate bar widths, rather than having it check the + plot_type directly. (Taken from another, experimental change. This + minimizes places where plot_type is directly used.) + +2010-10-03 (lbayuk) ===== Released as 5.2.0 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + * Makefile: Removed HorizontalBars.txt from release. This is now all + documented in the reference manual. + +2010-10-01 + * Rewrite color handling. Default and specified colors are now validated, + converted to RGBA arrays, and saved. The colors indexes are not + allocated until graph drawing time. Unneeded colors are not allocated. + + Fix bug 3045131 "SetTransparentColor problems": Transparency setup is + deferred to graph drawing time, after most other colors are allocated. + Fixes SetTransparentColor order dependency, and works with data colors. + + Fix bug 3049726 "Optimize color allocation": Colors allocation is + deferred to graph drawing time, and colors for most elements are only + allocated if needed. In particular, the data colors and dark colors, + which used 32 slots, now only get defined as needed. + + Feature request (partial) 3077554 "Finer control over plot element + colors": The colors of the main, X, and Y titles can now be controlled + separately. + + Change details: + New internal functions: + GetColorIndex(), GetDarkColorIndex() + Allocate pre-parsed colors for elements. + SetColorIndexes() + Does the deferred color allocation and defaults. + NeedDataDarkColors(), NeedErrorBarColors() + Called by graph drawing functions if those colors are needed. + GetDataColor(), GetDataErrorColors(), GetBarColors() + Custom or standard data color assignment for most plot types. + truncate_array() + Shorten an array. Used to limit data color allocation. + + Removed internal functions: + SetIndexColor(), SetIndexDarkColor() + Unneeded. Color handling is now in two separate phases. + + Removed internal member variable: + data_colors_alpha + PHPlot no longer calls SetDataColors before plotting, so this + variable is not needed to preserve the default alpha. + + New internal member variables: + transparent_color + Saves color value from SetTransparentColor. For bug 3045131. + x_title_color, y_title_color, ndx_x_title_color, ndx_y_title_color + For title colors. DrawXTitle and DrawYTitle use them now. + + Changed internal member variables: + i_border, plot_bg_color, bg_color, label_color, text_color, etc. + All variables for colors now always hold a parsed 4-component + (RGBA) color specification as an array, and are no longer + statically initialized to a color name. + + New public functions: + SetXTitleColor(), SetYTitleColor() + These can be used to make the 3 titles have different colors. + +2010-09-26 + * Don't let SetXDataLabelPos() accept 'xaxis' or 'all' as valid. + Don't let SetXTickLabelPos(), SetYTickLabelPos() accept 'all' as valid. + These were never implemented and never documented. + + + * Feature request #3073679 "Stacked bar plots with negative values": + Allow stacked bar plots (vertical and horizontal) to work with negative + values. Changed FindDataLimits() to not take abs() values for + stackedbar when calculating the data range. Changed DrawStackedBars() + and DrawHorizStackedBars() to handle negative values, including proper + label positions. The first non-zero value in a row sets the direction + of the bar. Mixing positive and negative values within a row works but + the results are not useful. + + * New internal DrawBar() moves common code from 4 bars and stackedbars + drawing functions and makes it easier to deal with shading vs bar + direction. + +2010-09-24 + * Fix bug 3074402 "Fix Y axis default for horizontal plots": + Make the default axis positions symmetrical for vertical plots + (X and Y) and horizontal plots (Y and X). This fixes the problem + with horizontal bar/thinbarline plots that have negative data, + where the Y axis stayed on the left and the bars went rightward. + +2010-09-01 + * Fix bug 3056991 "Internal methods should be 'protected'": + Changed CheckDataArray(), number_format(), FindDataLimits(), and + DrawBackground() to be 'protected'. The test suite no longer calls + these directly. For SetIndexColor(), SetRGBColor(), DrawText(), + SizeText(), xtr(), and ytr(), left these as public with a comment + indicating they should be treated as protected. + + * Fix bug 3057000 "Review 'deprecated' methods": + + Changed deprecated method SetNewPlotAreaPixels() to just call + SetPlotAreaPixels(). It was suspicious as coded, and was found + to be equivalent to SetPlotAreaPixels(). + + Removed SetColor(), which didn't do anything. It was calling + SetRGBColor and discarding the result. After reviewing the + history of this in all CVS versions, it does not seem to have + ever been coded correctly, so there is no harm in removing it. + + All other deprecated methods seem OK and are left as is. + +2010-08-30 (lbayuk) ===== Released as 5.1.3 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + +2010-08-27 + * Fix bug 3051832 "Let PHP/GD find the font file": + Instead of checking for file existence, PHPlot now uses a non-drawing GD + operation to validate a TrueType font in SetFontTTF(). This allows GD to + use its internal search path, making it likely that fonts can be found + without needing a platform-dependent path in your script. Full paths + will still work, so there is no compatibility issue. + + * Fix bug 3051906 "Better choice for default TT font": + Removed "benjamingothic.ttf" as the default TT font setting. This has + not been included in PHPlot since 2004. Changed SetFontTTF() to call + new GetDefaultFontTTF(), which will try a number of sans-serif font + names the first time it needs a default TT font. Considering the above + fix to finding fonts, this has a good chance of finding a working + font. It is known to work on Windows and some Linux distributions. + +2010-08-19 + * Makefile: Removed phplot_data.php from list of files to release. + Reference bug report 3048267. This file has not been maintained or + tested, and has bugs. It will remain in CVS, but not be included + in PHPlot releases. + +2010-08-17 + * Change new DrawLinePoints(). It does not have to check and + handle error bar plots, as DrawDots and DrawLines will do that. + +2010-08-16 + * Rewrote DecodeDataType(). Previous implementation was hard to + extend and inefficient. Now it uses new class variables (not a + returned array) and is only called once, by DrawGraph. Changed all + users of data_type to use the new variables. + + In CheckDataArray(), calculate data_columns properly for + text-data-single data type (pie chart) too. Simplify DrawPie + to use this, and merge 2 of the 3 cases. + + Have a single function handle each plot type, so it can properly + check the data type and report a correct error message showing + all supported types. For example, DrawBars is now the entry point + for both bars and horizontal bars; DrawGraph does not directly + call DrawHorizBars. Similar for DrawStackedBars and + DrawHorizStackedBars. Lines, Points, and Linepoints also now + have a single function each, dispatching to others as needed. + (These changes were split off from an upcoming, larger change.) + +2010-08-14 + * Fixes to SetDataValues: need to clear out the 2 arrays before + setting values in a loop, else if the function is used more than + once then old values will remain. + Move records_per_group calculation outside the loop. + (These were split off from upcoming, larger changes.) + + * Part 4 of horizontal plots: implement horizontal thinbarline plots. + Added new data type 'data-data-yx' (label, Y, X1, X2, ...). + DrawThinBarLines() now draws either vertical or horizontal plots, and + supports data types text-data, data-data, text-data-yx, data-data-yx. + + Fixed DecodeDataType() to handle text-data-single too, for completeness. + + * Fix for over-padding style and color arrays. These were padded to + records_per_group, but that is the maximum data array row size. + The number of actual data sets is less, and depends on the data type. + Calculate the correct number as data_columns at the top of DrawGraph, + and use that to pad the arrays. Also moved early error checking in + DrawGraph() into new CheckDataArray(). + +2010-08-09 + * Code cleanup. This is a large change to unify the comment and + coding stye used in PHPlot. The PEAR style guide is being used + as a reference, but PHPlot will never be 100% compliant. + This patch introduces no functional changes at all. + - Limit line length to 110. + - Remove obsolete, partially implemented Doxygen comments. + - Add descriptive comment above functions where missing. + - Use consistent comment markers and control structure spacing. + - Remove ctags-confusing end of function comments. + - Rewrote a few if/else blocks for cleaner logic. + - Re-order some functions for consistency (X, then Y). + +2010-08-04 + * Implemented horizontal stacked bar plots: + Use the same data type introduced for horizontal bars, 'text-data-yx', + and the same plot type 'stackedbars', to make a horizontal stacked bar + plot. Data value labels, both at the ends of the bars and within the + bars ('plotstack' labels) are available with horizontal stacked bars. + + * Internal function DrawDataLabel() is replaced by DrawDataValueLabel(), + with different usage. The new function can also check to see if a label + fits in the allocated space. + + * Fixed the text size check in stacked bar plots for data value labels + within the bars. The check only worked correctly for 0 degree labels. It + now works with any text angle. It suppresses the label if it is too high + (for vertical stacked bar plots) or too wide (for horizontal stacked bar + plots) to fit in the bar segment to which it belongs. Note that it only + checks in the bar direction. If the text is too wide (for vertical bars), + or too high (for horizontal bars), it will still be plotted, but will + cross the sides of the bar. + +2010-07-28 + * Allow callbacks to return a value (to support new data_color callback). + * Feature request 3034164 "Extended control of data colors": + Define new callback 'data_color' for picking the data color. + Changed internal plot drawing functions DrawDots, DrawLines, DrawSquared, + DrawBars, DrawStackedBars, DrawDotsError, DrawThinBarLines, + DrawLinesError, and DrawHorizBars to use the data_color callback + (if defined) to select the data colors. + * SetRGBArray code cleanup (no functional changes). + +2010-07-27 + * Fixes for error bars: + Code cleanup in DrawYErrorBar(), with no functional change. + Suppress duplicate drawing of error bars with 'linepoints' error plots. + This was already fixed for data labels. Now error bars will only be + drawn by the 'points' part, not the 'lines' part. There should be no + visible changes to plots. (This is needed for a future change). + +2010-07-26 + * Horizontal bar charts (still an experimental feature) can now have data + value labels. + * HorizontalBars.txt: Fix incorrect description of bar direction. Add + text explaining the new data value labels. + +2010-06-29 (lbayuk) ===== Released as 5.1.2 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + +2010-06-26 + * Feature request 2885930 "Horizontal Bars": + Horizontal bar charts are implemented, as an experimental feature. + A new data type 'text-data-yx' was added, which works with + 'bars' plot type to produce a horizontal bar chart from a data + array with X values for each Y value. Changes were made to + FindDataLimits, CalcMargins, CalcPlotAreaWorld, CalcBarWidths, + and CalcMaxDataLabelSize to handle the new data type. Other + changes were made to handle label position defaults and grid + defaults. New drawing functions were added for horizontal bars. + + * HorizontalBars.txt: new documentation file for experimental feature. + * Makefile: List new documentation file. + +2010-06-25 + * Each plot-type drawing function now checks that it is getting a data + type that it knows how to handle. A new internal function unifies the + checking and error message. (This is associated with an upcoming, + bigger change.) + + Compatibility: If you were using an invalid data type for a plot type + whose function did not check, will now get an error. + + * Removed some dubious code from DrawLines() and DrawSquared() and + rewrote comments there. The code initialized lastx[0] and lasty[0], + but lasty was mapped using the X (rather than Y) function. This was + obviously wrong, but closer inspection showed that the values were + never, used so the code was removed. + +2010-06-13 + * Truecolor.txt: removed + * Makefile, README.txt: Removed reference to Truecolor.txt. Full + documentation for truecolor images is now in the Reference Manual. + +2010-06-02 + * Fix bug 3010116 "Bad rendering of title in multi-plot image + when using TTF": + Make sure the main title is drawn only once. (If drawn multiple + times with TrueType font text, the anti-aliasing effects result + in poor quality text.) + +2010-05-31 + * Improvements to truecolor support (from feature request 2947679): + Truecolor support is now better integrated. The derived class only + has the constructor now, and the base class itself provides the alpha + color component support through the internal functions SetIndexColor(), + SetIndexDarkColor(), and SetRGBColor(). This means alpha channel + works with palette images too (in so far as GD supports this). + + * Truecolor.txt: Updated per changes to truecolor support. + + * Image tiling with mode 'scale' in tile_img(), used with image and + plot area backgrounds, now uses imagecopyresampled() rather than + imagecopyresized(). They are the same with palette images, but the + resampled copy gets better results with truecolor images. + +2010-05-29 + * Feature request 3002606 "Add to plot and image border options": + Added options 'right', 'top', and 'bottom' to SetPlotBorderType() + (existing options are 'left', 'sides', 'none', and 'full'). This + now also accepts an array of the above options, giving complete + control over which sides to draw. + Added option 'solid' to SetImageBorderType() to use the actual + color set with SetImageBorderColor(), rather than the darker + shade as type 'plain' does (for some reason). + New function SetImageBorderWidth() sets the width of the image + border. The image border width is now accounted for in margin + calculations, although existing plots will not change. + +2010-04-04 (lbayuk) ===== Released as 5.1.1 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + +2010-04-01 + * Remove & from argument in SetDataValues(). The data array is not + modified and does not need to be passed by reference. (There is + no performance advantage, either.) + +2010-03-29 + * Feature request 2947679 "Support for alpha blending/Truecolor": + Implemented truecolor image support with a new class + PHPlot_truecolor, extended color specifications to allow + specification of an alpha value, and added a new optional parameter + to SetDataColors for a default alpha value for all data colors. + This feature is *EXPERIMENTAL* (see next item). + + * Truecolor.txt: New file, documentation for the new truecolor capability. + (The Truecolor feature is experimental, which means it is subject to + change in incompatible ways and the documentation has not yet been + incorporated into the PHPlot Reference Manual.) + + * Makefile: Include new documentation file in release. + +2010-03-26 + Fixed bug 2976735 "Improvements and fixes for 'area' plots": + Rewrote DrawArea() function which handles 'area' plot. + Part 1: This is related to feature request 2947679, Truecolor support + with transparency. The area plot function was filling each area from the X + axis up to the Y value, resulting in area overlaps. This wasn't a problem + with opaque colors, but with transparency, the overlapping areas resulted + in changed colors. The rewritten function fills the area between each line + instead of from each line down to the X axis. Plots with opaque colors + will not change. + Part 2: Area plots now work when the X axis is moved up with + SetXAxisPosition(). + Part 3: Fixed FindDataLimits() for area (and stackedbars too) to + take absolute values of Y values. The drawing function was doing this, + but not FindDataLimits, resulting in incorrect limits if any Y<0. + Part 4: The rewritten DrawArea() also handles a new plot type + 'stackedarea'. This is an area plot where the Y values are stacked, + similar to 'stackedbars'. + Note: As part of the changes, it is now an error to try an area plot + with an unequal number of Y points for each X. + +2010-03-23 + * Feature request 2973995 "Add y-Data to Stackedbars": + Implemented Y Data Labels for Stacked Bar charts (stackedbars). + The labels are enabled with SetYDataLabelPos, same as with bar charts. + There are two types of labels: above the stack with the total, and + within the bars at each segment. 'plotin' turns on the upper ones, and + 'plotstack' turns both on. + + * Other changes: + + Removed unimplemented second argument to SetYDataLabelPos. + + Fixed questionable logic in SetYDataLabelPos when given an argument + that belongs with SetYTickLabelPos. + + Fix comments at top of plot-type Draw functions. + + * Fix for bug 2974639 "Stacked bars plot breaks with X axis != 0": + Stacked bar plots with non-zero X axis position no longer break apart + into segments with gaps. The bars are drawn up from the X axis, and + any segments or partial segments below the X axis are not drawn. + +2010-03-22 + * Change related to feature request 2947679 - Fix 'dot' point shape: + Use imagefilledellipse(), not imagefilledarc(), when drawing the 'dot' + point shape. The fix was needed for future support of truecolor images + with transparency, but filled dots from imagefilledellipse() look + better (rounder) with regular images and opaque colors. + Credit to mvaldez for identifying the problem and providing the fix. + +2010-03-04 + * Fix for bug 2963757 "point_counts undefined error in 5.1.0": + Fixed CheckPointParams so it sets point_counts even when the point shape + and point size arrays are already the same size and do not need padding. + +2010-01-26 + * Fix for bug 2938219 "Bars go in wrong direction": + Fixed CalcAxisPositions() to be consistent in positioning the X axis. + When all Y values are <0 and the Y=0 line is not part of the plot range, + PHPlot will now default the X axis to the top of the plot, not the + bottom. This fixes the problem with bars to negative Y values being + drawn downward if Y=0 is visible, but upward if Y=0 is not visible. + This also affects thinbarline plots. + Credit to lauryn1298 for finding the bug. + +2009-12-24 (lbayuk) ===== Released as 5.1.0 ===== + +2009-12-18 + * Change for bug 1795971 "Fix default data colors": + The default Data Color and Error Bar Color arrays now have 16 + different colors, no duplicates, and nothing so light that it + is invisible. + Using '' or False as the argument to SetDataColors, SetErrorBarColors, + and SetDataBorderColors now re-initializes the map to the defaults. + This was previously undocumented, and in some cases set the map to + something different from the default. + +2009-12-15 + * Cleanup: Remove DrawAxisLegend() - empty function marked TODO, + not really clear what it was meant to do. + +2009-12-14 + * Fix for bug 2914403 "Pie + X/Y titles: Undefined property error": + In DrawGraph(), don't try to draw X or Y titles for pie charts. + + * Feature request 2899921: "allow different format for data and tick + labels"; Bug 2906436: "Fixes for X Tick Labels vs X Data Labels", + and partial implementation of changes from user 'adoll' regarding + tick vs data labels: + + New public functions: + + SetXDataLabelType() : Sets formatting for X Data Labels + + SetYDataLabelType() : Sets formatting for Y Data Labels (bar charts) + + SetXDataLabelAngle() : Sets text angle for X Data Labels + + SetYDataLabelAngle() : Sets text angle for Y Data Label (bar charts) + The defaults for these are set up to be fully backward compatible + with previous releases of PHPlot (except see the next item). + + Re-used function name SetXDataLabelAngle(): + + This has been deprecated and undocumented since 2003-12-07, and + used to just call SetXLabelAngle(). For new behavior, see above. + + Changes to public functions: + + SetXDataLabelPos() and SetXTickLabelPos() no longer cancel each + other out (set the other control variable to 'none'). Instead, + they are both considered before plot drawing. + + Changes to internal functions: + + DrawDataLabel() now uses the font, angle, and color arguments as + provided, and does not substitute values if they are empty. + + SetLabelType() now takes mode='xd' and 'yd' for X Data and Y Data + label formatting; 'x' and 'y' are for tick labels only now. + + Functions that work on Data labels now call FormatLabel() with the + new mode parameter value 'xd' or 'yd, and use the new + data_label_angle variables. + + New CheckLabels(), used by DrawGraph to process label parameters. + + CalcMargins() - Rewritten to handle changes to Tick and Data labels. + + Changes to internal class variables: + + New: x_data_label_angle, y_data_label_angle + + Do not initialize x_tick_label_pos or x_data_label_pos, so that + CheckLabels() can tell if they were set or not and apply defaults. + + Initialize y_data_label_pos to 'none', not 'plotleft'. + + Add 2 more indexes to label_format[] array: 'xd' and 'yd'. + + * Cleanup: + + Delete unused internal class variable: draw_y_data_label_lines + + Delete unused function SetDrawYDataLabelLines() + +2009-12-07 + * Fix bug 1795972 "Fix default point shapes": + + Added 10 new point shapes to the existing 10 shapes. + + Changed the default point shape from all 'diamond' to a + selection of up to 10 different shapes. + + Fixed bug in the code that tried to set the point shapes + and sizes arrays to be the same size. This was not working, + resulting in unexpected point sizes. + + Changed default point size to 6 for all shapes. It was trying + to be "5, 5, 3" but due to several bugs this was not working. + + Do not adjust shape sizes to even numbers (was done for only two + shapes). Instead, consistently truncate size/2 when needed. + NOTE: These may change the look of 'points' and 'linepoints' plots. + + * Changed startup initialization code: + + SetDefaultStyles() was doing some odd things using a variable + called "session_set", with comments referring to non-existent + session support code. This has been removed. There should be + no visible changes from this. PHPlot does not use PHP sessions. + +2009-12-04 + * Fix for bug 2908256, errors in pie charts with bad data array: + (From a Drupal contrib module report by thekevinday.) + With pie charts only, a data array with no valid Y values resulted + in PHP error messages. All other plot types handle this by producing + an image without a graph. + Fixed DrawPieChart to behave this way too. If there are no valid Y + values, or if the sum of all Y values is 0, do not error out, but + don't draw a pie chart either. + Also, pie charts now ignore non-numeric Y values, like other plot types. + +2009-11-20 (lbayuk) + * Fix for bug 2900914 "Problem with display of 0 on Y axis": + Changed how X and Y values are stepped by tick intervals, to avoid + cumulative round-off error. This fixes the problem when Y crosses 0 with + a tick step such as 0.1 resulting in a long label for a very small but + non-zero number. Fixed DrawXTicks, DrawYTicks, and CalcMaxTickLabelSize. + (Originally reported by cncnet) + +2009-11-19 (lbayuk) + * Improve support for using callbacks to annotate plots: + Added new callback 'draw_all', called after all drawing. + Supply plot_area[] as argument to some drawing callbacks. + Added new method GetDeviceXY() to translate from world coordinates. + Allow NULL or '' for $font in DrawText() internal method, meaning to + use the generic font. If callbacks want to use DrawText, this + avoids them having to reference the internal fonts[] array. + +2009-11-01 (lbayuk) + * Address bug report 2886365 "Declare all functions and variables in + PHP5 style" + PHP5 deprecates the use of 'var' to declare a class member variable. + All initialized class member variables are now declared 'public'. + (It was tempting to make most or all 'protected' or 'private', but + that would likely break too much, including the PHPlot Test Suite.) + + Most class member functions which are meant for internal use only are + now declared 'protected', so they cannot be called from scripts + (except in child classes). (Note PHP5 does not deprecate the use of + just 'function' to mean public, so public functions were not changed.) + Internal functions are those documented in the manual under Developer's + Guide, Internal Functions. If your code breaks because you are using + a method which is now protected, please post the details on the help + forum. + + Some member variables which were set in the constructor are now + initialized with the class instead. (No impact.) + + Removed commented-out, FIXME-noted code for interim labels. + +2009-10-12 (lbayuk) + * Bug report 2839547, allow SetImageBorderType('none') to reset the image + border type. Also checked for other cases where there is no reset; + found one that exists (Set[XY]LabelType) but needs to be documented. + +2009-07-09 (lbayuk) + * Added a hook $plot->locale_override which can be set to True to prevent + PHPlot from loading locale settings from the environment with + setlocale(LC_ALL, ''). This is necessary for testing PHPlot on Windows, + where you cannot force a locale with an environment variable. It might + also be needed for people who want PHPlot's locale to differ from the + web server's locale. + +2009-06-12 (lbayuk) ===== Released as 5.0.7 ===== + +2009-06-11 (lbayuk) + * Change PHPlot license to LGPL, per Afan. + phplot.php, phplot_data.php - Change license notice. + rgb.inc.php - Change top comments and remove bottom marker. + COPYING - new file, text of LGPL. + LICENSE.* - removed files - old licenses. + Makefile - change list of distributed files. + + * Fix for bug 2803900: SetRGBArray('large') does not work. The include + file defined a different array name than the main script expected. + (This bug seems to have happened over 8 years ago.) Fixed the array + names to match. Also removed the ./ prefix from the included filename + so it will be found if on the include path but not in the script + directory. Also added error check if the rgb.inc.php include file + is needed and not found. + +2009-05-25 (lbayuk) + * Added new feature to allow partial margin or plot area specification. + You can omit, or specify as NULL, any of the 4 arguments to + SetMarginsPixels() or SetPlotAreaPixels(), and this means PHPlot + should use the automatically calculated margin on that side. + Credit to adoll for this feature. + +2009-05-17 (lbayuk) + * Fix for bug 2791502 "Error plots treat missing Y values as 0": + Plots with data type data-data-error now support missing Y values, + instead of treating them as 0. This works with lines, points, + and linepoints plot types, and also honors SetDrawBrokenLines. + + + * Fix for bug 2792860 "Wrong DataLabelLines with missing Y": + Do not draw X Data Label Lines at points with missing Y values. + + + * Fix for bug 2786350 "Missing Y data results in bad auto-range": + Rewrote FindDataLimits to ignore missing Y values, rather than + treating them as if 0, for calculating range. + Bug report and analysis by mrten. + + * Fix for bug 2786354 "Incorrect auto-range for data-data-error": + For data-data-error data type, apply the positive and negative error + amounts for each Y point to that point only, rather than applying the + largest errors to the overall minimum and maximum Y value for the row. + + Note: The two fixes above can change existing plots which rely on + automatic Y range calculation. The first fix affects plots with + missing Y values and min(Y)>0. The second fix can affect plots using + data-data-error data type and different error values for different + points. In both cases the new Y range can be smaller than before. + +2009-01-20 (lbayuk) ===== Released as 5.0.6 ===== + +2009-01-18 (lbayuk) + * Fix for bug 1891636 "Misaligned TTF X Labels": + PHPlot was using the actual bounding box of each line of text + to allocate space and set the text positioning, but was ignoring the + fact that the text baseline is not the same as the bottom of the + bounding box. This resulted in uneven alignment of the X labels if + they had different heights (for example, month names Jul and Aug). + + PHPlot now calculates the size of text for allocation (SizeText) using + the descenders on the last line, and calculates the size for drawing + (DrawText) only to the baseline. PHPlot also now uses a fixed line + spacing for each line of text in a font, rather than the actual text + height. This allows separately drawn multi-line labels to align. + + * Changes to line spacing when using multi-line labels: + PHPlot was using the class variable line_spacing to mean the + number of pixels between lines of multi-line labels. This made the + spacing too small for larger fonts, and it was not possible to adjust + line spacing for different types of text. + + PHPlot now interprets line_spacing as the number of pixels only + for GD text, and as a scale factor for the font's built-in line + spacing for TrueType text. In addition, a new optional argument is + added to SetFont, SetFontGD, and SetFontTTF to set a line spacing + specific to that type of text. + + * Changes had to be made to the legend drawing code to accommodate the + changes to font handling. + + Note: The line spacing change results in slightly looser spacing on + multi-line TrueType text labels, and slightly taller legends, compared + to version 5.0.5. + +2008-09-21 (lbayuk) + * Interim fix for bug 1932571 "Data-Data Plot fails with same X values". + PHPlot will no longer hang when the range of X values is 0 (that is, when + x_min == x_max). It will arbitrarily set an X range of 1, so the + calculated tick step is not 0. This is a temporary fix. Work on a smarter + X and Y range calculation is in progress, which will handle edge cases + like this better, but it isn't ready and this bug has been open too long. + Credit to andyl for finding the bug. + + * Fix font path: Use DIRECTORY_SEPARATOR constant not '/'. + + Extended the label formatting capabilities, adding 'printf' and 'custom' + types, added a prefix and suffix for 'data' type, and allow format controls + to be included in SetXLabelType and SetYLabelType. + + External changes: + * Added 'printf' label type. The caller specifies the print format as the + 2nd argument to SetXLabelType or SetYLabelType (default '%e'). + $plot->SetXLabelType('printf', '%5.2f'); + + * Added 'custom' label type. The caller supplies a callback (typically a + function name) and optional pass-through argument as the 2nd and 3rd + arguments to Set[XY]LabelType. The function is called as $f($value, $arg) + to return the formatted $value. + $plot->SetXLabelType('custom', 'myfunction', $arg_value); + + * In addition to Set[XY]TimeFormat, the format string for type 'time' can + now be set as the 2nd argument to Set[XY]LabelType. + $plot->SetXLabelType('time', '%H:%M'); + + * In addition to SetPrecision[XY], the precision for type 'data' can now be + set as the 2nd argument to Set[XY]LabelType. A 3rd and 4th argument + can supply a prefix and suffix for 'data' formatting. (All optional) + $plot->SetXLabelType('data', 2, '$', 'US'); + + Internal changes: + * Class variables x_precision, y_precision, x_label_type, y_label_type, + x_time_format, and y_time_format have been removed. + + * New class array variable label_format[], with elements 'x' and 'y' which + are arrays for label formatting. Elements in the sub-arrays are not + initialized until needed. + + * New function SetLabelType, which implements Set[XY]LabelType now. + + * FormatLabel() was rewritten to support the new label formatting. + + Compatibility: + * Any code that directly references class variables related to label + formatting will break, except for data_units_text. Use the documented + function methods instead. Setting data_units_text as a suffix is + deprecated but still works. + + * The 'data' type precision for 'Y' is still used for pie chart labels. + +2008-07-12 (lbayuk) + Multiple comment spelling error fixes. No functional changes. + +2008-07-06 (lbayuk) + Changes to allow mixing GD fixed-font text and TrueType Font (TTF) text + on the same plot. + (This change came from work done trying to fix TTF text positioning, + where it looks like additional information needs to be stored for TrueType + fonts. The old font data structure was awkward to extend, and allowing + mixed GD/TTF text was on the to-do list anyway.) + + External changes: + * SetFontGD(), SetFontTTF(): New functions to set a font, with type. + * SetFont(): Now calls SetFontGD or SetFontTTF depending on $use_ttf. + These changes should be fully compatible with existing programs. + + Internal changes: + * Updated comments explaining SetUseTTF() now sets the default type + (not the only type) of text used. + * Put all the font data into a class array. (Replaces $this->generic_font + with $this->fonts['generic'], etc.) + * ProcessTextGD() and ProcessTextTTF() now take the font array as one + argument, rather than separate arguments for font path and size. + +2008-01-13 (lbayuk) ===== Released as 5.0.5 ===== + * phplot.php: Updated version + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + * Makefile: Remove 'Callbacks' from release target, as this material is + now in the reference manual. + +2008-01-07 (lbayuk) + Copyright updated to 2008 and PHP4 no longer listed as supported. + + Major rewrite of the margin calculation functions to address multiple + problems. Fixes for bugs 1856207 "Margin error with 'xaxis'/'yaxis' + position, 1843012 "Make margins, drawing consistent", and 945439 + "x_tick_label_height not set correctly". + + Note: These changes are inter-dependent and cannot be split up. + + * Defer all calculations to DrawGraph time, to eliminate order dependencies. + These functions now just store their arguments in the object, and all + calculations happen later: + + SetXAxisPosition, SetYAxisPosition + + SetMarginsPixels + + SetPlotAreaPixels (Stores margins, not area, now.) + + SetPlotAreaWorld + + SetXTickIncrement, SetYTickIncrement + + * A new callback 'debug_scale' was added to trace the margin and scale + calculations. + + * CalcMargins was rewritten. Actual sizes of tick and data labels are now + used, rather than guesses like "use size of biggest Y value". A minimum + value (3 x safe_margin, or 15 pixels) applies to each margin. + + * FindDataLimits no longer needs to find the longest data label, since + CalcMargins now does that more precisely. + + * DrawXTitle and DrawYTitle now use position offsets calculated by + CalcMargins. Note: These titles are now offset from the plot area, + not the image area. The titles will move if you had set the plot area + or margins. + + * DrawYTick, DrawXTick rewritten to use pre-calculated offsets, and common + code moved to new CalcTicks(). + + * DrawXDataLabel: Use pre-calculated offsets for text. + + * DrawGraph: Rewrote top section (before drawing anything) to do the + calculations in the proper order, unconditionally. + + * Class variables removed: + x_label_inc, y_label_inc, _x_label_cnt : These were never used. + title_height, x_title_height, y_title_width : Now internal to CalcMargins. + data_limits_done : No more need to remember if FindDataLimits called. + + * New class variables added: + plot_margins_set : Keeps track of user-set plot area or automatic. + x_label_top_offset, x_label_bot_offset, x_offset_axis_offset, + y_label_left_offset, y_label_right_offset, y_label_axis_offset, + x_title_top_offset, x_title_bot_offset, + y_title_left_offset, y_title_left_offset : Label offsets + + * New internal functions: + CalcPlotAreaPixels : Deferred calculations taken out of SetPlotAreaPixels + and SetMarginsPixels. + CalcPlotAreaWorld : Deferred calculations taken out of SetPlotAreaWorld. + CalcAxisPositions : Calculate axis positions, moved from CalcTranslation. + CalcTicks : Calculate X and Y tick interval. This still uses the + same simple method (basically range/10), but now we could drop in a new + algorithm much more easily. This is now also used by CalcMargins. + Code taken out of DrawXTicks and DrawYTicks. + CalcMaxTickLabelSize : So CalcMargins can use the exact tick label sizes. + CalcMaxDataLabelSize : So CalcMargins can use the exact data label sizes. + DrawXTick : Code split out from DrawXTicks for symmetry with DrawYTick. + + +2007-12-13 (lbayuk) + * Changed ProcessTextTTF() so SizeText() will return integers. It rounds + the calculated values up, so the bounding box really contains the text. + This also prevents unneeded float calculations in derived values. + +2007-12-09 (lbayuk) + Major rewrite of the text drawing functions to address multiple problems. + Note: These changes are inter-dependent and cannot be split up. + + * Fixed bug 1813070 "Bad position for multi-line TrueType text": + TTF text is now drawn line-by-line, not as a block, for proper + alignment and positioning. + + * Fixed bug 1813071 "Wrong title height for multi-line TTF text": + Corrected miscalculation of overall height of multi-line TTF titles. + This bug resulted in over-sized margins. + The height is now computed line-by-line, including the inter-line spacing. + + * Fixed bug 1813474 "DrawText alignment arguments wrong": + Corrected meaning of 'top' vs 'bottom' alignment. PHPlot now follows + the usual conventions: 'top' alignment means top of text to reference. + DrawText default for vertical alignment is still 'bottom', but the + meaning was corrected. All callers of DrawText were fixed. + + * Fixed bug 1816844 "Fix order dependency for setting titles": + Defer processing titles strings until DrawGraph(), so there is no + more order dependency (no need to set font before setting title strings). + + * Fixed bug 1819668 "Horiz. align multi-line text: GD vs TTF": + The new text routines draw TTF text line-by-line and correctly do + right-, center-, and left- alignment of each line within a text block. + + * Fixed bug 1826513 "FIXME in DrawLegend: Max label length": + Use actual width of widest legend line to calculate legend box size. + + * Partial fix for bug 945439 "x_tick_label_height not set correctly": + In FindDataLimits(), save the longest data label, not just its length, + and use the actual rendered size of that string in CalcMargins() for + the margin calculations. + Also take into account which of the tick or data labels are visible. + This is not a complete fix, but is a significant improvement. + + The following changes were made related to the above fixes: + + + Replaced internal function TTFBBoxSize(), which didn't work right, with + SizeText(). It returns the orthogonal bounding box of a block of text, + and works with both GD and TTF text. + + + DrawText() and SizeText() call a single function ProcessText(), which is + the only place GD text and TTF text are distinguished. (So eventually + we will be able to mix GD and TTF text on a plot.) + + + New internal functions ProcessTextGD() and ProcessTextTTF() draw (or size) + GD and TTF text respectively. These are only called by ProcessText(). + These are re-implementations which properly position and align text. + + + Removed class variables title_angle, x_title_angle, and y_title_angle. The + titles only work at their fixed angles anyway (0, 0, and 90 respectively). + + + Line spacing set with SetLineSpacing() now affects TTF text as well as + GD text. Previously, it only affected GD text. The default line spacing + happens to be usable for TTF text. + + + Added new callback hook 'debug_textbox' for developing, testing, and + documenting. It provides access to the text area bounding box. + + + Removed unneeded class variables x_tick_label_height, y_tick_label_width, + x_tot_margin, y_tot_margin. + +2007-11-25 + * Improve error handling: + Internal functions PrintError() and DrawError() are now the same. Both + will draw the error message into the image and output it, and then + trigger a user-level error. If no error handler has been set, it will + exit, as before. But now the error message should also get logged, or + written to the standard error stream, depending on the SAPI in use. + You can now establish an error handler to catch most PHPlot errors and + do some cleanup before exit. + + This fix also covers bug #1823774 "Default Font Path and Error Message + Output". + + Fixed the return value of most PHPlot functions, to return False on + error, else True. Since uncaught errors are fatal anyway, this only + affects code with an error handler that returns, which is not + recommended and unsupported at this time. These changes are for + possible future error handling options. + +2007-11-22 + * Fix bug 1836528 "Insufficient checking of parameter values": + Rewrote CheckOption to correctly validate option choices. + (It previously accepted substrings and other incorrect values.) + PHPlot methods that use CheckOption now must be called with valid option + values. Empty strings are also no longer accepted. + +2007-11-17 (lbayuk) + * Change to callbacks to support extra arguments. + The PHPlot class can now pass extra arguments to a callback function. + Callback functions now take the following form: + my_callback($img, $passthru_arg, ...) + Where '...' is zero or more additional arguments supplied by PHPlot to + the callback. Each implemented callback reason will define any + additional arguments it uses. The existing defined callbacks have not + changed and do not currently pass any extra arguments. + +2007-11-10 (lbayuk) + * Fix bug 1827263 "Spoiled up pie-chart if $val is close to zero": + Skip pie slices which would result in an integer angle of zero + degrees, because the GD arc filling function will draw a complete + circle for that case. + Credit to Viacheslav for finding this. + + * Removed 8 of the functions (class methods) marked 'deprecated'. Only + deprecated functions which seem to have been for internal use have + been removed. Even old scripts shouldn't be using them, and they are + becoming a problem to maintain. + Removed: SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights() + CalcYWidths() DrawLabels() InitImage() DrawDashedLine(). + +2007-10-20 (lbayuk) ===== Released as 5.0.4 ===== + * phplot.php: Updated copyright, version, and authors comments at top. + * README.txt: Updated for new release + * NEWS.txt: Add text for new release + +2007-10-18 (lbayuk) + * Add callbacks - experimental feature: + New functions SetCallback, GetCallback, RemoveCallback. + New internal function DoCallback. + Added callback hooks to DrawGraph. + + Re-arranged code in DrawGraph to bring pie chart drawing into the main + switch on plot type, rather than a special case in its own block. This + makes it easier to follow and easier to add callback hooks. + + * Callbacks: New file, documentation for the new callbacks feature. + (This won't be in the manual while it is an experimental feature.) + +2007-10-15 (lbayuk) + * Fix for bug 1813021: Miss-positioned right-justified vertical GD text. + Fixed DrawText() to correctly position 90 degree right-justified text + drawn in a fixed GD font. This could be seen with 90 degree Y tick + labels. (Found by accident while working on TrueType text problems.) + Also some code cleanup in DrawText: use elseif where appropriate. + +2007-10-09 (lbayuk) + * Code cleanup: Simplify SetIndexColor() and SetIndexDarkColor(). + There is no need to first try ImageColorExact, then ImageColorResolve + if that fails. ImageColorResolve does all that for us. + + Code cleanup: Rewrite SetRGBColor(). It now detects if an unrecognized + color name or color value form is used, and draws an error message. + Before this it would get a PHP index error and "headers already sent" + condition. + + * Code cleanup: Remove duplicated code for loading image files. + Added new class-private function GetImage() which loads an image based + on the image type, and also returns the image size. This replaces + duplicated code in tile_img() and SetInputFile(). + Also fixed comment at top of SetImageFile which said it was deprecated. + It isn't - it is used by the constructor. Moved the function out of the + 'deprecated' area up to below where it is used. + + * Code cleanup: PHPlot should not define or affect anything outside its + own class. + - Removed the check for __FUNCTION__ (PHP 4.3 and up). This is obsolete. + - Do not set error_reporting to E_ALL. Although it is recommended that + scripts do this, it is not the place of loaded classes to do it. + - Remove unused global constant TOTY. + - Removed constants MAXY and MINY. Global constants like this are bad. + These were used as magic index values into data[] to hold min and max Y + values for the row. Instead, put them in separate arrays which are + named data_miny[] and data_maxy[]. (This seems to be only used by the + data line drawing function.) + + Comment cleanup: Remove one commented-out partial function DrawPlotLabel, + and fix another commented-out code fragment in DrawYErrorBar. Both of + these had unmatched braces in them which caused a balance-braces check + to fail. + + * Code cleanup, array padding: Get rid of functions outside the class + and remove the interim fix for PHP 5 (which changed the behavior of + array_merge). Rewrote external function array_pad_array() as a new + class function pad_array(). It does not need access to the class, + but I don't think PHPlot should add to the global namespace more + than necessary. The third argument (array to use for padding) was + never used, so it was removed. It always pads the array with itself. + It now only works on 'usual integer indexed' arrays (0-based + sequential integer index). The was previously required but + undocumented for some of the arrays (like line_widths); now it is + required for all style arrays and will be documented. Now we can pad + the array to the required length, not just N times its previous + length, and we don't need array_merge. Deleted external function + array_merge_php4() as it is no longer used. + + Deleted PHP end marker ?>. You don't need this and it can cause + problems with extra whitespace in your output. + +2007-09-24 (lbayuk) + * Code cleanup: Fix ternary operator misuse. This doesn't change + behavior, but it was annoying me so I fixed it. + Replaced all cases of code like this: $a = ($a > $b) ? $b : $a + With just: if ($a > $b) $a = $b + + * Fix Makefile 'release' target to set owner/group when creating + the tar file. This avoids having to run it as root, but it needs + GNU tar to work. + +2007-09-08 (lbayuk) + * Fix for bug 1790441: Removed the PHPlot quasi-destructor function and + the register_shutdown_function() call which arranged for it to be used. + This was preventing release of memory when a PHPlot object was unset, + because the registered shutdown function held a reference to it. + So rather than improving memory use, it had the opposite effect. + Note: It is no longer necessary or recommended to use reference + assignment ($plot =& new PHPlot) for PHPlot object creation. + Thanks to annajilly for the thorough analysis, bug report, and fix. + +2007-09-05 (lbayuk) + * Rewrote FormatLabel() to ignore blank label values. Adapted from a + patch and feature request submitted by Gerhard Reithofer (exgerhardr). + Blank labels used to produce an error if the LabelType was set to + 'time', and zero if set to 'data'. Now they are just ignored. This + provides a simple way to have labels only at selected intervals when + using time or data formats. For example, you can have a date/time + label at every 10th data point by setting the labels for the other 9 + to be empty strings. Also: Removed $which_pos values 'plotx' and + 'ploty'. These were unused by PHPlot and this is an internal-only + function so there is no compatibility issue. Removed error checking on + $which_pos for the same reason; the error message used an undefined + variable anyway so it wouldn't have worked. + +2007-08-26 (lbayuk) + * Allow SetLegendStyle colorbox_align argument to be 'none', to suppress + the colorboxes in the legend. + + Fix comment on $legend_text_align: empty means right, not left. + + Rewrote DrawLegend layout code to make it easier to understand. The + result should be within 1 or 2 pixels of the previous size and position. + + * Fixes for bug 1779115: SetLegendWorld() fails on undefined vars + Store the given coordinates and remember that they need to be converted + from world to pixel coordinates, but defer trying to actually convert + them until it is time to draw the legend. This way, there are no + problems with the scale having to being set up first (which is nearly + impossible to do). Made the following changes: + + Changed legend class variables to be uninitialized, and unset (rather + than empty string) means use the defaults. Added a new variable: + $legend_xy_world. If it is set, (legend_x_pos, legend_y_pos) need to + be converted to pixel coords. If it is unset, they are already pixel + coords (or undefined, meaning defaults). + + Changed usage of internal function DrawLegend(): removed all arguments. + X and Y were always the class variables anyway, and now it needs to + also use the new flag to tell it if X and Y are world or pixel coords. + The third argument was unused. + + Removed third, unused, default NULL argument from SetLegendPixels and + SetLegendWorld. + + Changes to DrawLegend to convert x, y coords to pixel coordinates + if they came from SetLegendWorld. Also account for new usage of + the class variables: Test for unset to mean use default. + +2007-08-04 (lbayuk) + * New feature: control legend text and color box alignment. + Adds a new function SetLegendStyle to adjust the alignment of the + text and the color boxes inside the legend. + Based on part of bug 1208054, contributed by David Hernández Sanz. + +2006-12-02 (lbayuk) + * Fixes for bug 1605555: Y Data Labels use wrong font and not formatted. + Use y_label_font (not x_label_font) for Y Data Labels. + Use the formatted value for the label, not the original text. + (This applies to bar charts only, with the new Y data labels.) + + * One fix for bug 1208054: Localization of number format. + If number formatting is enabled with 'data' format type, PHPlot previously + used dot for decimal point and comma for thousands separator, and there + was no way to change it. + + This fix adds a new function: + SetNumberFormat($decimal_point, $thousands_separator) + to set the separators. In addition, if that function is not used, + PHPlot will now try to use locale-dependent separators. If locale + information is not available, it will fall back to the old defaults + of dot and comma. + + Note: This change may have some negative effects. 1) If your locale is + "C" or "Posix", you might not get a thousands separator now by default. + You should be using a more specific locale. 2) If your PHP script is + forcing a specific locale with setlocale(), PHPlot will probably undo + that because it uses setlocale(LC_ALL, '') to import locale information + from the environment. We have to do that, or a locale set through + the environment is ignored. But it will override a manually set locale. + + * Fix for bug 937944: X/Y Tick Counts + PHPlot could draw one too few Y tick marks, and one too many X tick marks. + + Changed the code to stop drawing X (Y) tick marks when the current X (Y) + value exceeds the maximum X (Y) value plus a small fudge factor. The fudge + factor accounts for cumulative error when repeatedly adding a delta to + the X (Y) value. + + Notes: The bug report was writing about Y tick counts only, but X tick + counts can also be wrong. The proposed fix in the bug report does not + work in all cases. + + This fix changes the appearance of many plots which were missing the + top-most Y tick mark. The extra X-tick mark problem is less common. + +===== Released as 5.0rc3 ===== + +2006-11-13 (lbayuk) + * Fix for bug 1437912: x-axis label misalignment [bar charts] + The calculations were redone from scratch. + New control variable 'bar_extra_space', which works in addition to + 'group_frac_width' to control how much extra space is around the bars. + Made bar widths match for 'stackedbars' and 1-bar-per-group 'bars'. + + NOTE: This changes the appearance of charts. bars in 'stackedbars' + will now be thinner, and bars in 'bars' graphs will be thicker. I + saw no reason for them being different before. + + This fix required fixing the positioning on the new bar data labels, + which was off before. The bar data labels will now be centered. + Additional fixes to bar chart data labels: + For negative values, the label will center under the bar. + Fixed X-adjustment to account for shading. + Fixed to not suppress the data label if the value is 0. + + +2006-11-10 (lbayuk) + * Fix for bug 1594457: DrawError text wrap and background fix + Do error image white background correctly, and word-wrap the text. + + * Fix for bug 1594458: Suppress lines or points in 'linepoints' + Don't draw X data labels twice for 'linepoints'. + Allow SetPointShapes value 'none' to suppress points, and allow + SetLineStyles value 'none' to suppress lines. This allows a 'linepoints' + graph to mix lines only, points only, and both on the same graph. + + +2006-11-09 (lbayuk) + * Fixes for bug 1446523: + + Wrong variable name in deprecated SetAxisFontSize() + + Fails to properly handle error if SetDataValues() was never + called, or not called with a data array. + + * Fix for bug 1117122: Pie Chart ignores SetPlotAreaPixels + Don't let DrawGraph recalculate the plot area for pie charts if the + user already set it with SetPlotAreaPixels. + + NOTE: This fix may slightly change the appearance of some pie charts, + whether or not they use SetPlotAreaPixels. + + * Fix for bug 1103992: Wrong max Y calculated for stackedbars + Changes FindDataLimits to calculate max Y correctly. It was counting + the first Y value in each record twice, which is always wrong but + only affected stackedbars because the Y values are summed. + + * Fix for bug 1096199: Wrong error bar colors in DrawDotsError. + Rewrites DrawDotsError to make it work like DrawLinesError to + correctly increment the record and color indexes. + Also fixes uninitialized x_now_pixels. + + * Fix for bug 1096197: No borders on unshaded Draw[Stacked]Bars + Unshaded Bars and StackedBars covered the border with the rectangle. + The fix is to draw the rectangle, then the border. + + NOTE: This fix changes chart appearance. Bars and Stacked Bars + will now get a black border around each bar by default, if you + turn off the 3D-shading. If you want borderless, unshaded bars + you need to use SetDataBorderColors to set the data border colors + to be the same as the data colors. + + * Fix for bug 1333164: Negative data values, if string variables, result + in unfilled bars. The problem was a string-to-string compare of a + negative number with the empty string x_axis_position. Fixed by + initializing x_axis_y_pixels to 0 if SetXAxisPosition was not used. + + +2005-04-17 (afan) + * Fix for bug [ 1161072 ] SetInputFile warning, background overwrite + + * Bug 1182672 fixed + +2005-04-15 (afan) + * fix for bug: [ 1182666 ] Y Auto-scale rounds in wrong direction + + * Fix for bugs 1144644 TrueType font path problems and 1106328 TTF + path/filename inconsistency + + * Fix Bug: [ 1117120 ] X Title sizing uses Y Title font height + +2005-04-13 (afan) + * Error in SetLineStyles() - does not accept an array argument + + +2005-03-29 (afan) + * Small typo fixed in SetYDataLabelPos + + * Update SetDataLabelPos: For past compatibility we accept plotleft, + ...but pass it to SetTickLabelPos + +2005-03-26 (afan) + * Change to line 3802: data lables now work with multiple bars with *$idx + +2005-03-25 (afan) + * Added Function DrawDataLabels to put data labels in world coords, + added call from DrawBars and modified SetYDataLabelPos to flag + whether or not to call DrawDataLabels. + +2005-01-20 (migueldb) + * Many bugfixes reported and solved by L. J. Bayuk. Thanks! + + fixed bug #1096190 + + FindDataLimits(): fixed bug #1096192 + + CalcTranslation(): fixed bug #1101317 + + DrawImageBorder(): fixed bug 1096200 + + DrawXDataLabel(): fixed bug 1099879 + + DrawDots(): fixed bug #1096194 + +===== Released as 5.0rc2 ===== + +2004-10-24 (migueldb) + * array_merge_php4(): added to cope with the bug introduced by + the change in array_merge() from PHP4 to PHP5 (I haven't verified this) + * Fixed some divisions by zero, thanks to an old bug report. + +2004-09-09 (migueldb) + * SetPointSize(): deprecated + * SetPointSizes(): added as replacement for SetPointSize(). + Now able to set point sizes on a per line basis. + * SetPointShape(): deprecated. + * SetPointShapes(): added as replacement for SetPointShape(). + Now able to set point shape on a per line basis. + * DrawDot(): now needs record number to decide which dot shape and + size to draw. + * CalcMargins(): dirty fix for x data label placing. + * tile_img(): fixed tile placement. + +2004-06-14 (migueldb) + * SetXTickLabelPos() and others: more on the bug reported by Jo Demol. + * Fixed bug reported by Jo Demol. + +2004-05-11 (migueldb) + * SetBgImage(): added. + * SetPlotAreaBgImage(): added. + * SetInputFile(): deprecated. + * DrawBackground(): now accepts images as backgrounds. + * DrawPlotAreaBackground(): now accepts images as backgrounds. + * tile_img(): internal method added. + +.......... +Editor's Note: For older changes to PHPlot, please see the CVS logs. diff --git a/gui/bacula-web/classes/external/phplot/NEWS.txt b/gui/bacula-web/classes/external/phplot/NEWS.txt new file mode 100644 index 0000000000..fdd99fe18a --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/NEWS.txt @@ -0,0 +1,1047 @@ +This is the NEWS file for PHPlot, with release documentation. +The project web site is http://sourceforge.net/projects/phplot/ +The project home page is http://phplot.sourceforge.net/ +Refer the the ChangeLog file for detailed source changes. +----------------------------------------------------------------------------- + +2011-01-15 Release 5.3.1 + +Overview: + +This is the current stable release of PHPlot. This release focuses on +providing better support and documentation for creating multiple plots on a +single image. + +The PHPlot reference manual has been updated to match this release. Some +new material has been added, including a new section on multiple plots per +image, and a new example of overlay plots. + + +Bugs Fixed in 5.3.1: + +#3143586 "Multiple plots per image - fixes & docs": + The reference manual now contains a section on multiple plots, and a + new example. A bug was fixed with SetLegendWorld and multiple plots. + Image border will now be drawn at most once. It is now possible to + restore the default 'automatic' behavior for axis positioning. Other + functions were changed to make arguments optional, so when called with + no arguments they reset to the default. The reference manual has been + updated with these changes too. + +#3147397 "Data colors missing with multiple plots": + The fix for bug #3049726 "Optimize color allocation" caused a problem + with multiple plots. This has been fixed. PHPlot will no longer truncate + the data color table at each plot. It will still only allocate data colors + as needed, but all of the pre-set or configured data colors will be + available for each plot. + + +----------------------------------------------------------------------------- + +2010-12-04 Release 5.3.0 + +Overview: + +This is the current stable release of PHPlot. This release includes new +plot types and some new features. + +The PHPlot reference manual has been updated to match this release. Some of +the sections have been moved, there are new examples for the new plot types, +and a new section on tunable parameters has been added. + + +New features in 5.3.0: + +#3093483 "Investing support chart types": + Added 3 new plot types: Basic OHLC (Open/High/Low/Close), Candlesticks, + and Filled Candlesticks. These are variations of plots that show the + performance of a stock or other financial security. + +#3111166 "Control legend colorbox width": + It is now possible to control the width of the color boxes in the + legend, using a class variable which is documented in the manual. + +#3117873 "Data value labels in more plot types": + Data value labels, which show the dependent variable values near the + data points, are now available for more plot types: lines, linepoints, + points, and squared. (These were previously available only for bars and + stackedbars plots.) + +#3127005 "Ability to suppress X/Y axis lines": + New functions SetDrawXAxis() and SetDrawYAxis() were added to control + display of the X and Y axis lines. (These lines were probably the only + PHPlot elements that could not be turned off.) In special cases, these + can be used to produce a "bare" plot image. + + +----------------------------------------------------------------------------- + +2010-10-03 Release 5.2.0 + +Overview: + +This is the current stable release of PHPlot. This release includes some +bug fixes and new features, described below, and a reimplementation of +internal processing of colors. + +The PHPlot reference manual has been updated to match this release. +Horizontal plots are now documented in the manual, and the interim +documentation in the source release (HorizontalBars.txt) has been removed. +The manual is available in HTML format as a separate download from +Sourceforge. The manual is also available for on-line viewing from the +project home page. Starting with this release, the manual is also +available in PDF format from the project home page. + + +Cautions, Important Notes, and Compatibility Issues: + +Due to changes in color allocation (see bug #3049726 below), image files +produced with PHPlot-5.2.0 will differ when compared byte-for-byte with +those created by earlier releases, even when the images are identical (as +they nearly always are). + +If you are creating a horizontal plot with any negative X values, and not +setting the Y axis position, your plot will change (see bug #3074402 below) +because PHPlot no longer leaves the Y axis on the left for horizontal plots. + +Some internal methods that used to have 'public' visibility are now protected. +This will generally prevent you from using them. The list of changed functions +can be found in the release ChangeLog. Avoid using any internal methods. + +If you are making a stackedbar plot with any negative values, PHPlot-5.1.3 +and earlier took the absolute value of each data value (which was not +documented), but PHPlot-5.2.0 does not. See Feature Request #3073679 below. + +If your plot fills the 256 available color map slots in a palette image, +your image may look different with PHPlot-5.2.0 due to changes in color +allocation order. This was seen on two of the tests in the PHPlot test +suite. These tests tiled a JPEG image into the plot area or image +background. Being a truecolor image, the JPEG had a huge number of colors, +which filled all available slots in the color map. Additional colors for +plot elements had to be approximated, and different colors resulted with +PHPlot-5.2.0 versus previous releases. To avoid this problem, either use a +truecolor PHPlot object (PHPlot_truecolor constructor), or reduce the +number of colors in the background image and convert it to PNG or GIF. + +This release contains significant changes to PHPlot internals. In particular, +variables and functions related to element colors and color handling have +changed. Refer to the PHPlot release ChangeLog for more details. Remember, +if you rely on accessing any member variable, or on using any non-public +function or any function not documented in the reference section of the manual, +your code is at risk of breaking with each new release. + + +New features in 5.2.0: + +#3077554 "Finer control over plot element colors" (partial): + The X, Y, and main titles can now have different colors. See the PHPlot + Reference Manual entries for SetXTitleColor and SetYTitleColor. + +#3073679 "Stacked bar plots with negative values": + A stacked bar plot can now include negative values, and stacks of negative + values will be drawn downwards (or leftwards). See the PHPlot Reference + Manual under "Plot Type: stackedbars" for details. + + +Bugs Fixed in 5.2.0: + +#3045131 "SetTransparentColor problems": + Setting a transparent color now works whether before or after setting + the background color (for example), and also now works with a data color. + +#3049726 "Optimize color allocation" + PHPlot now defers allocating colors until drawing time, and tries to allocate + only the colors which are actually needed. For palette images, this results + in use of fewer color slots and slightly smaller image files. + +#3074402 "Fix Y axis default for horizontal plots": + When horizontal plots were introduced, an asymmetry with the X and Y axis + position defaults was known but left. This behavior was later determined + to be unhelpful. So now the Y axis on horizontal plots will default to X=0, + or the X value closest to zero within the plot area range. This is the same + behavior as for the X axis in vertical plots. + +#3056991 "Internal methods should be 'protected'": + More of the internal PHPlot functions were changed to 'protected' visibility, + as the test suite was fixed to not call them directly. + +#3057000 "Review 'deprecated' methods": + One broken deprecated method (SetColor) was removed and one changed. + Note that deprecated methods are not documented and not tested. + +----------------------------------------------------------------------------- + +2010-08-30 Release 5.1.3 + +Overview: + +This is the current stable release of PHPlot. Additional horizontal plot +types and features have been added, however horizontal plots are still +considered 'experimental'. A new callback has been added which allows +greater control over the data colors. An improved method for accessing +TrueType Font (TTF) files means that on many systems TTF text can be used +without specifying font paths. + + +Cautions and Important Notes: + +Since the previous PHPlot release, PHP-5.3.3 and PHP-5.2.14 have been +released, and these include a fix for the TrueType Font (TTF) rendering +problem. Use of these releases is now recommended. + +There has been extensive cleanup of the PHPlot code. If you have a +customized version of PHPlot, you may find it difficult to update. + +The "additional data support" script phplot_data.php has been removed from +this release. The script has not been developed or tested in a long time, +and was found to have numerous problems. The script can still be found in +the CVS repository. + +The changes in this release (horizontal plots, custom data color callback, +and TrueType Font handling) should not result in any compatibility issues. + + +New features in 5.1.3: + +#3049703 "Additional horizontal plots and features": + + Implemented data values labels in horizontal bar charts. + Use: SetXDataLabelPos('plotin'). + + Add horizontal stacked bar charts, with data value labels. + + Add horizontal thinbarline plots. + Horizontal plots are still considered 'experimental', and documentation is + in the HorizontalBars.txt text file rather than the PHPlot Reference Manual. + +#3034164 "Extended control of data colors": + New callback 'data_color' can be used to customize selection of the color + of each bar, line segment, point marker, etc. This is documented in the + PHPlot Reference Manual section "Custom Data Color Selection", with new + examples in the Examples chapter. + + +Bugs Fixed in 5.1.3: + +#3051906 "Better choice for default TT font": + Rather than always using the unlikely 'benjamingothic.ttf' as its default + TrueType font name, PHPlot now has a short list of sans-serif fonts, and + tries to find one that works if a default TT font is needed. On many + systems, this will provide a high-quality default font without help. + +#3051832 "Let PHP/GD find the font file": + Instead of using file existence to validate a TT font file, PHPlot now + just tries to use the font. This allows PHP/GD to use its own rules to + try to find the font, without needing a pathname. This works on Windows + and at least some Linux systems. + +#3048267 "phplot_data add-on is still broken" + Not fixed. phplot_data.php has been removed from the release. + +----------------------------------------------------------------------------- + +2010-06-29 Release 5.1.2 + +Overview: + +This is the current stable release of PHPlot. Truecolor image support is no +longer considered 'experimental', and is now documented in the reference +manual. There is a new experimental feature for horizontal bar charts. This +release also contains a bug fix and new feature. + + +Cautions and Important Notes: + +The advisory against using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use +TrueType fonts (TTF) continues. See the item below for PHPlot-5.1.1. The +good news is that this has been fixed by the PHP Team and will be in the +next releases. + +Compatibility of data type and plot type are now checked completely. If +you used an incorrect data type with certain plot types, your script may no +longer work until you fix the data type. Specifically, the area, squared, +and thinbarline plot types failed to check the data type they received, and +treated anything other than 'data-data' as 'text-data'. If you have a +squared plot with data type 'data-data-error', for example (which is not +supposed to work), it did produce a plot, but will now result in an error. + +The addition of horizontal bar charts should not impact any existing plot, +with one small exception. The function SetYDataLabelPos() used to accept +some additional, undocumented options (plotleft, plotright, both, yaxis) +and pass these through to SetYTickLabelPos() "for compatibility". It no +longer does so, as some of those are now used for horizontal bar chart +labels. To position Y tick labels, use only SetYTickLabelPos(). + + +New features in 5.1.2: + +#3002606 "Add to plot and image border options": + SetPlotBorderType() now accepts 'right', 'top', and 'bottom', as well + as an array of options. So you can now control exactly which of the 4 + border sides will be drawn. + SetImageBorderType() now accepts 'solid' as a choice. This will use the + actual color set with SetImageBorderColor(), rather than the darker + shade as type 'plain' does (which may have been a bug). + SetImageBorderWidth() is a new function that sets the width of the image + border. The defaults are the same as the fixed values used before: 1 + pixel for plain, 2 pixels for raised. The image border width is now + accounted for in margin calculations, if it is greater than 2 (to make + sure existing plots will not change). + +#2885930 "Horizontal Bars": + Horizontal bar charts are implemented, as an experimental feature. + 'Experimental' means they are not yet documented in the reference manual, + and subject to change or removal. + Refer to the text file HorizontalBars.txt for details. + +#2947679 (follow-up) "Support for alpha blending/Truecolor": + Truecolor support is now documented in the Reference Manual. The interim + documentation file Truecolor.txt has been removed. Alpha channel + specification now works with both constructors and both image types. This + fixes an issue if the base constructor was used with a truecolor background + image. (In PHPlot-5.1.1, the result would be a truecolor image, but the + alpha channel features were not available.) + + +Bug Fixed in 5.1.2: + +#3010116 "Bad rendering of title in multi-plot image when using TTF": + Make sure the main title is drawn only once, to avoid bad rendering of + TTF titles with multiple plots due to anti-aliasing. + +----------------------------------------------------------------------------- + +2010-04-04 Release 5.1.1 + +Overview: + +This is the current stable release of PHPlot. This release adds truecolor +image support as an experimental feature, fixes a number of bugs and adds +a few new features. + +The PHPlot reference manual has been updated to match this release. The +manual is available as a separate download from Sourceforge. The manual is +also available for on-line viewing from the project home page. + +See the ChangeLog file in the release for more about changes and bug fixes. + + +Cautions and Important Notes: + +Avoid using PHP-5.3.2 or PHP-5.2.13 with PHPlot if you use TrueType fonts +(TTF). Some new bugs were introduced in those releases that adversely +affects accurate positioning and rendering of TrueType font text. + + +New features in 5.1.1: + +#2947679 "Support for alpha blending/Truecolor": + PHPlot can now produce truecolor images, with alpha blending of colors and + other effects. This is considered an experimental feature, meaning it is + not yet documented in the PHPlot Reference Manual, and subject to change. + Refer to the text file Truecolor.txt included in the PHPlot release for + information on using truecolor. + Two drawing changes were made to improve plot appearance with Truecolor: + + Filled dots (in points & linepoints plots) are now drawn better. This + also makes them look rounder with regular (non-Truecolor) plots. + + Area plots have the areas filled without overlapping each area down to + the Y axis. This was needed to fix problems with alpha blending, and + should have no effect on non-Truecolor plots. + +#2973995 "Add y-Data to Stackedbars": + You can now have Y Data Labels with 'stackedbars' plots. These label the Y + values (incremental and total) for each bar. Refer to the reference manual + page for SetYDataLabelPos(). + + +Bug Fixes in 5.1.1: + +#2976735 "Improvements and fixes for 'area' plots": + Moving X axis works; handle Y<0 better; new 'stackedarea' plot type is a + variation on 'area' with the data represented differently. + +#2974639 "Stacked bars plot breaks with X axis != 0": + Moving X axis works. + +#2963757 "point_counts undefined error in 5.1.0": + Fixed an error introduced in PHPlot-5.1.0 when point size and shape arrays + were set to the same size. + +#2938219 "Bars go in wrong direction": + For bar charts with all Y<0, bars will still be drawn down even if Y=0 is + not in range. + +----------------------------------------------------------------------------- + +2009-12-24 Release 5.1.0 + +Overview: + +This is the current stable release of PHPlot. This release fixes a number of +bugs and adds some new features. Some of the changes in this release can +alter the appearance of plots, so be sure to review the information in this +NEWS file and test this release with your application. + +The PHPlot reference manual has been updated to match this release. The +manual is available as a separate download from Sourceforge. The manual is +also available for on-line viewing from the project home page. + +See the ChangeLog file in the release for more about changes and bug fixes. + + +New features in 5.1.0: + ++ A new "contrib" directory has been added for useful add-ons. + This currently contains: + * prune_labels : Control data label density on X axis. + * color_range : Define a gradient map for data colors. + ++ Feature Request 2899921 "Allow different format for data and tick labels" + Text angle and format can now be controlled separately for data labels. + ++ Locale loading override + New variable locale_override stops PHPlot from getting locale from system. + ++ Translating Coordinates + New function GetDeviceXY() to translate world to device coordinates. + ++ New drawing callback + New callback 'draw_all', called after all drawing is done. + The manual now contains an example of using this new callback and + the new GetDeviceXY() function to annotate a plot. + + +Bug Fixes in 5.1.0: + +#2914403 "Pie + X/Y titles: Undefined property error" + X/Y titles are now properly ignored for pie charts. + +#2908256 "Error: array_sum() should be an array" (drupal) +#2916864 "Should at least print legend on pie charts with empty data" + Pie charts with invalid data (no Y values > 0) now make an empty plot. + +#2906436 "Fixes for X Tick Labels vs X Data Labels" + Smarter determination of whether to do Tick labels, Data labels, or both. + +#2900914 "Problem with display of 0 on Y axis" + Fixed rounding error that could produce something like Y=8.12345E-16. + +#2886365 "PHP 5 patch" (Declare all functions and variables in PHP5 style) + Most internal PHPlot member functions now have "protected" visibility. + +#2839547 "SetImageBorderType('none') + You can use SetImageBorderType('none') to turn the image border back off. + +#1795972 "Fix default point shapes" + We now have 20 (vs 10) point shapes, with 10 (vs 1) used by default. + +#1795971 "Fix default data colors" + We now have 16 (vs 8) default data colors, no duplicates, all visible. + + +Visible Changes and Possible Incompatibilities: + ++ PHP5 visibility changes (Bug #2886365) +Details: Most internal PHPlot member functions now have visibility + 'protected', rather than all being public. All member variables are + still 'public'. + +Reason for the change: Use the recommended PHP5 syntax, better OO style. + +Compatibility: If you were calling a PHPlot internal function that got + changed to 'protected', this will break. Please report this. + + ++ Fix default point shapes (Bug 1795972) +Details: We now have 20 (vs 10) point shapes available, and by default we + have 10 (vs 1) different shapes in use. The default size is now 6 pixels + for all point shapes. + +Reason for the changes: Using different shapes helps distinguish the data + sets. The existing 10 defined shapes were not enough, since some of them + are not centered over the points, too small, or otherwise hard to see. + The code to synchronize the point shape and size arrays was broken, and + some dubious code to adjust sizes to even numbers needed to be fixed. + +Compatibility (1): If you have a points or linepoints plot with more than + one dataset, and you did not use SetPointShapes() to configure the + shapes, them your plot will change from using a diamond for all data + sets to using different shapes for up to 10 data sets. + +Compatibility (2): Fixing the point size/point shape array size bug may + slightly change the size of some shapes, but it now works the way it + was documented and supposed to work. + ++ Fix default data colors (Bug 1795971) +Details: Defined a new set of 16 default data colors. The colors are + different and contrast well against the default white background. + The first 4 colors were not changed. + +Reason for the change: The default 8 data colors included two instances + of orange, and one color which was invisible on a white background. + +Compatibility: Colors will change on any plot with more than 4 data sets + where you did not use SetDataColors() to set your own data colors. + ++ Re-used old function SetXDataLabelAngle() +Details: SetXDataLabelAngle() now does something different. + +Reason for the change: This name was needed for a new function, to set the + angle for the X Data Labels. The old use of this function was not + documented, and marked "deprecated" in the code since around 2003-12-07. + +Compatibility: If you are still using SetXDataLabelAngle() to set both Tick + and Data label angles, you need to use SetXLabelAngle() instead. + ++ Separate controls for tick and data labels (Feature Request 2899921) +Details: New functions SetXDataLabelAngle(), SetYDataLabelAngle(), + SetXDataLabelType(), and SetYDataLabelType() to allow separate control + over the angle and format of data labels, versus tick labels. + +Reason for the change: Allow Data Labels to use different formatting and + angle compared to Tick Labels. + +Compatibility: The default behavior has been set up such that there should + be no compatibility issues. For example: + Old behavior: SetXLabelType() sets the type for both tick and data labels. + New behavior: SetXLabelType() sets the type for tick labels and the + default type for data labels. SetXDataLabelType() sets the type for + data labels (overrides SetXLabelType). + ++ X Tick Labels vs X Data Labels (Bug 2906436) +Details: Regarding SetXTickLabelPos() and SetXDataLabelPos(): If only one + of them is called, the behavior is unchanged (only that label type will + be displayed). If both are called: Do exactly what was requested. If + neither was called: display only data labels if any data labels are + non-empty, else display only tick labels. + +Reason for the change: 1) Fix the long-standing problem behavior that by + default PHPlot overlays tick and data labels below the X axis. 2) Fix + order dependency between setting the position of tick and data labels. + 3) Prepare for future extension of data labels, and allow both tick + and data labels to be on if the programmer enables both. + +Compatibility: There are some cases where your plot will change. + (a) Calls neither SetXDataLabelPos() nor SetXTickLabelPos(): + Old behavior: Both tick and data labels displayed, possibly overlaid. + New behavior: If there are any non-blank data labels, then show only + the data labels, not the tick labels. Otherwise, show tick labels. + + (b) Calls both SetXDataLabelPos() and SetXTickLabelPos(), with other than + 'none' for each position: + Old behavior: The latter call was effective; earlier one ignored. + New behavior: Independent of order, both calls are effective. + +----------------------------------------------------------------------------- + +2009-06-14 Release 5.0.7 + +Overview: + +This is the current stable release of PHPlot. The release adds one new +feature, fixes a few bugs, and changes the license under which PHPlot +is released. + +The PHPlot reference manual has been updated to match this release. The +manual is available as a separate download from Sourceforge. The manual is +also now available for on-line viewing at http://phplot.sourceforge.net + +See the ChangeLog file for more about changes and bug fixes. + + +Licensing: + +PHPlot is now released on the terms of the GNU Lesser General Public +License, version 2.1. (Previous versions of PHPlot were released under +a dual "PHP/GPL" license.) The licensing change was authorized by the +original author and copyright holder of PHPlot. + + +New feature in 5.0.7: + ++ Plot area margins can now be partially specified, using either + SetMarginsPixels or SetPlotAreaPixels. In previous releases of + PHPlot you had to either specify all 4 margins or none. + Credit to adoll for this feature. + + +Visible Changes and Possible Incompatibilities: + ++ Y data range can change: + As a result of the bug fixes in this release, automatically-calculated + Y data ranges can change. If you have missing Y values in your data, + and you let PHPlot calculate the Y data range (that is, you do not + call SetPlotAreaWorld with a Ymin value), then the lower limit for Y + can change. If you have a plot with data-data-error data type, different + error values for different points, and let PHPlot calculate the Y data + range, then either Y limit can change. + + +Bug Fixes in 5.0.7: + + ++ Fix for bug 2803900: SetRGBArray('large') does not work: + Corrected an array name usage problem. You can now select the large + color map. Also PHPlot no longer overrides use of the PHP include + path when loading the large color map, and now reports an error if the + file is needed and not found. + ++ Fix for bug 2791502 "Error plots treat missing Y values as 0": + Missing Y values now with with data-data-error plots. + ++ Fix for bug 2792860 "Wrong DataLabelLines with missing Y": + Data label lines are now suppressed at missing Y values. + ++ Fix for bug 2786350 "Missing Y data results in bad auto-range": + Missing Y values are now ignored when calculating the Y data range. + Bug report and analysis by mrten. + ++ Fix for bug 2786354 "Incorrect auto-range for data-data-error": + The Y data range is now correctly calculated for data-data-error plots + when the error values differ from point to point. + + +----------------------------------------------------------------------------- + +2009-01-20 Release 5.0.6 + +Overview: + +This is the current stable release of PHPlot. The purpose of this release +is to fix additional problems with text spacing and positioning, and +introduce some minor new features. + +The PHPlot reference manual has been updated to match this release. The +manual is available as a separate download from Sourceforge. The manual is +also now available for on-line viewing at http://phplot.sourceforge.net + + +New features in 5.0.6: + ++ Allow mixing GD and TrueType font text on the same plot + You can use the new method functions SetFontGD() and SetFontTTF() to + select a font and font type for text element (labels, titles, etc.) For + example, you can have TrueType plot titles, and GD-fixed font labels. + SetUseTTF() now sets the default text type, TTF or GD. This is fully + backward compatible. + ++ Extended label formatting + See the reference manual for more information on these. + + New label formatting types are added: 'printf' (using a user-defined + format), and 'custom' (using a callback function). + + For 'data' type formatting, a prefix and suffix can be added. (PHPlot + previously had an undocumented suffix for 'data' type, which still + works.) + + For 'time' formatting, the format can now be specified in the same function + call rather than using SetXTimeFormat and SetYTimeFormat. + + For 'data' formatting, the precision can now be specified in the same + function call, rather than using SetPrecisionX and SetPrecisionY. + ++ Better control over line spacing in multi-line labels + + Line spacing can now be set separately for each text element using an + additional argument to SetFont, SetFontGD, and SetFontTTF. The overall + SetLineSpacing() value is the default for each text element that does not + have a specific line spacing set. + + PHPlot now interprets the value set for line spacing as the number of + pixels only for GD text. For TrueType text, it is a scale factor for the + font's built-in line spacing for TrueType text. The equation used is: + interline_spacing = line_spacing * font_natural_spacing / 6 + where line_spacing is either the global value set with SetLineSpacing + or a more specific value set with SetFont(), and font_natural_spacing + is the amount of space between lines built-in to the TrueType font. The + factor 6 should really be 4 (since PHPlot always used 4 as the default + line_spacing, this would give the natural font spacing by default). But + the text is too widely spaced with this value, and 6 was chosen to be + more compatible for typical font sizes. + +Visible Changes and Possible Incompatibilities: + ++ Line spacing + Multi-line TrueType titles and labels will have different inter-line + spacing. Since the text size affects the margin and plot area sizes, + this results in slightly different sized features on any plot with + multi-line TrueType text. + Previous versions of PHPlot used a default 4 pixels for inter-line + spacing of multi-line TrueType text, regardless of the font size. + PHPlot now uses the 'natural' font inter-line spacing, adjusted by a line + spacing parameter (per text type, with a global default). + + The same change can also increase the size of the legend box slightly. + ++ Internal changes were made to the way font information is stored. Anything + that directly references PHPlot internals regarding fonts will break. Usage + also changed for the internal functions to size and draw text (ProcessText*, + SizeText*) due to font data storage changes. + ++ Changes were made to internal class variables used to store label + formatting information. Anything relying on these internals may break. + + +Bug Fixes in 5.0.6: + +#1932571: Data-Data Plot fails with same X values + PHPlot will no longer hang if all X values are the same. But this is + interim fix to force the X range to 1 to prevent the hang. Eventually, + smarter automatic range code will handle this better. + Credit to andyl for finding this. + +#1891636: Misaligned TTF X Labels + PHPlot will now correctly line-up TrueType labels along the X axis. There + were small but very noticeable errors before, when the text had descenders + or lines with all short letters. + + +----------------------------------------------------------------------------- + +2008-01-13 Released 5.0.5 + +Overview: + +This is the current stable release of PHPlot. The emphasis of this release +is to improve text positioning, margin calculation, and error handling. + +Although this is considered a stable release, it has a large amount +of changed code compared to the previous release 5.0.4. Two of the more +complex components of PHPlot - text and margin calculations - were mostly +re-written in this release. You are advised to carefully test your own +applications with PHPlot-5.0.5 to see how your plots look. Refer to the +README.txt file included in the release for information on reporting problems. + +Starting with this release, PHPlot no longer supports PHP4, since the PHP +group officially declared end-of-life for PHP4 as of 31 December 2007. +PHPlot-5.0.5 was tested only with PHP-5.2.5 and we are unlikely to address +any issues using PHPlot with older versions of PHP. + +The PHPlot reference manual has been updated to match this release. The +manual is available as a separate download from Sourceforge. The manual is +now also now available for on-line viewing at http://phplot.sourceforge.net + +The callback feature added in 5.0.4 is now documented in the reference +manual. It is still considered experimental and subject to change, however. + + + +Visible Changes and Possible Incompatibilities: + ++ Dropped support for PHP4. + ++ Eliminated remaining order-dependent behavior related to margins and +text. PHPlot should now do nothing at all, except record parameters, until +you draw the graph with DrawGraph. I believe this was always the intended +behavior of PHPlot, but over time perhaps various pre-calculations and +dependencies crept in. Fixing this simplifies processing and should lead to +more consistent behavior. + ++ The rewritten margin calculation code now uses actual sizes of all tick +and data labels and tick marks, rather than guesses. Margins collapse to +remove unused elements, but a minimum margin (currently fixed at 15 pixels) +is applied so the plot edges don't get to close to the image edges. The +result is that most graphs with auto-calculated margins will change in +appearance. It most cases, the margins get slightly smaller. In other +cases, earlier releases mis-calculated the margins, so this release will +produce much neater margins. + ++ The X and Y titles are now offset out from the plot area, not in from the +image area. For auto-calculated margins this should not make any +difference, but if you use SetMarginsPixels or SetPlotAreaPixels to set +larger margins, the axis titles will move in closer to the plot with this +release. + ++ Changes were made to PHPlot internals, including removal of some class +variables and functions, and addition of new variables and functions. +These are documented in the ChangeLog. Relying on any internal variables +or functions in an application using PHPlot is unwise. The following +internal functions were removed: + SetImageArea() DrawDotSeries() DrawLineSeries() CalcXHeights() + CalcYWidths() DrawLabels() InitImage() DrawDashedLine() + These were marked 'deprecated', were undocumented and unmaintained. + TTFBBoxSize() + This was replaced with SizeText(). + ++ Line spacing set with SetLineSpacing() now affects TTF text as well as +GD text. Previously, it only affected GD text. The default line spacing +happens to be usable for TTF text. + ++ Changes were made to error handling. PHPlot will now trigger a user-level +error after producing an error image, instead of exiting. If no error +handler has been set, it will exit, as before. But now the error message +should also get logged, or written to the standard error stream, depending +on the SAPI in use. You can now establish an error handler to catch most +PHPlot errors and do some cleanup before exit. + ++ PHPlot no longer accepts some invalid option values (such as a substring +of a valid value, or empty strings) passed to functions. If your +application aborts in CheckOption with PHPlot-5.0.5 but 'worked' with +previous releases, them you were probably using an invalid option value. + + + +Bug Fixes in 5.0.5: + +#945439: x_tick_label_height not set correctly + Exact sizes of labels are now used to calculate margins. + +#1813070: Bad position for multi-line TrueType text + Fixed as part of text functions rewrite. Use correct basepoint + (lower left of each line) when positioning text lines. + +#1813071: Wrong title height for multi-line TTF text + Fixed as part of text functions rewrite: calculate height of + multi-line text correctly. Also now uses the line-spacing setting. + +#1813474: DrawText alignment arguments wrong + Fixed so 'top' and 'bottom' now have the usual meaning: top means + align top of text with reference, bottom means align bottom of text. + This was switched before. Changed every internal caller to compensate. + +#1816844: Fix order dependency for setting titles + Defer processing of title strings until DrawGraph(), + so it doesn't matter if fonts, etc. are set before or after. + +#1819668: Horiz. align multi-line text: GD vs TTF + The text functions were rewritten to draw TTF text line-by-line, + like GD text, and correctly align each line. + +#1823774: Default Font Path and Error Message + Error handling has been improved to make sure a message is logged, in + addition to the error image, and use error_trigger rather than exit. + +#1826513: FIXME in DrawLegend: Max label length + The actual size needed for legend text is now used. + +#1827263: Spoiled up pie-chart if $val is close to zero + Fixed by skipping over any segment that rounds to 0 degrees of + arc. (The GD function uses integer angles only, and 0 degrees + means draw a complete circle.) + +#1836528: Insufficient checking of parameter values + Rewrote validator function to reject improper parameter values. + +#1843012: Make margins, drawing consistent + Margin code logic was rewritten and checked for consistency. + +#1856207: Margin error with 'xaxis'/'yaxis' position + Margin space is now allocated for ticks and labels if their position + is 'xaxis' or 'yaxis' and the axis is at the plot edge. This is not + a perfect fix (the axis could be close but not at the edge). + + +----------------------------------------------------------------------------- + +2007-10-20 Released 5.0.4 + +Overview: + +This is the latest stable release of PHPlot. We are abandoning the 'rc' +version naming style, because we don't consider these last releases +'release candidate' versions. As we continue to make changes to PHPlot, +we are not converging toward a final "5.0" release, however we do consider +these releases stable and complete enough for production use. + +This release fixes a number of problems and introduces a few new features. + +The PHPlot reference manual has also been updated to match this release. +New material has been added documenting some of the PHPlot internals. +The manual is available as a separate download from Sourceforge. + + +Code Cleanup: + +Some code cleanup is going in to this release. It is hoped that these +changes will not impact any existing scripts using PHPlot, but will make +the PHPlot code itself easier to understand and maintain. + +PHPlot now avoids making changes outside its own class definition. There +are no longer any functions defined outside the class, nor any constants. +Three constants (MINY MAXY TOTY) were removed, and 2 functions were removed +(see Visible Changes below). Also PHPlot no longer sets the PHP error +reporting level to E_ALL. Although we highly recommend setting error +reporting to E_ALL in your php.ini file or scripts, it is not right for +PHPlot to assume that you want it. + + +Visible Changes and Possible Incompatibilities: + +Arrays containing color and style information are used with several PHPlot +functions to control the plot style array. These functions are: + SetPointShapes, SetPointSizes, SetLineWidths, SetLineStyles, + SetDataColors, SetDataBorderColors, and SetErrorBarColors. +The arrays passed to these functions MUST used sequential integer 0-based +indexes. This is what the PHP manual calls "Usual integer indices (starting +from zero, increasing by one)". This is the type of array you get in PHP by +default if you use array() without specifying key values, or use the +empty-bracket assignment operator to add values onto an array. In previous +versions of PHPlot, some of these functions would also work with +string-indexed or non-sequentially-indexed arrays, but this was not clearly +defined. Starting with PHPlot-5.0.4, only arrays with "usual integer +indices" work, and other array indexes will cause errors. + +Some internal-use-only functions have had their usage changed or been removed. +If you are using functions that are not documented in the PHPlot Function +Reference in the manual, your code may have to be changed. + +As part of the code cleanup, two functions which were defined outside the +PHPlot class were removed: array_pad_array(), and array_merge_php4(). +If your code used these, you need to fix your code. + +The routines which accept a color name, value, or array now check for a valid +color name. If you specify a color name which is not in your current color +table, PHPlot will draw an error and exit. Previously, PHP would report an +index error, continue, and get a 'headers already sent' message. + + +Bug Fixes in 5.0.4: + +#1813021: Miss-positioned right-justified vertical GD text. + Fixed DrawText() to correctly position 90 degree right-justified text + drawn in a fixed GD font. This could be seen with 90 degree Y tick labels. + +#1790441 Removed destructor/shutdown function, and no longer recommend + using reference assignment when creating a PHPlot object. This was + interfering with memory usage. + Credit to annajilly for analysis. + +#1779115 SetLegendWorld() failed because of undefined variables. The + required order dependency was too hard to meet. This is now fixed. + You can now use SetLegendWorld anywhere before DrawGraph. + +#1726810 (feature request, but actually a bug fix) Ignore empty strings + as data labels when doing time or data label formatting. These would + previously produce errors or bad formatting. Now you can omit labels + as needed even with time and data formatting. + Credit to exgerhardr for finding this. + +#1605555 Y data labels used wrong font and not formatted (bar charts only). + +#1208054 Localization of number formatting in 'data' format type. PHPlot + will attempt to format the numbers in a way appropriate to your locale. + You can also force the formatting with the new function SetNumberFormat. + Credit to David Hernández Sanz. + +#937944 X/Y Tick counts: PHPlot could draw one two few Y tick counts, and + one too many X tick counts. This is not a perfect fix, and more work is + needed here, but this fixes an error case in both X and Y values. + + +New Features in 5.0.4: + +New function SetLegendStyle allows control of the alignment of text and + color boxes within the legend. Also allows removing the color boxes. + Based on bug #1208054. + Credit to David Hernández Sanz. + +New function SetNumberFormat. See bug report #1208054 above. + +Callbacks are added. PHPlot can call back your functions while generating the + plot. This is experimental, and documented only in the file "Callbacks". + Credit to annajilly for the idea and design. + +----------------------------------------------------------------------------- + +2006-11-13 Released 5.0rc3 + +Overview: + +This is an interim release. It has been a long time since the previous +release 5.0rc2, and there have been a lot of changes. There are still more +changes likely to go in before we have "5.0", but there are enough for now. + +The PHPlot Reference Manual has also been released, and is available as a +separate download from Sourceforge. PHPlot users and developers are +strongly encouraged to read the manual. + +This release does not include the "doc/" and "examples/" directories of +previous releases. The Reference Manual contains more complete and +up-to-date information and examples, and I am unable to maintain the doc/ +and examples/ files while also maintaining the Reference Manual. If you +need those files, they can be accessed with the Sourceforge web CVS +browser. + + +New Features: + +The emphasis for this release is bug fixing, so there are few new features. + ++ You can now suppress lines or points on individual plots in a linepoints + graph. This feature was added because I needed a graph with several + linepoints lines, but also with a solid line showing an "80% goal". + Use SetPointShapes with the value 'none' in the array to suppress the + point markers for that plot (and only draw the line). + Use SetLineStyles with the value 'none' in the array to suppress the + line for that plot (and only draw the point markers). + [Bug # 1594458] + ++ Bar charts can have data labels above the bar with the value. Turn + these on with SetYDataLabelPos('plotin'). This is somewhat experimental, + since there isn't a lot of room for labels on top of the bars and you + may find the results are not useful. + + +Visible Changes: + +Here are the more significant changes in this release. These are changes +which may affect existing scripts and output from PHPlot. See the +ChangeLog file for information about all changes and bug fixes. + ++ A bug fix on bar chart bar borders results in black borders around the + bars if shading is turned off. The border was previously covered up, + but was supposed to be there. If you need borderless, unshaded bars, + you need to use SetDataBorderColors to make the borders the same colors + as the bars. [Bug # 1096197] + ++ TrueType font pathname handling was fixed. You no longer need to use + SetUseTTF(True). You can either use full paths to the font files with + SetDefaultTTFont() and SetFont(), or you can call SetTTFPath() to point + to a directory of font files, and then use simple font filenames without + paths in SetDefaultTTFont() and SetFont(). + [Bug # 1144644 plus several others] + ++ There have been several fixes regarding automatically calculated ranges + and scales. The result is that you may see less extra space and fewer + tick marks in some cases. + ++ A fix was made to bar and stackedbar graph bar widths in order to get + the X axis labels to properly center. As part of the fix, the bar widths + now match between the two graph types. (Before this fix, the bars were + narrower in bar graphs compared to the same data plotted as a stacked + bar.) As a result, bar graph bars will now be drawn with wider bars, and + stackedbar graph bars will be narrower. You can adjust this with the new + class variable bar_extra_space. [Bug # 1437912] + ++ Dot shapes and sizes were off by 1 or 2 slots in the array of shapes or + sizes. After the fix, you may get different dot shapes or sizes per + plot line. [Bug # 1096194] + + +Testing: + +Since its output is visual (graphics), and it has so many interconnected +modes and options, PHPlot is difficult to test. But at least we are now +trying. I have a collection of PHPlot scripts (currently about 60) and a +script to run through them. The script automatically checks that: + 1) Nothing was written to the standard error stream; + 2) An image file of size greater than 0 was written; + 3) Neither the test script nor PHPlot did exit(). This catches cases + where PHPlot aborts with DrawError(). + +The automated test is an easy way to check for serious regression, but you +really need to inspect the output files to validate PHPlot. This takes a +little time, and it is easy to overlook problems. + +The real issue is test coverage. Just as we can be sure that future +PHPlot releases will pass the test collection, we can also be sure that +future bug reports will be written against untested cases. + +-------------------- + +2006-11-08 PHPlot on Sourceforge has a new maintainer: lbayuk + +-------------------- + +2004-10-24 Released 5.0rc2 + +-------------------- + diff --git a/gui/bacula-web/classes/external/phplot/README.txt b/gui/bacula-web/classes/external/phplot/README.txt new file mode 100644 index 0000000000..fa81bcf42e --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/README.txt @@ -0,0 +1,168 @@ +This is the README file for PHPlot +Last updated for PHPlot-5.3.1 on 2011-01-15 +The project web site is http://sourceforge.net/projects/phplot/ +The project home page is http://phplot.sourceforge.net/ +----------------------------------------------------------------------------- + +OVERVIEW: + +PHPlot is a PHP class for creating scientific and business charts. + +The release documentation contains only summary information. For more +complete information, download the PHPlot Reference Manual from the +Sourceforge project web site. You can also view the manual online at +http://phplot.sourceforge.net + +For information about changes in this release, including any possible +incompatibilities, see the NEWS.txt file. + + +CONTENTS: + + COPYING . . . . . . . . . . . . LGPL 2.1 License file + ChangeLog . . . . . . . . . . . Lists changes to the sources + NEWS.txt . . . . . . . . . . . . Highlights changes in releases + README.txt . . . . . . . . . . This file + contrib . . . . . . . . . . . . "Contributed" directory, add-ons + phplot.php . . . . . . . . . . The main PHPlot source file + rgb.inc.php . . . . . . . . . . Optional extended color table + + +REQUIREMENTS: + +You need a recent version of PHP5, and you are advised to use the latest +stable release. This version of PHPlot has been tested with PHP-5.3.5 and +PHP-5.2.17 on Linux, and with PHP-5.3.5 on Windows XP. + +Use of PHP-5.3.2 or PHP-5.2.13 is not recommended, if you are using +TrueType Font (TTF) text. A bug with TTF rendering in those versions +affects PHPlot images. This was fixed in PHP-5.3.3 and PHP-5.2.14. + +You need the GD extension to PHP either built in to PHP or loaded as a +module. Refer to the PHP documentation for more information - see the +Image Functions chapter in the PHP Manual. We test PHPlot only with the +PHP-supported, bundled GD library. + +If you want to display PHPlot charts on a web site, you need a PHP-enabled +web server. You can also use the PHP CLI interface without a web server. + +PHPlot supports TrueType fonts, but does not include any TrueType font +files. If you want to use TrueType fonts on your charts, you need to have +TrueType support in GD, and some TrueType font files. By default, PHPlot +uses a simple font which is built in to the GD library. + + +INSTALLATION: + +Unpack the distribution. (If you are reading this file, you have probably +already done that.) + +Installation of PHPlot simply involves copying two script files somewhere +your PHP application scripts will be able to find them. The scripts are: + phplot.php - The main script file + rgb.inc.php - Optional large color table +Make sure the permissions on these files allow the web server to read them. + +The ideal place is a directory outside your web server document area, +and on your PHP include path. You can add to the include path in the PHP +configuration file; consult the PHP manual for details. + + +KNOWN ISSUES: + +Here are some of the problems we know about in PHPlot. See the bug tracker +on the PHPlot project web site for more information. + +#3142124 Clip plot elements to plot area + Plot elements are not currently clipped to the plot area, and may extend + beyond. PHP does not currently support the GD clipping control. + +#1795969 The automatic range calculation for Y values needs to be rewritten. + This is especially a problem with small offset ranges (e.g. Y=[999:1001]). + You can use SetPlotAreaWorld to set a specific range instead. + +#1605558 Wide/Custom dashed lines don't work well + This is partially a GD issue, partially PHPlot's fault. + +#2919086 Improve tick interval calculations + Tick interval calculations should try for intervals of 1, 2, or 5 times + a power of 10. + +PHP Issues: + + PHP has many build-time and configuration options, and these can affect +the operation of PHPlot (as well as any other application or library). Here +are some known issues: + + Slackware Linux includes a version of PHP built with --enable-gd-jis-conv +(JIS-mapped Japanese font support). This prevents the usual UTF-8 encoding +of characters from working in TrueType Font (TTF) text strings. + + The Ubuntu Linux PHP GD package (php5-gd) was built to use the external +shared GD library, not the one bundled with PHP. This can result in small +differences in images, and some unsupported features (such as advanced +truecolor image operations). Also, although this Ubuntu GD library was +built with fontconfig support, PHP does not use it, so you still need to +specify TrueType fonts with their actual file names. + + Some PHP installations may have a memory limit set too low to support +large images, especially truecolor images. + + +If you think you found a problem with PHPlot, or want to ask questions or +provide feedback, please use the Help and Discussion forum at + http://sourceforge.net/projects/phplot/ +If you are sure you have found a bug, you can report it on the Bug tracker +at the same web site. There is also a Features Request tracker. + + +TESTING: + +You can test your installation by creating the following two files somewhere +in your web document area. First, the HTML file: + +------------ simpleplot.html ---------------------------- + + +Hello, PHPlot! + + +

PHPlot Test

+ + + +--------------------------------------------------------- + +Second, in the same directory, the image file producing PHP script file. +Depending on where you installed phplot.php, you may need to specify a path +in the 'require' line below. + +------------ simpleplot.php ----------------------------- +SetDataValues($data); +$plot->SetDataType('data-data'); +$plot->DrawGraph(); +--------------------------------------------------------- + +Access the URL to 'simpleplot.html' in your web browser. If you see a +simple graph, you have successfully installed PHPlot. If you see no +graph, check your web server error log for more information. + + +COPYRIGHT and LICENSE: + +PHPlot is Copyright (C) 1998-2011 Afan Ottenheimer + +This 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; +version 2.1 of the License. + +This software 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 software; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/gui/bacula-web/classes/external/phplot/contrib/README.txt b/gui/bacula-web/classes/external/phplot/contrib/README.txt new file mode 100644 index 0000000000..3c63225200 --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/contrib/README.txt @@ -0,0 +1,31 @@ +This is the README for PHPlot Contributed Code +The project web site is http://sourceforge.net/projects/phplot/ +Last updated on 2009-12-08 +----------------------------------------------------------------------------- + +The PHPlot Contributed Code directory contains code you might find useful +with PHPlot, but that doesn't quite belong as part of PHPlot itself. + +You will have to read the comments in the code files, and see the example +files, to determine what these do and if they are useful to you. None of +these functions is documented in the PHPlot Reference Manual. + +You may include or paste these functions into your own scripts. Check the +files for details, but some of these are considered "public domain" with no +usage or license restrictions. + +----------------------------------------------------------------------------- +Contents: + +prune_labels: Reduce the number of labels along the X axis + prune_labels.php . . . . . . . . . . . . Code + prune_labels.example.php . . . . . . . . Example + prune_labels.test.php . . . . . . . . . Test + +color_range: Create a gradient color map for data colors + color_range.php . . . . . . . . . . . . Code + color_range.example.php . . . . . . . . Example + color_range.test1.php . . . . . . . . . Image creation test + color_range.test2.php . . . . . . . . . Unit test + +----------------------------------------------------------------------------- diff --git a/gui/bacula-web/classes/external/phplot/contrib/color_range.example.php b/gui/bacula-web/classes/external/phplot/contrib/color_range.example.php new file mode 100644 index 0000000000..d29978b770 --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/contrib/color_range.example.php @@ -0,0 +1,35 @@ +SetTitle('Example - Bar Chart with gradient colors'); +$p->SetDataType('text-data'); +$p->SetDataValues($data); +$p->SetPlotAreaWorld(0, 0, $x_values, 100); + +# This isn't necessary, as we do know how many data sets (bars_per_group): +$n_data = count_data_sets($data, 'text-data'); +# Make a gradient color map: +$colors = color_range($p->SetRGBColor('SkyBlue'), + $p->SetRGBColor('DarkGreen'), $n_data); +$p->SetDataColors($colors); +$p->SetXTickLabelPos('none'); +$p->SetXTickPos('none'); +$p->SetPlotType('bars'); +$p->DrawGraph(); diff --git a/gui/bacula-web/classes/external/phplot/contrib/color_range.php b/gui/bacula-web/classes/external/phplot/contrib/color_range.php new file mode 100755 index 0000000000..6ff4d6d0ab --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/contrib/color_range.php @@ -0,0 +1,103 @@ + + "I wrote this code to calculate the range of colors between 2 colors + to plot using the range from color_a to color_b..." + + I have changed the code and repackaged it, but the idea is the same. + Given 2 colors and number of data sets, computes an array of colors + that make up a gradient between the two provided colors, for use + with SetDataColors(). + + Provides the following functions: + $colors = color_range($color_a, $color_b, $n_intervals) + Returns a color array for SetDataColors. + + $n = count_data_sets($data, $data_type) + Counts the number of data sets in a data array. + This can be used to provide $n_intervals in color_range(). +*/ + + + +/* + Fill a color map with a gradient step between two colors. + Arguments: + $color_a : Starting color for the gradient. Array of (r, g, b) + $color_b : Ending color for the gradient. Array of (r, g, b) + $n_steps : Total number of color steps, including color_a and color_b. + + Returns: A color map array with n_steps colors in the form + $colors[i][3], suitable for SetDataColors(). + + Notes: + You may use the PHPlot internal function $plot->SetRGBColor($color) + to convert a color name or #rrggbb notation into the required array + of 3 values (r, g, b) for color_a and color_b. + + Newer versions of PHPlot use 4 components (r, g, b, a) arrays for color. + This script ignores the alpha component in those arrays. + +*/ +function color_range($color_a, $color_b, $n_steps) +{ + if ($n_steps < 2) $n_steps = 2; + $nc = $n_steps - 1; + # Note: $delta[] and $current[] are kept as floats. $colors is integers. + for ($i = 0; $i < 3; $i++) + $delta[$i] = ($color_b[$i] - $color_a[$i]) / $nc; + $current = $color_a; + for ($col = 0; $col < $nc; $col++) { + for ($i = 0; $i < 3; $i++) { + $colors[$col][$i] = (int)$current[$i]; + $current[$i] += $delta[$i]; + } + } + $colors[$nc] = $color_b; # Make sure the last color is exact. + return $colors; +} + + +/* + Determine the number of data sets (plot lines, bars per group, pie + segments, etc.) contained in a data array. + This can be used to determine n_steps for $color_range. + + Arguments: + $data : PHPlot data array + $data_type : PHPlot data type, describing $data. (e.g. 'data-data') + Returns: The number of data sets in the data array. + Notes: + This has to scan the entire data array. Don't use this unless you + really don't have a better way to determine the number of data sets. + + This does NOT require that the data array be integer indexed. + +*/ +function count_data_sets($data, $data_type) +{ + + if ($data_type == 'text-data-single') + return count($data); # Pie chart, 1 segment per record + + # Get the longest data record: + $max_row = 0; + foreach ($data as $row) + if (($n = count($row)) > $max_row) $max_row = $n; + + if ($data_type == 'text-data' || $data_type == 'text-data-yx') + return ($max_row - 1); # Each record is (label Y1 Y2...) + + if ($data_type == 'data-data' || $data_type == 'data-data-yx') + return ($max_row - 2); # Each record is (label X Y1 Y2...) + + if ($data_type == 'data-data-error') + return (($max_row - 2) / 3); # Each record is (label X Y1 Y1+ Y1-...) + + # Not a recognized data type... Just return something sane. + return $max_row; +} diff --git a/gui/bacula-web/classes/external/phplot/contrib/color_range.test1.php b/gui/bacula-web/classes/external/phplot/contrib/color_range.test1.php new file mode 100644 index 0000000000..661f591ea7 --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/contrib/color_range.test1.php @@ -0,0 +1,55 @@ +SetTitle('Example - pruned data labels'); +$p->SetDataType('data-data'); +$p->SetDataValues($data); +$p->SetXLabelType('time', '%Y-%m-%d'); +$p->SetXLabelAngle(90); +$p->SetXDataLabelPos('plotdown'); +$p->SetXTickLabelPos('none'); +$p->SetXTickPos('none'); +$p->SetDrawXGrid(False); +$p->SetDrawYGrid(False); +$p->SetPlotType('lines'); +$p->DrawGraph(); diff --git a/gui/bacula-web/classes/external/phplot/contrib/prune_labels.php b/gui/bacula-web/classes/external/phplot/contrib/prune_labels.php new file mode 100644 index 0000000000..5f272e52cd --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/contrib/prune_labels.php @@ -0,0 +1,36 @@ + 0) $data[$i][0] = ''; + if (++$k >= $m) $k = 0; + } +} diff --git a/gui/bacula-web/classes/external/phplot/contrib/prune_labels.test.php b/gui/bacula-web/classes/external/phplot/contrib/prune_labels.test.php new file mode 100644 index 0000000000..6d3bbb2635 --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/contrib/prune_labels.test.php @@ -0,0 +1,41 @@ + $non_blank labels\n"; + echo substr($line, 0, 80) . "\n"; # Only show first 80 chars. +} + +/* Test cases for prune_labels */ +for ($n = 7; $n <= 1000; $n *= 2) test($n, 10); +for ($g = 5; $g <= 40; $g++) test(72, $g); +# Edge cases +test(80, 41); +test(80, 40); +test(80, 39); diff --git a/gui/bacula-web/classes/external/phplot/phplot.php b/gui/bacula-web/classes/external/phplot/phplot.php new file mode 100644 index 0000000000..4abb7498bf --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/phplot.php @@ -0,0 +1,6536 @@ + + * + * Maintainer (2006-present) + * + * + * Requires PHP 5.2.x or later. (PHP 4 is unsupported as of Jan 2008) + */ + +class PHPlot +{ + /* Declare class variables which are initialized to static values. Many more class variables + * are used, defined as needed, but are unset by default. + * All these are declared as public. While it is tempting to make them private or protected, this + * is avoided for two reasons. First, it will break existing code, since all member variables + * were public in PHP4 and who knows what internal variables people used. Second, it makes + * testing harder and less effective. Nevertheless, your code should not modify these. + */ + + public $is_inline = FALSE; // FALSE = Sends headers, TRUE = sends just raw image data + public $browser_cache = FALSE; // FALSE = Sends headers for browser to not cache the image, + // (only if is_inline = FALSE also) + public $print_image = TRUE; // DrawGraph calls PrintImage. See SetPrintImage + + public $safe_margin = 5; // Extra margin used in several places, in pixels + + public $x_axis_position = ''; // X axis position in Y world coordinates, blank for default. + public $y_axis_position = ''; // Y axis position in X world coordinates, blank for default. + + public $xscale_type = 'linear'; // linear, log + public $yscale_type = 'linear'; + +//Fonts + public $use_ttf = FALSE; // Use True Type Fonts by default? + public $ttf_path = '.'; // Default path to look in for TT Fonts. + // public $default_ttfont; // Initialized in GetDefaultTTFont + public $line_spacing = 4; // Controls line spacing of multi-line labels + + // Label angles: 0 or 90 degrees for fixed fonts, any for TTF + public $x_label_angle = 0; // For X tick labels + // public $x_data_label_angle; // For X data labels; defaults to x_label_angle - see CheckLabels() + public $y_label_angle = 0; // For Y tick labels + public $y_data_label_angle = 0; // For Y data labels + +//Formats + public $file_format = 'png'; + public $output_file = ''; // For output to a file instead of stdout + +//Data + public $data_type = 'text-data'; // Structure of the data array + public $plot_type = 'linepoints'; // See $plots[] below + + public $label_scale_position = 0.5; // Shifts data labels in pie charts. 1 = top, 0 = bottom + public $group_frac_width = 0.7; // Bars use this fraction (0 to 1) of a group's space + public $bar_extra_space = 0.5; // Number of extra bar's worth of space in a group + public $bar_width_adjust = 1; // 1 = bars of normal width, must be > 0 + +// Titles + public $title_txt = ''; + + public $x_title_txt = ''; + public $x_title_pos = 'none'; // plotdown, plotup, both, none + + public $y_title_txt = ''; + public $y_title_pos = 'none'; // plotleft, plotright, both, none + +//Labels + // There are two types of labels in PHPlot: + // Tick labels: Follow the grid, next to ticks in axis. + // Are drawn at grid drawing time, by DrawXTicks() and DrawYTicks() + // Data labels: Follow the data points, and can be placed on the axis or the plot (x/y) + // Are drawn at graph plotting time, by Draw*DataLabel(), called by DrawLines(), etc. + // DrawXDataLabel() also draws vertical lines to data points, depending on + // draw_x_data_label_lines. + // Tick Labels + // Tick and Data label positions are not initialized, because PHPlot needs to tell if they + // defaulted or are set by the user. See CheckLabels() for details. The variables and + // effective defaults are shown here in comments (but CheckLabels adjusts the defaults). + // public $x_tick_label_pos = 'plotdown'; // X tick label position + // public $y_tick_label_pos = 'plotleft'; // Y tick label position + // public $x_data_label_pos = 'plotdown'; // X data label position + // public $y_data_label_pos = 'none'; // Y data label position + + public $draw_x_data_label_lines = FALSE; // Draw a line from the data point to the axis? + + // Label format controls: (for tick, data and plot labels) + // Unset by default, these array members are used as needed for 'x' (x tick labels), 'xd' (x data + // labels), 'y' (y tick labels), and 'yd' (y data labels). + // type, precision, prefix, suffix, time_format, printf_format, custom_callback, custom_arg. + // These replace the former: x_label_type, x_time_format, x_precision (similar for y), data_units_text. + public $label_format = array('x' => array(), 'xd' => array(), 'y' => array(), 'yd' => array()); + // data_units_text is retained for backward compatibility, because there was never a function + // to set it. Use the 'suffix' argument to Set[XY]LabelType instead. + public $data_units_text = ''; // Units text for 'data' labels (i.e: '¤', '$', etc.) + +// Legend + public $legend = ''; // An array with legend titles + // These variables are unset to take default values: + // public $legend_x_pos; // User-specified upper left coordinates of legend box + // public $legend_y_pos; + // public $legend_xy_world; // If set, legend_x/y_pos are world coords, else pixel coords + // public $legend_text_align; // left or right, Unset means right + // public $legend_colorbox_align; // left, right, or none; Unset means same as text_align + +//Ticks + public $x_tick_length = 5; // tick length in pixels for upper/lower axis + public $y_tick_length = 5; // tick length in pixels for left/right axis + + public $x_tick_cross = 3; // ticks cross x axis this many pixels + public $y_tick_cross = 3; // ticks cross y axis this many pixels + + public $x_tick_pos = 'plotdown'; // plotdown, plotup, both, xaxis, none + public $y_tick_pos = 'plotleft'; // plotright, plotleft, both, yaxis, none + + public $num_x_ticks = ''; + public $num_y_ticks = ''; + + public $x_tick_inc = ''; // Set num_x_ticks or x_tick_inc, not both. + public $y_tick_inc = ''; // Set num_y_ticks or y_tick_inc, not both. + + public $skip_top_tick = FALSE; + public $skip_bottom_tick = FALSE; + public $skip_left_tick = FALSE; + public $skip_right_tick = FALSE; + +//Grid Formatting + // public $draw_x_grid = FALSE; // Default is False except for swapped data type + // public $draw_y_grid = TRUE; // Default is True except for swapped data type + + public $dashed_grid = TRUE; + public $grid_at_foreground = FALSE; // Chooses whether to draw the grid below or above the graph + +//Colors and styles (all colors can be array (R,G,B) or named color) + public $color_array = 'small'; // 'small', 'large' or array (define your own colors) + // See rgb.inc.php and SetRGBArray() + public $default_colors = array( // The default colors for data and error bars + 'SkyBlue', 'green', 'orange', 'blue', 'red', 'DarkGreen', 'purple', 'peru', + 'cyan', 'salmon', 'SlateBlue', 'YellowGreen', 'magenta', 'aquamarine1', 'gold', 'violet'); + + // See SetDefaultStyles() for default colors for PHPlot elements. + + public $line_widths = 1; // single value or array + public $line_styles = array('solid', 'solid', 'dashed'); // single value or array + public $dashed_style = '2-4'; // colored dots-transparent dots + + public $point_sizes = array(6); // Array of sizes for points. See CheckPointParams() + public $point_shapes = array( // Array of point shapes. See SetPointShapes() and DrawDot() + 'diamond', 'dot', 'delta', 'home', 'yield', 'box', 'circle', 'up', 'down', 'cross' + ); + + public $error_bar_size = 5; // right and left size of tee + public $error_bar_shape = 'tee'; // 'tee' or 'line' + public $error_bar_line_width = 1; // single value (or array TODO) + + public $plot_border_type = 'sides'; // left, right, top, bottom, sides, none, full; or array + public $image_border_type = 'none'; // 'raised', 'plain', 'none' + // public $image_border_width; // NULL, 0, or unset for default. Default depends on type. + + public $shading = 5; // 0 for no shading, > 0 is size of shadows in pixels + + public $draw_plot_area_background = FALSE; + public $draw_broken_lines = FALSE; // Tells not to draw lines for missing Y data. + +//Miscellaneous + public $callbacks = array( // Valid callback reasons (see SetCallBack) + 'draw_setup' => NULL, + 'draw_image_background' => NULL, + 'draw_plotarea_background' => NULL, + 'draw_titles' => NULL, + 'draw_axes' => NULL, + 'draw_graph' => NULL, + 'draw_border' => NULL, + 'draw_legend' => NULL, + 'draw_all' => NULL, + 'data_color' => NULL, + 'debug_textbox' => NULL, // For testing/debugging text box alignment + 'debug_scale' => NULL, // For testing/debugging scale setup + ); + + // Defined plot types static array: + // Array key is the plot type. (Upper case letters are not allowed due to CheckOption) + // Value is an array with these keys: + // draw_method (required) : Class method to call to draw the plot. + // draw_arg : Optional array of arguments to pass to draw_method. + // draw_axes : If FALSE, do not draw X/Y axis lines, labels, ticks, grid, titles. + // abs_vals, sum_vals : Data array processing flags. See FindDataLimits(). + static protected $plots = array( + 'area' => array( + 'draw_method' => 'DrawArea', + 'abs_vals' => TRUE, + ), + 'bars' => array( + 'draw_method' => 'DrawBars', + ), + 'candlesticks' => array( + 'draw_method' => 'DrawOHLC', + 'draw_arg' => array(TRUE, FALSE), // Draw candlesticks, only fill if "closed down" + ), + 'candlesticks2' => array( + 'draw_method' => 'DrawOHLC', + 'draw_arg' => array(TRUE, TRUE), // Draw candlesticks, fill always + ), + 'linepoints' => array( + 'draw_method' => 'DrawLinePoints', + ), + 'lines' => array( + 'draw_method' => 'DrawLines', + ), + 'ohlc' => array( + 'draw_method' => 'DrawOHLC', + 'draw_arg' => array(FALSE), // Don't draw candlesticks + ), + 'pie' => array( + 'draw_method' => 'DrawPieChart', + 'draw_axes' => FALSE, + 'abs_vals' => TRUE, + ), + 'points' => array( + 'draw_method' => 'DrawDots', + ), + 'squared' => array( + 'draw_method' => 'DrawSquared', + ), + 'stackedarea' => array( + 'draw_method' => 'DrawArea', + 'draw_arg' => array(TRUE), // Tells DrawArea to draw stacked area plot + 'sum_vals' => TRUE, + 'abs_vals' => TRUE, + ), + 'stackedbars' => array( + 'draw_method' => 'DrawStackedBars', + 'sum_vals' => TRUE, + ), + 'thinbarline' => array( + 'draw_method' => 'DrawThinBarLines', + ), + ); + +////////////////////////////////////////////////////// +//BEGIN CODE +////////////////////////////////////////////////////// + + /* + * Constructor: Setup img resource, colors and size of the image, and font sizes. + * + * $which_width : Image width in pixels. + * $which_height : Image height in pixels. + * $which_output_file : Filename for output. + * $which_input_file : Path to a file to be used as background. + */ + function PHPlot($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL) + { + $this->SetRGBArray($this->color_array); + + if ($which_output_file) + $this->SetOutputFile($which_output_file); + + if ($which_input_file) { + $this->SetInputFile($which_input_file); + } else { + $this->image_width = $which_width; + $this->image_height = $which_height; + + $this->img = ImageCreate($this->image_width, $this->image_height); + if (! $this->img) + return $this->PrintError('PHPlot(): Could not create image resource.'); + } + + $this->SetDefaultStyles(); + $this->SetDefaultFonts(); + } + + /* + * Reads an image file. Stores width and height, and returns the image + * resource. On error, calls PrintError and returns False. + * This is used by the constructor via SetInputFile, and by tile_img(). + */ + protected function GetImage($image_filename, &$width, &$height) + { + $error = ''; + $size = getimagesize($image_filename); + if (!$size) { + $error = "Unable to query image file $image_filename"; + } else { + $image_type = $size[2]; + switch ($image_type) { + case IMAGETYPE_GIF: + $img = @ ImageCreateFromGIF ($image_filename); + break; + case IMAGETYPE_PNG: + $img = @ ImageCreateFromPNG ($image_filename); + break; + case IMAGETYPE_JPEG: + $img = @ ImageCreateFromJPEG ($image_filename); + break; + default: + $error = "Unknown image type ($image_type) for image file $image_filename"; + break; + } + } + if (empty($error) && !$img) { + // getimagesize is OK, but GD won't read it. Maybe unsupported format. + $error = "Failed to read image file $image_filename"; + } + if (!empty($error)) { + return $this->PrintError("GetImage(): $error"); + } + $width = $size[0]; + $height = $size[1]; + return $img; + } + + /* + * Selects an input file to be used as background for the whole graph. + * This resets the graph size to the image's size. + * Note: This is used by the constructor. It is deprecated for direct use. + */ + function SetInputFile($which_input_file) + { + $im = $this->GetImage($which_input_file, $this->image_width, $this->image_height); + if (!$im) + return FALSE; // GetImage already produced an error message. + + // Deallocate any resources previously allocated + if (isset($this->img)) + imagedestroy($this->img); + + $this->img = $im; + + // Do not overwrite the input file with the background color. + $this->done['background'] = TRUE; + + return TRUE; + } + +///////////////////////////////////////////// +////////////// COLORS +///////////////////////////////////////////// + + /* + * Allocate a GD color index for a color specified by a 4 component array. + * When a color is requested, it is parsed and checked by SetRGBColor, and then saved as an array + * of (R,G,B,A) components. At graph drawing time, this function is used to allocate the color. + * $color : The color specification as a 4 component array: R, G, B, A. + * Returns: A GD color index that can be used when drawing. + */ + protected function GetColorIndex($color) + { + list($r, $g, $b, $a) = $color; + return imagecolorresolvealpha($this->img, $r, $g, $b, $a); + } + + /* + * Allocate an array of GD color indexes for an array of color specifications. + * This is used for the data_colors array, for example. + * $color_array : Array of color specifications, each an array of R,G,B,A components. + * This must use 0-based sequential integer indexes. + * $max_colors : Limit color allocation to no more than this. + * Returns an array of GD color indexes. + */ + protected function GetColorIndexArray($color_array, $max_colors) + { + $n = min(count($color_array), $max_colors); + $result = array(); + for ($i = 0; $i < $n; $i++) + $result[] = $this->GetColorIndex($color_array[$i]); + return $result; + } + + /* + * Allocate an array of GD color indexes for darker shades of an array of color specifications. + * $color_array : Array of color specifications, each an array of R,G,B,A components. + * $max_colors : Limit color allocation to this many colors from the array. + * Returns an array of GD color indexes. + */ + protected function GetDarkColorIndexArray($color_array, $max_colors) + { + $n = min(count($color_array), $max_colors); + $result = array(); + for ($i = 0; $i < $n; $i++) + $result[] = $this->GetDarkColorIndex($color_array[$i]); + return $result; + } + + /* + * Allocate a GD color index for a darker shade of a color specified by a 4 component array. + * See notes for GetColorIndex() above. + * $color : The color specification as a 4 component array: R, G, B, A. + * Returns: A GD color index that can be used when drawing. + */ + protected function GetDarkColorIndex($color) + { + list ($r, $g, $b, $a) = $color; + $r = max(0, $r - 0x30); + $g = max(0, $g - 0x30); + $b = max(0, $b - 0x30); + return imagecolorresolvealpha($this->img, $r, $g, $b, $a); + } + + /* + * Sets/reverts all colors and styles to their defaults. + */ + protected function SetDefaultStyles() + { + $this->SetDefaultDashedStyle($this->dashed_style); + $this->SetImageBorderColor(array(194, 194, 194)); + $this->SetPlotBgColor('white'); + $this->SetBackgroundColor('white'); + $this->SetTextColor('black'); + $this->SetGridColor('black'); + $this->SetLightGridColor('gray'); + $this->SetTickColor('black'); + $this->SetTitleColor('black'); + // These functions set up the default colors when called without parameters + $this->SetDataColors(); + $this->SetErrorBarColors(); + $this->SetDataBorderColors(); + return TRUE; + } + + /* + * Set the image background color to $which_color. + */ + function SetBackgroundColor($which_color) + { + return (bool)($this->bg_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the plot area background color (if enabled) to $which_color. + */ + function SetPlotBgColor($which_color) + { + return (bool)($this->plot_bg_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the color of the titles (main, X, and Y) to $which_color. + * See also SetXTitleColor and SetYTitleColor. + */ + function SetTitleColor($which_color) + { + return (bool)($this->title_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the color of the X title to $which_color. + * This overrides the color set with SetTitleColor. + */ + function SetXTitleColor($which_color) + { + return (bool)($this->x_title_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the color of the Y title to $which_color. + * This overrides the color set with SetTitleColor. + */ + function SetYTitleColor($which_color) + { + return (bool)($this->y_title_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the color of the axis tick marks to $which_color. + */ + function SetTickColor($which_color) + { + return (bool)($this->tick_color = $this->SetRGBColor($which_color)); + } + + /* + * Deprecated. Use SetTitleColor() + */ + function SetLabelColor($which_color) + { + return $this->SetTitleColor($which_color); + } + + /* + * Set the general text color (tick and data labels, legend, etc) to $which_color. + */ + function SetTextColor($which_color) + { + return (bool)($this->text_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the X and Y grid colors to $which_color. Also sets the data label line color. + */ + function SetLightGridColor($which_color) + { + return (bool)($this->light_grid_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the color used for the X and Y axis, plot border, legend border to $which_color. + * Note: This has nothing to do with the grid, and we don't recall where this name came from. + */ + function SetGridColor($which_color) + { + return (bool)($this->grid_color = $this->SetRGBColor($which_color)); + } + + /* + * Set the color used for the image border to $which_color. + */ + function SetImageBorderColor($which_color) + { + return (bool)($this->i_border = $this->SetRGBColor($which_color)); + } + + /* + * Designate color $which_color to be transparent, if supported by the image format. + */ + function SetTransparentColor($which_color) + { + return (bool)($this->transparent_color = $this->SetRGBColor($which_color)); + } + + /* + * Sets the array of colors to be used. It can be user defined, a small predefined one + * or a large one included from 'rgb.inc.php'. + * + * $which_color_array : A color array, or 'small' or 'large'. + * Color arrays map color names into arrays of R, G, B and optionally A values. + */ + function SetRGBArray($which_color_array) + { + if (is_array($which_color_array)) { // User defined array + $this->rgb_array = $which_color_array; + } elseif ($which_color_array == 'small') { // Small predefined color array + $this->rgb_array = array( + 'white' => array(255, 255, 255), + 'snow' => array(255, 250, 250), + 'PeachPuff' => array(255, 218, 185), + 'ivory' => array(255, 255, 240), + 'lavender' => array(230, 230, 250), + 'black' => array( 0, 0, 0), + 'DimGrey' => array(105, 105, 105), + 'gray' => array(190, 190, 190), + 'grey' => array(190, 190, 190), + 'navy' => array( 0, 0, 128), + 'SlateBlue' => array(106, 90, 205), + 'blue' => array( 0, 0, 255), + 'SkyBlue' => array(135, 206, 235), + 'cyan' => array( 0, 255, 255), + 'DarkGreen' => array( 0, 100, 0), + 'green' => array( 0, 255, 0), + 'YellowGreen' => array(154, 205, 50), + 'yellow' => array(255, 255, 0), + 'orange' => array(255, 165, 0), + 'gold' => array(255, 215, 0), + 'peru' => array(205, 133, 63), + 'beige' => array(245, 245, 220), + 'wheat' => array(245, 222, 179), + 'tan' => array(210, 180, 140), + 'brown' => array(165, 42, 42), + 'salmon' => array(250, 128, 114), + 'red' => array(255, 0, 0), + 'pink' => array(255, 192, 203), + 'maroon' => array(176, 48, 96), + 'magenta' => array(255, 0, 255), + 'violet' => array(238, 130, 238), + 'plum' => array(221, 160, 221), + 'orchid' => array(218, 112, 214), + 'purple' => array(160, 32, 240), + 'azure1' => array(240, 255, 255), + 'aquamarine1' => array(127, 255, 212) + ); + } elseif ($which_color_array == 'large') { // Large color array + if (!@include('rgb.inc.php')) { + return $this->PrintError("SetRGBArray(): Large color map could not be loaded\n" + . "from 'rgb.inc.php'."); + } + $this->rgb_array = $ColorArray; + } else { // Default to black and white only. + $this->rgb_array = array('white' => array(255, 255, 255), 'black' => array(0, 0, 0)); + } + + return TRUE; + } + + /* + * Parse a color description and return the color component values. + * Arguments: + * $color_asked : The desired color description, in one of these forms: + * Component notation: array(R, G, B) or array(R, G, B, A) with each + * in the range described below for the return value. + * Examples: (255,255,0) (204,0,0,30) + * Hex notation: "#RRGGBB" or "#RRGGBBAA" where each pair is a 2 digit hex number. + * Examples: #FF00FF (magenta) #0000FF40 (Blue with alpha=64/127) + * Named color in the current colormap, with optional suffix ":alpha" for alpha value. + * Examples: blue red:60 yellow:20 + * $alpha : optional default alpha value. This is applied to the color if it doesn't + * already have an alpha value. If not supplied, colors are opaque (alpha=0) by default. + * + * Returns an array describing a color as (R, G, B, Alpha). + * R, G, and B are integers 0-255, and Alpha is 0 (opaque) to 127 (transparent). + * Note: This function should be considered 'protected', and is not documented for public use. + */ + function SetRGBColor($color_asked, $alpha = 0) + { + if (empty($color_asked)) { + $ret_val = array(0, 0, 0); + + } elseif (is_array($color_asked) && (($n = count($color_asked)) == 3 || $n == 4) ) { + // Already an array of 3 or 4 elements: + $ret_val = $color_asked; + + } elseif (preg_match('/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i', + $color_asked, $ss)) { + // #RRGGBB or #RRGGBBAA notation: + $ret_val = array(hexdec($ss[1]), hexdec($ss[2]), hexdec($ss[3])); + if (isset($ss[4])) $ret_val[] = hexdec($ss[4]); + + } elseif (isset($this->rgb_array[$color_asked])) { + // Color by name: + $ret_val = $this->rgb_array[$color_asked]; + + } elseif (preg_match('/(.+):([\d]+)$/', $color_asked, $ss) + && isset($this->rgb_array[$ss[1]])) { + // Color by name with ":alpha" suffix, alpha is a decimal number: + $ret_val = $this->rgb_array[$ss[1]]; + $ret_val[3] = (int)$ss[2]; + + } else { + return $this->PrintError("SetRGBColor(): Color '$color_asked' is not valid."); + } + + // Append alpha if not already provided for: + if (count($ret_val) == 3) + $ret_val[] = $alpha; + return $ret_val; + } + + /* + * Sets the colors for the data, with optional default alpha value (for PHPlot_truecolor only) + * Cases are: + * SetDataColors(array(...)) : Use the supplied array as the color map. + * SetDataColors(colorname) : Use an array of just colorname as the color map. + * SetDataColors() or SetDataColors(NULL) : Load default color map if no color map is already set. + * SetDataColors('') or SetDataColors(False) : Load default color map (even if one is already set). + * $which_border is passed to SetDataBorderColors, for backward compatibility. + * $alpha is a default Alpha to apply to all data colors that do not have alpha. + * The default for this is NULL, not 0, so we can tell if it was defaulted. But the effective + * default value is 0 (opaque). + */ + function SetDataColors($which_data = NULL, $which_border = NULL, $alpha = NULL) + { + if (is_array($which_data)) { + $colors = $which_data; // Use supplied array + } elseif (!empty($which_data)) { + $colors = array($which_data); // Use supplied single color + } elseif (empty($this->data_colors) || !is_null($which_data)) { + $colors = $this->default_colors; // Use default color array + } else { + // which_data is NULL or missing and a color array is already set. + // The existing color array is left alone, except that if $alpha is + // given this will replace the alpha value of each existing color. + // This makes SetDataColors(NULL, NULL, $alpha) work. + if (isset($alpha)) { + $n_colors = count($this->data_colors); + for ($i = 0; $i < $n_colors; $i++) { + $this->data_colors[$i][3] = $alpha; // Component 3 = alpha value + } + } + // No need to reparse the colors or anything else. + return TRUE; + } + + if (!isset($alpha)) + $alpha = 0; // Actual default is opaque colors. + + // Check each color and convert to array (r,g,b,a) form. + // Use the $alpha argument as a default for the alpha value of each color. + $this->data_colors = array(); + foreach ($colors as $color) { + $color_array = $this->SetRGBColor($color, $alpha); + if (!$color_array) return FALSE; // SetRGBColor already did an error message. + $this->data_colors[] = $color_array; + } + + // For past compatibility: + return $this->SetDataBorderColors($which_border); + } + + /* + * Set the colors for the bars and stacked bars outlines. + * Argument usage is similar to SetDataColors(), except the default is just black. + */ + function SetDataBorderColors($which_br = NULL) + { + if (is_array($which_br)) { + $colors = $which_br; // Use supplied array + } elseif (!empty($which_br)) { + $colors = array($which_br); // Use supplied single color + } elseif (empty($this->data_border_colors) || !is_null($which_br)) { + $colors = array('black'); // Use default + } else { + return TRUE; // Do nothing: which_br is NULL or missing and a color array is already set. + } + + // Check each color and convert to array (r,g,b,a) form. + $this->data_border_colors = array(); + foreach ($colors as $color) { + $color_array = $this->SetRGBColor($color); + if (!$color_array) return FALSE; // SetRGBColor already did an error message. + $this->data_border_colors[] = $color_array; + } + return TRUE; + } + + /* + * Sets the colors for the data error bars. + * Argument usage is the same as SetDataColors(). + */ + function SetErrorBarColors($which_err = NULL) + { + if (is_array($which_err)) { + $colors = $which_err; // Use supplied array + } elseif (!empty($which_err)) { + $colors = array($which_err); // Use supplied single color + } elseif (empty($this->error_bar_colors) || !is_null($which_err)) { + $colors = $this->default_colors; // Use default color array + } else { + return TRUE; // Do nothing: which_err is NULL or missing and a color array is already set. + } + + // Check each color and convert to array (r,g,b,a) form. + $this->error_bar_colors = array(); + foreach ($colors as $color) { + $color_array = $this->SetRGBColor($color); + if (!$color_array) return FALSE; // SetRGBColor already did an error message. + $this->error_bar_colors[] = $color_array; + } + return TRUE; + } + + /* + * Sets the default dashed line style. + * $which_style : A string specifying the dashed line style, as alternating numbers + * of the length (in pixels) of lines and spaces, separated by dashes. + * For example: '2-3-1-2' means 2 dots of color, 3 transparent, 1 color, then 2 transparent. + * This builds a string which will evaluate to an array of integers. Each colored dot + * is '$which_ndxcol' and each transparent dot is 'IMG_COLOR_TRANSPARENT'. When SetDashedStyle() + * eval's this with $which_ndxcol set, the result is a GD line style array. + */ + function SetDefaultDashedStyle($which_style) + { + // Explode "numcol-numtrans-numcol-numtrans..." into segment counts: + $asked = explode('-', $which_style); + + if (count($asked) < 2) { + return $this->PrintError("SetDefaultDashedStyle(): Wrong parameter '$which_style'."); + } + + // Build the string to be evaluated later by SetDashedStyle() with $which_ndxcolor set. + $result = ''; + $vals = array('$which_ndxcol,', 'IMG_COLOR_TRANSPARENT,'); + $index = 0; + foreach ($asked as $n) { + $result .= str_repeat($vals[$index], $n); + $index = 1 - $index; + } + $this->default_dashed_style = "array($result)"; + + return TRUE; + } + + /* + * Sets the style before drawing a dashed line. Defaults to $this->default_dashed_style + * $which_ndxcol : Color index to be used. + */ + protected function SetDashedStyle($which_ndxcol) + { + // See SetDefaultDashedStyle() to understand this. + eval ("\$style = $this->default_dashed_style;"); + return imagesetstyle($this->img, $style); + } + + /* + * Set line widths for each data set. + * $which_lw : Array of line widths in pixels, or a single value to use for all data sets. + */ + function SetLineWidths($which_lw=NULL) + { + if (is_array($which_lw)) { + $this->line_widths = $which_lw; // Use provided array + } elseif (!is_null($which_lw)) { + $this->line_widths = array($which_lw); // Convert value to array + } + return TRUE; + } + + /* + * Set line style ('solid' or 'dashed') for each data set. + * $which_ls : Array of keywords, or a single keyword to use for all data sets. + */ + function SetLineStyles($which_ls=NULL) + { + if (is_array($which_ls)) { + $this->line_styles = $which_ls; // Use provided array + } elseif (!is_null($which_ls)) { + $this->line_styles = ($which_ls) ? array($which_ls) : array('solid'); + } + return TRUE; + } + +///////////////////////////////////////////// +////////////// TEXT and FONTS +///////////////////////////////////////////// + + /* + * Controls the line spacing of multi-line labels. + * $which_spc : Line spacing factor for text + * For GD text, this is the number of pixels between lines. + * For TTF text, it controls line spacing in proportion to the normal + * spacing defined by the font. + */ + function SetLineSpacing($which_spc) + { + $this->line_spacing = $which_spc; + return TRUE; + } + + /* + * Select the default font type to use. + * $which_ttf : True to default to TrueType, False to default to GD (fixed) fonts. + * This also resets all font settings to the defaults. + */ + function SetUseTTF($which_ttf) + { + $this->use_ttf = $which_ttf; + return $this->SetDefaultFonts(); + } + + /* + * Sets the directory name to look into for TrueType fonts. + */ + function SetTTFPath($which_path) + { + if (!is_dir($which_path) || !is_readable($which_path)) { + return $this->PrintError("SetTTFPath(): $which_path is not a valid path."); + } + $this->ttf_path = $which_path; + return TRUE; + } + + /* + * Sets the default TrueType font and updates all fonts to that. + * The default font might be a full path, or relative to the TTFPath, + * so let SetFont check that it exists. + * Side effects: Enables use of TrueType fonts as the default font type, + * and resets all font settings. + */ + function SetDefaultTTFont($which_font) + { + $this->default_ttfont = $which_font; + return $this->SetUseTTF(TRUE); + } + + /* + * Return the default TrueType font name. If no default has been set, + * this tries some likely candidates for a font which can be loaded. + * If it finds one that works, that becomes the default TT font. + * If there is no default and it cannot find a working font, it falls + * back to the original PHPlot default (which will not likely work either). + */ + protected function GetDefaultTTFont() + { + if (!isset($this->default_ttfont)) { + // No default font yet. Try some common sans-serif fonts. + $fonts = array('LiberationSans-Regular.ttf', // For Linux with a correct GD font search path + 'Verdana.ttf', 'Arial.ttf', 'Helvetica.ttf', // For Windows, maybe others + 'ttf-liberation/LiberationSans-Regular.ttf', // For Debian, Ubuntu, and friends + 'benjamingothic.ttf', // Original PHPlot default + ); + foreach ($fonts as $font) { + // First try the font name alone, to see if GD can find and load it. + if (@imagettfbbox(10, 0, $font, "1") !== False) + break; + // If the font wasn't found, try it with the default TTF path in front. + $font_with_path = $this->ttf_path . DIRECTORY_SEPARATOR . $font; + if (@imagettfbbox(10, 0, $font_with_path, "1") !== False) { + $font = $font_with_path; + break; + } + } + // We either have a working font, or are using the last one regardless. + $this->default_ttfont = $font; + } + return $this->default_ttfont; + } + + /* + * Sets fonts to their defaults + */ + protected function SetDefaultFonts() + { + // TTF: + if ($this->use_ttf) { + return $this->SetFont('generic', '', 8) + && $this->SetFont('title', '', 14) + && $this->SetFont('legend', '', 8) + && $this->SetFont('x_label', '', 6) + && $this->SetFont('y_label', '', 6) + && $this->SetFont('x_title', '', 10) + && $this->SetFont('y_title', '', 10); + } + // Fixed GD Fonts: + return $this->SetFont('generic', 2) + && $this->SetFont('title', 5) + && $this->SetFont('legend', 2) + && $this->SetFont('x_label', 1) + && $this->SetFont('y_label', 1) + && $this->SetFont('x_title', 3) + && $this->SetFont('y_title', 3); + } + + /* + * Select a fixed (GD) font for an element. + * This allows using a fixed font, even with SetUseTTF(True). + * $which_elem : The element whose font is to be changed. + * One of: title legend generic x_label y_label x_title y_title + * $which_font : A GD font number 1-5 + * $which_spacing (optional) : Line spacing factor + */ + function SetFontGD($which_elem, $which_font, $which_spacing = NULL) + { + if ($which_font < 1 || 5 < $which_font) { + return $this->PrintError(__FUNCTION__ . ': Font size must be 1, 2, 3, 4 or 5'); + } + if (!$this->CheckOption($which_elem, + 'generic, title, legend, x_label, y_label, x_title, y_title', + __FUNCTION__)) { + return FALSE; + } + + // Store the font parameters: name/size, char cell height and width. + $this->fonts[$which_elem] = array('ttf' => FALSE, + 'font' => $which_font, + 'height' => ImageFontHeight($which_font), + 'width' => ImageFontWidth($which_font), + 'line_spacing' => $which_spacing); + return TRUE; + } + + /* + * Select a TrueType font for an element. + * This allows using a TrueType font, even with SetUseTTF(False). + * $which_elem : The element whose font is to be changed. + * One of: title legend generic x_label y_label x_title y_title + * $which_font : A TrueType font filename or pathname. + * $which_size : Font point size. + * $which_spacing (optional) : Line spacing factor + */ + function SetFontTTF($which_elem, $which_font, $which_size = 12, $which_spacing = NULL) + { + if (!$this->CheckOption($which_elem, + 'generic, title, legend, x_label, y_label, x_title, y_title', + __FUNCTION__)) { + return FALSE; + } + + // Empty font name means use the default font. + if (empty($which_font)) + $which_font = $this->GetDefaultTTFont(); + $path = $which_font; + + // First try the font name directly, if not then try with path. + // Use GD imagettfbbox() to determine if this is a valid font. + // The return $bbox is used below, if valid. + if (($bbox = @imagettfbbox($which_size, 0, $path, "E")) === False) { + $path = $this->ttf_path . DIRECTORY_SEPARATOR . $which_font; + if (($bbox = @imagettfbbox($which_size, 0, $path, "E")) === False) { + return $this->PrintError(__FUNCTION__ . ": Can't find TrueType font $which_font"); + } + } + + // Calculate the font height and inherent line spacing. TrueType fonts have this information + // internally, but PHP/GD has no way to directly access it. So get the bounding box size of + // an upper-case character without descenders, and the baseline-to-baseline height. + // Note: In practice, $which_size = $height, maybe +/-1 . But which_size is in points, + // and height is in pixels, and someday GD may be able to tell the difference. + // The character width is saved too, but not used by the normal text drawing routines - it + // isn't necessarily a fixed-space font. It is used in DrawLegend. + $height = $bbox[1] - $bbox[5]; + $width = $bbox[2] - $bbox[0]; + $bbox = ImageTTFBBox($which_size, 0, $path, "E\nE"); + $spacing = $bbox[1] - $bbox[5] - 2 * $height; + + // Store the font parameters: + $this->fonts[$which_elem] = array('ttf' => TRUE, + 'font' => $path, + 'size' => $which_size, + 'height' => $height, + 'width' => $width, + 'spacing' => $spacing, + 'line_spacing' => $which_spacing); + return TRUE; + } + + /* + * Select Fixed/TrueType font for an element. Which type of font is + * selected depends on the $use_ttf class variable (see SetUseTTF()). + * Before PHPlot supported mixing font types, only this function and + * SetUseTTF were available to select an overall font type, but now + * SetFontGD() and SetFontTTF() can be used for mixing font types. + * $which_elem : The element whose font is to be changed. + * One of: title legend generic x_label y_label x_title y_title + * $which_font : A number 1-5 for fixed fonts, or a TrueType font. + * $which_size : Ignored for Fixed fonts, point size for TrueType. + * $which_spacing (optional) : Line spacing factor + */ + function SetFont($which_elem, $which_font, $which_size = 12, $line_spacing = NULL) + { + if ($this->use_ttf) + return $this->SetFontTTF($which_elem, $which_font, $which_size, $line_spacing); + return $this->SetFontGD($which_elem, $which_font, $line_spacing); + } + + /* + * Return the inter-line spacing for a font. + * This is an internal function, used by ProcessText* and DrawLegend. + * $font : A font array variable. + * Returns: Spacing, in pixels, between text lines. + */ + protected function GetLineSpacing($font) + { + // Use the per-font line spacing preference, if set, else the global value: + if (isset($font['line_spacing'])) + $line_spacing = $font['line_spacing']; + else + $line_spacing = $this->line_spacing; + + // For GD fonts, that is the spacing in pixels. + // For TTF, adjust based on the 'natural' font spacing (see SetFontTTF): + if ($font['ttf']) { + $line_spacing = (int)($line_spacing * $font['spacing'] / 6.0); + } + return $line_spacing; + } + + /* + * Text drawing and sizing functions: + * ProcessText is meant for use only by DrawText and SizeText. + * ProcessText(True, ...) - Draw a block of text + * ProcessText(False, ...) - Just return ($width, $height) of + * the orthogonal bounding box containing the text. + * ProcessText is further split into separate functions for GD and TTF + * text, due to the size of the code. + * + * Horizontal and vertical alignment are relative to the drawing. That is: + * vertical text (90 deg) gets centered along Y position with + * v_align = 'center', and adjusted to the right of X position with + * h_align = 'right'. Another way to look at this is to say + * that text rotation happens first, then alignment. + * + * Original multiple lines code submitted by Remi Ricard. + * Original vertical code submitted by Marlin Viss. + * + * Text routines rewritten by ljb to fix alignment and position problems. + * Here is my explanation and notes. More information and pictures will be + * placed in the PHPlot Reference Manual. + * + * + Process TTF text one line at a time, not as a block. (See below) + * + Flipped top vs bottom vertical alignment. The usual interpretation + * is: bottom align means bottom of the text is at the specified Y + * coordinate. For some reason, PHPlot did left/right the correct way, + * but had top/bottom reversed. I fixed it, and left the default valign + * argument as bottom, but the meaning of the default value changed. + * + * For GD font text, only single-line text is handled by GD, and the + * basepoint is the upper left corner of each text line. + * For TTF text, multi-line text could be handled by GD, with the text + * basepoint at the lower left corner of the first line of text. + * (Behavior of TTF drawing routines on multi-line text is not documented.) + * But you cannot do left/center/right alignment on each line that way, + * or proper line spacing. + * Therefore, for either text type, we have to break up the text into + * lines and position each line independently. + * + * There are 9 alignment modes: Horizontal = left, center, or right, and + * Vertical = top, center, or bottom. Alignment is interpreted relative to + * the image, not as the text is read. This makes sense when you consider + * for example X axis labels. They need to be centered below the marks + * (center, top alignment) regardless of the text angle. + * 'Bottom' alignment really means baseline alignment. + * + * GD font text is supported (by libgd) at 0 degrees and 90 degrees only. + * Multi-line or single line text works with any of the 9 alignment modes. + * + * TTF text can be at any angle. The 9 alignment modes work for all angles, + * but the results might not be what you expect for multi-line text. See + * the PHPlot Reference Manual for pictures and details. In short, alignment + * applies to the orthogonal (aligned with X and Y axes) bounding box that + * contains the text, and to each line in the multi-line text box. Since + * alignment is relative to the image, 45 degree multi-line text aligns + * differently from 46 degree text. + * + * Note that PHPlot allows multi-line text for the 3 titles, and they + * are only drawn at 0 degrees (main and X titles) or 90 degrees (Y title). + * Data labels can also be multi-line, and they can be drawn at any angle. + * -ljb 2007-11-03 + * + */ + + /* + * ProcessTextGD() - Draw or size GD fixed-font text. + * This is intended for use only by ProcessText(). + * $draw_it : True to draw the text, False to just return the orthogonal width and height. + * $font : PHPlot font array (with 'ttf' = False) - see SetFontGD() + * $angle : Text angle in degrees. GD only supports 0 and 90. We treat >= 45 as 90, else 0. + * $x, $y : Reference point for the text (ignored if !$draw_it) + * $color : GD color index to use for drawing the text (ignored if !$draw_it) + * $text : The text to draw or size. Put a newline between lines. + * $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it) + * $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it) + * Returns: True, if drawing text, or an array of ($width, $height) if not. + */ + protected function ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor) + { + // Extract font parameters: + $font_number = $font['font']; + $font_width = $font['width']; + $font_height = $font['height']; + $line_spacing = $this->GetLineSpacing($font); + + // Break up the text into lines, trim whitespace, find longest line. + // Save the lines and length for drawing below. + $longest = 0; + foreach (explode("\n", $text) as $each_line) { + $lines[] = $line = trim($each_line); + $line_lens[] = $line_len = strlen($line); + if ($line_len > $longest) $longest = $line_len; + } + $n_lines = count($lines); + + // Width, height are based on font size and longest line, line count respectively. + // These are relative to the text angle. + $total_width = $longest * $font_width; + $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing; + + if (!$draw_it) { + if ($angle < 45) return array($total_width, $total_height); + return array($total_height, $total_width); + } + + $interline_step = $font_height + $line_spacing; // Line-to-line step + + if ($angle >= 45) { + // Vertical text (90 degrees): + // (Remember the alignment convention with vertical text) + // For 90 degree text, alignment factors change like this: + $temp = $v_factor; + $v_factor = $h_factor; + $h_factor = 1 - $temp; + + $draw_func = 'ImageStringUp'; + + // Rotation matrix "R" for 90 degrees (with Y pointing down): + $r00 = 0; $r01 = 1; + $r10 = -1; $r11 = 0; + + } else { + // Horizontal text (0 degrees): + $draw_func = 'ImageString'; + + // Rotation matrix "R" for 0 degrees: + $r00 = 1; $r01 = 0; + $r10 = 0; $r11 = 1; + } + + // Adjust for vertical alignment (horizontal text) or horizontal alignment (vertical text): + $factor = (int)($total_height * $v_factor); + $xpos = $x - $r01 * $factor; + $ypos = $y - $r11 * $factor; + + // Debug callback provides the bounding box: + if ($this->GetCallback('debug_textbox')) { + if ($angle >= 45) { + $bbox_width = $total_height; + $bbox_height = $total_width; + $px = $xpos; + $py = $ypos - (1 - $h_factor) * $total_width; + } else { + $bbox_width = $total_width; + $bbox_height = $total_height; + $px = $xpos - $h_factor * $total_width; + $py = $ypos; + } + $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height); + } + + for ($i = 0; $i < $n_lines; $i++) { + + // Adjust for alignment of this line within the text block: + $factor = (int)($line_lens[$i] * $font_width * $h_factor); + $x = $xpos - $r00 * $factor; + $y = $ypos - $r10 * $factor; + + // Call ImageString or ImageStringUp: + $draw_func($this->img, $font_number, $x, $y, $lines[$i], $color); + + // Step to the next line of text. This is a rotation of (x=0, y=interline_spacing) + $xpos += $r01 * $interline_step; + $ypos += $r11 * $interline_step; + } + return TRUE; + } + + /* + * ProcessTextTTF() - Draw or size TTF text. + * This is intended for use only by ProcessText(). + * $draw_it : True to draw the text, False to just return the orthogonal width and height. + * $font : PHPlot font array (with 'ttf' = True) - see SetFontTTF() + * $angle : Text angle in degrees. + * $x, $y : Reference point for the text (ignored if !$draw_it) + * $color : GD color index to use for drawing the text (ignored if !$draw_it) + * $text : The text to draw or size. Put a newline between lines. + * $h_factor : Horizontal alignment factor: 0(left), .5(center), or 1(right) (ignored if !$draw_it) + * $v_factor : Vertical alignment factor: 0(top), .5(center), or 1(bottom) (ignored if !$draw_it) + * Returns: True, if drawing text, or an array of ($width, $height) if not. + */ + protected function ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor) + { + // Extract font parameters (see SetFontTTF): + $font_file = $font['font']; + $font_size = $font['size']; + $font_height = $font['height']; + $line_spacing = $this->GetLineSpacing($font); + + // Break up the text into lines, trim whitespace. + // Calculate the total width and height of the text box at 0 degrees. + // Save the trimmed lines and their widths for later when drawing. + // To get uniform spacing, don't use the actual line heights. + // Total height = Font-specific line heights plus inter-line spacing. + // Total width = width of widest line. + // Last Line Descent is the offset from the bottom to the text baseline. + // Note: For some reason, ImageTTFBBox uses (-1,-1) as the reference point. + // So 1+bbox[1] is the baseline to bottom distance. + $total_width = 0; + $lastline_descent = 0; + foreach (explode("\n", $text) as $each_line) { + $lines[] = $line = trim($each_line); + $bbox = ImageTTFBBox($font_size, 0, $font_file, $line); + $line_widths[] = $width = $bbox[2] - $bbox[0]; + if ($width > $total_width) $total_width = $width; + $lastline_descent = 1 + $bbox[1]; + } + $n_lines = count($lines); + $total_height = $n_lines * $font_height + ($n_lines - 1) * $line_spacing; + + // Calculate the rotation matrix for the text's angle. Remember that GD points Y down, + // so the sin() terms change sign. + $theta = deg2rad($angle); + $cos_t = cos($theta); + $sin_t = sin($theta); + $r00 = $cos_t; $r01 = $sin_t; + $r10 = -$sin_t; $r11 = $cos_t; + + // Make a bounding box of the right size, with upper left corner at (0,0). + // By convention, the point order is: LL, LR, UR, UL. + // Note this is still working with the text at 0 degrees. + // When sizing text (SizeText), use the overall size with descenders. + // This tells the caller how much room to leave for the text. + // When drawing text (DrawText), use the size without descenders - that + // is, down to the baseline. This is for accurate positioning. + $b[0] = 0; + if ($draw_it) { + $b[1] = $total_height; + } else { + $b[1] = $total_height + $lastline_descent; + } + $b[2] = $total_width; $b[3] = $b[1]; + $b[4] = $total_width; $b[5] = 0; + $b[6] = 0; $b[7] = 0; + + // Rotate the bounding box, then offset to the reference point: + for ($i = 0; $i < 8; $i += 2) { + $x_b = $b[$i]; + $y_b = $b[$i+1]; + $c[$i] = $x + $r00 * $x_b + $r01 * $y_b; + $c[$i+1] = $y + $r10 * $x_b + $r11 * $y_b; + } + + // Get an orthogonal (aligned with X and Y axes) bounding box around it, by + // finding the min and max X and Y: + $bbox_ref_x = $bbox_max_x = $c[0]; + $bbox_ref_y = $bbox_max_y = $c[1]; + for ($i = 2; $i < 8; $i += 2) { + $x_b = $c[$i]; + if ($x_b < $bbox_ref_x) $bbox_ref_x = $x_b; + elseif ($bbox_max_x < $x_b) $bbox_max_x = $x_b; + $y_b = $c[$i+1]; + if ($y_b < $bbox_ref_y) $bbox_ref_y = $y_b; + elseif ($bbox_max_y < $y_b) $bbox_max_y = $y_b; + } + $bbox_width = $bbox_max_x - $bbox_ref_x; + $bbox_height = $bbox_max_y - $bbox_ref_y; + + if (!$draw_it) { + // Return the bounding box, rounded up (so it always contains the text): + return array((int)ceil($bbox_width), (int)ceil($bbox_height)); + } + + $interline_step = $font_height + $line_spacing; // Line-to-line step + + // Calculate the offsets from the supplied reference point to the + // upper-left corner of the text. + // Start at the reference point at the upper left corner of the bounding + // box (bbox_ref_x, bbox_ref_y) then adjust it for the 9 point alignment. + // h,v_factor are 0,0 for top,left, .5,.5 for center,center, 1,1 for bottom,right. + // $off_x = $bbox_ref_x + $bbox_width * $h_factor - $x; + // $off_y = $bbox_ref_y + $bbox_height * $v_factor - $y; + // Then use that offset to calculate back to the supplied reference point x, y + // to get the text base point. + // $qx = $x - $off_x; + // $qy = $y - $off_y; + // Reduces to: + $qx = 2 * $x - $bbox_ref_x - $bbox_width * $h_factor; + $qy = 2 * $y - $bbox_ref_y - $bbox_height * $v_factor; + + // Check for debug callback. Don't calculate bounding box unless it is wanted. + if ($this->GetCallback('debug_textbox')) { + // Calculate the orthogonal bounding box coordinates for debug testing. + + // qx, qy is upper left corner relative to the text. + // Calculate px,py: upper left corner (absolute) of the bounding box. + // There are 4 equation sets for this, depending on the quadrant: + if ($sin_t > 0) { + if ($cos_t > 0) { + // Quadrant: 0d - 90d: + $px = $qx; $py = $qy - $total_width * $sin_t; + } else { + // Quadrant: 90d - 180d: + $px = $qx + $total_width * $cos_t; $py = $qy - $bbox_height; + } + } else { + if ($cos_t < 0) { + // Quadrant: 180d - 270d: + $px = $qx - $bbox_width; $py = $qy + $total_height * $cos_t; + } else { + // Quadrant: 270d - 360d: + $px = $qx + $total_height * $sin_t; $py = $qy; + } + } + $this->DoCallback('debug_textbox', $px, $py, $bbox_width, $bbox_height); + } + + // Since alignment is applied after rotation, which parameter is used + // to control alignment of each line within the text box varies with + // the angle. + // Angle (degrees): Line alignment controlled by: + // -45 < angle <= 45 h_align + // 45 < angle <= 135 reversed v_align + // 135 < angle <= 225 reversed h_align + // 225 < angle <= 315 v_align + if ($cos_t >= $sin_t) { + if ($cos_t >= -$sin_t) $line_align_factor = $h_factor; + else $line_align_factor = $v_factor; + } else { + if ($cos_t >= -$sin_t) $line_align_factor = 1-$v_factor; + else $line_align_factor = 1-$h_factor; + } + + // Now we have the start point, spacing and in-line alignment factor. + // We are finally ready to start drawing the text, line by line. + for ($i = 0; $i < $n_lines; $i++) { + + // For drawing TTF text, the reference point is the left edge of the + // text baseline (not the lower left corner of the bounding box). + // The following also adjusts for horizontal (relative to + // the text) alignment of the current line within the box. + // What is happening is rotation of this vector by the text angle: + // (x = (total_width - line_width) * factor, y = font_height) + + $width_factor = ($total_width - $line_widths[$i]) * $line_align_factor; + $rx = $qx + $r00 * $width_factor + $r01 * $font_height; + $ry = $qy + $r10 * $width_factor + $r11 * $font_height; + + // Finally, draw the text: + ImageTTFText($this->img, $font_size, $angle, $rx, $ry, $color, $font_file, $lines[$i]); + + // Step to position of next line. + // This is a rotation of (x=0,y=height+line_spacing) by $angle: + $qx += $r01 * $interline_step; + $qy += $r11 * $interline_step; + } + return TRUE; + } + + /* + * ProcessText() - Wrapper for ProcessTextTTF() and ProcessTextGD(). See notes above. + * This is intended for use from within PHPlot only, and only by DrawText() and SizeText(). + * $draw_it : True to draw the text, False to just return the orthogonal width and height. + * $font : PHPlot font array, or NULL or empty string to use 'generic' + * $angle : Text angle in degrees + * $x, $y : Reference point for the text (ignored if !$draw_it) + * $color : GD color index to use for drawing the text (ignored if !$draw_it) + * $text : The text to draw or size. Put a newline between lines. + * $halign : Horizontal alignment: left, center, or right (ignored if !$draw_it) + * $valign : Vertical alignment: top, center, or bottom (ignored if !$draw_it) + * Note: Alignment is relative to the image, not the text. + * Returns: True, if drawing text, or an array of ($width, $height) if not. + */ + protected function ProcessText($draw_it, $font, $angle, $x, $y, $color, $text, $halign, $valign) + { + // Empty text case: + if ($text === '') { + if ($draw_it) return TRUE; + return array(0, 0); + } + + // Calculate width and height offset factors using the alignment args: + if ($valign == 'top') $v_factor = 0; + elseif ($valign == 'center') $v_factor = 0.5; + else $v_factor = 1.0; // 'bottom' + if ($halign == 'left') $h_factor = 0; + elseif ($halign == 'center') $h_factor = 0.5; + else $h_factor = 1.0; // 'right' + + // Apply a default font. This is mostly for external (callback) users. + if (empty($font)) $font = $this->fonts['generic']; + + if ($font['ttf']) { + return $this->ProcessTextTTF($draw_it, $font, $angle, $x, $y, $color, $text, + $h_factor, $v_factor); + } + return $this->ProcessTextGD($draw_it, $font, $angle, $x, $y, $color, $text, $h_factor, $v_factor); + } + + /* + * Draws a block of text. See comments above before ProcessText(). + * $which_font : PHPlot font array, or NULL or empty string to use 'generic' + * $which_angle : Text angle in degrees + * $which_xpos, $which_ypos: Reference point for the text + * $which_color : GD color index to use for drawing the text + * $which_text : The text to draw, with newlines (\n) between lines. + * $which_halign : Horizontal (relative to the image) alignment: left, center, or right. + * $which_valign : Vertical (relative to the image) alignment: top, center, or bottom. + * Note: This function should be considered 'protected', and is not documented for public use. + */ + function DrawText($which_font, $which_angle, $which_xpos, $which_ypos, $which_color, $which_text, + $which_halign = 'left', $which_valign = 'bottom') + { + return $this->ProcessText(TRUE, + $which_font, $which_angle, $which_xpos, $which_ypos, + $which_color, $which_text, $which_halign, $which_valign); + } + + /* + * Returns the size of block of text. This is the orthogonal width and height of a bounding + * box aligned with the X and Y axes of the text. Only for angle=0 is this the actual + * width and height of the text block, but for any angle it is the amount of space needed + * to contain the text. + * $which_font : PHPlot font array, or NULL or empty string to use 'generic' + * $which_angle : Text angle in degrees + * $which_text : The text to draw, with newlines (\n) between lines. + * Returns a two element array with: $width, $height. + * This is just a wrapper for ProcessText() - see above. + * Note: This function should be considered 'protected', and is not documented for public use. + */ + function SizeText($which_font, $which_angle, $which_text) + { + // Color, position, and alignment are not used when calculating the size. + return $this->ProcessText(FALSE, + $which_font, $which_angle, 0, 0, 1, $which_text, '', ''); + } + +///////////////////////////////////////////// +/////////// INPUT / OUTPUT CONTROL +///////////////////////////////////////////// + + /* + * Sets output file format to $format (jpg, png, ...) + */ + function SetFileFormat($format) + { + $asked = $this->CheckOption($format, 'jpg, png, gif, wbmp', __FUNCTION__); + if (!$asked) return FALSE; + switch ($asked) { + case 'jpg': + $format_test = IMG_JPG; + break; + case 'png': + $format_test = IMG_PNG; + break; + case 'gif': + $format_test = IMG_GIF; + break; + case 'wbmp': + $format_test = IMG_WBMP; + break; + } + if (!(imagetypes() & $format_test)) { + return $this->PrintError("SetFileFormat(): File format '$format' not supported"); + } + $this->file_format = $asked; + return TRUE; + } + + /* + * Selects an input file to be used as graph background and scales or tiles this image + * to fit the sizes. + * $input_file : Path to the file to be used (jpeg, png and gif accepted) + * $mode : 'centeredtile', 'tile', or 'scale' (the image to the graph's size) + */ + function SetBgImage($input_file, $mode='centeredtile') + { + $this->bgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__); + $this->bgimg = $input_file; + return (boolean)$this->bgmode; + } + + /* + * Selects an input file to be used as plot area background and scales or tiles this image + * to fit the sizes. + * $input_file : Path to the file to be used (jpeg, png and gif accepted) + * $mode : 'centeredtile', 'tile', or 'scale' (the image to the graph's size) + */ + function SetPlotAreaBgImage($input_file, $mode='tile') + { + $this->plotbgmode = $this->CheckOption($mode, 'tile, centeredtile, scale', __FUNCTION__); + $this->plotbgimg = $input_file; + return (boolean)$this->plotbgmode; + } + + /* + * Sets the name of the file to be used as output file. + */ + function SetOutputFile($which_output_file) + { + $this->output_file = $which_output_file; + return TRUE; + } + + /* + * Sets the output image as 'inline', that is: no Content-Type headers are sent + * to the browser. Needed if you want to embed the images. + */ + function SetIsInline($which_ii) + { + $this->is_inline = (bool)$which_ii; + return TRUE; + } + + /* + * Performs the actual outputting of the generated graph. + */ + function PrintImage() + { + // Browser cache stuff submitted by Thiemo Nagel + if ( (! $this->browser_cache) && (! $this->is_inline)) { + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); + header('Cache-Control: no-cache, must-revalidate'); + header('Pragma: no-cache'); + } + + switch ($this->file_format) { + case 'png': + $mime_type = 'image/png'; + $output_f = 'imagepng'; + break; + case 'jpg': + $mime_type = 'image/jpeg'; + $output_f = 'imagejpeg'; + break; + case 'gif': + $mime_type = 'image/gif'; + $output_f = 'imagegif'; + break; + case 'wbmp': + $mime_type = 'image/wbmp'; + $output_f = 'imagewbmp'; + break; + default: + return $this->PrintError('PrintImage(): Please select an image type!'); + } + if (!$this->is_inline) { + Header("Content-type: $mime_type"); + } + if ($this->is_inline && $this->output_file != '') { + $output_f($this->img, $this->output_file); + } else { + $output_f($this->img); + } + return TRUE; + } + + /* + * Error handling for 'fatal' errors: + * $error_message Text of the error message + * Standard output from PHPlot is expected to be an image file, such as + * when handling an tag browser request. So it is not permitted to + * output text to standard output. (You should have display_errors=off) + * Here is how PHPlot handles fatal errors: + * + Write the error message into an image, and output the image. + * + If no image can be output, write nothing and produce an HTTP + * error header. + * + Trigger a user-level error containing the error message. + * If no error handler was set up, the script will log the + * error and exit with non-zero status. + * + * PrintError() and DrawError() are now equivalent. Both are provided for + * compatibility. (In earlier releases, PrintError sent the message to + * stdout only, and DrawError sent it in an image only.) + * + * This function does not return, unless the calling script has set up + * an error handler which does not exit. In that case, PrintError will + * return False. But not all of PHPlot will handle this correctly, so + * it is probably a bad idea for an error handler to return. + */ + protected function PrintError($error_message) + { + // Be sure not to loop recursively, e.g. PrintError - PrintImage - PrintError. + if (isset($this->in_error)) return FALSE; + $this->in_error = TRUE; + + // Output an image containing the error message: + if (!empty($this->img)) { + $ypos = $this->image_height/2; + $xpos = $this->image_width/2; + $bgcolor = ImageColorResolve($this->img, 255, 255, 255); + $fgcolor = ImageColorResolve($this->img, 0, 0, 0); + ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height, $bgcolor); + + // Switch to built-in fonts, in case of error with TrueType fonts: + $this->SetUseTTF(FALSE); + + $this->DrawText($this->fonts['generic'], 0, $xpos, $ypos, $fgcolor, + wordwrap($error_message), 'center', 'center'); + + $this->PrintImage(); + } elseif (! $this->is_inline) { + Header('HTTP/1.0 500 Internal Server Error'); + } + trigger_error($error_message, E_USER_ERROR); + unset($this->in_error); + return FALSE; // In case error handler returns, rather than doing exit(). + } + + /* + * Display an error message and exit. + * This is provided for backward compatibility only. Use PrintError() instead. + * $error_message Text of the error message + * $where_x, $where_y Ignored, provided for compatibility. + */ + protected function DrawError($error_message, $where_x = NULL, $where_y = NULL) + { + return $this->PrintError($error_message); + } + +///////////////////////////////////////////// +/////////// LABELS +///////////////////////////////////////////// + + /* + * Sets position for X data labels. + * For vertical plots, these are X axis data labels, showing label strings from the data array. + * Accepted positions are: plotdown, plotup, both, none. + * For horizontal plots (bar, stackedbar only), these are X data value labels, show the data values. + * Accepted positions are: plotin, plotstack, none. + */ + function SetXDataLabelPos($which_xdlp) + { + $which_xdlp = $this->CheckOption($which_xdlp, 'plotdown, plotup, both, none, plotin, plotstack', + __FUNCTION__); + if (!$which_xdlp) return FALSE; + $this->x_data_label_pos = $which_xdlp; + + return TRUE; + } + + /* + * Sets position for Y data labels. + * For vertical plots (where available), these are Y data value labels, showing the data values. + * Accepted positions are: plotin, plotstack, none. + * For horizontal plots, these are Y axis data labels, showing label strings from the data array. + * Accepted positions are: plotleft, plotright, both, none. + */ + function SetYDataLabelPos($which_ydlp) + { + $which_ydlp = $this->CheckOption($which_ydlp, 'plotleft, plotright, both, none, plotin, plotstack', + __FUNCTION__); + if (!$which_ydlp) return FALSE; + $this->y_data_label_pos = $which_ydlp; + + return TRUE; + } + + /* + * Set position for X tick labels. + */ + function SetXTickLabelPos($which_xtlp) + { + $which_xtlp = $this->CheckOption($which_xtlp, 'plotdown, plotup, both, xaxis, none', + __FUNCTION__); + if (!$which_xtlp) return FALSE; + $this->x_tick_label_pos = $which_xtlp; + + return TRUE; + } + + /* + * Set position for Y tick labels. + */ + function SetYTickLabelPos($which_ytlp) + { + $which_ytlp = $this->CheckOption($which_ytlp, 'plotleft, plotright, both, yaxis, none', + __FUNCTION__); + if (!$which_ytlp) return FALSE; + $this->y_tick_label_pos = $which_ytlp; + + return TRUE; + } + + /* + * Set formatting type for tick and data labels on X or Y axis. + * This implements the 4 functions Set[XY]LabelType() and Set[XY]DataLabelType(). + * $mode : 'x', 'y', 'xd', or 'yd' - which type of label to configure. + * 'x' and 'y' set the type for tick labels, and the default type for data labels + * if they are not separately configured. 'xd' and 'yd' set the type for data labels. + * $args : Variable arguments, passed as an array. + * [0] = $type (required) : Label type. 'data', 'time', 'printf', or 'custom'. + * For type 'data': + * [1] = $precision (optional). Numeric precision. Can also be set by SetPrecision[XY](). + * [2] = $prefix (optional) - prefix string for labels. + * [3] = $suffix (optional) - suffix string for labels. This replaces data_units_text. + * For type 'time': + * [1] = $format for strftime (optional). Can also be set by Set[XY]TimeFormat(). + * For type 'printf': + * [1] = $format (optional) for sprintf. + * For type 'custom': + * [1] = $callback (required) - Custom function or array of (instance,method) to call. + * [2] = $argument (optional) - Pass-through argument for the formatting function. + */ + protected function SetLabelType($mode, $args) + { + if (!$this->CheckOption($mode, 'x, y, xd, yd', __FUNCTION__)) + return FALSE; + + $type = isset($args[0]) ? $args[0] : ''; + $format =& $this->label_format[$mode]; // Shorthand reference to format storage variables + switch ($type) { + case 'data': + if (isset($args[1])) + $format['precision'] = $args[1]; + elseif (!isset($format['precision'])) + $format['precision'] = 1; + $format['prefix'] = isset($args[2]) ? $args[2] : ''; + $format['suffix'] = isset($args[3]) ? $args[3] : ''; + break; + + case 'time': + if (isset($args[1])) + $format['time_format'] = $args[1]; + elseif (!isset($format['time_format'])) + $format['time_format'] = '%H:%M:%S'; + break; + + case 'printf': + if (isset($args[1])) + $format['printf_format'] = $args[1]; + elseif (!isset($format['printf_format'])) + $format['printf_format'] = '%e'; + break; + + case 'custom': + if (isset($args[1])) { + $format['custom_callback'] = $args[1]; + $format['custom_arg'] = isset($args[2]) ? $args[2] : NULL; + } else { + $type = ''; // Error, 'custom' without a function, set to no-format mode. + } + break; + + case '': + case 'title': // Retained for backwards compatibility? + break; + + default: + $this->CheckOption($type, 'data, time, printf, custom', __FUNCTION__); + $type = ''; + } + $format['type'] = $type; + return (boolean)$type; + } + + /* + * Select label formating for X tick labels, and for X data labels + * (unless SetXDataLabelType was called). + * See SetLabelType() for details. + */ + function SetXLabelType() // Variable arguments: $type, ... + { + $args = func_get_args(); + return $this->SetLabelType('x', $args); + } + + /* + * Select label formatting for X data labels, overriding SetXLabelType. + */ + function SetXDataLabelType() // Variable arguments: $type, ... + { + $args = func_get_args(); + return $this->SetLabelType('xd', $args); + } + + /* + * Select label formating for Y tick labels, and for Y data labels + * (unless SetYDataLabelType was called). + * See SetLabelType() for details. + */ + function SetYLabelType() // Variable arguments: $type, ... + { + $args = func_get_args(); + return $this->SetLabelType('y', $args); + } + + /* + * Select label formatting for Y data labels, overriding SetYLabelType. + */ + function SetYDataLabelType() // Variable arguments: $type, ... + { + $args = func_get_args(); + return $this->SetLabelType('yd', $args); + } + + /* + * Set the date/time format code for X labels. + * Note: Use of SetXLabelType('time', $which_xtf) is preferred, because + * SetXTimeFormat does not also enable date/time formatting. + */ + function SetXTimeFormat($which_xtf) + { + $this->label_format['x']['time_format'] = $which_xtf; + return TRUE; + } + + /* + * Set the date/time format code for Y labels. + * Note: Use of SetYLabelType('time', $which_ytf) is preferred, because + * SetYTimeFormat does not also enable date/time formatting. + */ + function SetYTimeFormat($which_ytf) + { + $this->label_format['y']['time_format'] = $which_ytf; + return TRUE; + } + + /* + * Set number format parameters (decimal point and thousands separator) for + * 'data' mode label formatting, overriding the locale-defaults. + */ + function SetNumberFormat($decimal_point, $thousands_sep) + { + $this->decimal_point = $decimal_point; + $this->thousands_sep = $thousands_sep; + return TRUE; + } + + /* + * Set the text angle for X labels to $which_xla degrees. + */ + function SetXLabelAngle($which_xla) + { + $this->x_label_angle = $which_xla; + return TRUE; + } + + /* + * Set the text angle for Y labels to $which_xla degrees. + */ + function SetYLabelAngle($which_yla) + { + $this->y_label_angle = $which_yla; + return TRUE; + } + + /* + * Set the angle for X Data Labels to $which_xdla degrees. + * If not used, this defaults to the value set with SetXLabelAngle. + */ + function SetXDataLabelAngle($which_xdla) + { + $this->x_data_label_angle = $which_xdla; + return TRUE; + } + + /* + * Set the angle for Y Data Labels to $which_ydla degrees. + * If not used, this defaults to zero (unlike X data labels). + */ + function SetYDataLabelAngle($which_ydla) + { + $this->y_data_label_angle = $which_ydla; + return TRUE; + } + +///////////////////////////////////////////// +/////////// MISC +///////////////////////////////////////////// + + /* + * Checks the validity of an option. + * $which_opt String to check, such as the provided value of a function argument. + * $which_acc String of accepted choices. Must be lower-case, and separated + * by exactly ', ' (comma, space). + * $which_func Name of the calling function, for error messages. + * Returns the supplied option value, downcased and trimmed, if it is valid. + * Reports an error if the supplied option is not valid. + */ + protected function CheckOption($which_opt, $which_acc, $which_func) + { + $asked = strtolower(trim($which_opt)); + + // Look for the supplied value in a comma/space separated list. + if (strpos(", $which_acc,", ", $asked,") !== FALSE) + return $asked; + + $this->PrintError("$which_func(): '$which_opt' not in available choices: '$which_acc'."); + return NULL; + } + + /* + * Checks the validity of an array of options. + * $opt Array or string to check. + * $acc String of accepted choices. Must be lower-case, and separated + * by exactly ', ' (comma, space). + * $func Name of the calling function, for error messages. + * Returns a array option value(s), downcased and trimmed, if all entries in $opt are valid. + * Reports an error if any supplied option is not valid. Returns NULL if the error handler returns. + */ + protected function CheckOptionArray($opt, $acc, $func) + { + $opt_array = (array)$opt; + $result = array(); + foreach ($opt_array as $option) { + $choice = $this->CheckOption($option, $acc, $func); + if (is_null($choice)) return NULL; // In case CheckOption error handler returns + $result[] = $choice; + } + return $result; + } + + /* + * Check compatibility of a plot type and data type. + * This is called by the plot-type-specific drawing functions. + * $valid_types String of supported data types. Multiple values must be + * separated by exactly ', ' (comma, space). + * Returns True if the type is valid for this plot. + * Reports an error if the data type is not value. If the error is handled and + * the handler returns, this returns False. + */ + protected function CheckDataType($valid_types) + { + if (strpos(", $valid_types,", ", $this->data_type,") !== FALSE) + return TRUE; + + $this->PrintError("Data type '$this->data_type' is not valid for '$this->plot_type' plots." + . " Supported data type(s): '$valid_types'"); + return FALSE; + } + + /* + * Decode the data type into variables used to determine how to process a data array. + * The goal is minimize which functions understand the actual data type values. + * This sets the datatype_* variables for use by other member functions. + * datatype_implied : Implicit independent variable (e.g. text-data vs data-data) + * datatype_swapped_xy : Swapped X/Y (horizontal plot) + * datatype_error_bars : Data array has error bar data + * datatype_pie_single : Data array is for a pie chart with one row per slice + */ + protected function DecodeDataType() + { + $dt = $this->data_type; + + $this->datatype_implied = ($dt == 'text-data' || $dt == 'text-data-single' + || $dt == 'text-data-yx'); + $this->datatype_swapped_xy = ($dt == 'text-data-yx' || $dt == 'data-data-yx'); + $this->datatype_error_bars = ($dt == 'data-data-error'); + $this->datatype_pie_single = ($dt == 'text-data-single'); + } + + /* + * Make sure the data array is populated, and calculate the number of columns. + * This is called from DrawGraph. Calculates data_columns, which is the + * maximum number of dependent variable values (usually Y) in the data array rows. + * (For pie charts, this is the number of slices.) + * This depends on the data_type, unlike records_per_group (which was + * previously used to pad style arrays, but is not accurate). + * Returns True if the data array is OK, else reports an error (and may return False). + * Note error messages refer to the caller, the public DrawGraph(). + */ + protected function CheckDataArray() + { + // Test for missing image, which really should never happen. + if (!$this->img) { + return $this->PrintError('DrawGraph(): No image resource allocated'); + } + + // Test for missing or empty data array: + if (empty($this->data) || !is_array($this->data)) { + return $this->PrintError("DrawGraph(): No data array"); + } + if ($this->total_records == 0) { + return $this->PrintError('DrawGraph(): Empty data set'); + } + + // Decode the data type into functional flags. + $this->DecodeDataType(); + + // Calculate the maximum number of dependent values per independent value + // (e.g. Y for each X), or the number of pie slices. + if ($this->datatype_pie_single) { + $this->data_columns = $this->num_data_rows; // Special case for 1 type of pie chart. + } else { + $skip = $this->datatype_implied ? 1 : 2; // Skip data label and independent variable if used + $this->data_columns = $this->records_per_group - $skip; + if ($this->datatype_error_bars) // Each Y has +err and -err along with it + $this->data_columns = (int)($this->data_columns / 3); + } + return TRUE; + } + + /* + * Control headers for browser-side image caching. + * $which_browser_cache : True to allow browsers to cache the image. + */ + function SetBrowserCache($which_browser_cache) + { + $this->browser_cache = $which_browser_cache; + return TRUE; + } + + /* + * Set whether DrawGraph automatically outputs the image too. + * $which_pi : True to have DrawGraph call PrintImage at the end. + */ + function SetPrintImage($which_pi) + { + $this->print_image = $which_pi; + return TRUE; + } + + /* + * Set text to display in the graph's legend. + * $which_leg : Array of strings for the complete legend, or a single string + * to be appended to the legend. + * Or NULL (or an empty array) to cancel the legend. + */ + function SetLegend($which_leg) + { + if (is_array($which_leg)) { // use array (or cancel, if empty array) + $this->legend = $which_leg; + } elseif (!is_null($which_leg)) { // append string + $this->legend[] = $which_leg; + } else { + $this->legend = ''; // Reinitialize to empty, meaning no legend. + } + return TRUE; + } + + /* + * Specifies the position of the legend's upper/leftmost corner, + * in pixel (device) coordinates. + * Both X and Y must be provided, or both omitted (or use NULL) to restore auto-positioning. + */ + function SetLegendPixels($which_x=NULL, $which_y=NULL) + { + $this->legend_x_pos = $which_x; + $this->legend_y_pos = $which_y; + // Make sure this is unset, meaning we have pixel coords: + unset($this->legend_xy_world); + + return TRUE; + } + + /* + * Specifies the position of the legend's upper/leftmost corner, + * in world (data space) coordinates. + */ + function SetLegendWorld($which_x, $which_y) + { + // Since conversion from world to pixel coordinates is not yet available, just + // remember the coordinates and set a flag to indicate conversion is needed. + $this->legend_x_pos = $which_x; + $this->legend_y_pos = $which_y; + $this->legend_xy_world = TRUE; + + return TRUE; + } + + /* + * Set legend text alignment, color box alignment, and style options. + * $text_align : Alignment of the text, 'left' or 'right'. + * $colorbox_align : Alignment of the color boxes, 'left', 'right', 'none', or missing/empty. + * If missing or empty, the same alignment as $text_align is used. Color box is positioned first. + * $style : reserved for future use. + */ + function SetLegendStyle($text_align, $colorbox_align = '', $style = '') + { + $this->legend_text_align = $this->CheckOption($text_align, 'left, right', __FUNCTION__); + if (empty($colorbox_align)) + $this->legend_colorbox_align = $this->legend_text_align; + else + $this->legend_colorbox_align = $this->CheckOption($colorbox_align, 'left, right, none', + __FUNCTION__); + return ((boolean)$this->legend_text_align && (boolean)$this->legend_colorbox_align); + } + + /* + * Set border for the plot area. + * Accepted values are: left, right, top, bottom, sides, none, full or an array of those. + */ + function SetPlotBorderType($pbt) + { + $this->plot_border_type = $this->CheckOptionArray($pbt, 'left, right, top, bottom, sides, none, full', + __FUNCTION__); + return !empty($this->plot_border_type); + } + + /* + * Set border style for the image. + * Accepted values are: raised, plain, solid, none + * 'solid' is the same as 'plain' except it fixes the color (see DrawImageBorder) + */ + function SetImageBorderType($sibt) + { + $this->image_border_type = $this->CheckOption($sibt, 'raised, plain, solid, none', __FUNCTION__); + return (boolean)$this->image_border_type; + } + + /* + * Set border width for the image to $width in pixels. + */ + function SetImageBorderWidth($width) + { + $this->image_border_width = $width; + return TRUE; + } + + /* + * Enable or disable drawing of the plot area background color. + */ + function SetDrawPlotAreaBackground($dpab) + { + $this->draw_plot_area_background = (bool)$dpab; + return TRUE; + } + + /* + * Enable or disable drawing of the X grid lines. + */ + function SetDrawXGrid($dxg) + { + $this->draw_x_grid = (bool)$dxg; + return TRUE; + } + + /* + * Enable or disable drawing of the Y grid lines. + */ + function SetDrawYGrid($dyg) + { + $this->draw_y_grid = (bool)$dyg; + return TRUE; + } + + /* + * Select dashed or solid grid lines. + * $ddg : True for dashed grid lines, false for solid grid lines. + */ + function SetDrawDashedGrid($ddg) + { + $this->dashed_grid = (bool)$ddg; + return TRUE; + } + + /* + * Enable or disable drawing of X Data Label Lines. + */ + function SetDrawXDataLabelLines($dxdl) + { + $this->draw_x_data_label_lines = (bool)$dxdl; + return TRUE; + } + + /* + * Set the main title text for the plot. + */ + function SetTitle($which_title) + { + $this->title_txt = $which_title; + return TRUE; + } + + /* + * Set the X axis title and position. + */ + function SetXTitle($which_xtitle, $which_xpos = 'plotdown') + { + if ($which_xtitle == '') + $which_xpos = 'none'; + + $this->x_title_pos = $this->CheckOption($which_xpos, 'plotdown, plotup, both, none', __FUNCTION__); + if (!$this->x_title_pos) return FALSE; + $this->x_title_txt = $which_xtitle; + return TRUE; + } + + /* + * Set the Y axis title and position. + */ + function SetYTitle($which_ytitle, $which_ypos = 'plotleft') + { + if ($which_ytitle == '') + $which_ypos = 'none'; + + $this->y_title_pos = $this->CheckOption($which_ypos, 'plotleft, plotright, both, none', __FUNCTION__); + if (!$this->y_title_pos) return FALSE; + $this->y_title_txt = $which_ytitle; + return TRUE; + } + + /* + * Set the size of the drop shadow for bar and pie charts. + * $which_s : Size of the drop shadow in pixels. + */ + function SetShading($which_s) + { + $this->shading = (int)$which_s; + return TRUE; + } + + /* + * Set the plot type (bars, points, ...) + */ + function SetPlotType($which_pt) + { + $avail_plot_types = implode(', ', array_keys(PHPlot::$plots)); // List of known plot types + $this->plot_type = $this->CheckOption($which_pt, $avail_plot_types, __FUNCTION__); + return (boolean)$this->plot_type; + } + + /* + * Set the position of the X axis. + * $pos : Axis position in world coordinates (as an integer). + */ + function SetXAxisPosition($pos='') + { + $this->x_axis_position = ($pos === '') ? $pos : (int)$pos; + return TRUE; + } + + /* + * Set the position of the Y axis. + * $pos : Axis position in world coordinates (as an integer). + */ + function SetYAxisPosition($pos='') + { + $this->y_axis_position = ($pos === '') ? $pos : (int)$pos; + return TRUE; + } + + /* + * Enable or disable drawing of the X axis line. + * $draw : True to draw the axis (default if not called), False to suppress it. + * This controls drawing of the axis line only, and not the ticks, labels, or grid. + */ + function SetDrawXAxis($draw) + { + $this->suppress_x_axis = !$draw; // See DrawXAxis() + return TRUE; + } + + /* + * Enable or disable drawing of the Y axis line. + * $draw : True to draw the axis (default if not called), False to suppress it. + * This controls drawing of the axis line only, and not the ticks, labels, or grid. + */ + function SetDrawYAxis($draw) + { + $this->suppress_y_axis = !$draw; // See DrawYAxis() + return TRUE; + } + + /* + * Select linear or log scale for the X axis. + */ + function SetXScaleType($which_xst) + { + $this->xscale_type = $this->CheckOption($which_xst, 'linear, log', __FUNCTION__); + return (boolean)$this->xscale_type; + } + + /* + * Select linear or log scale for the Y axis. + */ + function SetYScaleType($which_yst) + { + $this->yscale_type = $this->CheckOption($which_yst, 'linear, log', __FUNCTION__); + return (boolean)$this->yscale_type; + } + + /* + * Set the precision for numerically formatted X labels. + * $which_prec : Number of digits to display. + * Note: This is equivalent to: SetXLabelType('data', $which_prec) + */ + function SetPrecisionX($which_prec) + { + return $this->SetXLabelType('data', $which_prec); + } + + /* + * Set the precision for numerically formatted Y labels. + * $which_prec : Number of digits to display. + * Note: This is equivalent to: SetYLabelType('data', $which_prec) + */ + function SetPrecisionY($which_prec) + { + return $this->SetYLabelType('data', $which_prec); + } + + /* + * Set the line width (in pixels) for error bars. + */ + function SetErrorBarLineWidth($which_seblw) + { + $this->error_bar_line_width = $which_seblw; + return TRUE; + } + + /* + * Set the position for pie chart percentage labels. + * $which_blb : Real number between 0 and 1. + * Smaller values move the labels in towards the center. + */ + function SetLabelScalePosition($which_blp) + { + $this->label_scale_position = $which_blp; + return TRUE; + } + + /* + * Set the size (in pixels) of the "T" in error bars. + */ + function SetErrorBarSize($which_ebs) + { + $this->error_bar_size = $which_ebs; + return TRUE; + } + + /* + * Set the shape of the in error bars. + * $which_ebs : Error bar shape, 'tee' or 'line'. + */ + function SetErrorBarShape($which_ebs) + { + $this->error_bar_shape = $this->CheckOption($which_ebs, 'tee, line', __FUNCTION__); + return (boolean)$this->error_bar_shape; + } + + /* + * Synchronize the point shape and point size arrays. + * This is called just before drawing any plot that needs 'points'. + */ + protected function CheckPointParams() + { + // Make both point_shapes and point_sizes the same size, by padding the smaller. + $ps = count($this->point_sizes); + $pt = count($this->point_shapes); + + if ($ps < $pt) { + $this->pad_array($this->point_sizes, $pt); + $this->point_counts = $pt; + } elseif ($ps > $pt) { + $this->pad_array($this->point_shapes, $ps); + $this->point_counts = $ps; + } else { + $this->point_counts = $ps; + } + + // Note: PHPlot used to check and adjust point_sizes to be an even number here, + // for all 'diamond' and 'triangle' shapes. The reason for this having been + // lost, and the current maintainer seeing no sense it doing this for only + // some shapes, the code has been removed. But see what DrawDot() does. + } + + /* + * Set the point shape for each data set. + * $which_pt : Array (or single value) of valid point shapes. See also DrawDot() for valid shapes. + * The point shape and point sizes arrays are synchronized before drawing a graph + * that uses points. See CheckPointParams() + */ + function SetPointShapes($which_pt) + { + $this->point_shapes = $this->CheckOptionArray($which_pt, 'halfline, line, plus, cross, rect,' + . ' circle, dot, diamond, triangle, trianglemid, delta, yield, star, hourglass,' + . ' bowtie, target, box, home, up, down, none', __FUNCTION__); + return !empty($this->point_shapes); + } + + /* + * Set the point size for point plots. + * $which_ps : Array (or single value) of point sizes in pixels. + * The point shape and point sizes arrays are synchronized before drawing a graph + * that uses points. See CheckPointParams() + */ + function SetPointSizes($which_ps) + { + if (is_array($which_ps)) { + // Use provided array: + $this->point_sizes = $which_ps; + } elseif (!is_null($which_ps)) { + // Make the single value into an array: + $this->point_sizes = array($which_ps); + } + return TRUE; + } + + /* + * Sets whether lines should be broken at missing data. + * $bl : True to break the lines, false to connect around missing data. + * This only works with 'lines' and 'squared' plots. + */ + function SetDrawBrokenLines($bl) + { + $this->draw_broken_lines = (bool)$bl; + return TRUE; + } + + /* + * Set the data type, which defines the structure of the data array + * text-data: ('label', y1, y2, y3, ...) + * text-data-single: ('label', data), for some pie charts. + * data-data: ('label', x, y1, y2, y3, ...) + * data-data-error: ('label', x1, y1, e1+, e2-, y2, e2+, e2-, y3, e3+, e3-, ...) + * data-data-yx: ('label', y, x1, x2, x3, ..) + * text-data-yx: ('label', x1, x2, x3, ...) + */ + function SetDataType($which_dt) + { + //The next four lines are for past compatibility. + if ($which_dt == 'text-linear') $which_dt = 'text-data'; + elseif ($which_dt == 'linear-linear') $which_dt = 'data-data'; + elseif ($which_dt == 'linear-linear-error') $which_dt = 'data-data-error'; + elseif ($which_dt == 'text-data-pie') $which_dt = 'text-data-single'; + + $this->data_type = $this->CheckOption($which_dt, 'text-data, text-data-single, '. + 'data-data, data-data-error, '. + 'data-data-yx, text-data-yx', + __FUNCTION__); + return (boolean)$this->data_type; + } + + /* + * Copy the array passed as data values. We convert to numerical indexes, for its + * use for (or while) loops, which sometimes are faster. Performance improvements + * vary from 28% in DrawLines() to 49% in DrawArea() for plot drawing functions. + */ + function SetDataValues($which_dv) + { + $this->num_data_rows = count($which_dv); + $this->total_records = 0; + $this->data = array(); + $this->num_recs = array(); + for ($i = 0; $i < $this->num_data_rows; $i++) { + $this->data[$i] = array_values($which_dv[$i]); // convert to numerical indices. + + // Count size of each row, and total for the array. + $recs = count($this->data[$i]); + $this->total_records += $recs; + $this->num_recs[$i] = $recs; + } + // This is the size of the widest row in the data array + // Note records_per_group isn't used much anymore. See data_columns in CheckDataArray() + $this->records_per_group = max($this->num_recs); + return TRUE; + } + + /* + * Pad styles arrays for later use by plot drawing functions: + * This removes the need for $max_data_colors, etc. and $color_index = $color_index % $max_data_colors + * in DrawBars(), DrawLines(), etc. + * The arrays are padded to data_columns which is the maximum number of data sets. + * See CheckDataArray() for the calculation. + */ + protected function PadArrays() + { + $this->pad_array($this->line_widths, $this->data_columns); + $this->pad_array($this->line_styles, $this->data_columns); + $this->pad_array($this->ndx_data_colors, $this->data_columns); + $this->pad_array($this->ndx_data_border_colors, $this->data_columns); + // Other data color arrays are handled in the Need*Colors() functions. + + return TRUE; + } + + /* + * Pads an array with itself. This only works on 0-based sequential integer indexed arrays. + * $arr : The array (or scalar) to pad. This argument is modified. + * $size : Minimum size of the resulting array. + * If $arr is a scalar, it will be converted first to a single element array. + * If $arr has at least $size elements, it is unchanged. + * Otherwise, append elements of $arr to itself until it reaches $size elements. + */ + protected function pad_array(&$arr, $size) + { + if (! is_array($arr)) { + $arr = array($arr); + } + $n = count($arr); + $base = 0; + while ($n < $size) $arr[$n++] = $arr[$base++]; + } + + /* + * Format a floating-point number. + * $number : A floating point number to format + * $decimals : Number of decimal places in the result + * Returns the formatted result. + * This is like PHP's number_format, but uses class variables for separators. + * The separators will default to locale-specific values, if available. + */ + protected function number_format($number, $decimals=0) + { + if (!isset($this->decimal_point) || !isset($this->thousands_sep)) { + // Load locale-specific values from environment, unless disabled: + if (empty($this->locale_override)) + @setlocale(LC_ALL, ''); + // Fetch locale settings: + $locale = @localeconv(); + if (isset($locale['decimal_point']) && isset($locale['thousands_sep'])) { + $this->decimal_point = $locale['decimal_point']; + $this->thousands_sep = $locale['thousands_sep']; + } else { + // Locale information not available. + $this->decimal_point = '.'; + $this->thousands_sep = ','; + } + } + return number_format($number, $decimals, $this->decimal_point, $this->thousands_sep); + } + + /* + * Register a callback (hook) function + * $reason : A pre-defined name where a callback can be defined. + * $function : The name of a function to register for callback, or an instance/method + * pair in an array (see 'callbacks' in the PHP reference manual). + * $arg : Optional argument to supply to the callback function when it is triggered. + * (Often called "clientData") + * Returns True if the callback reason is valid, else False. + */ + function SetCallback($reason, $function, $arg = NULL) + { + // Use array_key_exists because valid reason keys have NULL as value. + if (!array_key_exists($reason, $this->callbacks)) + return FALSE; + $this->callbacks[$reason] = array($function, $arg); + return TRUE; + } + + /* + * Return the name of a function registered for callback. See SetCallBack. + * $reason - A pre-defined name where a callback can be defined. + * Returns the current callback function (name or array) for the given reason, + * or False if there was no active callback or the reason is not valid. + * Note you can safely test the return value with a simple 'if', as + * no valid function name evaluates to false. + */ + function GetCallback($reason) + { + if (isset($this->callbacks[$reason])) + return $this->callbacks[$reason][0]; + return FALSE; + } + + /* + * Un-register (remove) a function registered for callback. + * $reason - A pre-defined name where a callback can be defined. + * Returns: True if it was a valid callback reason, else False. + * Note: Returns True whether or not there was a callback registered. + */ + function RemoveCallback($reason) + { + if (!array_key_exists($reason, $this->callbacks)) + return FALSE; + $this->callbacks[$reason] = NULL; + return TRUE; + } + + /* + * Invoke a callback, if one is registered. + * Accepts a variable number of arguments >= 1: + * $reason : A string naming the callback. + * ... : Zero or more additional arguments to be passed to the + * callback function, after the passthru argument: + * callback_function($image, $passthru, ...) + * Returns: whatever value (if any) was returned by the callback. + */ + protected function DoCallback() // Note: Variable arguments + { + $args = func_get_args(); + $reason = $args[0]; + if (!isset($this->callbacks[$reason])) + return; + list($function, $args[0]) = $this->callbacks[$reason]; + array_unshift($args, $this->img); + // Now args[] looks like: img, passthru, extra args... + return call_user_func_array($function, $args); + } + + /* + * Allocate colors for the plot. + * This is called by DrawGraph to allocate the colors needed for the plot. Each selectable + * color has already been validated, parsed into an array (r,g,b,a), and stored into a member + * variable. Now the GD color indexes are assigned and stored into the ndx_*_color variables. + * This is deferred here to avoid allocating unneeded colors and to avoid order dependencies, + * especially with the transparent color. + * + * For drawing data elements, only the main data colors and border colors are allocated here. + * Dark colors and error bar colors are allocated by Need*Color() functions. + * (Data border colors default to just black, so there is no cost to always allocating.) + * + * Data color allocation works as follows. If there is a data_color callback, then allocate all + * defined data colors (because the callback can use them however it wants). Otherwise, only allocate + * the number of colors that will be used. This is the larger of the number of data sets and the + * number of legend lines. + */ + protected function SetColorIndexes() + { + $this->ndx_bg_color = $this->GetColorIndex($this->bg_color); // Background first + $this->ndx_plot_bg_color = $this->GetColorIndex($this->plot_bg_color); + if ($this->image_border_type != 'none') { + $this->ndx_i_border = $this->GetColorIndex($this->i_border); + $this->ndx_i_border_dark = $this->GetDarkColorIndex($this->i_border); + } + + // Handle defaults for X and Y title colors. + $this->ndx_title_color = $this->GetColorIndex($this->title_color); + if (empty($this->x_title_color)) { + $this->ndx_x_title_color = $this->ndx_title_color; + } else { + $this->ndx_x_title_color = $this->GetColorIndex($this->x_title_color); + } + if (empty($this->y_title_color)) { + $this->ndx_y_title_color = $this->ndx_title_color; + } else { + $this->ndx_y_title_color = $this->GetColorIndex($this->y_title_color); + } + + $this->ndx_text_color = $this->GetColorIndex($this->text_color); + $this->ndx_grid_color = $this->GetColorIndex($this->grid_color); + $this->ndx_light_grid_color = $this->GetColorIndex($this->light_grid_color); + $this->ndx_tick_color = $this->GetColorIndex($this->tick_color); + + // Maximum number of data & border colors to allocate: + if ($this->GetCallback('data_color')) { + $n_data = count($this->data_colors); // Need all of them + $n_border = count($this->data_border_colors); + } else { + $n_data = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend)); + $n_border = $n_data; // One border color per data color + } + + // Allocate main data colors. For other colors used for data, see the functions which follow. + $this->ndx_data_colors = $this->GetColorIndexArray($this->data_colors, $n_data); + $this->ndx_data_border_colors = $this->GetColorIndexArray($this->data_border_colors, $n_border); + + // Set up a color as transparent, if SetTransparentColor was used. + if (!empty($this->transparent_color)) { + imagecolortransparent($this->img, $this->GetColorIndex($this->transparent_color)); + } + } + + /* + * Allocate dark-shade data colors. Called if needed by graph drawing functions. + */ + protected function NeedDataDarkColors() + { + // This duplicates the calculation in SetColorIndexes() for number of data colors to allocate. + if ($this->GetCallback('data_color')) { + $n_data = count($this->data_colors); + } else { + $n_data = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend)); + } + $this->ndx_data_dark_colors = $this->GetDarkColorIndexArray($this->data_colors, $n_data); + $this->pad_array($this->ndx_data_dark_colors, $this->data_columns); + } + + /* + * Allocate error bar colors. Called if needed by graph drawing functions. + */ + protected function NeedErrorBarColors() + { + // This is similar to the calculation in SetColorIndexes() for number of data colors to allocate. + if ($this->GetCallback('data_color')) { + $n_err = count($this->error_bar_colors); + } else { + $n_err = max($this->data_columns, empty($this->legend) ? 0 : count($this->legend)); + } + $this->ndx_error_bar_colors = $this->GetColorIndexArray($this->error_bar_colors, $n_err); + $this->pad_array($this->ndx_error_bar_colors, $this->data_columns); + } + + /* + * Determine if, and where, to draw Data Value Labels. + * $label_control : Label position control. Either x_data_label_pos or y_data_label_pos. + * &$x_adj, &$y_adj : Returns X,Y adjustments (offset in pixels) to the text position. + * &$h_align, &$v_align : Returns horizontal and vertical alignment for the label. + * The above 4 argument values should be passed to DrawDataValueLabel() + * Returns True if data value labels should be drawn (based on $label_control), else False. + * This is used for plot types other than bars/stackedbars (which have their own way of doing it). + * It uses two member variables (unset by default): data_value_label_angle and data_value_label_distance + * to define the vector to the label. Default is 90 degrees at 5 pixels. + */ + protected function CheckDataValueLabels($label_control, &$x_adj, &$y_adj, &$h_align, &$v_align) + { + if ($label_control != 'plotin') + return FALSE; // No data value labels + $angle = deg2rad(isset($this->data_value_label_angle) ? $this->data_value_label_angle : 90); + $radius = isset($this->data_value_label_distance) ? $this->data_value_label_distance : 5; + $cos = cos($angle); + $sin = sin($angle); + $x_adj = (int)($radius * $cos); + $y_adj = -(int)($radius * $sin); // Y is reversed in device coordinates + + // Choose from 8 (not 9, center/center can't happen) text alignments based on angle: + if ($sin >= 0.383) $v_align = 'bottom'; // 0.383 = sin(360deg / 16) + elseif ($sin >= -0.383) $v_align = 'center'; + else $v_align = 'top'; + if ($cos >= 0.383) $h_align = 'left'; + elseif ($cos >= -0.383) $h_align = 'center'; + else $h_align = 'right'; + return TRUE; + } + +////////////////////////////////////////////////////////// +/////////// DATA ANALYSIS, SCALING AND TRANSLATION +////////////////////////////////////////////////////////// + + /* + * Analyzes the data array and calculates the minimum and maximum values. + * In this function, IV refers to the independent variable, and DV the dependent variable. + * For most plots, IV is X and DV is Y. For swapped X/Y plots, IV is Y and DV is X. + * At the end of the function, IV and DV ranges get assigned into X or Y. + * + * The data type mostly determines the data array structure, but some plot types do special + * things such as sum the values in a row. This information is in the plots[] array. + * + * This calculates min_x, max_x, min_y, and max_y. It also calculates two arrays + * data_min[] and data_max[] with per-row min and max values. These are used for + * data label lines. For normal (unswapped) data, these are the Y range for each X. + * For swapped X/Y data, they are the X range for each Y. + */ + protected function FindDataLimits() + { + // Does this plot type need special processing of the data values? + $sum_vals = !empty(PHPlot::$plots[$this->plot_type]['sum_vals']); // Add up values in each row + $abs_vals = !empty(PHPlot::$plots[$this->plot_type]['abs_vals']); // Take absolute values + + // These need to be initialized in case there are multiple plots and missing data points. + $this->data_min = array(); + $this->data_max = array(); + + // Independent values are in the data array or assumed? + if ($this->datatype_implied) { + $all_iv = array(0, $this->num_data_rows - 1); + } else { + $all_iv = array(); + } + + // Process all rows of data: + for ($i = 0; $i < $this->num_data_rows; $i++) { + $n_vals = $this->num_recs[$i]; + $j = 1; // Skips label at [0] + + if (!$this->datatype_implied) { + $all_iv[] = (double)$this->data[$i][$j++]; + } + + if ($sum_vals) { + $all_dv = array(0, 0); // One limit is 0, other calculated below + } else { + $all_dv = array(); + } + while ($j < $n_vals) { + if (is_numeric($this->data[$i][$j])) { + $val = (double)$this->data[$i][$j++]; + + if ($this->datatype_error_bars) { + $all_dv[] = $val + (double)$this->data[$i][$j++]; + $all_dv[] = $val - (double)$this->data[$i][$j++]; + } else { + if ($abs_vals) { + $val = abs($val); // Use absolute values + } + if ($sum_vals) { + $all_dv[1] += $val; // Sum of values + } else { + $all_dv[] = $val; // List of all values + } + } + } else { // Missing DV value + $j++; + if ($this->datatype_error_bars) $j += 2; + } + } + if (!empty($all_dv)) { + $this->data_min[$i] = min($all_dv); // Store per-row DV range + $this->data_max[$i] = max($all_dv); + } + } + + if ($this->datatype_swapped_xy) { + // Assign min and max for swapped X/Y plots: IV=Y and DV=X + $this->min_y = min($all_iv); + $this->max_y = max($all_iv); + if (empty($this->data_min)) { // Guard against regressive case: No X at all + $this->min_x = 0; + $this->max_x = 0; + } else { + $this->min_x = min($this->data_min); // Store global X range + $this->max_x = max($this->data_max); + } + } else { + // Assign min and max for normal plots: IV=X and DV=Y + $this->min_x = min($all_iv); + $this->max_x = max($all_iv); + if (empty($this->data_min)) { // Guard against regressive case: No Y at all + $this->min_y = 0; + $this->max_y = 0; + } else { + $this->min_y = min($this->data_min); // Store global Y range + $this->max_y = max($this->data_max); + } + } + + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'min_x' => $this->min_x, 'min_y' => $this->min_y, + 'max_x' => $this->max_x, 'max_y' => $this->max_y)); + } + return TRUE; + } + + /* + * Calculates image margins on the fly from title positions and sizes, + * and tick labels positions and sizes. + * + * A picture of the locations of elements and spacing can be found in the + * PHPlot Reference Manual. + * + * Calculates the following (class variables unless noted): + * + * Plot area margins (see note below): + * y_top_margin + * y_bot_margin + * x_left_margin + * x_right_margin + * + * Title sizes (these are now local, not class variables, since they are not used elsewhere): + * title_height : Height of main title + * x_title_height : Height of X axis title, 0 if no X title + * y_title_width : Width of Y axis title, 0 if no Y title + * + * Tick/Data label offsets, relative to plot_area: + * x_label_top_offset, x_label_bot_offset, x_label_axis_offset + * y_label_left_offset, y_label_right_offset, y_label_axis_offset + * + * Title offsets, relative to plot area: + * x_title_top_offset, x_title_bot_offset + * y_title_left_offset, y_title_left_offset + * title_offset (for main title, relative to image edge) + * + * Note: The margins are calculated, but not stored, if margins or plot area were + * set by the user with SetPlotAreaPixels or SetMarginsPixels. The margin + * calculation is mixed in with the offset variables, so it doesn't seem worth the + * trouble to separate them. + * + * If the $maximize argument is true, we use the full image size, minus safe_margin + * and main title, for the plot. This is for pie charts which have no axes or X/Y titles. + */ + protected function CalcMargins($maximize) + { + // This is the line-to-line or line-to-text spacing: + $gap = $this->safe_margin; + // Initial margin on each side takes into account a possible image border. + // For compatibility, if border is 1 or 2, don't increase the margins. + $base_margin = max($gap, $this->GetImageBorderWidth() + 3); + $this->title_offset = $base_margin; // For use in DrawTitle + + // Minimum margin on each side. This reduces the chance that the + // right-most tick label (for example) will run off the image edge + // if there are no titles on that side. + $min_margin = 2 * $gap + $base_margin; + + // Calculate the title sizes: + list($unused, $title_height) = $this->SizeText($this->fonts['title'], 0, $this->title_txt); + list($unused, $x_title_height) = $this->SizeText($this->fonts['x_title'], 0, $this->x_title_txt); + list($y_title_width, $unused) = $this->SizeText($this->fonts['y_title'], 90, $this->y_title_txt); + + // Special case for maximum area usage with no X/Y titles or labels, only main title: + if ($maximize) { + if (!isset($this->x_left_margin)) + $this->x_left_margin = $base_margin; + if (!isset($this->x_right_margin)) + $this->x_right_margin = $base_margin; + if (!isset($this->y_top_margin)) { + $this->y_top_margin = $base_margin; + if ($title_height > 0) + $this->y_top_margin += $title_height + $gap; + } + if (!isset($this->y_bot_margin)) + $this->y_bot_margin = $base_margin; + + return TRUE; + } + + // Make local variables for these. (They get used a lot and I'm tired of this, this, this.) + $x_tick_label_pos = $this->x_tick_label_pos; + $x_data_label_pos = $this->x_data_label_pos; + $x_tick_pos = $this->x_tick_pos; + $x_tick_len = $this->x_tick_length; + $y_tick_label_pos = $this->y_tick_label_pos; + $y_tick_pos = $this->y_tick_pos; + $y_tick_len = $this->y_tick_length; + $y_data_label_pos = $this->y_data_label_pos; + + // For X/Y tick and label position of 'xaxis' or 'yaxis', determine if the axis happens to be + // on an edge of a plot. If it is, we need to account for the margins there. + if ($this->x_axis_position <= $this->plot_min_y) + $x_axis_pos = 'bottom'; + elseif ($this->x_axis_position >= $this->plot_max_y) + $x_axis_pos = 'top'; + else + $x_axis_pos = 'none'; + if ($this->y_axis_position <= $this->plot_min_x) + $y_axis_pos = 'left'; + elseif ($this->y_axis_position >= $this->plot_max_x) + $y_axis_pos = 'right'; + else + $y_axis_pos = 'none'; + + // Calculate the heights for X tick and data labels, and the max (used if they are overlaid): + $x_data_label_height = ($x_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('x'); + $x_tick_label_height = ($x_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('x'); + $x_max_label_height = max($x_data_label_height, $x_tick_label_height); + + // Calculate the space needed above and below the plot for X tick and X data labels: + + // Above the plot: + $tick_labels_above = ($x_tick_label_pos == 'plotup' || $x_tick_label_pos == 'both' + || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'top')); + $data_labels_above = ($x_data_label_pos == 'plotup' || $x_data_label_pos == 'both'); + if ($tick_labels_above) { + if ($data_labels_above) { + $label_height_above = $x_max_label_height; + } else { + $label_height_above = $x_tick_label_height; + } + } elseif ($data_labels_above) { + $label_height_above = $x_data_label_height; + } else { + $label_height_above = 0; + } + + // Below the plot: + $tick_labels_below = ($x_tick_label_pos == 'plotdown' || $x_tick_label_pos == 'both' + || ($x_tick_label_pos == 'xaxis' && $x_axis_pos == 'bottom')); + $data_labels_below = ($x_data_label_pos == 'plotdown' || $x_data_label_pos == 'both'); + if ($tick_labels_below) { + if ($data_labels_below) { + $label_height_below = $x_max_label_height; + } else { + $label_height_below = $x_tick_label_height; + } + } elseif ($data_labels_below) { + $label_height_below = $x_data_label_height; + } else { + $label_height_below = 0; + } + + // Calculate the width for Y tick and data labels, if on, and the max: + // Note CalcMaxDataLabelSize('y') returns 0 except for swapped X/Y plots. + $y_data_label_width = ($y_data_label_pos == 'none') ? 0 : $this->CalcMaxDataLabelSize('y'); + $y_tick_label_width = ($y_tick_label_pos == 'none') ? 0 : $this->CalcMaxTickLabelSize('y'); + $y_max_label_width = max($y_data_label_width, $y_tick_label_width); + + // Calculate the space needed left and right of the plot for Y tick and Y data labels: + // (Y data labels here are for swapped X/Y plots such has horizontal bars) + + // Left of the plot: + $tick_labels_left = ($y_tick_label_pos == 'plotleft' || $y_tick_label_pos == 'both' + || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'left')); + $data_labels_left = ($y_data_label_pos == 'plotleft' || $y_data_label_pos == 'both'); + if ($tick_labels_left) { + if ($data_labels_left) { + $label_width_left = $y_max_label_width; + } else { + $label_width_left = $y_tick_label_width; + } + } elseif ($data_labels_left) { + $label_width_left = $y_data_label_width; + } else { + $label_width_left = 0; + } + + // Right of the plot: + $tick_labels_right = ($y_tick_label_pos == 'plotright' || $y_tick_label_pos == 'both' + || ($y_tick_label_pos == 'yaxis' && $y_axis_pos == 'right')); + $data_labels_right = ($y_data_label_pos == 'plotright' || $y_data_label_pos == 'both'); + if ($tick_labels_right) { + if ($data_labels_right) { + $label_width_right = $y_max_label_width; + } else { + $label_width_right = $y_tick_label_width; + } + } elseif ($data_labels_right) { + $label_width_right = $y_data_label_width; + } else { + $label_width_right = 0; + } + + ///////// Calculate margins: + + // Calculating Top and Bottom margins: + // y_top_margin: Main title, Upper X title, X ticks and tick labels, and X data labels: + // y_bot_margin: Lower title, ticks and tick labels, and data labels: + $top_margin = $base_margin; + $bot_margin = $base_margin; + $this->x_title_top_offset = $gap; + $this->x_title_bot_offset = $gap; + + // Space for main title? + if ($title_height > 0) + $top_margin += $title_height + $gap; + + // Space for X Title? + if ($x_title_height > 0) { + $pos = $this->x_title_pos; + if ($pos == 'plotup' || $pos == 'both') + $top_margin += $x_title_height + $gap; + if ($pos == 'plotdown' || $pos == 'both') + $bot_margin += $x_title_height + $gap; + } + + // Space for X Labels above the plot? + if ($label_height_above > 0) { + $top_margin += $label_height_above + $gap; + $this->x_title_top_offset += $label_height_above + $gap; + } + + // Space for X Labels below the plot? + if ($label_height_below > 0) { + $bot_margin += $label_height_below + $gap; + $this->x_title_bot_offset += $label_height_below + $gap; + } + + // Space for X Ticks above the plot? + if ($x_tick_pos == 'plotup' || $x_tick_pos == 'both' + || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'top')) { + $top_margin += $x_tick_len; + $this->x_label_top_offset = $x_tick_len + $gap; + $this->x_title_top_offset += $x_tick_len; + } else { + // No X Ticks above the plot: + $this->x_label_top_offset = $gap; + } + + // Space for X Ticks below the plot? + if ($x_tick_pos == 'plotdown' || $x_tick_pos == 'both' + || ($x_tick_pos == 'xaxis' && $x_axis_pos == 'bottom')) { + $bot_margin += $x_tick_len; + $this->x_label_bot_offset = $x_tick_len + $gap; + $this->x_title_bot_offset += $x_tick_len; + } else { + // No X Ticks below the plot: + $this->x_label_bot_offset = $gap; + } + // Label offsets for on-axis ticks: + if ($x_tick_pos == 'xaxis') { + $this->x_label_axis_offset = $x_tick_len + $gap; + } else { + $this->x_label_axis_offset = $gap; + } + + // Calculating Left and Right margins: + // x_left_margin: Left Y title, Y ticks and tick labels: + // x_right_margin: Right Y title, Y ticks and tick labels: + $left_margin = $base_margin; + $right_margin = $base_margin; + $this->y_title_left_offset = $gap; + $this->y_title_right_offset = $gap; + + // Space for Y Title? + if ($y_title_width > 0) { + $pos = $this->y_title_pos; + if ($pos == 'plotleft' || $pos == 'both') + $left_margin += $y_title_width + $gap; + if ($pos == 'plotright' || $pos == 'both') + $right_margin += $y_title_width + $gap; + } + + // Space for Y Labels left of the plot? + if ($label_width_left > 0) { + $left_margin += $label_width_left + $gap; + $this->y_title_left_offset += $label_width_left + $gap; + } + + // Space for Y Labels right of the plot? + if ($label_width_right > 0) { + $right_margin += $label_width_right + $gap; + $this->y_title_right_offset += $label_width_right + $gap; + } + + // Space for Y Ticks left of plot? + if ($y_tick_pos == 'plotleft' || $y_tick_pos == 'both' + || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'left')) { + $left_margin += $y_tick_len; + $this->y_label_left_offset = $y_tick_len + $gap; + $this->y_title_left_offset += $y_tick_len; + } else { + // No Y Ticks left of plot: + $this->y_label_left_offset = $gap; + } + + // Space for Y Ticks right of plot? + if ($y_tick_pos == 'plotright' || $y_tick_pos == 'both' + || ($y_tick_pos == 'yaxis' && $y_axis_pos == 'right')) { + $right_margin += $y_tick_len; + $this->y_label_right_offset = $y_tick_len + $gap; + $this->y_title_right_offset += $y_tick_len; + } else { + // No Y Ticks right of plot: + $this->y_label_right_offset = $gap; + } + + // Label offsets for on-axis ticks: + if ($x_tick_pos == 'yaxis') { + $this->y_label_axis_offset = $y_tick_len + $gap; + } else { + $this->y_label_axis_offset = $gap; + } + + // Apply the minimum margins and store in the object. + // Do not set margins which were user-defined (see note at top of function). + if (!isset($this->y_top_margin)) + $this->y_top_margin = max($min_margin, $top_margin); + if (!isset($this->y_bot_margin)) + $this->y_bot_margin = max($min_margin, $bot_margin); + if (!isset($this->x_left_margin)) + $this->x_left_margin = max($min_margin, $left_margin); + if (!isset($this->x_right_margin)) + $this->x_right_margin = max($min_margin, $right_margin); + + if ($this->GetCallback('debug_scale')) { + // (Too bad compact() doesn't work on class member variables...) + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'label_height_above' => $label_height_above, + 'label_height_below' => $label_height_below, + 'label_width_left' => $label_width_left, + 'label_width_right' => $label_width_right, + 'x_tick_len' => $x_tick_len, + 'y_tick_len' => $y_tick_len, + 'x_left_margin' => $this->x_left_margin, + 'x_right_margin' => $this->x_right_margin, + 'y_top_margin' => $this->y_top_margin, + 'y_bot_margin' => $this->y_bot_margin, + 'x_label_top_offset' => $this->x_label_top_offset, + 'x_label_bot_offset' => $this->x_label_bot_offset, + 'y_label_left_offset' => $this->y_label_left_offset, + 'y_label_right_offset' => $this->y_label_right_offset, + 'x_title_top_offset' => $this->x_title_top_offset, + 'x_title_bot_offset' => $this->x_title_bot_offset, + 'y_title_left_offset' => $this->y_title_left_offset, + 'y_title_right_offset' => $this->y_title_right_offset)); + } + + return TRUE; + } + + /* + * Calculate the plot area (device coordinates) from the margins. + * (This used to be part of SetPlotAreaPixels.) + * The margins might come from SetMarginsPixels, SetPlotAreaPixels, + * or CalcMargins. + */ + protected function CalcPlotAreaPixels() + { + $this->plot_area = array($this->x_left_margin, $this->y_top_margin, + $this->image_width - $this->x_right_margin, + $this->image_height - $this->y_bot_margin); + $this->plot_area_width = $this->plot_area[2] - $this->plot_area[0]; + $this->plot_area_height = $this->plot_area[3] - $this->plot_area[1]; + + $this->DoCallback('debug_scale', __FUNCTION__, $this->plot_area); + return TRUE; + } + + /* + * Set the margins in pixels (left, right, top, bottom) + * This determines the plot area, equivalent to SetPlotAreaPixels(). + * Deferred calculations now occur in CalcPlotAreaPixels(). + */ + function SetMarginsPixels($which_lm = NULL, $which_rm = NULL, $which_tm = NULL, $which_bm = NULL) + { + $this->x_left_margin = $which_lm; + $this->x_right_margin = $which_rm; + $this->y_top_margin = $which_tm; + $this->y_bot_margin = $which_bm; + + return TRUE; + } + + /* + * Sets the limits for the plot area. + * This stores the margins, not the area. That may seem odd, but + * the idea is to make SetPlotAreaPixels and SetMarginsPixels two + * ways to accomplish the same thing, and the deferred calculations + * in CalcMargins and CalcPlotAreaPixels don't need to know which + * was used. + * (x1, y1) - Upper left corner of the plot area + * (x2, y2) - Lower right corner of the plot area + */ + function SetPlotAreaPixels($x1 = NULL, $y1 = NULL, $x2 = NULL, $y2 = NULL) + { + $this->x_left_margin = $x1; + if (isset($x2)) $this->x_right_margin = $this->image_width - $x2; + else unset($this->x_right_margin); + $this->y_top_margin = $y1; + if (isset($y2)) $this->y_bot_margin = $this->image_height - $y2; + else unset($this->y_bot_margin); + + return TRUE; + } + + /* + * Calculate the World Coordinate limits of the plot area. + * This goes with SetPlotAreaWorld, but the calculations are + * deferred until the graph is being drawn. + * Uses and sets: plot_min_x, plot_max_x, plot_min_y, plot_max_y + * These can be user-supplied or NULL to auto-calculate. + * Pre-requisites: FindDataLimits() calculates min_x, max_x, min_y, max_y + * which are the limits of the data to be plotted. + * + * The general method is this: + * If any part of the range is user-defined (via SetPlotAreaWorld), + * use the user-defined value. + * Else, if this is an implicitly-defined independent variable, + * use the fixed range of 0 to (max+1). + * Else, if this is an explicitly-defined independent variable, + * use the exact data range (min to max). + * Else, this is the dependent variable, so define a range which + * includes and exceeds the data range by a bit. + */ + protected function CalcPlotAreaWorld() + { + // Data array omits X or Y? + $implied_x = $this->datatype_implied && !$this->datatype_swapped_xy; + $implied_y = $this->datatype_implied && $this->datatype_swapped_xy; + + if (isset($this->plot_min_x) && $this->plot_min_x !== '') + $xmin = $this->plot_min_x; // Use user-provided value + elseif ($implied_x) + $xmin = 0; // Implied X starts at zero + elseif ($this->datatype_swapped_xy) + // If X is the dependent variable, leave some room below. + $xmin = floor($this->min_x - abs($this->min_x) * 0.1); + else + $xmin = $this->min_x; // Otherwise just start at the min data X + + if (isset($this->plot_max_x) && $this->plot_max_x !== '') + $xmax = $this->plot_max_x; // Use user-provided value + elseif ($implied_x) + $xmax = $this->max_x + 1; // Implied X ends after last value + elseif ($this->datatype_swapped_xy) + // If X is the dependent variable, leave some room above. + $xmax = ceil($this->max_x + abs($this->max_x) * 0.1); + else + $xmax = $this->max_x; // Otherwise just end at the max data X + + if (isset($this->plot_min_y) && $this->plot_min_y !== '') + $ymin = $this->plot_min_y; // Use user-provided value + elseif ($implied_y) + $ymin = 0; // Implied Y starts at zero + elseif ($this->datatype_swapped_xy) + $ymin = $this->min_y; // Start at min data Y + else + // If Y is the dependent variable, leave some room below. + $ymin = floor($this->min_y - abs($this->min_y) * 0.1); + + if (isset($this->plot_max_y) && $this->plot_max_y !== '') + $ymax = $this->plot_max_y; // Use user-provided value + elseif ($implied_y) + $ymax = $this->max_y + 1; // Implied Y ends after last value + elseif ($this->datatype_swapped_xy) + $ymax = $this->max_y; // End at max data Y + else + // If Y is the dependent variable, leave some room above. + $ymax = ceil($this->max_y + abs($this->max_y) * 0.1); + + // Error checking + + if ($ymin == $ymax) + $ymax++; + if ($xmin == $xmax) + $xmax++; + + if ($this->yscale_type == 'log') { + if ($ymin <= 0) { + $ymin = 1; + } + if ($ymax <= 0) { + // Note: Error messages reference the user function, not this function. + return $this->PrintError('SetPlotAreaWorld(): Log plots need data greater than 0'); + } + } + + if ($ymax <= $ymin) { + return $this->PrintError('SetPlotAreaWorld(): Error in data - max not greater than min'); + } + + $this->plot_min_x = $xmin; + $this->plot_max_x = $xmax; + $this->plot_min_y = $ymin; + $this->plot_max_y = $ymax; + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'plot_min_x' => $this->plot_min_x, 'plot_min_y' => $this->plot_min_y, + 'plot_max_x' => $this->plot_max_x, 'plot_max_y' => $this->plot_max_y)); + } + return TRUE; + } + + /* + * Stores the desired World Coordinate range of the plot. + * The user calls this to force one or more of the range limits to + * specific values. Anything not set will be calculated in CalcPlotAreaWorld(). + */ + function SetPlotAreaWorld($xmin=NULL, $ymin=NULL, $xmax=NULL, $ymax=NULL) + { + $this->plot_min_x = $xmin; + $this->plot_max_x = $xmax; + $this->plot_min_y = $ymin; + $this->plot_max_y = $ymax; + return TRUE; + } + + /* + * Calculate the width (or height) of bars for bar plots. + * $stacked : If true, this is a stacked bar plot (1 bar per group). + * $verticals : If false, this is a horizontal bar plot. + * This calculates: + * record_bar_width : Allocated width for each bar (including gaps) + * actual_bar_width : Actual drawn width of each bar + * bar_adjust_gap : Gap on each side of each bar (0 if they touch) + * For the case $verticals=False, horizontal bars are being drawn, + * but the same variable names are used. Think of "bar_width" as being + * the width if you are standing on the Y axis looking towards positive X. + */ + protected function CalcBarWidths($stacked, $verticals) + { + // group_width is the width of a group, including padding + if ($verticals) { + $group_width = $this->plot_area_width / $this->num_data_rows; + } else { + $group_width = $this->plot_area_height / $this->num_data_rows; + } + + // Actual number of bar spaces in the group. This includes the drawn bars, and + // 'bar_extra_space'-worth of extra bars. + if ($stacked) { + $num_spots = 1 + $this->bar_extra_space; + } else { + $num_spots = $this->data_columns + $this->bar_extra_space; + } + + // record_bar_width is the width of each bar's allocated area. + // If bar_width_adjust=1 this is the width of the bar, otherwise + // the bar is centered inside record_bar_width. + // The equation is: + // group_frac_width * group_width = record_bar_width * num_spots + $this->record_bar_width = $this->group_frac_width * $group_width / $num_spots; + + // Note that the extra space due to group_frac_width and bar_extra_space will be + // evenly divided on each side of the group: the drawn bars are centered in the group. + + // Within each bar's allocated space, if bar_width_adjust=1 the bar fills the + // space, otherwise it is centered. + // This is the actual drawn bar width: + $this->actual_bar_width = $this->record_bar_width * $this->bar_width_adjust; + // This is the gap on each side of the bar (0 if bar_width_adjust=1): + $this->bar_adjust_gap = ($this->record_bar_width - $this->actual_bar_width) / 2; + + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'record_bar_width' => $this->record_bar_width, + 'actual_bar_width' => $this->actual_bar_width, + 'bar_adjust_gap' => $this->bar_adjust_gap)); + } + return TRUE; + } + + /* + * Calculate X and Y Axis Positions, world coordinates. + * This needs the min/max x/y range set by CalcPlotAreaWorld. + * It adjusts or sets x_axis_position and y_axis_position per the data. + * Empty string means the values need to be calculated; otherwise they + * are supplied but need to be validated against the World area. + * + * Note: This used to be in CalcTranslation, but CalcMargins needs it too. + * This does not calculate the pixel values of the axes. That happens in + * CalcTranslation, after scaling is set up (which has to happen after + * margins are set up). + * + * For vertical plots, the X axis defaults to Y=0 if that is inside the plot range, else whichever + * of the top or bottom that has the smallest absolute value (that is, the value closest to 0). + * The Y axis defaults to the left edge. For horizontal plots, the axis roles and defaults are switched. + */ + protected function CalcAxisPositions() + { + // Validate user-provided X axis position, or calculate a default if not provided: + if ($this->x_axis_position !== '') { + // Force user-provided X axis position to be within the plot range: + $this->x_axis_position = min(max($this->plot_min_y, $this->x_axis_position), $this->plot_max_y); + } elseif ($this->yscale_type == 'log') { + // Always use 1 for X axis position on log scale plots. + $this->x_axis_position = 1; + } elseif ($this->datatype_swapped_xy || $this->plot_min_y > 0) { + // Horizontal plot, or Vertical Plot with all Y > 0: Place X axis on the bottom. + $this->x_axis_position = $this->plot_min_y; + } elseif ($this->plot_max_y < 0) { + // Vertical plot with all Y < 0, so place the X axis at the top. + $this->x_axis_position = $this->plot_max_y; + } else { + // Vertical plot range includes Y=0, so place X axis at 0. + $this->x_axis_position = 0; + } + + // Validate user-provided Y axis position, or calculate a default if not provided: + if ($this->y_axis_position !== '') { + // Force user-provided Y axis position to be within the plot range: + $this->y_axis_position = min(max($this->plot_min_x, $this->y_axis_position), $this->plot_max_x); + } elseif ($this->xscale_type == 'log') { + // Always use 1 for Y axis position on log scale plots. + $this->y_axis_position = 1; + } elseif (!$this->datatype_swapped_xy || $this->plot_min_x > 0) { + // Vertical plot, or Horizontal Plot with all X > 0: Place Y axis on left side. + $this->y_axis_position = $this->plot_min_x; + } elseif ($this->plot_max_x < 0) { + // Horizontal plot with all X < 0, so place the Y axis on the right side. + $this->y_axis_position = $this->plot_max_x; + } else { + // Horizontal plot range includes X=0: place Y axis at 0. + $this->y_axis_position = 0; + } + + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'x_axis_position' => $this->x_axis_position, + 'y_axis_position' => $this->y_axis_position)); + } + + return TRUE; + } + + /* + * Calculates scaling stuff... + */ + protected function CalcTranslation() + { + if ($this->plot_max_x - $this->plot_min_x == 0) { // Check for div by 0 + $this->xscale = 0; + } else { + if ($this->xscale_type == 'log') { + $this->xscale = $this->plot_area_width / + (log10($this->plot_max_x) - log10($this->plot_min_x)); + } else { + $this->xscale = $this->plot_area_width / ($this->plot_max_x - $this->plot_min_x); + } + } + + if ($this->plot_max_y - $this->plot_min_y == 0) { // Check for div by 0 + $this->yscale = 0; + } else { + if ($this->yscale_type == 'log') { + $this->yscale = $this->plot_area_height / + (log10($this->plot_max_y) - log10($this->plot_min_y)); + } else { + $this->yscale = $this->plot_area_height / ($this->plot_max_y - $this->plot_min_y); + } + } + // GD defines x = 0 at left and y = 0 at TOP so -/+ respectively + if ($this->xscale_type == 'log') { + $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * log10($this->plot_min_x) ); + } else { + $this->plot_origin_x = $this->plot_area[0] - ($this->xscale * $this->plot_min_x); + } + if ($this->yscale_type == 'log') { + $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * log10($this->plot_min_y)); + } else { + $this->plot_origin_y = $this->plot_area[3] + ($this->yscale * $this->plot_min_y); + } + + // Convert axis positions to device coordinates: + $this->y_axis_x_pixels = $this->xtr($this->y_axis_position); + $this->x_axis_y_pixels = $this->ytr($this->x_axis_position); + + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'xscale' => $this->xscale, 'yscale' => $this->yscale, + 'plot_origin_x' => $this->plot_origin_x, 'plot_origin_y' => $this->plot_origin_y, + 'y_axis_x_pixels' => $this->y_axis_x_pixels, + 'x_axis_y_pixels' => $this->x_axis_y_pixels)); + } + + return TRUE; + } + + /* + * Translate X world coordinate into pixel coordinate + * See CalcTranslation() for calculation of xscale. + * Note: This function should be 'protected', but is left public for historical reasons. + * See GetDeviceXY() for a preferred public method. + */ + function xtr($x_world) + { + if ($this->xscale_type == 'log') { + $x_pixels = $this->plot_origin_x + log10($x_world) * $this->xscale ; + } else { + $x_pixels = $this->plot_origin_x + $x_world * $this->xscale ; + } + return round($x_pixels); + } + + /* + * Translate Y world coordinate into pixel coordinate. + * See CalcTranslation() for calculation of yscale. + * Note: This function should be 'protected', but is left public for historical reasons. + * See GetDeviceXY() for a preferred public method. + */ + function ytr($y_world) + { + if ($this->yscale_type == 'log') { + //minus because GD defines y = 0 at top. doh! + $y_pixels = $this->plot_origin_y - log10($y_world) * $this->yscale ; + } else { + $y_pixels = $this->plot_origin_y - $y_world * $this->yscale ; + } + return round($y_pixels); + } + + /* A public interface to xtr and ytr. Translates (x,y) in world coordinates + * to (x,y) in device coordinates and returns them as an array. + * Usage is: list($x_pixel, $y_pixel) = $plot->GetDeviceXY($x_world, $y_world) + */ + function GetDeviceXY($x_world, $y_world) + { + if (!isset($this->xscale)) { + return $this->PrintError("GetDeviceXY() was called before translation factors were calculated"); + } + return array($this->xtr($x_world), $this->ytr($y_world)); + } + + /* + * Calculate tick parameters: Start, end, and delta values. This is used + * by both DrawXTicks() and DrawYTicks(). + * This currently uses the same simplistic method previously used by + * PHPlot (basically just range/10), but splitting this out into its + * own function is the first step in replacing the method. + * This is also used by CalcMaxTickSize() for CalcMargins(). + * + * $which : 'x' or 'y' : Which tick parameters to calculate + * + * Returns an array of 3 elements: tick_start, tick_end, tick_step + */ + protected function CalcTicks($which) + { + if ($which == 'x') { + $num_ticks = $this->num_x_ticks; + $tick_inc = $this->x_tick_inc; + $data_max = $this->plot_max_x; + $data_min = $this->plot_min_x; + $skip_lo = $this->skip_left_tick; + $skip_hi = $this->skip_right_tick; + } elseif ($which == 'y') { + $num_ticks = $this->num_y_ticks; + $tick_inc = $this->y_tick_inc; + $data_max = $this->plot_max_y; + $data_min = $this->plot_min_y; + $skip_lo = $this->skip_bottom_tick; + $skip_hi = $this->skip_top_tick; + } else { + return $this->PrintError("CalcTicks: Invalid usage ($which)"); + } + + if (!empty($tick_inc)) { + $tick_step = $tick_inc; + } elseif (!empty($num_ticks)) { + $tick_step = ($data_max - $data_min) / $num_ticks; + } else { + $tick_step = ($data_max - $data_min) / 10; + } + + // NOTE: When working with floats, because of approximations when adding $tick_step, + // the value may not quite reach the end, or may exceed it very slightly. + // So apply a "fudge" factor. + $tick_start = (double)$data_min; + $tick_end = (double)$data_max + ($data_max - $data_min) / 10000.0; + + if ($skip_lo) + $tick_start += $tick_step; + + if ($skip_hi) + $tick_end -= $tick_step; + + return array($tick_start, $tick_end, $tick_step); + } + + /* + * Calculate the size of the biggest tick label. This is used by CalcMargins(). + * For 'x' ticks, it returns the height . For 'y' ticks, it returns the width. + * This means height along Y, or width along X - not relative to the text angle. + * That is what we need to calculate the needed margin space. + * (Previous versions of PHPlot estimated this, using the maximum X or Y value, + * or maybe the longest string. That doesn't work. -10 is longer than 9, etc. + * So this gets the actual size of each label, slow as that may be. + */ + protected function CalcMaxTickLabelSize($which) + { + list($tick_start, $tick_end, $tick_step) = $this->CalcTicks($which); + + if ($which == 'x') { + $font = $this->fonts['x_label']; + $angle = $this->x_label_angle; + } elseif ($which == 'y') { + $font = $this->fonts['y_label']; + $angle = $this->y_label_angle; + } else { + return $this->PrintError("CalcMaxTickLabelSize: Invalid usage ($which)"); + } + + $max_width = 0; + $max_height = 0; + + // Loop over ticks, same as DrawXTicks and DrawYTicks: + // Avoid cumulative round-off errors from $val += $delta + $n = 0; + $tick_val = $tick_start; + while ($tick_val <= $tick_end) { + $tick_label = $this->FormatLabel($which, $tick_val); + list($width, $height) = $this->SizeText($font, $angle, $tick_label); + if ($width > $max_width) $max_width = $width; + if ($height > $max_height) $max_height = $height; + $tick_val = $tick_start + ++$n * $tick_step; + } + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'which' => $which, 'height' => $max_height, 'width' => $max_width)); + } + + if ($which == 'x') + return $max_height; + return $max_width; + } + + /* + * Calculate the size of the biggest data label. This is used by CalcMargins(). + * For $which='x', it returns the height of labels along the top or bottom. + * For $which='y', it returns the width of labels along the left or right sides. + * There is only one set of data labels (the first position in each data record). + * They normally go along the top or bottom (or both). If the data type indicates + * X/Y swapping (which is used for horizontal bar charts), the data labels go + * along the sides instead. So CalcMaxDataLabelSize('x') returns 0 if the + * data is X/Y swapped, and CalcMaxDataLabelSize('y') returns 0 if the data is + * is not X/Y swapped. + */ + protected function CalcMaxDataLabelSize($which = 'x') + { + if ($which == 'x') { + if ($this->datatype_swapped_xy) + return 0; // Shortcut: labels aren't on top/bottom. + $font = $this->fonts['x_label']; + $angle = $this->x_data_label_angle; + $format_code = 'xd'; + } elseif ($which == 'y') { + if (!$this->datatype_swapped_xy) + return 0; // Shortcut: labels aren't on left/right. + $font = $this->fonts['y_label']; + $angle = $this->y_data_label_angle; + $format_code = 'yd'; + } else { + return $this->PrintError("CalcMaxDataLabelSize: Invalid usage ($which)"); + } + $max_width = 0; + $max_height = 0; + + // Loop over all data labels and find the biggest: + for ($i = 0; $i < $this->num_data_rows; $i++) { + $label = $this->FormatLabel($format_code, $this->data[$i][0]); + list($width, $height) = $this->SizeText($font, $angle, $label); + if ($width > $max_width) $max_width = $width; + if ($height > $max_height) $max_height = $height; + } + if ($this->GetCallback('debug_scale')) { + $this->DoCallback('debug_scale', __FUNCTION__, array( + 'height' => $max_height, 'width' => $max_width)); + } + + if ($this->datatype_swapped_xy) + return $max_width; + return $max_height; + } + + /* + * Set grid control defaults. + * X grid defaults off, Y grid defaults on, except the reverse is true + * with swapped graphs such as horizontal bars. + */ + protected function CalcGridSettings() + { + if (!isset($this->draw_x_grid)) + $this->draw_x_grid = $this->datatype_swapped_xy; + if (!isset($this->draw_y_grid)) + $this->draw_y_grid = !$this->datatype_swapped_xy; + } + + /* + * Helper for CheckLabels() - determine if there are any non-empty labels. + * Returns True if all data labels are empty, else False. + */ + protected function CheckLabelsAllEmpty() + { + for ($i = 0; $i < $this->num_data_rows; $i++) + if ($this->data[$i][0] !== '') return FALSE; + return TRUE; + } + + /* + * Check and set label parameters. This handles deferred processing for label + * positioning and other label-related parameters. + * Copy label_format from 'x' to 'xd', and 'y' to 'yd', if not already set. + * Set x_data_label_angle from x_label_angle, if not already set. + * Apply defaults to X and Y tick and data label positions. + * Note: the label strings in the data array are used as X data labels in + * the normal case, but as Y data labels in the swapped X/Y case. + */ + protected function CheckLabels() + { + // The X and Y data labels are formatted the same as X and Y tick labels, + // unless overridden. Check and apply defaults for FormatLabel here: + if (empty($this->label_format['xd']) && !empty($this->label_format['x'])) + $this->label_format['xd'] = $this->label_format['x']; + if (empty($this->label_format['yd']) && !empty($this->label_format['y'])) + $this->label_format['yd'] = $this->label_format['y']; + + // The X tick label angle setting controls X data label angles too, + // unless overridden. Check and apply the default here: + if (!isset($this->x_data_label_angle)) + $this->x_data_label_angle = $this->x_label_angle; + // Note: Y data label angle defaults to zero, unlike X, + // for compatibility with older releases. + + // X Label position fixups, for x_data_label_pos and x_tick_label_pos: + if ($this->datatype_swapped_xy) { + // Just apply defaults - there is no position conflict for X labels. + if (!isset($this->x_tick_label_pos)) + $this->x_tick_label_pos = 'plotdown'; + if (!isset($this->x_data_label_pos)) + $this->x_data_label_pos = 'none'; + } else { + // Apply defaults but do not allow conflict between tick and data labels. + if (isset($this->x_data_label_pos)) { + if (!isset($this->x_tick_label_pos)) { + // Case: data_label_pos is set, tick_label_pos needs a default: + if ($this->x_data_label_pos == 'none') + $this->x_tick_label_pos = 'plotdown'; + else + $this->x_tick_label_pos = 'none'; + } + } elseif (isset($this->x_tick_label_pos)) { + // Case: tick_label_pos is set, data_label_pos needs a default: + if ($this->x_tick_label_pos == 'none') + $this->x_data_label_pos = 'plotdown'; + else + $this->x_data_label_pos = 'none'; + } else { + // Case: Neither tick_label_pos nor data_label_pos is set. + // We do not want them to be both on (as PHPlot used to do in this case). + // Turn on data labels if any were supplied, else tick labels. + if ($this->CheckLabelsAllEmpty()) { + $this->x_data_label_pos = 'none'; + $this->x_tick_label_pos = 'plotdown'; + } else { + $this->x_data_label_pos = 'plotdown'; + $this->x_tick_label_pos = 'none'; + } + } + } + + // Y Label position fixups, for y_data_label_pos and y_tick_label_pos: + if (!$this->datatype_swapped_xy) { + // Just apply defaults - there is no position conflict. + if (!isset($this->y_tick_label_pos)) + $this->y_tick_label_pos = 'plotleft'; + if (!isset($this->y_data_label_pos)) + $this->y_data_label_pos = 'none'; + } else { + // Apply defaults but do not allow conflict between tick and data labels. + if (isset($this->y_data_label_pos)) { + if (!isset($this->y_tick_label_pos)) { + // Case: data_label_pos is set, tick_label_pos needs a default: + if ($this->y_data_label_pos == 'none') + $this->y_tick_label_pos = 'plotleft'; + else + $this->y_tick_label_pos = 'none'; + } + } elseif (isset($this->y_tick_label_pos)) { + // Case: tick_label_pos is set, data_label_pos needs a default: + if ($this->y_tick_label_pos == 'none') + $this->y_data_label_pos = 'plotleft'; + else + $this->y_data_label_pos = 'none'; + } else { + // Case: Neither tick_label_pos nor data_label_pos is set. + // Turn on data labels if any were supplied, else tick labels. + if ($this->CheckLabelsAllEmpty()) { + $this->y_data_label_pos = 'none'; + $this->y_tick_label_pos = 'plotleft'; + } else { + $this->y_data_label_pos = 'plotleft'; + $this->y_tick_label_pos = 'none'; + } + } + } + return TRUE; + } + + /* + * Formats a tick or data label. + * which_pos - 'x', 'xd', 'y', or 'yd', selects formatting controls. + * x, y are for tick labels; xd, yd are for data labels. + * which_lab - String to format as a label. + * Credits: Time formatting suggested by Marlin Viss + * Custom formatting suggested by zer0x333 + * Notes: + * Type 'title' is obsolete and retained for compatibility. + * Class variable 'data_units_text' is retained as a suffix for 'data' type formatting for + * backward compatibility. Since there was never a function/method to set it, there + * could be somebody out there who sets it directly in the object. + */ + protected function FormatLabel($which_pos, $which_lab) + { + // Assign a reference shortcut to the label format controls. + // Note CheckLabels() made sure the 'xd' and 'yd' arrays are set. + $format =& $this->label_format[$which_pos]; + + // Don't format empty strings (especially as time or numbers), or if no type was set. + if ($which_lab !== '' && !empty($format['type'])) { + switch ($format['type']) { + case 'title': // Note: This is obsolete + $which_lab = @ $this->data[$which_lab][0]; + break; + case 'data': + $which_lab = $format['prefix'] + . $this->number_format($which_lab, $format['precision']) + . $this->data_units_text // Obsolete + . $format['suffix']; + break; + case 'time': + $which_lab = strftime($format['time_format'], $which_lab); + break; + case 'printf': + $which_lab = sprintf($format['printf_format'], $which_lab); + break; + case 'custom': + $which_lab = call_user_func($format['custom_callback'], $which_lab, $format['custom_arg']); + break; + + } + } + return $which_lab; + } + +///////////////////////////////////////////// +/////////////// TICKS +///////////////////////////////////////////// + + /* + * Set the step (interval) between X ticks. + * Use either this or SetNumXTicks(), not both, to control the X tick marks. + */ + function SetXTickIncrement($which_ti='') + { + $this->x_tick_inc = $which_ti; + if (!empty($which_ti)) { + $this->num_x_ticks = ''; + } + return TRUE; + } + + /* + * Set the step (interval) between Y ticks. + * Use either this or SetNumYTicks(), not both, to control the Y tick marks. + */ + function SetYTickIncrement($which_ti='') + { + $this->y_tick_inc = $which_ti; + if (!empty($which_ti)) { + $this->num_y_ticks = ''; + } + return TRUE; + } + + /* + * Set the number of X tick marks. + * Use either this or SetXTickIncrement(), not both, to control the X tick marks. + */ + function SetNumXTicks($which_nt='') + { + $this->num_x_ticks = $which_nt; + if (!empty($which_nt)) { + $this->x_tick_inc = ''; + } + return TRUE; + } + + /* + * Set the number of Y tick marks. + * Use either this or SetYTickIncrement(), not both, to control the Y tick marks. + */ + function SetNumYTicks($which_nt='') + { + $this->num_y_ticks = $which_nt; + if (!empty($which_nt)) { + $this->y_tick_inc = ''; //either use num_y_ticks or y_tick_inc, not both + } + return TRUE; + } + + /* + * Set the position for the X tick marks. + * These can be above the plot, below, both positions, at the X axis, or suppressed. + */ + function SetXTickPos($which_tp) + { + $this->x_tick_pos = $this->CheckOption($which_tp, 'plotdown, plotup, both, xaxis, none', + __FUNCTION__); + return (boolean)$this->x_tick_pos; + } + + /* + * Set the position for the Y tick marks. + * These can be left of the plot, right, both positions, at the Y axis, or suppressed. + */ + function SetYTickPos($which_tp) + { + $this->y_tick_pos = $this->CheckOption($which_tp, 'plotleft, plotright, both, yaxis, none', + __FUNCTION__); + return (boolean)$this->y_tick_pos; + } + + /* + * Skip the top-most Y axis tick mark and label if $skip is true. + */ + function SetSkipTopTick($skip) + { + $this->skip_top_tick = (bool)$skip; + return TRUE; + } + + /* + * Skip the bottom-most Y axis tick mark and label if $skip is true. + */ + function SetSkipBottomTick($skip) + { + $this->skip_bottom_tick = (bool)$skip; + return TRUE; + } + + /* + * Skip the left-most X axis tick mark and label if $skip is true. + */ + function SetSkipLeftTick($skip) + { + $this->skip_left_tick = (bool)$skip; + return TRUE; + } + + /* + * Skip the right-most X axis tick mark and label if $skip is true. + */ + function SetSkipRightTick($skip) + { + $this->skip_right_tick = (bool)$skip; + return TRUE; + } + + /* + * Set the outer length of X tick marks to $which_xln pixels. + * This is the part of the tick mark that sticks out from the plot area. + */ + function SetXTickLength($which_xln) + { + $this->x_tick_length = $which_xln; + return TRUE; + } + + /* + * Set the outer length of Y tick marks to $which_yln pixels. + * This is the part of the tick mark that sticks out from the plot area. + */ + function SetYTickLength($which_yln) + { + $this->y_tick_length = $which_yln; + return TRUE; + } + + /* + * Set the crossing length of X tick marks to $which_xc pixels. + * This is the part of the tick mark that sticks into the plot area. + */ + function SetXTickCrossing($which_xc) + { + $this->x_tick_cross = $which_xc; + return TRUE; + } + + /* + * Set the crossing length of Y tick marks to $which_yc pixels. + * This is the part of the tick mark that sticks into the plot area. + */ + function SetYTickCrossing($which_yc) + { + $this->y_tick_cross = $which_yc; + return TRUE; + } + +///////////////////////////////////////////// +//////////////////// GENERIC DRAWING +///////////////////////////////////////////// + + /* + * Fill the image background, with a tiled image file or solid color. + */ + protected function DrawBackground() + { + // Don't draw this twice if drawing two plots on one image + if (empty($this->done['background'])) { + if (isset($this->bgimg)) { // If bgimg is defined, use it + $this->tile_img($this->bgimg, 0, 0, $this->image_width, $this->image_height, $this->bgmode); + } else { // Else use solid color + ImageFilledRectangle($this->img, 0, 0, $this->image_width, $this->image_height, + $this->ndx_bg_color); + } + $this->done['background'] = TRUE; + } + return TRUE; + } + + /* + * Fill the plot area background, with a tiled image file or solid color. + */ + protected function DrawPlotAreaBackground() + { + if (isset($this->plotbgimg)) { + $this->tile_img($this->plotbgimg, $this->plot_area[0], $this->plot_area[1], + $this->plot_area_width, $this->plot_area_height, $this->plotbgmode); + } elseif ($this->draw_plot_area_background) { + ImageFilledRectangle($this->img, $this->plot_area[0], $this->plot_area[1], + $this->plot_area[2], $this->plot_area[3], $this->ndx_plot_bg_color); + } + return TRUE; + } + + /* + * Tiles an image at some given coordinates. + * $file : Filename of the picture to be used as tile. + * $xorig : X device coordinate of where the tile is to begin. + * $yorig : Y device coordinate of where the tile is to begin. + * $width : Width of the area to be tiled. + * $height : Height of the area to be tiled. + * $mode : Tiling mode. One of 'centeredtile', 'tile', 'scale'. + */ + protected function tile_img($file, $xorig, $yorig, $width, $height, $mode) + { + $im = $this->GetImage($file, $tile_width, $tile_height); + if (!$im) + return FALSE; // GetImage already produced an error message. + + if ($mode == 'scale') { + imagecopyresampled($this->img, $im, $xorig, $yorig, 0, 0, $width, $height, + $tile_width, $tile_height); + return TRUE; + } + + if ($mode == 'centeredtile') { + $x0 = - floor($tile_width/2); // Make the tile look better + $y0 = - floor($tile_height/2); + } else { // Accept anything else as $mode == 'tile' + $x0 = 0; + $y0 = 0; + } + + // Draw the tile onto a temporary image first. + $tmp = imagecreate($width, $height); + if (! $tmp) + return $this->PrintError('tile_img(): Could not create image resource.'); + + for ($x = $x0; $x < $width; $x += $tile_width) + for ($y = $y0; $y < $height; $y += $tile_height) + imagecopy($tmp, $im, $x, $y, 0, 0, $tile_width, $tile_height); + + // Copy the temporary image onto the final one. + imagecopy($this->img, $tmp, $xorig, $yorig, 0,0, $width, $height); + + // Free resources + imagedestroy($tmp); + imagedestroy($im); + + return TRUE; + } + + /* + * Return the image border width. + * This is used by CalcMargins() and DrawImageBorder(). + */ + protected function GetImageBorderWidth() + { + if ($this->image_border_type == 'none') + return 0; // No border + if (!empty($this->image_border_width)) + return $this->image_border_width; // Specified border width + if ($this->image_border_type == 'raised') + return 2; // Default for raised border is 2 pixels. + return 1; // Default for other border types is 1 pixel. + } + + /* + * Draws a border around the final image. + * Note: 'plain' draws a flat border using the dark shade of the border color. + * This probably should have been written to use the actual border color, but + * it is too late to fix it without changing plot appearances. Therefore a + * new type 'solid' was added to use the SetImageBorderColor color. + */ + protected function DrawImageBorder() + { + // Do nothing if already drawn, or if no border has been set. + if ($this->image_border_type == 'none' || !empty($this->done['border'])) + return TRUE; + $width = $this->GetImageBorderWidth(); + $color1 = $this->ndx_i_border; + $color2 = $this->ndx_i_border_dark; + $ex = $this->image_width - 1; + $ey = $this->image_height - 1; + switch ($this->image_border_type) { + case 'raised': + // Top and left lines use border color, right and bottom use the darker shade. + // Drawing order matters in the upper right and lower left corners. + for ($i = 0; $i < $width; $i++, $ex--, $ey--) { + imageline($this->img, $i, $i, $ex, $i, $color1); // Top + imageline($this->img, $ex, $i, $ex, $ey, $color2); // Right + imageline($this->img, $i, $i, $i, $ey, $color1); // Left + imageline($this->img, $i, $ey, $ex, $ey, $color2); // Bottom + } + break; + case 'plain': // See note above re colors + $color1 = $color2; + // Fall through + case 'solid': + for ($i = 0; $i < $width; $i++, $ex--, $ey--) { + imagerectangle($this->img, $i, $i, $ex, $ey, $color1); + } + break; + default: + return $this->PrintError( + "DrawImageBorder(): unknown image_border_type: '$this->image_border_type'"); + } + $this->done['border'] = TRUE; // Border should only be drawn once per image. + return TRUE; + } + + /* + * Draws the main title on the graph. + * The title must not be drawn more than once (in the case of multiple plots + * on the image), because TTF text antialiasing makes it look bad. + */ + protected function DrawTitle() + { + if (!empty($this->done['title']) || $this->title_txt === '') + return TRUE; + + // Center of the image: + $xpos = $this->image_width / 2; + + // Place it at almost at the top + $ypos = $this->title_offset; + + $this->DrawText($this->fonts['title'], 0, $xpos, $ypos, + $this->ndx_title_color, $this->title_txt, 'center', 'top'); + + $this->done['title'] = TRUE; + return TRUE; + } + + /* + * Draws the X-Axis Title + */ + protected function DrawXTitle() + { + if ($this->x_title_pos == 'none') + return TRUE; + + // Center of the plot + $xpos = ($this->plot_area[2] + $this->plot_area[0]) / 2; + + // Upper title + if ($this->x_title_pos == 'plotup' || $this->x_title_pos == 'both') { + $ypos = $this->plot_area[1] - $this->x_title_top_offset; + $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_x_title_color, + $this->x_title_txt, 'center', 'bottom'); + } + // Lower title + if ($this->x_title_pos == 'plotdown' || $this->x_title_pos == 'both') { + $ypos = $this->plot_area[3] + $this->x_title_bot_offset; + $this->DrawText($this->fonts['x_title'], 0, $xpos, $ypos, $this->ndx_x_title_color, + $this->x_title_txt, 'center', 'top'); + } + return TRUE; + } + + /* + * Draws the Y-Axis Title + */ + protected function DrawYTitle() + { + if ($this->y_title_pos == 'none') + return TRUE; + + // Center the title vertically to the plot area + $ypos = ($this->plot_area[3] + $this->plot_area[1]) / 2; + + if ($this->y_title_pos == 'plotleft' || $this->y_title_pos == 'both') { + $xpos = $this->plot_area[0] - $this->y_title_left_offset; + $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_y_title_color, + $this->y_title_txt, 'right', 'center'); + } + if ($this->y_title_pos == 'plotright' || $this->y_title_pos == 'both') { + $xpos = $this->plot_area[2] + $this->y_title_right_offset; + $this->DrawText($this->fonts['y_title'], 90, $xpos, $ypos, $this->ndx_y_title_color, + $this->y_title_txt, 'left', 'center'); + } + + return TRUE; + } + + /* + * Draw the X axis, including ticks and labels, and X (vertical) grid lines. + */ + protected function DrawXAxis() + { + // Draw ticks, labels and grid + $this->DrawXTicks(); + + //Draw X Axis at Y = x_axis_y_pixels, unless suppressed (See SetXAxisPosition) + if (empty($this->suppress_x_axis)) { + ImageLine($this->img, $this->plot_area[0]+1, $this->x_axis_y_pixels, + $this->plot_area[2]-1, $this->x_axis_y_pixels, $this->ndx_grid_color); + } + return TRUE; + } + + /* + * Draw the Y axis, including ticks and labels, and Y (horizontal) grid lines. + * Horizontal grid lines overwrite horizontal axis with y=0, so call this first, then DrawXAxis() + */ + protected function DrawYAxis() + { + // Draw ticks, labels and grid + $this->DrawYTicks(); + + // Draw Y axis at X = y_axis_x_pixels, unless suppressed (See SetYAxisPosition) + if (empty($this->suppress_y_axis)) { + ImageLine($this->img, $this->y_axis_x_pixels, $this->plot_area[1], + $this->y_axis_x_pixels, $this->plot_area[3], $this->ndx_grid_color); + } + return TRUE; + } + + /* + * Draw one X tick mark and its tick label. + * $which_xlab : Formatted X value for the label. + * $which_xpix : X device coordinate for this tick mark. + */ + protected function DrawXTick($which_xlab, $which_xpix) + { + // Ticks on X axis + if ($this->x_tick_pos == 'xaxis') { + ImageLine($this->img, $which_xpix, $this->x_axis_y_pixels - $this->x_tick_cross, + $which_xpix, $this->x_axis_y_pixels + $this->x_tick_length, $this->ndx_tick_color); + } + + // Ticks on top of the Plot Area + if ($this->x_tick_pos == 'plotup' || $this->x_tick_pos == 'both') { + ImageLine($this->img, $which_xpix, $this->plot_area[1] - $this->x_tick_length, + $which_xpix, $this->plot_area[1] + $this->x_tick_cross, $this->ndx_tick_color); + } + + // Ticks on bottom of Plot Area + if ($this->x_tick_pos == 'plotdown' || $this->x_tick_pos == 'both') { + ImageLine($this->img, $which_xpix, $this->plot_area[3] + $this->x_tick_length, + $which_xpix, $this->plot_area[3] - $this->x_tick_cross, $this->ndx_tick_color); + } + + // Label on X axis + if ($this->x_tick_label_pos == 'xaxis') { + $this->DrawText($this->fonts['x_label'], $this->x_label_angle, + $which_xpix, $this->x_axis_y_pixels + $this->x_label_axis_offset, + $this->ndx_text_color, $which_xlab, 'center', 'top'); + } + + // Label on top of the Plot Area + if ($this->x_tick_label_pos == 'plotup' || $this->x_tick_label_pos == 'both') { + $this->DrawText($this->fonts['x_label'], $this->x_label_angle, + $which_xpix, $this->plot_area[1] - $this->x_label_top_offset, + $this->ndx_text_color, $which_xlab, 'center', 'bottom'); + } + + // Label on bottom of the Plot Area + if ($this->x_tick_label_pos == 'plotdown' || $this->x_tick_label_pos == 'both') { + $this->DrawText($this->fonts['x_label'], $this->x_label_angle, + $which_xpix, $this->plot_area[3] + $this->x_label_bot_offset, + $this->ndx_text_color, $which_xlab, 'center', 'top'); + } + return TRUE; + } + + /* + * Draw one Y tick mark and its tick label. Called from DrawYTicks() and DrawXAxis() + * $which_ylab : Formatted Y value for the label. + * $which_ypix : Y device coordinate for this tick mark. + */ + protected function DrawYTick($which_ylab, $which_ypix) + { + // Ticks on Y axis + if ($this->y_tick_pos == 'yaxis') { + ImageLine($this->img, $this->y_axis_x_pixels - $this->y_tick_length, $which_ypix, + $this->y_axis_x_pixels + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color); + } + + // Ticks to the left of the Plot Area + if (($this->y_tick_pos == 'plotleft') || ($this->y_tick_pos == 'both') ) { + ImageLine($this->img, $this->plot_area[0] - $this->y_tick_length, $which_ypix, + $this->plot_area[0] + $this->y_tick_cross, $which_ypix, $this->ndx_tick_color); + } + + // Ticks to the right of the Plot Area + if (($this->y_tick_pos == 'plotright') || ($this->y_tick_pos == 'both') ) { + ImageLine($this->img, $this->plot_area[2] + $this->y_tick_length, $which_ypix, + $this->plot_area[2] - $this->y_tick_cross, $which_ypix, $this->ndx_tick_color); + } + + // Labels on Y axis + if ($this->y_tick_label_pos == 'yaxis') { + $this->DrawText($this->fonts['y_label'], $this->y_label_angle, + $this->y_axis_x_pixels - $this->y_label_axis_offset, $which_ypix, + $this->ndx_text_color, $which_ylab, 'right', 'center'); + } + + // Labels to the left of the plot area + if ($this->y_tick_label_pos == 'plotleft' || $this->y_tick_label_pos == 'both') { + $this->DrawText($this->fonts['y_label'], $this->y_label_angle, + $this->plot_area[0] - $this->y_label_left_offset, $which_ypix, + $this->ndx_text_color, $which_ylab, 'right', 'center'); + } + // Labels to the right of the plot area + if ($this->y_tick_label_pos == 'plotright' || $this->y_tick_label_pos == 'both') { + $this->DrawText($this->fonts['y_label'], $this->y_label_angle, + $this->plot_area[2] + $this->y_label_right_offset, $which_ypix, + $this->ndx_text_color, $which_ylab, 'left', 'center'); + } + return TRUE; + } + + /* + * Draws Grid, Ticks and Tick Labels along X-Axis + * Ticks and tick labels can be down of plot only, up of plot only, + * both on up and down of plot, or crossing a user defined X-axis + * + * Original vertical code submitted by Marlin Viss + */ + protected function DrawXTicks() + { + // Sets the line style for IMG_COLOR_STYLED lines (grid) + if ($this->dashed_grid) { + $this->SetDashedStyle($this->ndx_light_grid_color); + $style = IMG_COLOR_STYLED; + } else { + $style = $this->ndx_light_grid_color; + } + + // Calculate the tick start, end, and step: + list($x_start, $x_end, $delta_x) = $this->CalcTicks('x'); + + // Loop, avoiding cumulative round-off errors from $x_tmp += $delta_x + $n = 0; + $x_tmp = $x_start; + while ($x_tmp <= $x_end) { + $xlab = $this->FormatLabel('x', $x_tmp); + $x_pixels = $this->xtr($x_tmp); + + // Vertical grid lines + if ($this->draw_x_grid) { + ImageLine($this->img, $x_pixels, $this->plot_area[1], $x_pixels, $this->plot_area[3], $style); + } + + // Draw tick mark(s) + $this->DrawXTick($xlab, $x_pixels); + + // Step to next X, without accumulating error + $x_tmp = $x_start + ++$n * $delta_x; + } + return TRUE; + } + + /* + * Draw the grid, ticks, and tick labels along the Y axis. + * Ticks and tick labels can be left of plot only, right of plot only, + * both on the left and right of plot, or crossing a user defined Y-axis + */ + protected function DrawYTicks() + { + // Sets the line style for IMG_COLOR_STYLED lines (grid) + if ($this->dashed_grid) { + $this->SetDashedStyle($this->ndx_light_grid_color); + $style = IMG_COLOR_STYLED; + } else { + $style = $this->ndx_light_grid_color; + } + + // Calculate the tick start, end, and step: + list($y_start, $y_end, $delta_y) = $this->CalcTicks('y'); + + // Loop, avoiding cumulative round-off errors from $y_tmp += $delta_y + $n = 0; + $y_tmp = $y_start; + while ($y_tmp <= $y_end) { + $ylab = $this->FormatLabel('y', $y_tmp); + $y_pixels = $this->ytr($y_tmp); + + // Horizontal grid line + if ($this->draw_y_grid) { + ImageLine($this->img, $this->plot_area[0]+1, $y_pixels, $this->plot_area[2]-1, + $y_pixels, $style); + } + + // Draw tick mark(s) + $this->DrawYTick($ylab, $y_pixels); + + // Step to next Y, without accumulating error + $y_tmp = $y_start + ++$n * $delta_y; + } + return TRUE; + } + + /* + * Draw a border around the plot area. See SetPlotBorderType. + * Note: SetPlotBorderType sets plot_border_type to an array, but + * it won't be an array if it defaults or is set directly (backward compatibility). + */ + protected function DrawPlotBorder() + { + $pbt = (array)$this->plot_border_type; + $sides = 0; // Bitmap: 1=left 2=top 4=right 8=bottom + $map = array('left' => 1, 'plotleft' => 1, 'right' => 4, 'plotright' => 4, 'top' => 2, + 'bottom' => 8, 'both' => 5, 'sides' => 5, 'full' => 15, 'none' => 0); + foreach ($pbt as $option) $sides |= $map[$option]; + if ($sides == 15) { // Border on all 4 sides + imagerectangle($this->img, $this->plot_area[0], $this->plot_area[1], + $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color); + } else { + if ($sides & 1) // Left + imageline($this->img, $this->plot_area[0], $this->plot_area[1], + $this->plot_area[0], $this->plot_area[3], $this->ndx_grid_color); + if ($sides & 2) // Top + imageline($this->img, $this->plot_area[0], $this->plot_area[1], + $this->plot_area[2], $this->plot_area[1], $this->ndx_grid_color); + if ($sides & 4) // Right + imageline($this->img, $this->plot_area[2], $this->plot_area[1], + $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color); + if ($sides & 8) // Bottom + imageline($this->img, $this->plot_area[0], $this->plot_area[3], + $this->plot_area[2], $this->plot_area[3], $this->ndx_grid_color); + } + return TRUE; + } + + /* + * Draw the data value label associated with a point in the plot. + * These are labels that show the value (dependent variable, usually Y) of the data point, + * and are drawn within the plot area (not to be confused with axis data labels). + * + * $x_or_y : Specify 'x' or 'y' labels. This selects font, angle, and formatting. + * $x_world, $y_world : World coordinates of the text (see also x/y_adjustment). + * $text : The text to draw, after formatting with FormatLabel(). + * $halign, $valign : Selects from 9-point text alignment. + * $x_adjustment, $y_adjustment : Text position offsets, in device coordinates. + * $min_width, $min_height : If supplied, suppress the text if it will not fit. + * Returns True, if the text was drawn, or False, if it will not fit. + */ + protected function DrawDataValueLabel($x_or_y, $x_world, $y_world, $text, $halign, $valign, + $x_adjustment=0, $y_adjustment=0, $min_width=NULL, $min_height=NULL) + { + if ($x_or_y == 'x') { + $angle = $this->x_data_label_angle; + $font = $this->fonts['x_label']; + $formatted_text = $this->FormatLabel('xd', $text); + } else { // Assumed 'y' + $angle = $this->y_data_label_angle; + $font = $this->fonts['y_label']; + $formatted_text = $this->FormatLabel('yd', $text); + } + $color = $this->ndx_title_color; // Currently this is the same for X and Y labels + + // Check to see if the text fits in the available space, if requested. + if (isset($min_width) || isset($min_height)) { + list($width, $height) = $this->SizeText($font, $angle, $formatted_text); + if ((isset($min_width) && ($min_width - $width) < 2) + || (isset($min_height) && ($min_height - $height) < 2)) + return FALSE; + } + + $this->DrawText($font, $angle, $this->xtr($x_world) + $x_adjustment, + $this->ytr($y_world) + $y_adjustment, + $color, $formatted_text, $halign, $valign); + return TRUE; + } + + /* + * Draws the axis data label associated with a point in the plot. + * This is different from x_labels drawn by DrawXTicks() and care + * should be taken not to draw both, as they'd probably overlap. + * Calling of this function in DrawLines(), etc is decided after x_data_label_pos value. + * Leave the last parameter out, to avoid the drawing of vertical lines, no matter + * what the setting is (for plots that need it, like DrawSquared()) + */ + protected function DrawXDataLabel($xlab, $xpos, $row=FALSE) + { + $xlab = $this->FormatLabel('xd', $xlab); + + // Labels below the plot area + if ($this->x_data_label_pos == 'plotdown' || $this->x_data_label_pos == 'both') + $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle, + $xpos, $this->plot_area[3] + $this->x_label_bot_offset, + $this->ndx_text_color, $xlab, 'center', 'top'); + + // Labels above the plot area + if ($this->x_data_label_pos == 'plotup' || $this->x_data_label_pos == 'both') + $this->DrawText($this->fonts['x_label'], $this->x_data_label_angle, + $xpos, $this->plot_area[1] - $this->x_label_top_offset, + $this->ndx_text_color, $xlab, 'center', 'bottom'); + + // $row=0 means this is the first row. $row=FALSE means don't do any rows. + if ($row !== FALSE && $this->draw_x_data_label_lines) + $this->DrawXDataLine($xpos, $row); + return TRUE; + } + + /* + * Draw a data label along the Y axis or side. + * This is used by horizontal plots. + */ + protected function DrawYDataLabel($ylab, $ypos) + { + $ylab = $this->FormatLabel('yd', $ylab); + + // Labels left of the plot area + if ($this->y_data_label_pos == 'plotleft' || $this->y_data_label_pos == 'both') + $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle, + $this->plot_area[0] - $this->y_label_left_offset, $ypos, + $this->ndx_text_color, $ylab, 'right', 'center'); + + // Labels right of the plot area + if ($this->y_data_label_pos == 'plotright' || $this->y_data_label_pos == 'both') + $this->DrawText($this->fonts['y_label'], $this->y_data_label_angle, + $this->plot_area[2] + $this->y_label_right_offset, $ypos, + $this->ndx_text_color, $ylab, 'left', 'center'); + return TRUE; + } + + /* + * Draws Vertical lines from data points up and down. + * Which lines are drawn depends on the value of x_data_label_pos, + * and whether this is at all done or not, on draw_x_data_label_lines + * + * $xpos : position in pixels of the line. + * $row : index of the data row being drawn. + */ + protected function DrawXDataLine($xpos, $row) + { + // Sets the line style for IMG_COLOR_STYLED lines (grid) + if ($this->dashed_grid) { + $this->SetDashedStyle($this->ndx_light_grid_color); + $style = IMG_COLOR_STYLED; + } else { + $style = $this->ndx_light_grid_color; + } + + if ($this->x_data_label_pos == 'both') { + // Lines from the bottom up + ImageLine($this->img, $xpos, $this->plot_area[3], $xpos, $this->plot_area[1], $style); + } elseif ($this->x_data_label_pos == 'plotdown' && isset($this->data_max[$row])) { + // Lines from the bottom of the plot up to the max Y value at this X: + $ypos = $this->ytr($this->data_max[$row]); + ImageLine($this->img, $xpos, $ypos, $xpos, $this->plot_area[3], $style); + } elseif ($this->x_data_label_pos == 'plotup' && isset($this->data_min[$row])) { + // Lines from the top of the plot down to the min Y value at this X: + $ypos = $this->ytr($this->data_min[$row]); + ImageLine($this->img, $xpos, $this->plot_area[1], $xpos, $ypos, $style); + } + return TRUE; + } + + /* + * Draws the graph legend + * This is called by DrawGraph only if $this->legend is not empty. + * Base code submitted by Marlin Viss + */ + protected function DrawLegend() + { + $font = &$this->fonts['legend']; + + // Find maximum legend label line width. + $max_width = 0; + foreach ($this->legend as $line) { + list($width, $unused) = $this->SizeText($font, 0, $line); + if ($width > $max_width) $max_width = $width; + } + + // Use the font parameters to size the color boxes: + $char_w = $font['width']; + $char_h = $font['height']; + $line_spacing = $this->GetLineSpacing($font); + + // Normalize text alignment and colorbox alignment variables: + $text_align = isset($this->legend_text_align) ? $this->legend_text_align : 'right'; + $colorbox_align = isset($this->legend_colorbox_align) ? $this->legend_colorbox_align : 'right'; + + // Sizing parameters: + $v_margin = $char_h/2; // Between vertical borders and labels + $dot_height = $char_h + $line_spacing; // Height of the small colored boxes + // Color boxes are $char_w wide, but can be adjusted using legend_colorbox_width: + $colorbox_width = $char_w; + if (isset($this->legend_colorbox_width)) + $colorbox_width *= $this->legend_colorbox_width; + + // Overall legend box width e.g.: | space colorbox space text space | + // where each space adds $char_w, and colorbox adds $char_w * its width adjustment. + if (($draw_colorbox = ($colorbox_align != 'none'))) { + $width = $max_width + 3 * $char_w + $colorbox_width; + } else { + $width = $max_width + 2 * $char_w; + } + + //////// Calculate box position + // User-defined position specified? + if ( !isset($this->legend_x_pos) || !isset($this->legend_y_pos)) { + // No, use default + $box_start_x = $this->plot_area[2] - $width - $this->safe_margin; + $box_start_y = $this->plot_area[1] + $this->safe_margin; + } elseif (isset($this->legend_xy_world)) { + // User-defined position in world-coordinates (See SetLegendWorld). + $box_start_x = $this->xtr($this->legend_x_pos); + $box_start_y = $this->ytr($this->legend_y_pos); + } else { + // User-defined position in pixel coordinates. + $box_start_x = $this->legend_x_pos; + $box_start_y = $this->legend_y_pos; + } + + // Lower right corner + $box_end_y = $box_start_y + $dot_height*(count($this->legend)) + 2*$v_margin; + $box_end_x = $box_start_x + $width; + + // Draw outer box + ImageFilledRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y, + $this->ndx_bg_color); + ImageRectangle($this->img, $box_start_x, $box_start_y, $box_end_x, $box_end_y, + $this->ndx_grid_color); + + $color_index = 0; + $max_color_index = count($this->ndx_data_colors) - 1; + + // Calculate color box and text horizontal positions. + if (!$draw_colorbox) { + if ($text_align == 'left') + $x_pos = $box_start_x + $char_w; + else + $x_pos = $box_end_x - $char_w; + } elseif ($colorbox_align == 'left') { + $dot_left_x = $box_start_x + $char_w; + $dot_right_x = $dot_left_x + $colorbox_width; + if ($text_align == 'left') + $x_pos = $dot_right_x + $char_w; + else + $x_pos = $box_end_x - $char_w; + } else { // $colorbox_align == 'right' + $dot_right_x = $box_end_x - $char_w; + $dot_left_x = $dot_right_x - $colorbox_width; + if ($text_align == 'left') + $x_pos = $box_start_x + $char_w; + else + $x_pos = $dot_left_x - $char_w; + } + + // Calculate starting position of first text line. The bottom of each color box + // lines up with the bottom (baseline) of its text line. + $y_pos = $box_start_y + $v_margin + $dot_height; + + foreach ($this->legend as $leg) { + // Draw text with requested alignment: + $this->DrawText($font, 0, $x_pos, $y_pos, $this->ndx_text_color, $leg, $text_align, 'bottom'); + if ($draw_colorbox) { + // Draw a box in the data color + $y1 = $y_pos - $dot_height + 1; + $y2 = $y_pos - 1; + ImageFilledRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2, + $this->ndx_data_colors[$color_index]); + // Draw a rectangle around the box + ImageRectangle($this->img, $dot_left_x, $y1, $dot_right_x, $y2, + $this->ndx_text_color); + } + $y_pos += $dot_height; + + $color_index++; + if ($color_index > $max_color_index) + $color_index = 0; + } + return TRUE; + } + +///////////////////////////////////////////// +//////////////////// PLOT DRAWING HELPERS +///////////////////////////////////////////// + + /* + * Get data color to use for plotting. + * $row, $idx : Index arguments for the current data point. + * &$vars : Variable storage. Caller makes an empty array, and this function uses it. + * &$data_color : Returned result - Color index for the data point. + * $extra : Extra info flag passed through to data color callback. + */ + protected function GetDataColor($row, $idx, &$vars, &$data_color, $extra = 0) + { + // Initialize or extract variables: + if (empty($vars)) { + $custom_color = (bool)$this->GetCallback('data_color'); + $num_data_colors = count($this->ndx_data_colors); + $vars = compact('custom_color', 'num_data_colors'); + } else { + extract($vars); + } + + // Select the colors. + if ($custom_color) { + $col_i = $this->DoCallback('data_color', $row, $idx, $extra); // Custom color index + $data_color = $this->ndx_data_colors[$col_i % $num_data_colors]; + } else { + $data_color = $this->ndx_data_colors[$idx]; + } + } + + /* + * Get data color and error bar color to use for plotting. + * $row, $idx : Index arguments for the current bar. + * &$vars : Variable storage. Caller makes an empty array, and this function uses it. + * &$data_color : Returned result - Color index for the data (bar fill) + * &$error_color : Returned result - Color index for the error bars + * $extra : Extra info flag passed through to data color callback. + */ + protected function GetDataErrorColors($row, $idx, &$vars, &$data_color, &$error_color, $extra = 0) + { + // Initialize or extract variables: + if (empty($vars)) { + $this->NeedErrorBarColors(); // This plot needs error bar colors. + $custom_color = (bool)$this->GetCallback('data_color'); + $num_data_colors = count($this->ndx_data_colors); + $num_error_colors = count($this->ndx_error_bar_colors); + $vars = compact('custom_color', 'num_data_colors', 'num_error_colors'); + } else { + extract($vars); + } + + // Select the colors. + if ($custom_color) { + $col_i = $this->DoCallback('data_color', $row, $idx, $extra); // Custom color index + $data_color = $this->ndx_data_colors[$col_i % $num_data_colors]; + $error_color = $this->ndx_error_bar_colors[$col_i % $num_error_colors]; + } else { + $data_color = $this->ndx_data_colors[$idx]; + $error_color = $this->ndx_error_bar_colors[$idx]; + } + } + + /* + * Get colors to use for a bar chart. There is a data color, and either a border color + * or a shading color (data dark color). + * $row, $idx : Index arguments for the current bar. + * &$vars : Variable storage. Caller makes an empty array, and this function uses it. + * &$data_color : Returned result - Color index for the data (bar fill). + * &$alt_color : Returned result - Color index for the shading or outline. + */ + protected function GetBarColors($row, $idx, &$vars, &$data_color, &$alt_color) + { + // Initialize or extract variables: + if (empty($vars)) { + if ($this->shading > 0) // This plot needs dark colors if shading is on. + $this->NeedDataDarkColors(); + $custom_color = (bool)$this->GetCallback('data_color'); + $num_data_colors = count($this->ndx_data_colors); + $num_border_colors = count($this->ndx_data_border_colors); + $vars = compact('custom_color', 'num_data_colors', 'num_border_colors'); + } else { + extract($vars); + } + + // Select the colors. + if ($custom_color) { + $col_i = $this->DoCallback('data_color', $row, $idx); // Custom color index + $i_data = $col_i % $num_data_colors; // Index for data colors and dark colors + $i_border = $col_i % $num_border_colors; // Index for data borders (if used) + } else { + $i_data = $i_border = $idx; + } + $data_color = $this->ndx_data_colors[$i_data]; + if ($this->shading > 0) { + $alt_color = $this->ndx_data_dark_colors[$i_data]; + } else { + $alt_color = $this->ndx_data_border_colors[$i_border]; + } + } + + /* + * Draws a styled dot. Uses world coordinates. + * The list of supported shapes can also be found in SetPointShapes(). + * All shapes are drawn using a 3x3 grid, centered on the data point. + * The center is (x_mid, y_mid) and the corners are (x1, y1) and (x2, y2). + * $record is the 0-based index that selects the shape and size. + */ + protected function DrawDot($x_world, $y_world, $record, $color) + { + $index = $record % $this->point_counts; + $point_size = $this->point_sizes[$index]; + + $half_point = (int)($point_size / 2); + + $x_mid = $this->xtr($x_world); + $y_mid = $this->ytr($y_world); + + $x1 = $x_mid - $half_point; + $x2 = $x_mid + $half_point; + $y1 = $y_mid - $half_point; + $y2 = $y_mid + $half_point; + + switch ($this->point_shapes[$index]) { + case 'halfline': + ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color); + break; + case 'line': + ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); + break; + case 'plus': + ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); + ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); + break; + case 'cross': + ImageLine($this->img, $x1, $y1, $x2, $y2, $color); + ImageLine($this->img, $x1, $y2, $x2, $y1, $color); + break; + case 'circle': + ImageArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color); + break; + case 'dot': + ImageFilledEllipse($this->img, $x_mid, $y_mid, $point_size, $point_size, $color); + break; + case 'diamond': + $arrpoints = array( $x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2); + ImageFilledPolygon($this->img, $arrpoints, 4, $color); + break; + case 'triangle': + $arrpoints = array( $x1, $y_mid, $x2, $y_mid, $x_mid, $y2); + ImageFilledPolygon($this->img, $arrpoints, 3, $color); + break; + case 'trianglemid': + $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y_mid); + ImageFilledPolygon($this->img, $arrpoints, 3, $color); + break; + case 'yield': + $arrpoints = array( $x1, $y1, $x2, $y1, $x_mid, $y2); + ImageFilledPolygon($this->img, $arrpoints, 3, $color); + break; + case 'delta': + $arrpoints = array( $x1, $y2, $x2, $y2, $x_mid, $y1); + ImageFilledPolygon($this->img, $arrpoints, 3, $color); + break; + case 'star': + ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); + ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); + ImageLine($this->img, $x1, $y1, $x2, $y2, $color); + ImageLine($this->img, $x1, $y2, $x2, $y1, $color); + break; + case 'hourglass': + $arrpoints = array( $x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2); + ImageFilledPolygon($this->img, $arrpoints, 4, $color); + break; + case 'bowtie': + $arrpoints = array( $x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2); + ImageFilledPolygon($this->img, $arrpoints, 4, $color); + break; + case 'target': + ImageFilledRectangle($this->img, $x1, $y1, $x_mid, $y_mid, $color); + ImageFilledRectangle($this->img, $x_mid, $y_mid, $x2, $y2, $color); + ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); + break; + case 'box': + ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); + break; + case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */ + $arrpoints = array( $x1, $y2, $x2, $y2, $x2, $y_mid, $x_mid, $y1, $x1, $y_mid); + ImageFilledPolygon($this->img, $arrpoints, 5, $color); + break; + case 'up': + ImagePolygon($this->img, array($x_mid, $y1, $x2, $y2, $x1, $y2), 3, $color); + break; + case 'down': + ImagePolygon($this->img, array($x_mid, $y2, $x1, $y1, $x2, $y1), 3, $color); + break; + case 'none': /* Special case, no point shape here */ + break; + default: /* Also 'rect' */ + ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); + break; + } + return TRUE; + } + + /* + * Draw a bar (or segment of a bar), with optional shading or border. + * This is used by the bar and stackedbar plots, vertical and horizontal. + * $x1, $y1 : One corner of the bar. + * $x2, $y2 : Other corner of the bar. + * $data_color : Color index to use for the bar fill. + * $alt_color : Color index to use for the shading (if shading is on), else for the border. + * Note the same color is NOT used for shading and border - just the same argument. + * See GetBarColors() for where these arguments come from. + * $shade_top : Shade the top? (Suppressed for downward stack segments except first.) + * $shade_side : Shade the right side? (Suppressed for leftward stack segments except first.) + * Only one of $shade_top or $shade_side can be FALSE. Both default to TRUE. + */ + protected function DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color, + $shade_top = TRUE, $shade_side = TRUE) + { + // Sort the points so x1,y1 is upper left and x2,y2 is lower right. This + // is needed in order to get the shading right, and imagerectangle may require it. + if ($x1 > $x2) { + $t = $x1; $x1 = $x2; $x2 = $t; + } + if ($y1 > $y2) { + $t = $y1; $y1 = $y2; $y2 = $t; + } + + // Draw the bar + ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $data_color); + + // Draw a shade, or a border. + if (($shade = $this->shading) > 0) { + if ($shade_top && $shade_side) { + $npts = 6; + $pts = array($x1, $y1, $x1 + $shade, $y1 - $shade, $x2 + $shade, $y1 - $shade, + $x2 + $shade, $y2 - $shade, $x2, $y2, $x2, $y1); + } else { + $npts = 4; + if ($shade_top) { // Suppress side shading + $pts = array($x1, $y1, $x1 + $shade, $y1 - $shade, $x2 + $shade, $y1 - $shade, $x2, $y1); + } else { // Suppress top shading + $pts = array($x2, $y2, $x2, $y1, $x2 + $shade, $y1 - $shade, $x2 + $shade, $y2 - $shade); + } + } + ImageFilledPolygon($this->img, $pts, $npts, $alt_color); + } else { + ImageRectangle($this->img, $x1, $y1, $x2,$y2, $alt_color); + } + } + + /* + * Draw an Error Bar set. Used by DrawDotsError and DrawLinesError + */ + protected function DrawYErrorBar($x_world, $y_world, $error_height, $error_bar_type, $color) + { + $x1 = $this->xtr($x_world); + $y1 = $this->ytr($y_world); + $y2 = $this->ytr($y_world+$error_height) ; + + ImageSetThickness($this->img, $this->error_bar_line_width); + ImageLine($this->img, $x1, $y1 , $x1, $y2, $color); + if ($error_bar_type == 'tee') { + ImageLine($this->img, $x1-$this->error_bar_size, $y2, $x1+$this->error_bar_size, $y2, $color); + } + ImageSetThickness($this->img, 1); + return TRUE; + } + +///////////////////////////////////////////// +//////////////////// PLOT DRAWING +///////////////////////////////////////////// + + /* + * Draws a pie chart. Data is 'text-data', 'data-data', or 'text-data-single'. + * + * For text-data-single, the data array contains records with an ignored label, + * and one Y value. Each record defines a sector of the pie, as a portion of + * the sum of all Y values. + * + * For text-data and data-data, the data array contains records with an ignored label, + * an ignored X value (for data-data only), and N (N>=1) Y values per record. + * The pie chart will be produced with N segments. The relative size of the first + * sector of the pie is the sum of the first Y data value in each record, etc. + * + * Note: With text-data-single, the data labels could be used, but are not currently. + * + * If there are no valid data points > 0 at all, just draw nothing. It may seem more correct to + * raise an error, but all of the other plot types handle it this way implicitly. DrawGraph + * checks for an empty data array, but this is different: a non-empty data array with no Y values, + * or all Y=0. + */ + protected function DrawPieChart() + { + if (!$this->CheckDataType('text-data, text-data-single, data-data')) + return FALSE; + + // Allocate dark colors only if they will be used for shading. + if ($this->shading > 0) + $this->NeedDataDarkColors(); + + $xpos = $this->plot_area[0] + $this->plot_area_width/2; + $ypos = $this->plot_area[1] + $this->plot_area_height/2; + $diameter = min($this->plot_area_width, $this->plot_area_height); + $radius = $diameter/2; + + $num_slices = $this->data_columns; // See CheckDataArray which calculates this for us. + if ($num_slices < 1) return TRUE; // Give up early if there is no data at all. + $sumarr = array_fill(0, $num_slices, 0); + + if ($this->datatype_pie_single) { + // text-data-single: One data column per row, one pie slice per row. + for ($i = 0; $i < $num_slices; $i++) { + // $legend[$i] = $this->data[$i][0]; // Note: Labels are not used yet + if (is_numeric($this->data[$i][1])) + $sumarr[$i] = abs($this->data[$i][1]); + } + } else { + // text-data: Sum each column (skipping label), one pie slice per column. + // data-data: Sum each column (skipping X value and label), one pie slice per column. + $skip = ($this->datatype_implied) ? 1 : 2; // Leading values to skip in each row. + for ($i = 0; $i < $this->num_data_rows; $i++) { + for ($j = $skip; $j < $this->num_recs[$i]; $j++) { + if (is_numeric($this->data[$i][$j])) + $sumarr[$j-$skip] += abs($this->data[$i][$j]); + } + } + } + + $total = array_sum($sumarr); + + if ($total == 0) { + // There are either no valid data points, or all are 0. + // See top comment about why not to make this an error. + return TRUE; + } + + if ($this->shading) { + $diam2 = $diameter / 2; + } else { + $diam2 = $diameter; + } + $max_data_colors = count($this->ndx_data_colors); + + // Use the Y label format precision, with default value: + if (isset($this->label_format['y']['precision'])) + $precision = $this->label_format['y']['precision']; + else + $precision = 1; + + for ($h = $this->shading; $h >= 0; $h--) { + $color_index = 0; + $start_angle = 0; + $end_angle = 0; + for ($j = 0; $j < $num_slices; $j++) { + $val = $sumarr[$j]; + + // For shaded pies: the last one (at the top of the "stack") has a brighter color: + if ($h == 0) + $slicecol = $this->ndx_data_colors[$color_index]; + else + $slicecol = $this->ndx_data_dark_colors[$color_index]; + + $label_txt = $this->number_format(($val / $total * 100), $precision) . '%'; + $val = 360 * ($val / $total); + + // NOTE that imagefilledarc measures angles CLOCKWISE (go figure why), + // so the pie chart would start clockwise from 3 o'clock, would it not be + // for the reversal of start and end angles in imagefilledarc() + // Also note ImageFilledArc only takes angles in integer degrees, and if the + // the start and end angles match then you get a full circle not a zero-width + // pie. This is bad. So skip any zero-size wedge. On the other hand, we cannot + // let cumulative error from rounding to integer result in missing wedges. So + // keep the running total as a float, and round the angles. It should not + // be necessary to check that the last wedge ends at 360 degrees. + $start_angle = $end_angle; + $end_angle += $val; + // This method of conversion to integer - truncate after reversing it - was + // chosen to match the implicit method of PHPlot<=5.0.4 to get the same slices. + $arc_start_angle = (int)(360 - $start_angle); + $arc_end_angle = (int)(360 - $end_angle); + + if ($arc_start_angle > $arc_end_angle) { + $mid_angle = deg2rad($end_angle - ($val / 2)); + + // Draw the slice + ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2, + $arc_end_angle, $arc_start_angle, + $slicecol, IMG_ARC_PIE); + + // Draw the labels only once + if ($h == 0) { + // Draw the outline + if (! $this->shading) + ImageFilledArc($this->img, $xpos, $ypos+$h, $diameter, $diam2, + $arc_end_angle, $arc_start_angle, $this->ndx_grid_color, + IMG_ARC_PIE | IMG_ARC_EDGED |IMG_ARC_NOFILL); + + // The '* 1.2' trick is to get labels out of the pie chart so there are more + // chances they can be seen in small sectors. + $label_x = $xpos + ($diameter * 1.2 * cos($mid_angle)) * $this->label_scale_position; + $label_y = $ypos+$h - ($diam2 * 1.2 * sin($mid_angle)) * $this->label_scale_position; + + $this->DrawText($this->fonts['generic'], 0, $label_x, $label_y, $this->ndx_grid_color, + $label_txt, 'center', 'center'); + } + } + if (++$color_index >= $max_data_colors) + $color_index = 0; + } // end for + } // end for + return TRUE; + } + + /* + * Draw the points and errors bars for an error plot of types points and linepoints + * Supports only data-data-error format, with each row of the form + * array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...) + * This is called from DrawDots, with data type already checked. + * $paired is true for linepoints error plots, to make sure elements are + * only drawn once. If true, data labels are drawn by DrawLinesError, and error + * bars are drawn by DrawDotsError. (This choice is for backwards compatibility.) + */ + protected function DrawDotsError($paired = FALSE) + { + // Adjust the point shapes and point sizes arrays: + $this->CheckPointParams(); + + $gcvars = array(); // For GetDataErrorColors, which initializes and uses this. + // Special flag for data color callback to indicate the 'points' part of 'linepoints': + $alt_flag = $paired ? 1 : 0; + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (title) + + $x_now = $this->data[$row][$record++]; // Read it, advance record index + + $x_now_pixels = $this->xtr($x_now); // Absolute coordinates. + + // Draw X Data labels? + if ($this->x_data_label_pos != 'none' && !$paired) + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row); + + // Now go for Y, E+, E- + for ($idx = 0; $record < $this->num_recs[$row]; $idx++) { + if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data + + // Select the colors: + $this->GetDataErrorColors($row, $idx, $gcvars, $data_color, $error_color, $alt_flag); + + // Y: + $y_now = $this->data[$row][$record++]; + $this->DrawDot($x_now, $y_now, $idx, $data_color); + + // Error + + $val = $this->data[$row][$record++]; + $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape, $error_color); + // Error - + $val = $this->data[$row][$record++]; + $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape, $error_color); + } else { + $record += 3; // Skip over missing Y and its error values + } + } + } + return TRUE; + } + + /* + * Draw a points plot, or the points for a linepoints plot + * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...) + * Points plot with error bars (data-data-error format) is redirected to DrawDotsError. + * $paired is true for linepoints plots, to make sure elements are only drawn once. + */ + protected function DrawDots($paired = FALSE) + { + if (!$this->CheckDataType('text-data, data-data, data-data-error')) + return FALSE; + if ($this->datatype_error_bars) + return $this->DrawDotsError($paired); // Redirect for points+errorbars plot + + // Adjust the point shapes and point sizes arrays: + $this->CheckPointParams(); + + $gcvars = array(); // For GetDataColor, which initializes and uses this. + // Special flag for data color callback to indicate the 'points' part of 'linepoints': + $alt_flag = $paired ? 1 : 0; + + // Data Value Labels? (Skip if doing the points from a linepoints plot) + $do_dvls = !$paired && $this->CheckDataValueLabels($this->y_data_label_pos, + $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align); + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $rec = 1; // Skip record #0 (data label) + + if ($this->datatype_implied) // Implied X values? + $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc... + else + $x_now = $this->data[$row][$rec++]; // Read it, advance record index + + $x_now_pixels = $this->xtr($x_now); + + // Draw X Data labels? + if (!$paired && $this->x_data_label_pos != 'none') + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row); + + // Proceed with Y values + for ($idx = 0;$rec < $this->num_recs[$row]; $rec++, $idx++) { + if (is_numeric($this->data[$row][$rec])) { // Allow for missing Y data + $y_now = (double)$this->data[$row][$rec]; + + // Select the color: + $this->GetDataColor($row, $idx, $gcvars, $data_color, $alt_flag); + // Draw the marker: + $this->DrawDot($x_now, $y_now, $idx, $data_color); + + // Draw data value labels? + if ($do_dvls) { + $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align, + $dvl_x_off, $dvl_y_off); + } + } + } + } + return TRUE; + } + + /* + * Draw a Thin Bar Line plot, also known as an Impulse plot. + * A clean, fast routine for when you just want charts like stock volume charts. + * Supports data-data and text-data formats for vertical plots, + * and data-data-yx and text-data-yx for horizontal plots. + * Note that although this plot type supports multiple data sets, it rarely makes + * sense to have more than 1, because the lines will overlay. + * This one function does both vertical and horizontal plots. "iv" is used for the + * independent variable (X for vertical plots, Y for horizontal) and "dv" is used + * for the dependent variable (Y for vertical plots, X for horizontal). + */ + protected function DrawThinBarLines() + { + if (!$this->CheckDataType('text-data, data-data, text-data-yx, data-data-yx')) + return FALSE; + + $gcvars = array(); // For GetDataColor, which initializes and uses this. + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $rec = 1; // Skip record #0 (data label) + + if ($this->datatype_implied) // Implied independent variable values? + $iv_now = 0.5 + $cnt++; // Place text-data at 0.5, 1.5, 2.5, etc... + else + $iv_now = $this->data[$row][$rec++]; // Read it, advance record index + + if ($this->datatype_swapped_xy) { + $y_now_pixels = $this->ytr($iv_now); + // Draw Y Data labels? + if ($this->y_data_label_pos != 'none') + $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels); + } else { + $x_now_pixels = $this->xtr($iv_now); + // Draw X Data labels? + if ($this->x_data_label_pos != 'none') + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); + } + + // Proceed with dependent values + for ($idx = 0; $rec < $this->num_recs[$row]; $rec++, $idx++) { + if (is_numeric($this->data[$row][$rec])) { // Allow for missing data + $dv = $this->data[$row][$rec]; + ImageSetThickness($this->img, $this->line_widths[$idx]); + + // Select the color: + $this->GetDataColor($row, $idx, $gcvars, $data_color); + + if ($this->datatype_swapped_xy) { + // Draw a line from user defined y axis position right (or left) to xtr($dv) + ImageLine($this->img, $this->y_axis_x_pixels, $y_now_pixels, + $this->xtr($dv), $y_now_pixels, $data_color); + } else { + // Draw a line from user defined x axis position up (or down) to ytr($dv) + ImageLine($this->img, $x_now_pixels, $this->x_axis_y_pixels, + $x_now_pixels, $this->ytr($dv), $data_color); + } + } + } + } + + ImageSetThickness($this->img, 1); + return TRUE; + } + + /* + * Draw an 'area' or 'stacked area' plot. + * Both of these fill the area between lines, but in the stacked area graph the Y values + * are accumulated for each X, same as stacked bars. In the regular area graph, the areas + * are filled in order from the X axis up to each Y (so the Y values for each X need to be + * in decreasing order in this case). + * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...) + * Notes: + * All Y values must be >= 0. (If any Y<0 the absolute value is used.) + * Missing data points are NOT handled. (They are counted as 0.) + * All rows must have the same number of Y points, or an error image will be produced. + */ + protected function DrawArea($do_stacked = FALSE) + { + if (!$this->CheckDataType('text-data, data-data')) + return FALSE; + + $n = $this->num_data_rows; // Number of X values + + // These arrays store the device X and Y coordinates for all lines: + $xd = array(); + $yd = array(); + + // Make sure each row has the same number of values. Note records_per_group is max(num_recs). + if ($this->records_per_group != min($this->num_recs)) { + return $this->PrintError("DrawArea(): Data array must contain the same number" + . " of Y values for each X"); + } + + // Calculate the Y value for each X, and store the device + // coordinates into the xd and yd arrays. + // For stacked area plots, the Y values accumulate. + for ($row = 0; $row < $n; $row++) { + $rec = 1; // Skip record #0 (data label) + + if ($this->datatype_implied) // Implied X values? + $x_now = 0.5 + $row; // Place text-data at X = 0.5, 1.5, 2.5, etc... + else + $x_now = $this->data[$row][$rec++]; // Read it, advance record index + + $x_now_pixels = $this->xtr($x_now); + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); + + // Store the X value. + // There is an artificial Y value at the axis. For 'area' it goes + // at the end; for stackedarea it goes before the start. + $xd[$row] = $x_now_pixels; + $yd[$row] = array(); + if ($do_stacked) + $yd[$row][] = $this->x_axis_y_pixels; + + // Store the Y values for this X. + // All Y values are clipped to the x axis which should be zero but can be moved. + $y = 0; + while ($rec < $this->records_per_group) { + if (is_numeric($this->data[$row][$rec])) { // Treat missing values as 0. + $y += abs($this->data[$row][$rec]); + } + $yd[$row][] = $this->ytr(max($this->x_axis_position, $y)); + if (!$do_stacked) $y = 0; + $rec++; + } + + if (!$do_stacked) + $yd[$row][] = $this->x_axis_y_pixels; + } + + // Now draw the filled polygons. + // Note data_columns is the number of Y points (columns excluding label and X), and the + // number of entries in the yd[] arrays is data_columns+1. + $prev_row = 0; + for ($row = 1; $row <= $this->data_columns; $row++) { // 1 extra for X axis artificial row + $pts = array(); + // Previous data set forms top (for area) or bottom (for stackedarea): + for ($j = 0; $j < $n; $j++) { + $pts[] = $xd[$j]; + $pts[] = $yd[$j][$prev_row]; + } + // Current data set forms bottom (for area) or top (for stackedarea): + for ($j = $n- 1; $j >= 0; $j--) { + $pts[] = $xd[$j]; + $pts[] = $yd[$j][$row]; + } + // Draw it: + ImageFilledPolygon($this->img, $pts, $n * 2, $this->ndx_data_colors[$prev_row]); + + $prev_row = $row; + } + return TRUE; + } + + /* + * Draw a line plot, or the lines part of a linepoints plot + * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...) + * Line plot with error bars (data-data-error format) is redirected to DrawLinesError. + * $paired is true for linepoints plots, to make sure elements are only drawn once. + */ + protected function DrawLines($paired = FALSE) + { + if (!$this->CheckDataType('text-data, data-data, data-data-error')) + return FALSE; + if ($this->datatype_error_bars) + return $this->DrawLinesError($paired); // Redirect for lines+errorbar plot + + // Flag array telling if the current point is valid, one element per plot line. + // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point. + $start_lines = array_fill(0, $this->data_columns, FALSE); + + $gcvars = array(); // For GetDataColor, which initializes and uses this. + + // Data Value Labels? + $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos, + $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align); + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + if ($this->datatype_implied) // Implied X values? + $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc... + else + $x_now = $this->data[$row][$record++]; // Read it, advance record index + + $x_now_pixels = $this->xtr($x_now); // Absolute coordinates + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row); + + for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { + if (($line_style = $this->line_styles[$idx]) == 'none') + continue; //Allow suppressing entire line, useful with linepoints + if (is_numeric($this->data[$row][$record])) { //Allow for missing Y data + $y_now = (double)$this->data[$row][$record]; + $y_now_pixels = $this->ytr($y_now); + + if ($start_lines[$idx]) { + // Set line width, revert it to normal at the end + ImageSetThickness($this->img, $this->line_widths[$idx]); + + // Select the color: + $this->GetDataColor($row, $idx, $gcvars, $data_color); + + if ($line_style == 'dashed') { + $this->SetDashedStyle($data_color); + $data_color = IMG_COLOR_STYLED; + } + ImageLine($this->img, $x_now_pixels, $y_now_pixels, + $lastx[$idx], $lasty[$idx], $data_color); + } + + // Draw data value labels? + if ($do_dvls) { + $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align, + $dvl_x_off, $dvl_y_off); + } + + $lasty[$idx] = $y_now_pixels; + $lastx[$idx] = $x_now_pixels; + $start_lines[$idx] = TRUE; + } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap. + $start_lines[$idx] = FALSE; + } + } // end for + } // end for + + ImageSetThickness($this->img, 1); // Revert to original state for lines to be drawn later. + return TRUE; + } + + /* + * Draw lines with error bars for an error plot of types lines and linepoints + * Supports only data-data-error format, with each row of the form + * array("title", x, y1, error1+, error1-, y2, error2+, error2-, ...) + * This is called from DrawLines, with data type already checked. + * $paired is true for linepoints error plots, to make sure elements are + * only drawn once. If true, data labels are drawn by DrawLinesError, and error + * bars are drawn by DrawDotsError. (This choice is for backwards compatibility.) + */ + protected function DrawLinesError($paired = FALSE) + { + $start_lines = array_fill(0, $this->data_columns, FALSE); + + $gcvars = array(); // For GetDataErrorColors, which initializes and uses this. + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + $x_now = $this->data[$row][$record++]; // Read X value, advance record index + + $x_now_pixels = $this->xtr($x_now); // Absolute coordinates. + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row); + + // Now go for Y, E+, E- + for ($idx = 0; $record < $this->num_recs[$row]; $idx++) { + if (($line_style = $this->line_styles[$idx]) == 'none') + continue; //Allow suppressing entire line, useful with linepoints + if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data + + // Select the colors: + $this->GetDataErrorColors($row, $idx, $gcvars, $data_color, $error_color); + + // Y + $y_now = $this->data[$row][$record++]; + $y_now_pixels = $this->ytr($y_now); + + if ($start_lines[$idx]) { + ImageSetThickness($this->img, $this->line_widths[$idx]); + + if ($line_style == 'dashed') { + $this->SetDashedStyle($data_color); + $data_color = IMG_COLOR_STYLED; + } + ImageLine($this->img, $x_now_pixels, $y_now_pixels, + $lastx[$idx], $lasty[$idx], $data_color); + } + + if ($paired) { + $record += 2; // Skip error bars - done in the 'points' part of 'linepoints'. + } else { + // Error+ + $val = $this->data[$row][$record++]; + $this->DrawYErrorBar($x_now, $y_now, $val, $this->error_bar_shape, $error_color); + + // Error- + $val = $this->data[$row][$record++]; + $this->DrawYErrorBar($x_now, $y_now, -$val, $this->error_bar_shape, $error_color); + } + + // Update indexes: + $start_lines[$idx] = TRUE; // Tells us if we already drew the first column of points, + // thus having $lastx and $lasty ready for the next column. + $lastx[$idx] = $x_now_pixels; + $lasty[$idx] = $y_now_pixels; + + } else { + $record += 3; // Skip over missing Y and its error values + if ($this->draw_broken_lines) { + $start_lines[$idx] = FALSE; + } + } + } // end for + } // end for + + ImageSetThickness($this->img, 1); // Revert to original state for lines to be drawn later. + return TRUE; + } + + /* + * Draw a Lines+Points plot (linepoints). + * This just uses DrawLines and DrawDots. They handle the error-bar case themselves. + */ + protected function DrawLinePoints() + { + // This check is redundant, as DrawLines and DrawDots do it, but left here as insurance. + if (!$this->CheckDataType('text-data, data-data, data-data-error')) + return FALSE; + $this->DrawLines(TRUE); + $this->DrawDots(TRUE); + return TRUE; + } + + /* + * Draw a Squared Line plot. + * Data format can be text-data (label, y1, y2, ...) or data-data (label, x, y1, y2, ...) + * This is based on DrawLines(), with one more line drawn for each point. + */ + protected function DrawSquared() + { + if (!$this->CheckDataType('text-data, data-data')) + return FALSE; + + // Flag array telling if the current point is valid, one element per plot line. + // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point. + $start_lines = array_fill(0, $this->data_columns, FALSE); + + $gcvars = array(); // For GetDataColor, which initializes and uses this. + + // Data Value Labels? + $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos, + $dvl_x_off, $dvl_y_off, $dvl_h_align, $dvl_v_align); + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + if ($this->datatype_implied) // Implied X values? + $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc... + else + $x_now = $this->data[$row][$record++]; // Read it, advance record index + + $x_now_pixels = $this->xtr($x_now); // Absolute coordinates + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); // notice there is no last param. + + // Draw Lines + for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { + if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data + $y_now = (double)$this->data[$row][$record]; + $y_now_pixels = $this->ytr($y_now); + + if ($start_lines[$idx]) { + // Set line width, revert it to normal at the end + ImageSetThickness($this->img, $this->line_widths[$idx]); + + // Select the color: + $this->GetDataColor($row, $idx, $gcvars, $data_color); + + if ($this->line_styles[$idx] == 'dashed') { + $this->SetDashedStyle($data_color); + $data_color = IMG_COLOR_STYLED; + } + ImageLine($this->img, $lastx[$idx], $lasty[$idx], + $x_now_pixels, $lasty[$idx], $data_color); + ImageLine($this->img, $x_now_pixels, $lasty[$idx], + $x_now_pixels, $y_now_pixels, $data_color); + } + + // Draw data value labels? + if ($do_dvls) { + $this->DrawDataValueLabel('y', $x_now, $y_now, $y_now, $dvl_h_align, $dvl_v_align, + $dvl_x_off, $dvl_y_off); + } + + $lastx[$idx] = $x_now_pixels; + $lasty[$idx] = $y_now_pixels; + $start_lines[$idx] = TRUE; + } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap. + $start_lines[$idx] = FALSE; + } + } + } // end while + + ImageSetThickness($this->img, 1); + return TRUE; + } + + /* + * Draw a Bar chart + * Supports text-data format, with each row in the form array(label, y1, y2, y3, ...) + * Horizontal bars (text-data-yx format) are sent to DrawHorizBars() instead. + */ + protected function DrawBars() + { + if (!$this->CheckDataType('text-data, text-data-yx')) + return FALSE; + if ($this->datatype_swapped_xy) + return $this->DrawHorizBars(); + $this->CalcBarWidths(FALSE, TRUE); // Calculate bar widths for unstacked, vertical + + // This is the X offset from the bar group's label center point to the left side of the first bar + // in the group. See also CalcBarWidths above. + $x_first_bar = ($this->data_columns * $this->record_bar_width) / 2 - $this->bar_adjust_gap; + + $gcvars = array(); // For GetBarColors, which initializes and uses this. + + for ($row = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + $x_now_pixels = $this->xtr(0.5 + $row); // Place text-data at X = 0.5, 1.5, 2.5, etc... + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); + + // Lower left X of first bar in the group: + $x1 = $x_now_pixels - $x_first_bar; + + // Draw the bars in the group: + for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { + if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data + $y = $this->data[$row][$record]; + $x2 = $x1 + $this->actual_bar_width; + + if (($upgoing_bar = $y >= $this->x_axis_position)) { + $y1 = $this->ytr($y); + $y2 = $this->x_axis_y_pixels; + } else { + $y1 = $this->x_axis_y_pixels; + $y2 = $this->ytr($y); + } + + // Select the colors: + $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color); + + // Draw the bar, and the shade or border: + $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color); + + // Draw optional data labels above the bars (or below, for negative values). + if ( $this->y_data_label_pos == 'plotin') { + if ($upgoing_bar) { + $v_align = 'bottom'; + $y_offset = -5 - $this->shading; + } else { + $v_align = 'top'; + $y_offset = 2; + } + $this->DrawDataValueLabel('y', $row+0.5, $y, $y, 'center', $v_align, + ($idx + 0.5) * $this->record_bar_width - $x_first_bar, $y_offset); + } + } + // Step to next bar in group: + $x1 += $this->record_bar_width; + } // end for + } // end for + return TRUE; + } + + /* + * Draw a Horizontal Bar chart + * Supports only text-data-yx format, with each row in the form array(label, x1, x2, x3, ...) + * Note that the data values are X not Y, and the bars are drawn horizontally. + * This is called from DrawBars, which has already checked the data type. + */ + protected function DrawHorizBars() + { + $this->CalcBarWidths(FALSE, FALSE); // Calculate bar widths for unstacked, vertical + + // This is the Y offset from the bar group's label center point to the bottom of the first bar + // in the group. See also CalcBarWidths above. + $y_first_bar = ($this->data_columns * $this->record_bar_width) / 2 - $this->bar_adjust_gap; + + $gcvars = array(); // For GetBarColors, which initializes and uses this. + + for ($row = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + $y_now_pixels = $this->ytr(0.5 + $row); // Place bars at Y=0.5, 1.5, 2.5, etc... + + if ($this->y_data_label_pos != 'none') // Draw Y Data Labels? + $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels); + + // Lower left Y of first bar in the group: + $y1 = $y_now_pixels + $y_first_bar; + + // Draw the bars in the group: + for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { + if (is_numeric($this->data[$row][$record])) { // Allow for missing X data + $x = $this->data[$row][$record]; + $y2 = $y1 - $this->actual_bar_width; + + if (($rightwards_bar = $x >= $this->y_axis_position)) { + $x1 = $this->xtr($x); + $x2 = $this->y_axis_x_pixels; + } else { + $x1 = $this->y_axis_x_pixels; + $x2 = $this->xtr($x); + } + + // Select the colors: + $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color); + + // Draw the bar, and the shade or border: + $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color); + + // Draw optional data labels to the right of the bars (or left, if the bar + // goes left of the Y axis line). + if ($this->x_data_label_pos == 'plotin') { + if ($rightwards_bar) { + $h_align = 'left'; + $x_offset = 5 + $this->shading; + } else { + $h_align = 'right'; + $x_offset = -2; + } + $this->DrawDataValueLabel('x', $x, $row+0.5, $x, $h_align, 'center', + $x_offset, $y_first_bar - ($idx + 0.5) * $this->record_bar_width); + } + + } + // Step to next bar in group: + $y1 -= $this->record_bar_width; + } // end for + } // end for + + return TRUE; + } + + /* + * Draw a Stacked Bar chart + * Supports text-data format, with each row in the form array(label, y1, y2, y3, ...) + * Horizontal stacked bars (text-data-yx format) are sent to DrawHorizStackedBars() instead. + * Original stacked bars idea by Laurent Kruk < lolok at users.sourceforge.net > + */ + protected function DrawStackedBars() + { + if (!$this->CheckDataType('text-data, text-data-yx')) + return FALSE; + if ($this->datatype_swapped_xy) + return $this->DrawHorizStackedBars(); + $this->CalcBarWidths(TRUE, TRUE); // Calculate bar widths for stacked, vertical + + // This is the X offset from the bar's label center point to the left side of the bar. + $x_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap; + + $gcvars = array(); // For GetBarColors, which initializes and uses this. + + // Determine if any data labels are on: + $data_labels_within = ($this->y_data_label_pos == 'plotstack'); + $data_labels_end = $data_labels_within || ($this->y_data_label_pos == 'plotin'); + $data_label_y_offset = -5 - $this->shading; // For upward labels only. + + for ($row = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + $x_now_pixels = $this->xtr(0.5 + $row); // Place text-data at X = 0.5, 1.5, 2.5, etc... + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); + + // Lower left and lower right X of the bars in this stack: + $x1 = $x_now_pixels - $x_first_bar; + $x2 = $x1 + $this->actual_bar_width; + + // Draw the bar segments in this stack. + $wy1 = 0; // World coordinates Y1, current sum of values + $wy2 = $this->x_axis_position; // World coordinates Y2, last drawn value + $first = TRUE; + + for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { + + // Skip missing Y values, and ignore Y=0 values. + if (is_numeric($this->data[$row][$record]) + && ($this_y = $this->data[$row][$record]) != 0) { + + // First non-zero value sets the direction, $upward. Note this compares to 0, + // not the axis position. Segments are based at 0 but clip to the axis. + if ($first) + $upward = ($this_y > 0); + + $wy1 += $this_y; // Keep the running total for this bar stack + + // Draw nothing if this segment would not increase the bar height. + // Upward bars: draw if wy1>wy2. Downward bars: Draw if wy1ytr($wy1); // Convert to device coordinates. $y1 is outermost value. + $y2 = $this->ytr($wy2); // $y2 is innermost (closest to axis). + + // Select the colors: + $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color); + + // Draw the bar, and the shade or border: + $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color, + // Only shade the top for upward bars, or the first segment of downward bars: + $upward || $first, TRUE); + + // Draw optional data label for this bar segment just inside the end. + // Text value is the current Y, but position is the cumulative Y. + // The label is only drawn if it fits in the segment height |y2-y1|. + if ($data_labels_within) { + $this->DrawDataValueLabel('y', $row+0.5, $wy1, $this_y, + 'center', $upward ? 'top' : 'bottom', + 0, $upward ? 3 : -3, NULL, abs($y1 - $y2)); + } + // Mark the new end of the bar, conditional on segment height > 0. + $wy2 = $wy1; + } + $first = FALSE; + } + } // end for + + // Draw optional data label above the bar with the total value. + // Value is wy1 (total value), but position is wy2 (end of the bar stack). + // These differ only with wrong-direction segments, or a stack completely clipped by the axis. + if ($data_labels_end) { + $this->DrawDataValueLabel('y', $row+0.5, $wy2, $wy1, 'center', $upward ? 'bottom' : 'top', + 0, $upward ? $data_label_y_offset : 5); + } + } // end for + return TRUE; + } + + /* + * Draw a Horizontal Stacked Bar chart + * Supports only text-data-yx format, with each row in the form array(label, x1, x2, x3, ...) + * Note that the data values are X not Y, and the bars are drawn horizontally. + * This is called from DrawStackedBars, which has already checked the data type. + */ + protected function DrawHorizStackedBars() + { + $this->CalcBarWidths(TRUE, FALSE); // Calculate bar widths for stacked, horizontal + + // This is the Y offset from the bar's label center point to the bottom of the bar + $y_first_bar = $this->record_bar_width / 2 - $this->bar_adjust_gap; + + $gcvars = array(); // For GetBarColors, which initializes and uses this. + + // Determine if any data labels are on: + $data_labels_within = ($this->x_data_label_pos == 'plotstack'); + $data_labels_end = $data_labels_within || ($this->x_data_label_pos == 'plotin'); + $data_label_x_offset = 5 + $this->shading; // For rightward labels only + + for ($row = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + $y_now_pixels = $this->ytr(0.5 + $row); // Place bars at Y=0.5, 1.5, 2.5, etc... + + if ($this->y_data_label_pos != 'none') // Draw Y Data labels? + $this->DrawYDataLabel($this->data[$row][0], $y_now_pixels); + + // Lower left and upper left Y of the bars in this stack: + $y1 = $y_now_pixels + $y_first_bar; + $y2 = $y1 - $this->actual_bar_width; + + // Draw the bar segments in this stack: + $wx1 = 0; // World coordinates X1, current sum of values + $wx2 = $this->y_axis_position; // World coordinates X2, last drawn value + $first = TRUE; + + for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { + + // Skip missing X values, and ignore X<0 values. + if (is_numeric($this->data[$row][$record]) + && ($this_x = $this->data[$row][$record]) != 0) { + + // First non-zero value sets the direction, $rightward. Note this compares to 0, + // not the axis position. Segments are based at 0 but clip to the axis. + if ($first) + $rightward = ($this_x > 0); + + $wx1 += $this_x; // Keep the running total for this bar stack + + // Draw nothing if this segment would not increase the bar length. + // Rightward bars: draw if wx1>wx2. Leftward bars: Draw if wx1xtr($wx1); // Convert to device coordinates. $x1 is outermost value. + $x2 = $this->xtr($wx2); // $x2 is innermost (closest to axis). + + // Select the colors: + $this->GetBarColors($row, $idx, $gcvars, $data_color, $alt_color); + + // Draw the bar, and the shade or border: + $this->DrawBar($x1, $y1, $x2, $y2, $data_color, $alt_color, + // Only shade the side for rightward bars, or the first segment of leftward bars: + TRUE, $rightward || $first); + // Draw optional data label for this bar segment just inside the end. + // Text value is the current X, but position is the cumulative X. + // The label is only drawn if it fits in the segment width |x2-x1|. + if ($data_labels_within) { + $this->DrawDataValueLabel('x', $wx1, $row+0.5, $this_x, + $rightward ? 'right' : 'left', 'center', + $rightward ? -3 : 3, 0, abs($x1 - $x2), NULL); + } + // Mark the new end of the bar, conditional on segment width > 0. + $wx2 = $wx1; + } + $first = FALSE; + } + } // end for + + // Draw optional data label right of the bar with the total value. + // Value is wx1 (total value), but position is wx2 (end of the bar stack). + // These differ only with wrong-direction segments, or a stack completely clipped by the axis. + if ($data_labels_end) { + $this->DrawDataValueLabel('x', $wx2, $row+0.5, $wx1, $rightward ? 'left' : 'right', 'center', + $rightward ? $data_label_x_offset : -5, 0); + } + } // end for + return TRUE; + } + + /* + * Draw a financial "Open/High/Low/Close" (OHLC) plot, including candlestick plots. + * Data format can be text-data (label, Yo, Yh, Yl, Yc) or data-data (label, X, Yo, Yh, Yl, Yc). + * Yo="Opening price", Yc="Closing price", Yl="Low price", Yh="High price". + * Each row must have exactly 4 Y values. No multiple data sets, no missing values. + * There are 3 subtypes, selected by $draw_candles and $always_fill. + * $draw_candles $always_fill Description: + * FALSE N/A A basic OHLC chart with a vertical line for price range, horizontal + * tick marks on left for opening price and right for closing price. + * TRUE FALSE A candlestick plot with filled body indicating close down, outline + * for closing up, and vertical wicks for low and high prices. + * TRUE TRUE A candlestick plot where the candle bodies are always filled. + * These map to 3 plot types per the $plots[] array. + * + * Data color usage: If closes down: If closes up or unchanged: + * Candlestick body, ohlc range line: color 0 color 1 + * Candlestick wicks, ohlc tick marks: color 2 color 3 + * There are three member variables that control the width (candlestick body or tick marks): + * ohlc_max_width, ohlc_min_width, ohlc_frac_width + * (There is no API to change them at this time.) + */ + protected function DrawOHLC($draw_candles, $always_fill = FALSE) + { + if (!$this->CheckDataType('text-data, data-data')) + return FALSE; + + // Assign name of GD function to draw candlestick bodies for stocks that close up. + $draw_body_close_up = $always_fill ? 'imagefilledrectangle' : 'imagerectangle'; + + // These 3 variables control the calculation of the half-width of the candle body, or length of + // the tick marks. This is scaled based on the plot density, but within tight limits. + $min_width = isset($this->ohlc_min_width) ? $this->ohlc_min_width : 2; + $max_width = isset($this->ohlc_max_width) ? $this->ohlc_max_width : 8; + $width_factor = isset($this->ohlc_frac_width) ? $this->ohlc_frac_width : 0.3; + $dw = max($min_width, min($max_width, + (int)($width_factor * $this->plot_area_width / $this->num_data_rows))); + + // Get line widths to use: index 0 for body/stroke, 1 for wick/tick. + list($body_thickness, $wick_thickness) = $this->line_widths; + + $gcvars = array(); // For GetDataColor, which initializes and uses this. + + for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { + $record = 1; // Skip record #0 (data label) + + if ($this->datatype_implied) // Implied X values? + $x_now = 0.5 + $cnt++; // Place text-data at X = 0.5, 1.5, 2.5, etc... + else + $x_now = $this->data[$row][$record++]; // Read it, advance record index + + $x_now_pixels = $this->xtr($x_now); // Convert X to device coordinates + $x_left = $x_now_pixels - $dw; + $x_right = $x_now_pixels + $dw; + + if ($this->x_data_label_pos != 'none') // Draw X Data labels? + $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row); + + // Require and use 4 numeric values in each row. + if ($this->num_recs[$row] - $record != 4 + || !is_numeric($yo = $this->data[$row][$record++]) + || !is_numeric($yh = $this->data[$row][$record++]) + || !is_numeric($yl = $this->data[$row][$record++]) + || !is_numeric($yc = $this->data[$row][$record++])) { + return $this->PrintError("DrawOHLC: row $row must have 4 values."); + } + + // Set device coordinates for each value and direction flag: + $yh_pixels = $this->ytr($yh); + $yl_pixels = $this->ytr($yl); + $yc_pixels = $this->ytr($yc); + $yo_pixels = $this->ytr($yo); + $closed_up = $yc >= $yo; + + // Get data colors and line thicknesses: + if ($closed_up) { + $this->GetDataColor($row, 1, $gcvars, $body_color); // Color 1 for body, closing up + $this->GetDataColor($row, 3, $gcvars, $ext_color); // Color 3 for wicks/ticks + } else { + $this->GetDataColor($row, 0, $gcvars, $body_color); // Color 0 for body, closing down + $this->GetDataColor($row, 2, $gcvars, $ext_color); // Color 2 for wicks/ticks + } + imagesetthickness($this->img, $body_thickness); + + if ($draw_candles) { + // Note: Unlike ImageFilledRectangle, ImageRectangle 'requires' its arguments in + // order with upper left corner first. + if ($closed_up) { + $yb1_pixels = $yc_pixels; // Upper body Y + $yb2_pixels = $yo_pixels; // Lower body Y + $draw_body = $draw_body_close_up; + // Avoid a PHP/GD bug resulting in "T"-shaped ends to zero height unfilled rectangle: + if ($yb1_pixels == $yb2_pixels) + $draw_body = 'imagefilledrectangle'; + } else { + $yb1_pixels = $yo_pixels; + $yb2_pixels = $yc_pixels; + $draw_body = 'imagefilledrectangle'; + } + + // Draw candle body + $draw_body($this->img, $x_left, $yb1_pixels, $x_right, $yb2_pixels, $body_color); + + // Draw upper and lower wicks, if they have height. (In device coords, that's dY<0) + imagesetthickness($this->img, $wick_thickness); + if ($yh_pixels < $yb1_pixels) { + imageline($this->img, $x_now_pixels, $yb1_pixels, $x_now_pixels, $yh_pixels, $ext_color); + } + if ($yl_pixels > $yb2_pixels) { + imageline($this->img, $x_now_pixels, $yb2_pixels, $x_now_pixels, $yl_pixels, $ext_color); + } + } else { + // Basic OHLC + imageline($this->img, $x_now_pixels, $yl_pixels, $x_now_pixels, $yh_pixels, $body_color); + imagesetthickness($this->img, $wick_thickness); + imageline($this->img, $x_left, $yo_pixels, $x_now_pixels, $yo_pixels, $ext_color); + imageline($this->img, $x_right, $yc_pixels, $x_now_pixels, $yc_pixels, $ext_color); + } + imagesetthickness($this->img, 1); + } + return TRUE; + } + + /* + * Draw the graph. + * This is the function that performs the actual drawing, after all + * the parameters and data are set up. + * It also outputs the finished image, unless told not to. + * Note: It is possible for this to be called multiple times. + */ + function DrawGraph() + { + // Test for missing image, missing data, empty data: + if (!$this->CheckDataArray()) + return FALSE; // Error message already reported. + + // Set defaults then import plot type configuration: + $draw_axes = TRUE; + $draw_arg = array(); // Default is: no arguments to the drawing function + extract(PHPlot::$plots[$this->plot_type]); + + // Allocate colors for the plot: + $this->SetColorIndexes(); + + // Get maxima and minima for scaling: + if (!$this->FindDataLimits()) + return FALSE; + + // Set plot area world values (plot_max_x, etc.): + if (!$this->CalcPlotAreaWorld()) + return FALSE; + + // Calculate X and Y axis positions in World Coordinates: + $this->CalcAxisPositions(); + + // Process label-related parameters: + $this->CheckLabels(); + + // Apply grid defaults: + $this->CalcGridSettings(); + + // Calculate the plot margins, if needed. + // For pie charts, set the $maximize argument to maximize space usage. + $this->CalcMargins(!$draw_axes); + + // Calculate the actual plot area in device coordinates: + $this->CalcPlotAreaPixels(); + + // Calculate the mapping between world and device coordinates: + $this->CalcTranslation(); + + // Pad color and style arrays to fit records per group: + $this->PadArrays(); + $this->DoCallback('draw_setup'); + + $this->DrawBackground(); + $this->DrawImageBorder(); + $this->DoCallback('draw_image_background'); + + $this->DrawPlotAreaBackground(); + $this->DoCallback('draw_plotarea_background', $this->plot_area); + + $this->DrawTitle(); + if ($draw_axes) { // If no axes (pie chart), no axis titles either + $this->DrawXTitle(); + $this->DrawYTitle(); + } + $this->DoCallback('draw_titles'); + + if ($draw_axes && ! $this->grid_at_foreground) { // Usually one wants grids to go back, but... + $this->DrawYAxis(); // Y axis must be drawn before X axis (see DrawYAxis()) + $this->DrawXAxis(); + $this->DoCallback('draw_axes'); + } + + // Call the plot-type drawing method: + call_user_func_array(array($this, $draw_method), $draw_arg); + $this->DoCallback('draw_graph', $this->plot_area); + + if ($draw_axes && $this->grid_at_foreground) { // Usually one wants grids to go back, but... + $this->DrawYAxis(); // Y axis must be drawn before X axis (see DrawYAxis()) + $this->DrawXAxis(); + $this->DoCallback('draw_axes'); + } + + if ($draw_axes) { + $this->DrawPlotBorder(); + $this->DoCallback('draw_border'); + } + + if ($this->legend) { + $this->DrawLegend(); + $this->DoCallback('draw_legend'); + } + $this->DoCallback('draw_all', $this->plot_area); + + if ($this->print_image && !$this->PrintImage()) + return FALSE; + + return TRUE; + } + +///////////////////////////////////////////// +////////////////// DEPRECATED METHODS +///////////////////////////////////////////// + + /* + * Note on deprecated methods - as these pre-date the PHPlot Reference + * Manual, and there is minimal documentation about them, I have neither + * removed them nor changed them. They are not tested or documented, and + * should not be used. + */ + + /* + * Deprecated, use SetYTickPos() + */ + function SetDrawVertTicks($which_dvt) + { + if ($which_dvt != 1) + $this->SetYTickPos('none'); + return TRUE; + } + + /* + * Deprecated, use SetXTickPos() + */ + function SetDrawHorizTicks($which_dht) + { + if ($which_dht != 1) + $this->SetXTickPos('none'); + return TRUE; + } + + /* + * Deprecated - use SetNumXTicks() + */ + function SetNumHorizTicks($n) + { + return $this->SetNumXTicks($n); + } + + /* + * Deprecated - use SetNumYTicks() + */ + function SetNumVertTicks($n) + { + return $this->SetNumYTicks($n); + } + + /* + * Deprecated - use SetXTickIncrement() + */ + function SetHorizTickIncrement($inc) + { + return $this->SetXTickIncrement($inc); + } + + /* + * Deprecated - use SetYTickIncrement() + */ + function SetVertTickIncrement($inc) + { + return $this->SetYTickIncrement($inc); + } + + /* + * Deprecated - use SetYTickPos() + */ + function SetVertTickPosition($which_tp) + { + return $this->SetYTickPos($which_tp); + } + + /* + * Deprecated - use SetXTickPos() + */ + function SetHorizTickPosition($which_tp) + { + return $this->SetXTickPos($which_tp); + } + + /* + * Deprecated - use SetFont() + */ + function SetTitleFontSize($which_size) + { + return $this->SetFont('title', $which_size); + } + + /* + * Deprecated - use SetFont() + */ + function SetAxisFontSize($which_size) + { + $this->SetFont('x_label', $which_size); + $this->SetFont('y_label', $which_size); + } + + /* + * Deprecated - use SetFont() + */ + function SetSmallFontSize($which_size) + { + return $this->SetFont('generic', $which_size); + } + + /* + * Deprecated - use SetFont() + */ + function SetXLabelFontSize($which_size) + { + return $this->SetFont('x_title', $which_size); + } + + /* + * Deprecated - use SetFont() + */ + function SetYLabelFontSize($which_size) + { + return $this->SetFont('y_title', $which_size); + } + + /* + * Deprecated - use SetXTitle() + */ + function SetXLabel($which_xlab) + { + return $this->SetXTitle($which_xlab); + } + + /* + * Deprecated - use SetYTitle() + */ + function SetYLabel($which_ylab) + { + return $this->SetYTitle($which_ylab); + } + + /* + * Deprecated - use SetXTickLength() and SetYTickLength() instead. + */ + function SetTickLength($which_tl) + { + $this->SetXTickLength($which_tl); + $this->SetYTickLength($which_tl); + return TRUE; + } + + /* + * Deprecated - use SetYLabelType() + */ + function SetYGridLabelType($which_yglt) + { + return $this->SetYLabelType($which_yglt); + } + + /* + * Deprecated - use SetXLabelType() + */ + function SetXGridLabelType($which_xglt) + { + return $this->SetXLabelType($which_xglt); + } + /* + * Deprecated - use SetYTickLabelPos() + */ + function SetYGridLabelPos($which_yglp) + { + return $this->SetYTickLabelPos($which_yglp); + } + /* + * Deprecated - use SetXTickLabelPos() + */ + function SetXGridLabelPos($which_xglp) + { + return $this->SetXTickLabelPos($which_xglp); + } + + /* + * Deprecated - use SetXtitle() + */ + function SetXTitlePos($xpos) + { + $this->x_title_pos = $xpos; + return TRUE; + } + + /* + * Deprecated - use SetYTitle() + */ + function SetYTitlePos($xpos) + { + $this->y_title_pos = $xpos; + return TRUE; + } + + /* + * Deprecated - use SetXDataLabelPos() + */ + function SetDrawXDataLabels($which_dxdl) + { + if ($which_dxdl == '1' ) + $this->SetXDataLabelPos('plotdown'); + else + $this->SetXDataLabelPos('none'); + } + + /* + * Deprecated - use SetPlotAreaPixels() + */ + function SetNewPlotAreaPixels($x1, $y1, $x2, $y2) + { + return $this->SetPlotAreaPixels($x1, $y1, $x2, $y2); + } + + /* + * Deprecated - use SetLineWidths(). + */ + function SetLineWidth($which_lw) + { + + $this->SetLineWidths($which_lw); + + if (!$this->error_bar_line_width) { + $this->SetErrorBarLineWidth($which_lw); + } + return TRUE; + } + + /* + * Deprecated - use SetPointShapes(). + */ + function SetPointShape($which_pt) + { + $this->SetPointShapes($which_pt); + return TRUE; + } + + /* + * Deprecated - use SetPointSizes(). + */ + function SetPointSize($which_ps) + { + $this->SetPointSizes($which_ps); + return TRUE; + } +} + +/* + * The PHPlot_truecolor class extends PHPlot to use GD truecolor images. + */ + +class PHPlot_truecolor extends PHPlot +{ + /* + * PHPlot Truecolor variation constructor: Create a PHPlot_truecolor object and initialize it. + * Note this does NOT call the parent (PHPlot) constructor. It duplicates the code here. + * Everything is the same as the PHPlot constructor except for imagecreatetruecolor. + * + * Parameters are the same as PHPlot: + * $which_width : Image width in pixels. + * $which_height : Image height in pixels. + * $which_output_file : Filename for output. + * $which_input_file : Path to a file to be used as background. + */ + function __construct($which_width=600, $which_height=400, $which_output_file=NULL, $which_input_file=NULL) + { + $this->SetRGBArray($this->color_array); + + if ($which_output_file) + $this->SetOutputFile($which_output_file); + + if ($which_input_file) { + $this->SetInputFile($which_input_file); + } else { + $this->image_width = $which_width; + $this->image_height = $which_height; + + $this->img = imagecreatetruecolor($this->image_width, $this->image_height); + if (! $this->img) + return $this->PrintError('PHPlot_truecolor(): Could not create image resource.'); + } + + $this->SetDefaultStyles(); + $this->SetDefaultFonts(); + } +} diff --git a/gui/bacula-web/classes/external/phplot/rgb.inc.php b/gui/bacula-web/classes/external/phplot/rgb.inc.php new file mode 100644 index 0000000000..41256ee25d --- /dev/null +++ b/gui/bacula-web/classes/external/phplot/rgb.inc.php @@ -0,0 +1,752 @@ +SetRGBArray('large') + * For more information on PHPlot see http://sourceforge.net/projects/phplot/ + * + * rgb.inc.php comes with PHPlot but is derived from the X11 rgb.txt color + * database file, which contains no specific copyright notice. It may be + * covered by X.Org, XFree86, or MIT/X11 copyright and license, all of which + * allow redistribution on terms which are less strict than the LGPL which + * covers PHPlot. + */ +$ColorArray = array( + "snow" => array(255, 250, 250), + "ghost white" => array(248, 248, 255), + "GhostWhite" => array(248, 248, 255), + "white smoke" => array(245, 245, 245), + "WhiteSmoke" => array(245, 245, 245), + "gainsboro" => array(220, 220, 220), + "floral white" => array(255, 250, 240), + "FloralWhite" => array(255, 250, 240), + "old lace" => array(253, 245, 230), + "OldLace" => array(253, 245, 230), + "linen" => array(250, 240, 230), + "antique white" => array(250, 235, 215), + "AntiqueWhite" => array(250, 235, 215), + "papaya whip" => array(255, 239, 213), + "PapayaWhip" => array(255, 239, 213), + "blanched almond" => array(255, 235, 205), + "BlanchedAlmond" => array(255, 235, 205), + "bisque" => array(255, 228, 196), + "peach puff" => array(255, 218, 185), + "PeachPuff" => array(255, 218, 185), + "navajo white" => array(255, 222, 173), + "NavajoWhite" => array(255, 222, 173), + "moccasin" => array(255, 228, 181), + "cornsilk" => array(255, 248, 220), + "ivory" => array(255, 255, 240), + "lemon chiffon" => array(255, 250, 205), + "LemonChiffon" => array(255, 250, 205), + "seashell" => array(255, 245, 238), + "honeydew" => array(240, 255, 240), + "mint cream" => array(245, 255, 250), + "MintCream" => array(245, 255, 250), + "azure" => array(240, 255, 255), + "alice blue" => array(240, 248, 255), + "AliceBlue" => array(240, 248, 255), + "lavender" => array(230, 230, 250), + "lavender blush" => array(255, 240, 245), + "LavenderBlush" => array(255, 240, 245), + "misty rose" => array(255, 228, 225), + "MistyRose" => array(255, 228, 225), + "white" => array(255, 255, 255), + "black" => array( 0, 0, 0), + "dark slate gray" => array( 47, 79, 79), + "DarkSlateGray" => array( 47, 79, 79), + "dark slate grey" => array( 47, 79, 79), + "DarkSlateGrey" => array( 47, 79, 79), + "dim gray" => array(105, 105, 105), + "DimGray" => array(105, 105, 105), + "dim grey" => array(105, 105, 105), + "DimGrey" => array(105, 105, 105), + "slate gray" => array(112, 128, 144), + "SlateGray" => array(112, 128, 144), + "slate grey" => array(112, 128, 144), + "SlateGrey" => array(112, 128, 144), + "light slate gray" => array(119, 136, 153), + "LightSlateGray" => array(119, 136, 153), + "light slate grey" => array(119, 136, 153), + "LightSlateGrey" => array(119, 136, 153), + "gray" => array(190, 190, 190), + "grey" => array(190, 190, 190), + "light grey" => array(211, 211, 211), + "LightGrey" => array(211, 211, 211), + "light gray" => array(211, 211, 211), + "LightGray" => array(211, 211, 211), + "midnight blue" => array( 25, 25, 112), + "MidnightBlue" => array( 25, 25, 112), + "navy" => array( 0, 0, 128), + "navy blue" => array( 0, 0, 128), + "NavyBlue" => array( 0, 0, 128), + "cornflower blue" => array(100, 149, 237), + "CornflowerBlue" => array(100, 149, 237), + "dark slate blue" => array( 72, 61, 139), + "DarkSlateBlue" => array( 72, 61, 139), + "slate blue" => array(106, 90, 205), + "SlateBlue" => array(106, 90, 205), + "medium slate blue" => array(123, 104, 238), + "MediumSlateBlue" => array(123, 104, 238), + "light slate blue" => array(132, 112, 255), + "LightSlateBlue" => array(132, 112, 255), + "medium blue" => array( 0, 0, 205), + "MediumBlue" => array( 0, 0, 205), + "royal blue" => array( 65, 105, 225), + "RoyalBlue" => array( 65, 105, 225), + "blue" => array( 0, 0, 255), + "dodger blue" => array( 30, 144, 255), + "DodgerBlue" => array( 30, 144, 255), + "deep sky blue" => array( 0, 191, 255), + "DeepSkyBlue" => array( 0, 191, 255), + "sky blue" => array(135, 206, 235), + "SkyBlue" => array(135, 206, 235), + "light sky blue" => array(135, 206, 250), + "LightSkyBlue" => array(135, 206, 250), + "steel blue" => array( 70, 130, 180), + "SteelBlue" => array( 70, 130, 180), + "light steel blue" => array(176, 196, 222), + "LightSteelBlue" => array(176, 196, 222), + "light blue" => array(173, 216, 230), + "LightBlue" => array(173, 216, 230), + "powder blue" => array(176, 224, 230), + "PowderBlue" => array(176, 224, 230), + "pale turquoise" => array(175, 238, 238), + "PaleTurquoise" => array(175, 238, 238), + "dark turquoise" => array( 0, 206, 209), + "DarkTurquoise" => array( 0, 206, 209), + "medium turquoise" => array( 72, 209, 204), + "MediumTurquoise" => array( 72, 209, 204), + "turquoise" => array( 64, 224, 208), + "cyan" => array( 0, 255, 255), + "light cyan" => array(224, 255, 255), + "LightCyan" => array(224, 255, 255), + "cadet blue" => array( 95, 158, 160), + "CadetBlue" => array( 95, 158, 160), + "medium aquamarine" => array(102, 205, 170), + "MediumAquamarine" => array(102, 205, 170), + "aquamarine" => array(127, 255, 212), + "dark green" => array( 0, 100, 0), + "DarkGreen" => array( 0, 100, 0), + "dark olive green" => array( 85, 107, 47), + "DarkOliveGreen" => array( 85, 107, 47), + "dark sea green" => array(143, 188, 143), + "DarkSeaGreen" => array(143, 188, 143), + "sea green" => array( 46, 139, 87), + "SeaGreen" => array( 46, 139, 87), + "medium sea green" => array( 60, 179, 113), + "MediumSeaGreen" => array( 60, 179, 113), + "light sea green" => array( 32, 178, 170), + "LightSeaGreen" => array( 32, 178, 170), + "pale green" => array(152, 251, 152), + "PaleGreen" => array(152, 251, 152), + "spring green" => array( 0, 255, 127), + "SpringGreen" => array( 0, 255, 127), + "lawn green" => array(124, 252, 0), + "LawnGreen" => array(124, 252, 0), + "green" => array( 0, 255, 0), + "chartreuse" => array(127, 255, 0), + "medium spring green" => array( 0, 250, 154), + "MediumSpringGreen" => array( 0, 250, 154), + "green yellow" => array(173, 255, 47), + "GreenYellow" => array(173, 255, 47), + "lime green" => array( 50, 205, 50), + "LimeGreen" => array( 50, 205, 50), + "yellow green" => array(154, 205, 50), + "YellowGreen" => array(154, 205, 50), + "forest green" => array( 34, 139, 34), + "ForestGreen" => array( 34, 139, 34), + "olive drab" => array(107, 142, 35), + "OliveDrab" => array(107, 142, 35), + "dark khaki" => array(189, 183, 107), + "DarkKhaki" => array(189, 183, 107), + "khaki" => array(240, 230, 140), + "pale goldenrod" => array(238, 232, 170), + "PaleGoldenrod" => array(238, 232, 170), + "light goldenrod yellow" => array(250, 250, 210), + "LightGoldenrodYellow" => array(250, 250, 210), + "light yellow" => array(255, 255, 224), + "LightYellow" => array(255, 255, 224), + "yellow" => array(255, 255, 0), + "gold" => array(255, 215, 0), + "light goldenrod" => array(238, 221, 130), + "LightGoldenrod" => array(238, 221, 130), + "goldenrod" => array(218, 165, 32), + "dark goldenrod" => array(184, 134, 11), + "DarkGoldenrod" => array(184, 134, 11), + "rosy brown" => array(188, 143, 143), + "RosyBrown" => array(188, 143, 143), + "indian red" => array(205, 92, 92), + "IndianRed" => array(205, 92, 92), + "saddle brown" => array(139, 69, 19), + "SaddleBrown" => array(139, 69, 19), + "sienna" => array(160, 82, 45), + "peru" => array(205, 133, 63), + "burlywood" => array(222, 184, 135), + "beige" => array(245, 245, 220), + "wheat" => array(245, 222, 179), + "sandy brown" => array(244, 164, 96), + "SandyBrown" => array(244, 164, 96), + "tan" => array(210, 180, 140), + "chocolate" => array(210, 105, 30), + "firebrick" => array(178, 34, 34), + "brown" => array(165, 42, 42), + "dark salmon" => array(233, 150, 122), + "DarkSalmon" => array(233, 150, 122), + "salmon" => array(250, 128, 114), + "light salmon" => array(255, 160, 122), + "LightSalmon" => array(255, 160, 122), + "orange" => array(255, 165, 0), + "dark orange" => array(255, 140, 0), + "DarkOrange" => array(255, 140, 0), + "coral" => array(255, 127, 80), + "light coral" => array(240, 128, 128), + "LightCoral" => array(240, 128, 128), + "tomato" => array(255, 99, 71), + "orange red" => array(255, 69, 0), + "OrangeRed" => array(255, 69, 0), + "red" => array(255, 0, 0), + "hot pink" => array(255, 105, 180), + "HotPink" => array(255, 105, 180), + "deep pink" => array(255, 20, 147), + "DeepPink" => array(255, 20, 147), + "pink" => array(255, 192, 203), + "light pink" => array(255, 182, 193), + "LightPink" => array(255, 182, 193), + "pale violet red" => array(219, 112, 147), + "PaleVioletRed" => array(219, 112, 147), + "maroon" => array(176, 48, 96), + "medium violet red" => array(199, 21, 133), + "MediumVioletRed" => array(199, 21, 133), + "violet red" => array(208, 32, 144), + "VioletRed" => array(208, 32, 144), + "magenta" => array(255, 0, 255), + "violet" => array(238, 130, 238), + "plum" => array(221, 160, 221), + "orchid" => array(218, 112, 214), + "medium orchid" => array(186, 85, 211), + "MediumOrchid" => array(186, 85, 211), + "dark orchid" => array(153, 50, 204), + "DarkOrchid" => array(153, 50, 204), + "dark violet" => array(148, 0, 211), + "DarkViolet" => array(148, 0, 211), + "blue violet" => array(138, 43, 226), + "BlueViolet" => array(138, 43, 226), + "purple" => array(160, 32, 240), + "medium purple" => array(147, 112, 219), + "MediumPurple" => array(147, 112, 219), + "thistle" => array(216, 191, 216), + "snow1" => array(255, 250, 250), + "snow2" => array(238, 233, 233), + "snow3" => array(205, 201, 201), + "snow4" => array(139, 137, 137), + "seashell1" => array(255, 245, 238), + "seashell2" => array(238, 229, 222), + "seashell3" => array(205, 197, 191), + "seashell4" => array(139, 134, 130), + "AntiqueWhite1" => array(255, 239, 219), + "AntiqueWhite2" => array(238, 223, 204), + "AntiqueWhite3" => array(205, 192, 176), + "AntiqueWhite4" => array(139, 131, 120), + "bisque1" => array(255, 228, 196), + "bisque2" => array(238, 213, 183), + "bisque3" => array(205, 183, 158), + "bisque4" => array(139, 125, 107), + "PeachPuff1" => array(255, 218, 185), + "PeachPuff2" => array(238, 203, 173), + "PeachPuff3" => array(205, 175, 149), + "PeachPuff4" => array(139, 119, 101), + "NavajoWhite1" => array(255, 222, 173), + "NavajoWhite2" => array(238, 207, 161), + "NavajoWhite3" => array(205, 179, 139), + "NavajoWhite4" => array(139, 121, 94), + "LemonChiffon1" => array(255, 250, 205), + "LemonChiffon2" => array(238, 233, 191), + "LemonChiffon3" => array(205, 201, 165), + "LemonChiffon4" => array(139, 137, 112), + "cornsilk1" => array(255, 248, 220), + "cornsilk2" => array(238, 232, 205), + "cornsilk3" => array(205, 200, 177), + "cornsilk4" => array(139, 136, 120), + "ivory1" => array(255, 255, 240), + "ivory2" => array(238, 238, 224), + "ivory3" => array(205, 205, 193), + "ivory4" => array(139, 139, 131), + "honeydew1" => array(240, 255, 240), + "honeydew2" => array(224, 238, 224), + "honeydew3" => array(193, 205, 193), + "honeydew4" => array(131, 139, 131), + "LavenderBlush1" => array(255, 240, 245), + "LavenderBlush2" => array(238, 224, 229), + "LavenderBlush3" => array(205, 193, 197), + "LavenderBlush4" => array(139, 131, 134), + "MistyRose1" => array(255, 228, 225), + "MistyRose2" => array(238, 213, 210), + "MistyRose3" => array(205, 183, 181), + "MistyRose4" => array(139, 125, 123), + "azure1" => array(240, 255, 255), + "azure2" => array(224, 238, 238), + "azure3" => array(193, 205, 205), + "azure4" => array(131, 139, 139), + "SlateBlue1" => array(131, 111, 255), + "SlateBlue2" => array(122, 103, 238), + "SlateBlue3" => array(105, 89, 205), + "SlateBlue4" => array( 71, 60, 139), + "RoyalBlue1" => array( 72, 118, 255), + "RoyalBlue2" => array( 67, 110, 238), + "RoyalBlue3" => array( 58, 95, 205), + "RoyalBlue4" => array( 39, 64, 139), + "blue1" => array( 0, 0, 255), + "blue2" => array( 0, 0, 238), + "blue3" => array( 0, 0, 205), + "blue4" => array( 0, 0, 139), + "DodgerBlue1" => array( 30, 144, 255), + "DodgerBlue2" => array( 28, 134, 238), + "DodgerBlue3" => array( 24, 116, 205), + "DodgerBlue4" => array( 16, 78, 139), + "SteelBlue1" => array( 99, 184, 255), + "SteelBlue2" => array( 92, 172, 238), + "SteelBlue3" => array( 79, 148, 205), + "SteelBlue4" => array( 54, 100, 139), + "DeepSkyBlue1" => array( 0, 191, 255), + "DeepSkyBlue2" => array( 0, 178, 238), + "DeepSkyBlue3" => array( 0, 154, 205), + "DeepSkyBlue4" => array( 0, 104, 139), + "SkyBlue1" => array(135, 206, 255), + "SkyBlue2" => array(126, 192, 238), + "SkyBlue3" => array(108, 166, 205), + "SkyBlue4" => array( 74, 112, 139), + "LightSkyBlue1" => array(176, 226, 255), + "LightSkyBlue2" => array(164, 211, 238), + "LightSkyBlue3" => array(141, 182, 205), + "LightSkyBlue4" => array( 96, 123, 139), + "SlateGray1" => array(198, 226, 255), + "SlateGray2" => array(185, 211, 238), + "SlateGray3" => array(159, 182, 205), + "SlateGray4" => array(108, 123, 139), + "LightSteelBlue1" => array(202, 225, 255), + "LightSteelBlue2" => array(188, 210, 238), + "LightSteelBlue3" => array(162, 181, 205), + "LightSteelBlue4" => array(110, 123, 139), + "LightBlue1" => array(191, 239, 255), + "LightBlue2" => array(178, 223, 238), + "LightBlue3" => array(154, 192, 205), + "LightBlue4" => array(104, 131, 139), + "LightCyan1" => array(224, 255, 255), + "LightCyan2" => array(209, 238, 238), + "LightCyan3" => array(180, 205, 205), + "LightCyan4" => array(122, 139, 139), + "PaleTurquoise1" => array(187, 255, 255), + "PaleTurquoise2" => array(174, 238, 238), + "PaleTurquoise3" => array(150, 205, 205), + "PaleTurquoise4" => array(102, 139, 139), + "CadetBlue1" => array(152, 245, 255), + "CadetBlue2" => array(142, 229, 238), + "CadetBlue3" => array(122, 197, 205), + "CadetBlue4" => array( 83, 134, 139), + "turquoise1" => array( 0, 245, 255), + "turquoise2" => array( 0, 229, 238), + "turquoise3" => array( 0, 197, 205), + "turquoise4" => array( 0, 134, 139), + "cyan1" => array( 0, 255, 255), + "cyan2" => array( 0, 238, 238), + "cyan3" => array( 0, 205, 205), + "cyan4" => array( 0, 139, 139), + "DarkSlateGray1" => array(151, 255, 255), + "DarkSlateGray2" => array(141, 238, 238), + "DarkSlateGray3" => array(121, 205, 205), + "DarkSlateGray4" => array( 82, 139, 139), + "aquamarine1" => array(127, 255, 212), + "aquamarine2" => array(118, 238, 198), + "aquamarine3" => array(102, 205, 170), + "aquamarine4" => array( 69, 139, 116), + "DarkSeaGreen1" => array(193, 255, 193), + "DarkSeaGreen2" => array(180, 238, 180), + "DarkSeaGreen3" => array(155, 205, 155), + "DarkSeaGreen4" => array(105, 139, 105), + "SeaGreen1" => array( 84, 255, 159), + "SeaGreen2" => array( 78, 238, 148), + "SeaGreen3" => array( 67, 205, 128), + "SeaGreen4" => array( 46, 139, 87), + "PaleGreen1" => array(154, 255, 154), + "PaleGreen2" => array(144, 238, 144), + "PaleGreen3" => array(124, 205, 124), + "PaleGreen4" => array( 84, 139, 84), + "SpringGreen1" => array( 0, 255, 127), + "SpringGreen2" => array( 0, 238, 118), + "SpringGreen3" => array( 0, 205, 102), + "SpringGreen4" => array( 0, 139, 69), + "green1" => array( 0, 255, 0), + "green2" => array( 0, 238, 0), + "green3" => array( 0, 205, 0), + "green4" => array( 0, 139, 0), + "chartreuse1" => array(127, 255, 0), + "chartreuse2" => array(118, 238, 0), + "chartreuse3" => array(102, 205, 0), + "chartreuse4" => array( 69, 139, 0), + "OliveDrab1" => array(192, 255, 62), + "OliveDrab2" => array(179, 238, 58), + "OliveDrab3" => array(154, 205, 50), + "OliveDrab4" => array(105, 139, 34), + "DarkOliveGreen1" => array(202, 255, 112), + "DarkOliveGreen2" => array(188, 238, 104), + "DarkOliveGreen3" => array(162, 205, 90), + "DarkOliveGreen4" => array(110, 139, 61), + "khaki1" => array(255, 246, 143), + "khaki2" => array(238, 230, 133), + "khaki3" => array(205, 198, 115), + "khaki4" => array(139, 134, 78), + "LightGoldenrod1" => array(255, 236, 139), + "LightGoldenrod2" => array(238, 220, 130), + "LightGoldenrod3" => array(205, 190, 112), + "LightGoldenrod4" => array(139, 129, 76), + "LightYellow1" => array(255, 255, 224), + "LightYellow2" => array(238, 238, 209), + "LightYellow3" => array(205, 205, 180), + "LightYellow4" => array(139, 139, 122), + "yellow1" => array(255, 255, 0), + "yellow2" => array(238, 238, 0), + "yellow3" => array(205, 205, 0), + "yellow4" => array(139, 139, 0), + "gold1" => array(255, 215, 0), + "gold2" => array(238, 201, 0), + "gold3" => array(205, 173, 0), + "gold4" => array(139, 117, 0), + "goldenrod1" => array(255, 193, 37), + "goldenrod2" => array(238, 180, 34), + "goldenrod3" => array(205, 155, 29), + "goldenrod4" => array(139, 105, 20), + "DarkGoldenrod1" => array(255, 185, 15), + "DarkGoldenrod2" => array(238, 173, 14), + "DarkGoldenrod3" => array(205, 149, 12), + "DarkGoldenrod4" => array(139, 101, 8), + "RosyBrown1" => array(255, 193, 193), + "RosyBrown2" => array(238, 180, 180), + "RosyBrown3" => array(205, 155, 155), + "RosyBrown4" => array(139, 105, 105), + "IndianRed1" => array(255, 106, 106), + "IndianRed2" => array(238, 99, 99), + "IndianRed3" => array(205, 85, 85), + "IndianRed4" => array(139, 58, 58), + "sienna1" => array(255, 130, 71), + "sienna2" => array(238, 121, 66), + "sienna3" => array(205, 104, 57), + "sienna4" => array(139, 71, 38), + "burlywood1" => array(255, 211, 155), + "burlywood2" => array(238, 197, 145), + "burlywood3" => array(205, 170, 125), + "burlywood4" => array(139, 115, 85), + "wheat1" => array(255, 231, 186), + "wheat2" => array(238, 216, 174), + "wheat3" => array(205, 186, 150), + "wheat4" => array(139, 126, 102), + "tan1" => array(255, 165, 79), + "tan2" => array(238, 154, 73), + "tan3" => array(205, 133, 63), + "tan4" => array(139, 90, 43), + "chocolate1" => array(255, 127, 36), + "chocolate2" => array(238, 118, 33), + "chocolate3" => array(205, 102, 29), + "chocolate4" => array(139, 69, 19), + "firebrick1" => array(255, 48, 48), + "firebrick2" => array(238, 44, 44), + "firebrick3" => array(205, 38, 38), + "firebrick4" => array(139, 26, 26), + "brown1" => array(255, 64, 64), + "brown2" => array(238, 59, 59), + "brown3" => array(205, 51, 51), + "brown4" => array(139, 35, 35), + "salmon1" => array(255, 140, 105), + "salmon2" => array(238, 130, 98), + "salmon3" => array(205, 112, 84), + "salmon4" => array(139, 76, 57), + "LightSalmon1" => array(255, 160, 122), + "LightSalmon2" => array(238, 149, 114), + "LightSalmon3" => array(205, 129, 98), + "LightSalmon4" => array(139, 87, 66), + "orange1" => array(255, 165, 0), + "orange2" => array(238, 154, 0), + "orange3" => array(205, 133, 0), + "orange4" => array(139, 90, 0), + "DarkOrange1" => array(255, 127, 0), + "DarkOrange2" => array(238, 118, 0), + "DarkOrange3" => array(205, 102, 0), + "DarkOrange4" => array(139, 69, 0), + "coral1" => array(255, 114, 86), + "coral2" => array(238, 106, 80), + "coral3" => array(205, 91, 69), + "coral4" => array(139, 62, 47), + "tomato1" => array(255, 99, 71), + "tomato2" => array(238, 92, 66), + "tomato3" => array(205, 79, 57), + "tomato4" => array(139, 54, 38), + "OrangeRed1" => array(255, 69, 0), + "OrangeRed2" => array(238, 64, 0), + "OrangeRed3" => array(205, 55, 0), + "OrangeRed4" => array(139, 37, 0), + "red1" => array(255, 0, 0), + "red2" => array(238, 0, 0), + "red3" => array(205, 0, 0), + "red4" => array(139, 0, 0), + "DeepPink1" => array(255, 20, 147), + "DeepPink2" => array(238, 18, 137), + "DeepPink3" => array(205, 16, 118), + "DeepPink4" => array(139, 10, 80), + "HotPink1" => array(255, 110, 180), + "HotPink2" => array(238, 106, 167), + "HotPink3" => array(205, 96, 144), + "HotPink4" => array(139, 58, 98), + "pink1" => array(255, 181, 197), + "pink2" => array(238, 169, 184), + "pink3" => array(205, 145, 158), + "pink4" => array(139, 99, 108), + "LightPink1" => array(255, 174, 185), + "LightPink2" => array(238, 162, 173), + "LightPink3" => array(205, 140, 149), + "LightPink4" => array(139, 95, 101), + "PaleVioletRed1" => array(255, 130, 171), + "PaleVioletRed2" => array(238, 121, 159), + "PaleVioletRed3" => array(205, 104, 137), + "PaleVioletRed4" => array(139, 71, 93), + "maroon1" => array(255, 52, 179), + "maroon2" => array(238, 48, 167), + "maroon3" => array(205, 41, 144), + "maroon4" => array(139, 28, 98), + "VioletRed1" => array(255, 62, 150), + "VioletRed2" => array(238, 58, 140), + "VioletRed3" => array(205, 50, 120), + "VioletRed4" => array(139, 34, 82), + "magenta1" => array(255, 0, 255), + "magenta2" => array(238, 0, 238), + "magenta3" => array(205, 0, 205), + "magenta4" => array(139, 0, 139), + "orchid1" => array(255, 131, 250), + "orchid2" => array(238, 122, 233), + "orchid3" => array(205, 105, 201), + "orchid4" => array(139, 71, 137), + "plum1" => array(255, 187, 255), + "plum2" => array(238, 174, 238), + "plum3" => array(205, 150, 205), + "plum4" => array(139, 102, 139), + "MediumOrchid1" => array(224, 102, 255), + "MediumOrchid2" => array(209, 95, 238), + "MediumOrchid3" => array(180, 82, 205), + "MediumOrchid4" => array(122, 55, 139), + "DarkOrchid1" => array(191, 62, 255), + "DarkOrchid2" => array(178, 58, 238), + "DarkOrchid3" => array(154, 50, 205), + "DarkOrchid4" => array(104, 34, 139), + "purple1" => array(155, 48, 255), + "purple2" => array(145, 44, 238), + "purple3" => array(125, 38, 205), + "purple4" => array( 85, 26, 139), + "MediumPurple1" => array(171, 130, 255), + "MediumPurple2" => array(159, 121, 238), + "MediumPurple3" => array(137, 104, 205), + "MediumPurple4" => array( 93, 71, 139), + "thistle1" => array(255, 225, 255), + "thistle2" => array(238, 210, 238), + "thistle3" => array(205, 181, 205), + "thistle4" => array(139, 123, 139), + "gray0" => array( 0, 0, 0), + "grey0" => array( 0, 0, 0), + "gray1" => array( 3, 3, 3), + "grey1" => array( 3, 3, 3), + "gray2" => array( 5, 5, 5), + "grey2" => array( 5, 5, 5), + "gray3" => array( 8, 8, 8), + "grey3" => array( 8, 8, 8), + "gray4" => array( 10, 10, 10), + "grey4" => array( 10, 10, 10), + "gray5" => array( 13, 13, 13), + "grey5" => array( 13, 13, 13), + "gray6" => array( 15, 15, 15), + "grey6" => array( 15, 15, 15), + "gray7" => array( 18, 18, 18), + "grey7" => array( 18, 18, 18), + "gray8" => array( 20, 20, 20), + "grey8" => array( 20, 20, 20), + "gray9" => array( 23, 23, 23), + "grey9" => array( 23, 23, 23), + "gray10" => array( 26, 26, 26), + "grey10" => array( 26, 26, 26), + "gray11" => array( 28, 28, 28), + "grey11" => array( 28, 28, 28), + "gray12" => array( 31, 31, 31), + "grey12" => array( 31, 31, 31), + "gray13" => array( 33, 33, 33), + "grey13" => array( 33, 33, 33), + "gray14" => array( 36, 36, 36), + "grey14" => array( 36, 36, 36), + "gray15" => array( 38, 38, 38), + "grey15" => array( 38, 38, 38), + "gray16" => array( 41, 41, 41), + "grey16" => array( 41, 41, 41), + "gray17" => array( 43, 43, 43), + "grey17" => array( 43, 43, 43), + "gray18" => array( 46, 46, 46), + "grey18" => array( 46, 46, 46), + "gray19" => array( 48, 48, 48), + "grey19" => array( 48, 48, 48), + "gray20" => array( 51, 51, 51), + "grey20" => array( 51, 51, 51), + "gray21" => array( 54, 54, 54), + "grey21" => array( 54, 54, 54), + "gray22" => array( 56, 56, 56), + "grey22" => array( 56, 56, 56), + "gray23" => array( 59, 59, 59), + "grey23" => array( 59, 59, 59), + "gray24" => array( 61, 61, 61), + "grey24" => array( 61, 61, 61), + "gray25" => array( 64, 64, 64), + "grey25" => array( 64, 64, 64), + "gray26" => array( 66, 66, 66), + "grey26" => array( 66, 66, 66), + "gray27" => array( 69, 69, 69), + "grey27" => array( 69, 69, 69), + "gray28" => array( 71, 71, 71), + "grey28" => array( 71, 71, 71), + "gray29" => array( 74, 74, 74), + "grey29" => array( 74, 74, 74), + "gray30" => array( 77, 77, 77), + "grey30" => array( 77, 77, 77), + "gray31" => array( 79, 79, 79), + "grey31" => array( 79, 79, 79), + "gray32" => array( 82, 82, 82), + "grey32" => array( 82, 82, 82), + "gray33" => array( 84, 84, 84), + "grey33" => array( 84, 84, 84), + "gray34" => array( 87, 87, 87), + "grey34" => array( 87, 87, 87), + "gray35" => array( 89, 89, 89), + "grey35" => array( 89, 89, 89), + "gray36" => array( 92, 92, 92), + "grey36" => array( 92, 92, 92), + "gray37" => array( 94, 94, 94), + "grey37" => array( 94, 94, 94), + "gray38" => array( 97, 97, 97), + "grey38" => array( 97, 97, 97), + "gray39" => array( 99, 99, 99), + "grey39" => array( 99, 99, 99), + "gray40" => array(102, 102, 102), + "grey40" => array(102, 102, 102), + "gray41" => array(105, 105, 105), + "grey41" => array(105, 105, 105), + "gray42" => array(107, 107, 107), + "grey42" => array(107, 107, 107), + "gray43" => array(110, 110, 110), + "grey43" => array(110, 110, 110), + "gray44" => array(112, 112, 112), + "grey44" => array(112, 112, 112), + "gray45" => array(115, 115, 115), + "grey45" => array(115, 115, 115), + "gray46" => array(117, 117, 117), + "grey46" => array(117, 117, 117), + "gray47" => array(120, 120, 120), + "grey47" => array(120, 120, 120), + "gray48" => array(122, 122, 122), + "grey48" => array(122, 122, 122), + "gray49" => array(125, 125, 125), + "grey49" => array(125, 125, 125), + "gray50" => array(127, 127, 127), + "grey50" => array(127, 127, 127), + "gray51" => array(130, 130, 130), + "grey51" => array(130, 130, 130), + "gray52" => array(133, 133, 133), + "grey52" => array(133, 133, 133), + "gray53" => array(135, 135, 135), + "grey53" => array(135, 135, 135), + "gray54" => array(138, 138, 138), + "grey54" => array(138, 138, 138), + "gray55" => array(140, 140, 140), + "grey55" => array(140, 140, 140), + "gray56" => array(143, 143, 143), + "grey56" => array(143, 143, 143), + "gray57" => array(145, 145, 145), + "grey57" => array(145, 145, 145), + "gray58" => array(148, 148, 148), + "grey58" => array(148, 148, 148), + "gray59" => array(150, 150, 150), + "grey59" => array(150, 150, 150), + "gray60" => array(153, 153, 153), + "grey60" => array(153, 153, 153), + "gray61" => array(156, 156, 156), + "grey61" => array(156, 156, 156), + "gray62" => array(158, 158, 158), + "grey62" => array(158, 158, 158), + "gray63" => array(161, 161, 161), + "grey63" => array(161, 161, 161), + "gray64" => array(163, 163, 163), + "grey64" => array(163, 163, 163), + "gray65" => array(166, 166, 166), + "grey65" => array(166, 166, 166), + "gray66" => array(168, 168, 168), + "grey66" => array(168, 168, 168), + "gray67" => array(171, 171, 171), + "grey67" => array(171, 171, 171), + "gray68" => array(173, 173, 173), + "grey68" => array(173, 173, 173), + "gray69" => array(176, 176, 176), + "grey69" => array(176, 176, 176), + "gray70" => array(179, 179, 179), + "grey70" => array(179, 179, 179), + "gray71" => array(181, 181, 181), + "grey71" => array(181, 181, 181), + "gray72" => array(184, 184, 184), + "grey72" => array(184, 184, 184), + "gray73" => array(186, 186, 186), + "grey73" => array(186, 186, 186), + "gray74" => array(189, 189, 189), + "grey74" => array(189, 189, 189), + "gray75" => array(191, 191, 191), + "grey75" => array(191, 191, 191), + "gray76" => array(194, 194, 194), + "grey76" => array(194, 194, 194), + "gray77" => array(196, 196, 196), + "grey77" => array(196, 196, 196), + "gray78" => array(199, 199, 199), + "grey78" => array(199, 199, 199), + "gray79" => array(201, 201, 201), + "grey79" => array(201, 201, 201), + "gray80" => array(204, 204, 204), + "grey80" => array(204, 204, 204), + "gray81" => array(207, 207, 207), + "grey81" => array(207, 207, 207), + "gray82" => array(209, 209, 209), + "grey82" => array(209, 209, 209), + "gray83" => array(212, 212, 212), + "grey83" => array(212, 212, 212), + "gray84" => array(214, 214, 214), + "grey84" => array(214, 214, 214), + "gray85" => array(217, 217, 217), + "grey85" => array(217, 217, 217), + "gray86" => array(219, 219, 219), + "grey86" => array(219, 219, 219), + "gray87" => array(222, 222, 222), + "grey87" => array(222, 222, 222), + "gray88" => array(224, 224, 224), + "grey88" => array(224, 224, 224), + "gray89" => array(227, 227, 227), + "grey89" => array(227, 227, 227), + "gray90" => array(229, 229, 229), + "grey90" => array(229, 229, 229), + "gray91" => array(232, 232, 232), + "grey91" => array(232, 232, 232), + "gray92" => array(235, 235, 235), + "grey92" => array(235, 235, 235), + "gray93" => array(237, 237, 237), + "grey93" => array(237, 237, 237), + "gray94" => array(240, 240, 240), + "grey94" => array(240, 240, 240), + "gray95" => array(242, 242, 242), + "grey95" => array(242, 242, 242), + "gray96" => array(245, 245, 245), + "grey96" => array(245, 245, 245), + "gray97" => array(247, 247, 247), + "grey97" => array(247, 247, 247), + "gray98" => array(250, 250, 250), + "grey98" => array(250, 250, 250), + "gray99" => array(252, 252, 252), + "grey99" => array(252, 252, 252), + "gray100" => array(255, 255, 255) +); diff --git a/gui/bacula-web/classes/external/smarty/BUGS b/gui/bacula-web/classes/external/smarty/BUGS new file mode 100644 index 0000000000..9f1a80f31c --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/BUGS @@ -0,0 +1,7 @@ +Smarty is supported only in PHP 4.0.6 or later. + +Smarty versions previous to 2.0 require the PEAR libraries. Be sure to include +the path to the PEAR libraries in your php include_path. Config_file.class.php +uses the PEAR library for its error handling routines. PEAR comes with the PHP +distribution. Unix users check /usr/local/lib/php, windows users check +C:/php/pear. diff --git a/gui/bacula-web/classes/external/smarty/COPYING.lib b/gui/bacula-web/classes/external/smarty/COPYING.lib new file mode 100644 index 0000000000..3b204400cf --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/COPYING.lib @@ -0,0 +1,458 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 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 diff --git a/gui/bacula-web/classes/external/smarty/ChangeLog b/gui/bacula-web/classes/external/smarty/ChangeLog new file mode 100644 index 0000000000..4dd5340598 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/ChangeLog @@ -0,0 +1,9179 @@ +2007-09-27 TAKAGI Masahiro + + * docs/ja/designers/language-custom-functions/language-function-html-checkboxes.xml: + sync with en. + +2007-09-27 Monte Ohrt + + * docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml: + remove redundant attribute + +2007-09-18 Messju Mohr + + * docs/id/programmers/plugins/plugins-functions.xml: + removed errornous whitespace + +2007-09-18 Zaenal Mutaqin + + * docs/id/designers/language-basic-syntax/language-escaping.xml + docs/id/designers/language-basic-syntax/language-math.xml + docs/id/designers/language-basic-syntax/language-syntax-attributes.xml + docs/id/designers/language-basic-syntax/language-syntax-comments.xml + docs/id/designers/language-basic-syntax/language-syntax-functions.xml + docs/id/designers/language-basic-syntax/language-syntax-quotes.xml + docs/id/designers/language-basic-syntax/language-syntax-variables.xml + docs/id/designers/language-builtin-functions/language-function-capture.xml + docs/id/designers/language-builtin-functions/language-function-config-load.xml + docs/id/designers/language-builtin-functions/language-function-foreach.xml + docs/id/designers/language-builtin-functions/language-function-if.xml + docs/id/designers/language-builtin-functions/language-function-include-php.xml + docs/id/designers/language-builtin-functions/language-function-include.xml + docs/id/designers/language-builtin-functions/language-function-insert.xml + docs/id/designers/language-builtin-functions/language-function-ldelim.xml + docs/id/designers/language-builtin-functions/language-function-literal.xml + docs/id/designers/language-builtin-functions/language-function-php.xml + docs/id/designers/language-builtin-functions/language-function-section.xml + docs/id/designers/language-builtin-functions/language-function-strip.xml + docs/id/designers/language-custom-functions/language-function-assign.xml + docs/id/designers/language-custom-functions/language-function-counter.xml + docs/id/designers/language-custom-functions/language-function-cycle.xml + docs/id/designers/language-custom-functions/language-function-debug.xml + docs/id/designers/language-custom-functions/language-function-eval.xml + docs/id/designers/language-custom-functions/language-function-fetch.xml + docs/id/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/id/designers/language-custom-functions/language-function-html-image.xml + docs/id/designers/language-custom-functions/language-function-html-options.xml + docs/id/designers/language-custom-functions/language-function-html-radios.xml + docs/id/designers/language-custom-functions/language-function-html-select-date.xml + docs/id/designers/language-custom-functions/language-function-html-select-time.xml + docs/id/designers/language-custom-functions/language-function-html-table.xml + docs/id/designers/language-custom-functions/language-function-mailto.xml + docs/id/designers/language-custom-functions/language-function-math.xml + docs/id/designers/language-custom-functions/language-function-popup-init.xml + docs/id/designers/language-custom-functions/language-function-popup.xml + docs/id/designers/language-custom-functions/language-function-textformat.xml + docs/id/designers/language-modifiers/language-modifier-capitalize.xml + docs/id/designers/language-modifiers/language-modifier-cat.xml + docs/id/designers/language-modifiers/language-modifier-count-characters.xml + docs/id/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/id/designers/language-modifiers/language-modifier-count-sentences.xml + docs/id/designers/language-modifiers/language-modifier-count-words.xml + docs/id/designers/language-modifiers/language-modifier-date-format.xml + docs/id/designers/language-modifiers/language-modifier-default.xml + docs/id/designers/language-modifiers/language-modifier-escape.xml + docs/id/designers/language-modifiers/language-modifier-indent.xml + docs/id/designers/language-modifiers/language-modifier-lower.xml + docs/id/designers/language-modifiers/language-modifier-nl2br.xml + docs/id/designers/language-modifiers/language-modifier-regex-replace.xml + docs/id/designers/language-modifiers/language-modifier-replace.xml + docs/id/designers/language-modifiers/language-modifier-spacify.xml + docs/id/designers/language-modifiers/language-modifier-string-format.xml + docs/id/designers/language-modifiers/language-modifier-strip-tags.xml + docs/id/designers/language-modifiers/language-modifier-strip.xml + docs/id/designers/language-modifiers/language-modifier-truncate.xml + docs/id/designers/language-modifiers/language-modifier-upper.xml + docs/id/designers/language-modifiers/language-modifier-wordwrap.xml + docs/id/designers/language-variables/language-assigned-variables.xml + docs/id/designers/language-variables/language-config-variables.xml + docs/id/designers/language-variables/language-variables-smarty.xml + docs/id/programmers/advanced-features/advanced-features-objects.xml + docs/id/programmers/advanced-features/advanced-features-outputfilters.xml + docs/id/programmers/advanced-features/advanced-features-postfilters.xml + docs/id/programmers/advanced-features/advanced-features-prefilters.xml + docs/id/programmers/advanced-features/section-template-cache-handler-func.xml + docs/id/programmers/advanced-features/template-resources.xml + docs/id/programmers/api-functions/api-append-by-ref.xml + docs/id/programmers/api-functions/api-append.xml + docs/id/programmers/api-functions/api-assign-by-ref.xml + docs/id/programmers/api-functions/api-assign.xml + docs/id/programmers/api-functions/api-clear-all-assign.xml + docs/id/programmers/api-functions/api-clear-all-cache.xml + docs/id/programmers/api-functions/api-clear-assign.xml + docs/id/programmers/api-functions/api-clear-cache.xml + docs/id/programmers/api-functions/api-clear-compiled-tpl.xml + docs/id/programmers/api-functions/api-clear-config.xml + docs/id/programmers/api-functions/api-config-load.xml + docs/id/programmers/api-functions/api-display.xml + docs/id/programmers/api-functions/api-fetch.xml + docs/id/programmers/api-functions/api-get-config-vars.xml + docs/id/programmers/api-functions/api-get-registered-object.xml + docs/id/programmers/api-functions/api-get-template-vars.xml + docs/id/programmers/api-functions/api-is-cached.xml + docs/id/programmers/api-functions/api-load-filter.xml + docs/id/programmers/api-functions/api-register-block.xml + docs/id/programmers/api-functions/api-register-compiler-function.xml + docs/id/programmers/api-functions/api-register-function.xml + docs/id/programmers/api-functions/api-register-modifier.xml + docs/id/programmers/api-functions/api-register-object.xml + docs/id/programmers/api-functions/api-register-outputfilter.xml + docs/id/programmers/api-functions/api-register-postfilter.xml + docs/id/programmers/api-functions/api-register-prefilter.xml + docs/id/programmers/api-functions/api-register-resource.xml + docs/id/programmers/api-functions/api-template-exists.xml + docs/id/programmers/api-functions/api-trigger-error.xml + docs/id/programmers/api-functions/api-unregister-block.xml + docs/id/programmers/api-functions/api-unregister-compiler-function.xml + docs/id/programmers/api-functions/api-unregister-function.xml + docs/id/programmers/api-functions/api-unregister-modifier.xml + docs/id/programmers/api-functions/api-unregister-object.xml + docs/id/programmers/api-functions/api-unregister-outputfilter.xml + docs/id/programmers/api-functions/api-unregister-postfilter.xml + docs/id/programmers/api-functions/api-unregister-prefilter.xml + docs/id/programmers/api-functions/api-unregister-resource.xml + docs/id/programmers/api-variables/variable-autoload-filters.xml + docs/id/programmers/api-variables/variable-cache-dir.xml + docs/id/programmers/api-variables/variable-cache-handler-func.xml + docs/id/programmers/api-variables/variable-cache-lifetime.xml + docs/id/programmers/api-variables/variable-cache-modified-check.xml + docs/id/programmers/api-variables/variable-caching.xml + docs/id/programmers/api-variables/variable-compile-check.xml + docs/id/programmers/api-variables/variable-compile-dir.xml + docs/id/programmers/api-variables/variable-compile-id.xml + docs/id/programmers/api-variables/variable-compiler-class.xml + docs/id/programmers/api-variables/variable-config-booleanize.xml + docs/id/programmers/api-variables/variable-config-dir.xml + docs/id/programmers/api-variables/variable-config-fix-newlines.xml + docs/id/programmers/api-variables/variable-config-overwrite.xml + docs/id/programmers/api-variables/variable-config-read-hidden.xml + docs/id/programmers/api-variables/variable-debug-tpl.xml + docs/id/programmers/api-variables/variable-debugging-ctrl.xml + docs/id/programmers/api-variables/variable-debugging.xml + docs/id/programmers/api-variables/variable-default-modifiers.xml + docs/id/programmers/api-variables/variable-default-resource-type.xml + docs/id/programmers/api-variables/variable-default-template-handler-func.xml + docs/id/programmers/api-variables/variable-error-reporting.xml + docs/id/programmers/api-variables/variable-force-compile.xml + docs/id/programmers/api-variables/variable-left-delimiter.xml + docs/id/programmers/api-variables/variable-php-handling.xml + docs/id/programmers/api-variables/variable-plugins-dir.xml + docs/id/programmers/api-variables/variable-request-use-auto-globals.xml + docs/id/programmers/api-variables/variable-request-vars-order.xml + docs/id/programmers/api-variables/variable-right-delimiter.xml + docs/id/programmers/api-variables/variable-secure-dir.xml + docs/id/programmers/api-variables/variable-security-settings.xml + docs/id/programmers/api-variables/variable-security.xml + docs/id/programmers/api-variables/variable-template-dir.xml + docs/id/programmers/api-variables/variable-trusted-dir.xml + docs/id/programmers/api-variables/variable-use-sub-dirs.xml + docs/id/programmers/caching/caching-cacheable.xml + docs/id/programmers/caching/caching-groups.xml + docs/id/programmers/caching/caching-multiple-caches.xml + docs/id/programmers/caching/caching-setting-up.xml + docs/id/programmers/plugins/plugins-block-functions.xml + docs/id/programmers/plugins/plugins-compiler-functions.xml + docs/id/programmers/plugins/plugins-functions.xml + docs/id/programmers/plugins/plugins-howto.xml + docs/id/programmers/plugins/plugins-inserts.xml + docs/id/programmers/plugins/plugins-modifiers.xml + docs/id/programmers/plugins/plugins-naming-conventions.xml + docs/id/programmers/plugins/plugins-outputfilters.xml + docs/id/programmers/plugins/plugins-prefilters-postfilters.xml + docs/id/programmers/plugins/plugins-resources.xml + docs/id/programmers/plugins/plugins-writing.xml: + Typos correction and all translated now. + +2007-09-17 Messju Mohr + + * docs/id/bookinfo.xml + docs/id/getting-started.xml + docs/id/language-defs.ent + docs/id/language-snippets.ent + docs/id/livedocs.ent + docs/id/preface.xml: + added indonesian docs - thanks Zaenal Mutaqin + + * docs/scripts/generate_web.php: + raise pcre.backtrack_limit - thanks to takagi + +2007-09-16 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix typo + +2007-08-22 George Miroshnikov + + * docs/ru/getting-started.xml + docs/ru/getting-started.xml: + Sync with EN. + +2007-08-01 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + add append feature to capture + +2007-06-24 TAKAGI Masahiro + + * docs/ja/getting-started.xml: + sync with en. + +2007-06-24 Messju Mohr + + * docs/Makefile.in: + reverted accidently modified file + + * docs/Makefile.in + docs/de/getting-started.xml: + sync with en + + * docs/en/getting-started.xml: + fixed link to ini_set(). thanks to Lee Yunyoung. + +2007-06-18 TAKAGI Masahiro + + * docs/ja/language-snippets.ent + docs/ja/programmers/api-functions/api-register-outputfilter.xml + docs/ja/programmers/api-functions/api-register-postfilter.xml + docs/ja/programmers/api-functions/api-register-prefilter.xml: + sync with en. + +2007-06-18 Danilo Buerger + + * docs/en/language-snippets.ent + docs/en/programmers/api-functions/api-register-outputfilter.xml + docs/en/programmers/api-functions/api-register-postfilter.xml + docs/en/programmers/api-functions/api-register-prefilter.xml: + Updated docs according to the changes from the previous commit + + * NEWS + libs/Smarty.class.php: + Added the ability to (un)register multiple filters of the same type with + the same method name but different class name. Before it was not possible + due to the fact that only the method name was used to distinguish between + different filters of the same type. This does however not allow (same as + before) to register multiple filters of the same type with the same method + and class name (i.e. different instances of the same class). + +2007-05-29 Messju Mohr + + * libs/plugins/compiler.assign.php: + fixed typo + +2007-05-11 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed calling registered objects' methods with an empty argument list. + thanks marcello + +2007-05-03 TAKAGI Masahiro + + * docs/ja/designers/language-variables.xml + docs/ja/designers/language-builtin-functions/language-function-config-load.xml + docs/ja/designers/language-builtin-functions/language-function-foreach.xml + docs/ja/designers/language-builtin-functions/language-function-if.xml + docs/ja/designers/language-modifiers/language-modifier-cat.xml + docs/ja/designers/language-modifiers/language-modifier-wordwrap.xml + docs/ja/designers/language-variables/language-variables-smarty.xml: + sync with en. + +2007-05-03 Monte Ohrt + + * docs/en/designers/language-variables.xml + docs/en/designers/language-builtin-functions/language-function-config-load.xml + docs/en/designers/language-builtin-functions/language-function-foreach.xml + docs/en/designers/language-builtin-functions/language-function-if.xml + docs/en/designers/language-modifiers/language-modifier-cat.xml + docs/en/designers/language-modifiers/language-modifier-wordwrap.xml + docs/en/designers/language-variables/language-variables-smarty.xml: + update documentation corrections from marcello in the forums. Thanks + marcello! + +2007-04-22 TAKAGI Masahiro + + * docs/ja/programmers/advanced-features.xml + docs/ja/programmers/api-functions.xml + docs/ja/programmers/api-variables.xml: + corrected the garbled text. + +2007-04-21 TAKAGI Masahiro + + * docs/ja/bookinfo.xml + docs/ja/getting-started.xml + docs/ja/language-defs.ent + docs/ja/language-snippets.ent + docs/ja/livedocs.ent + docs/ja/make_chm_index.html + docs/ja/preface.xml + docs/ja/translation.xml + docs/ja/appendixes/bugs.xml + docs/ja/appendixes/resources.xml + docs/ja/appendixes/tips.xml + docs/ja/appendixes/troubleshooting.xml + docs/ja/designers/chapter-debugging-console.xml + docs/ja/designers/config-files.xml + docs/ja/designers/language-basic-syntax.xml + docs/ja/designers/language-builtin-functions.xml + docs/ja/designers/language-combining-modifiers.xml + docs/ja/designers/language-custom-functions.xml + docs/ja/designers/language-modifiers.xml + docs/ja/designers/language-variables.xml + docs/ja/designers/language-basic-syntax/language-escaping.xml + docs/ja/designers/language-basic-syntax/language-math.xml + docs/ja/designers/language-basic-syntax/language-syntax-attributes.xml + docs/ja/designers/language-basic-syntax/language-syntax-comments.xml + docs/ja/designers/language-basic-syntax/language-syntax-functions.xml + docs/ja/designers/language-basic-syntax/language-syntax-quotes.xml + docs/ja/designers/language-basic-syntax/language-syntax-variables.xml + docs/ja/designers/language-builtin-functions/language-function-capture.xml + docs/ja/designers/language-builtin-functions/language-function-config-load.xml + docs/ja/designers/language-builtin-functions/language-function-foreach.xml + docs/ja/designers/language-builtin-functions/language-function-if.xml + docs/ja/designers/language-builtin-functions/language-function-include-php.xml + docs/ja/designers/language-builtin-functions/language-function-include.xml + docs/ja/designers/language-builtin-functions/language-function-insert.xml + docs/ja/designers/language-builtin-functions/language-function-ldelim.xml + docs/ja/designers/language-builtin-functions/language-function-literal.xml + docs/ja/designers/language-builtin-functions/language-function-php.xml + docs/ja/designers/language-builtin-functions/language-function-section.xml + docs/ja/designers/language-builtin-functions/language-function-strip.xml + docs/ja/designers/language-custom-functions/language-function-assign.xml + docs/ja/designers/language-custom-functions/language-function-counter.xml + docs/ja/designers/language-custom-functions/language-function-cycle.xml + docs/ja/designers/language-custom-functions/language-function-debug.xml + docs/ja/designers/language-custom-functions/language-function-eval.xml + docs/ja/designers/language-custom-functions/language-function-fetch.xml + docs/ja/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/ja/designers/language-custom-functions/language-function-html-image.xml + docs/ja/designers/language-custom-functions/language-function-html-options.xml + docs/ja/designers/language-custom-functions/language-function-html-radios.xml + docs/ja/designers/language-custom-functions/language-function-html-select-date.xml + docs/ja/designers/language-custom-functions/language-function-html-select-time.xml + docs/ja/designers/language-custom-functions/language-function-html-table.xml + docs/ja/designers/language-custom-functions/language-function-mailto.xml + docs/ja/designers/language-custom-functions/language-function-math.xml + docs/ja/designers/language-custom-functions/language-function-popup-init.xml + docs/ja/designers/language-custom-functions/language-function-popup.xml + docs/ja/designers/language-custom-functions/language-function-textformat.xml + docs/ja/designers/language-modifiers/language-modifier-capitalize.xml + docs/ja/designers/language-modifiers/language-modifier-cat.xml + docs/ja/designers/language-modifiers/language-modifier-count-characters.xml + docs/ja/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/ja/designers/language-modifiers/language-modifier-count-sentences.xml + docs/ja/designers/language-modifiers/language-modifier-count-words.xml + docs/ja/designers/language-modifiers/language-modifier-date-format.xml + docs/ja/designers/language-modifiers/language-modifier-default.xml + docs/ja/designers/language-modifiers/language-modifier-escape.xml + docs/ja/designers/language-modifiers/language-modifier-indent.xml + docs/ja/designers/language-modifiers/language-modifier-lower.xml + docs/ja/designers/language-modifiers/language-modifier-nl2br.xml + docs/ja/designers/language-modifiers/language-modifier-regex-replace.xml + docs/ja/designers/language-modifiers/language-modifier-replace.xml + docs/ja/designers/language-modifiers/language-modifier-spacify.xml + docs/ja/designers/language-modifiers/language-modifier-string-format.xml + docs/ja/designers/language-modifiers/language-modifier-strip-tags.xml + docs/ja/designers/language-modifiers/language-modifier-strip.xml + docs/ja/designers/language-modifiers/language-modifier-truncate.xml + docs/ja/designers/language-modifiers/language-modifier-upper.xml + docs/ja/designers/language-modifiers/language-modifier-wordwrap.xml + docs/ja/designers/language-variables/language-assigned-variables.xml + docs/ja/designers/language-variables/language-config-variables.xml + docs/ja/designers/language-variables/language-variables-smarty.xml + docs/ja/programmers/advanced-features.xml + docs/ja/programmers/api-functions.xml + docs/ja/programmers/api-variables.xml + docs/ja/programmers/caching.xml + docs/ja/programmers/plugins.xml + docs/ja/programmers/smarty-constants.xml + docs/ja/programmers/advanced-features/advanced-features-objects.xml + docs/ja/programmers/advanced-features/advanced-features-outputfilters.xml + docs/ja/programmers/advanced-features/advanced-features-postfilters.xml + docs/ja/programmers/advanced-features/advanced-features-prefilters.xml + docs/ja/programmers/advanced-features/section-template-cache-handler-func.xml + docs/ja/programmers/advanced-features/template-resources.xml + docs/ja/programmers/api-functions/api-append-by-ref.xml + docs/ja/programmers/api-functions/api-append.xml + docs/ja/programmers/api-functions/api-assign-by-ref.xml + docs/ja/programmers/api-functions/api-assign.xml + docs/ja/programmers/api-functions/api-clear-all-assign.xml + docs/ja/programmers/api-functions/api-clear-all-cache.xml + docs/ja/programmers/api-functions/api-clear-assign.xml + docs/ja/programmers/api-functions/api-clear-cache.xml + docs/ja/programmers/api-functions/api-clear-compiled-tpl.xml + docs/ja/programmers/api-functions/api-clear-config.xml + docs/ja/programmers/api-functions/api-config-load.xml + docs/ja/programmers/api-functions/api-display.xml + docs/ja/programmers/api-functions/api-fetch.xml + docs/ja/programmers/api-functions/api-get-config-vars.xml + docs/ja/programmers/api-functions/api-get-registered-object.xml + docs/ja/programmers/api-functions/api-get-template-vars.xml + docs/ja/programmers/api-functions/api-is-cached.xml + docs/ja/programmers/api-functions/api-load-filter.xml + docs/ja/programmers/api-functions/api-register-block.xml + docs/ja/programmers/api-functions/api-register-compiler-function.xml + docs/ja/programmers/api-functions/api-register-function.xml + docs/ja/programmers/api-functions/api-register-modifier.xml + docs/ja/programmers/api-functions/api-register-object.xml + docs/ja/programmers/api-functions/api-register-outputfilter.xml + docs/ja/programmers/api-functions/api-register-postfilter.xml + docs/ja/programmers/api-functions/api-register-prefilter.xml + docs/ja/programmers/api-functions/api-register-resource.xml + docs/ja/programmers/api-functions/api-template-exists.xml + docs/ja/programmers/api-functions/api-trigger-error.xml + docs/ja/programmers/api-functions/api-unregister-block.xml + docs/ja/programmers/api-functions/api-unregister-compiler-function.xml + docs/ja/programmers/api-functions/api-unregister-function.xml + docs/ja/programmers/api-functions/api-unregister-modifier.xml + docs/ja/programmers/api-functions/api-unregister-object.xml + docs/ja/programmers/api-functions/api-unregister-outputfilter.xml + docs/ja/programmers/api-functions/api-unregister-postfilter.xml + docs/ja/programmers/api-functions/api-unregister-prefilter.xml + docs/ja/programmers/api-functions/api-unregister-resource.xml + docs/ja/programmers/api-variables/variable-autoload-filters.xml + docs/ja/programmers/api-variables/variable-cache-dir.xml + docs/ja/programmers/api-variables/variable-cache-handler-func.xml + docs/ja/programmers/api-variables/variable-cache-lifetime.xml + docs/ja/programmers/api-variables/variable-cache-modified-check.xml + docs/ja/programmers/api-variables/variable-caching.xml + docs/ja/programmers/api-variables/variable-compile-check.xml + docs/ja/programmers/api-variables/variable-compile-dir.xml + docs/ja/programmers/api-variables/variable-compile-id.xml + docs/ja/programmers/api-variables/variable-compiler-class.xml + docs/ja/programmers/api-variables/variable-config-booleanize.xml + docs/ja/programmers/api-variables/variable-config-dir.xml + docs/ja/programmers/api-variables/variable-config-fix-newlines.xml + docs/ja/programmers/api-variables/variable-config-overwrite.xml + docs/ja/programmers/api-variables/variable-config-read-hidden.xml + docs/ja/programmers/api-variables/variable-debug-tpl.xml + docs/ja/programmers/api-variables/variable-debugging-ctrl.xml + docs/ja/programmers/api-variables/variable-debugging.xml + docs/ja/programmers/api-variables/variable-default-modifiers.xml + docs/ja/programmers/api-variables/variable-default-resource-type.xml + docs/ja/programmers/api-variables/variable-default-template-handler-func.xml + docs/ja/programmers/api-variables/variable-error-reporting.xml + docs/ja/programmers/api-variables/variable-force-compile.xml + docs/ja/programmers/api-variables/variable-left-delimiter.xml + docs/ja/programmers/api-variables/variable-php-handling.xml + docs/ja/programmers/api-variables/variable-plugins-dir.xml + docs/ja/programmers/api-variables/variable-request-use-auto-globals.xml + docs/ja/programmers/api-variables/variable-request-vars-order.xml + docs/ja/programmers/api-variables/variable-right-delimiter.xml + docs/ja/programmers/api-variables/variable-secure-dir.xml + docs/ja/programmers/api-variables/variable-security-settings.xml + docs/ja/programmers/api-variables/variable-security.xml + docs/ja/programmers/api-variables/variable-template-dir.xml + docs/ja/programmers/api-variables/variable-trusted-dir.xml + docs/ja/programmers/api-variables/variable-use-sub-dirs.xml + docs/ja/programmers/caching/caching-cacheable.xml + docs/ja/programmers/caching/caching-groups.xml + docs/ja/programmers/caching/caching-multiple-caches.xml + docs/ja/programmers/caching/caching-setting-up.xml + docs/ja/programmers/plugins/plugins-block-functions.xml + docs/ja/programmers/plugins/plugins-compiler-functions.xml + docs/ja/programmers/plugins/plugins-functions.xml + docs/ja/programmers/plugins/plugins-howto.xml + docs/ja/programmers/plugins/plugins-inserts.xml + docs/ja/programmers/plugins/plugins-modifiers.xml + docs/ja/programmers/plugins/plugins-naming-conventions.xml + docs/ja/programmers/plugins/plugins-outputfilters.xml + docs/ja/programmers/plugins/plugins-prefilters-postfilters.xml + docs/ja/programmers/plugins/plugins-resources.xml + docs/ja/programmers/plugins/plugins-writing.xml: + added Japanese translation files. + + * docs/Makefile.in + docs/configure.in: + added the configuration for Japanese translation. + +2007-04-11 Messju Mohr + + * docs/en/programmers/smarty-constants.xml: + fixed typo + +2007-04-04 Messju Mohr + + * docs/ru/getting-started.xml: + fixed uri for Zend Accelerator + +2007-04-03 Messju Mohr + + * docs/de/getting-started.xml + docs/es/getting-started.xml + docs/it/getting-started.xml + docs/pt_BR/getting-started.xml: + fixed uris for php-accelerator + +2007-03-08 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + +2007-03-07 Monte Ohrt + + * (Smarty_2_6_18) + NEWS: + update NEWS file with patch + + * (Smarty_2_6_18) + docs/en/designers/language-builtin-functions/language-function-section.xml: + note the fact that section loop will accept an integer + +2007-03-06 Monte Ohrt + + * NEWS + libs/plugins/function.html_select_date.php: + fix html_select_date separator when parts are missing (thanks to kayk for + the patch) + +2007-03-06 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + bumped version number + + * NEWS: + added release headline + + * libs/internals/core.write_compiled_include.php: + fixed detection of non-cached block when writing compiled includes + +2007-03-01 Danilo Buerger + + * NEWS + libs/Smarty_Compiler.class.php: + Applied boots clean up patch and removed commented out code. + Updated NEWS file + +2007-02-27 Danilo Buerger + + * NEWS + docs/en/designers/language-modifiers/language-modifier-date-format.xml + libs/internals/core.write_file.php + libs/plugins/modifier.date_format.php: + Updated smarty_core_write_file() and smarty_modifier_date_format() to speed + up Windows detection. + Emulated more parameters for Windows in smarty_modifier_date_format() and + fixed some old ones. + Updated the docs to tell what parameters are emulated on Windows. + Updated NEWS file. + + * NEWS: + Updated NEWS file to reflect changes commited in the last revision + +2007-02-27 Monte Ohrt + + * docs/en/appendixes/troubleshooting.xml: + fix typo + +2007-02-27 Danilo Buerger + + * libs/Smarty_Compiler.class.php: + Modified _(push|pop)_cacheable_state() to embedd alternate syntax. See this + bug report: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=10502 + +2007-02-26 Peter 'Mash' Morgan + + * docs/en/designers/language-custom-functions/language-function-html-options.xml: + Fix incorrect var name + +2007-02-23 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + escape creating of language=php from interleaving + + * libs/Smarty_Compiler.class.php: + add removed line back in + + * libs/Smarty_Compiler.class.php: + fix up last patch, remove unnecessary lines + + * libs/Smarty_Compiler.class.php: + fix situation when no compiled tags are present + + * libs/Smarty_Compiler.class.php: + fix problem with php open tags generated from tag interleaving + +2007-02-06 boots + + * docs/en/programmers/advanced-features/template-resources.xml: + Correct default template handler function example. + +2007-01-17 Messju Mohr + + * NEWS + libs/plugins/modifier.truncate.php: + fixed handling of $etc in the truncate modifier when $etc is longer + than $length. + + thanks to Sylvinus! + +2007-01-10 boots + + * NEWS + libs/plugins/modifier.date_format.php + libs/plugins/modifier.date_format.php: + fix handling of %I with mysql timestamps + + Thanks to Danilo Buerger + + * NEWS + libs/internals/core.write_file.php: + Better recognize Windows filesystems to reduce warnings + + * NEWS + libs/plugins/modifier.date_format.php: + Emulate %R in the date_format modifier on Windows + + Thanks to Danilo Buerger + +2006-12-10 Yannick Torres + + * docs/fr/getting-started.xml: + fix build + + * docs/fr/language-snippets.ent + docs/fr/designers/language-builtin-functions/language-function-include-php.xml + docs/fr/designers/language-modifiers/language-modifier-truncate.xml + docs/fr/designers/language-variables/language-variables-smarty.xml: + sync with EN + +2006-12-02 Peter 'Mash' Morgan + + * docs/en/designers/language-builtin-functions/language-function-include-php.xml: + Tidy example, speeling andd add links + + * docs/en/getting-started.xml: + Add/correct entities + + * docs/entities/global.ent: + Fix entities (strange) + +2006-12-01 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update dev version numbers + +2006-12-01 boots + + * (Smarty_2_6_16) + NEWS: + Fixed replacement bug introduced in trimwhitespaces output filter that + was introduced in the last release. + + Thanks to Spuerhund from the forums. + + * (Smarty_2_6_16) + libs/plugins/outputfilter.trimwhitespace.php: + Fixed replacement bug introduced by last changes. + + Thanks to Spuerhund from the forums. + +2006-11-30 Monte Ohrt + + * NEWS + docs/en/designers/language-modifiers/language-modifier-truncate.xml + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update dev version numbers, fix manual typo + +2006-11-22 George Miroshnikov + + * docs/ru/getting-started.xml + docs/ru/language-snippets.ent: + sync with EN + + * docs/en/getting-started.xml: + replaced hardcoded path separator with PATH_SEPARATOR constant + +2006-11-20 boots + + * libs/plugins/modifier.debug_print_var.php: + fix depth formatting of arrays and objects in modifier debug_print_var + +2006-11-10 Messju Mohr + + * docs/en/designers/language-variables/language-variables-smarty.xml: + fixed typo. thanks jonez. + +2006-11-08 boots + + * NEWS + libs/internals/core.write_file.php: + change file writing semantics in smarty_core_write_file() + + This avoids unlink() unless rename() fails or a Windows system is detected + + see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=6956 + + Thanks to c960657 from the forums. + +2006-11-07 boots + + * NEWS + libs/debug.tpl: + update debug.tpl to xhtml 1.1 compliance, fix javascript escaping in debug + output and apply a Smarty based color scheme + + see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=7178 + + thanks to cybot from the forums! + + * NEWS + libs/plugins/modifier.debug_print_var.php: + enhance reporting precision of debug_print_var modifier + + see: http://www.phpinsider.com/smarty-forum/viewtopic.php?t=9281 + + thanks to cybot from the forums + +2006-11-01 boots + + * NEWS + libs/plugins/function.html_select_date.php: + make html_select_date work consistently with 0000-00-00 00:00:00 and + 0000-00-00 inputs + + Thanks to cybot from forums + +2006-10-16 George Miroshnikov + + * docs/en/language-snippets.ent: + minor typo fix - &$class doesn't make sense. + +2006-10-14 Yannick Torres + + * docs/fr/designers/language-basic-syntax.xml + docs/fr/designers/language-builtin-functions.xml + docs/fr/designers/language-basic-syntax/language-syntax-attributes.xml + docs/fr/designers/language-basic-syntax/language-syntax-comments.xml + docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml + docs/fr/designers/language-builtin-functions/language-function-capture.xml + docs/fr/designers/language-builtin-functions/language-function-php.xml + docs/fr/designers/language-builtin-functions/language-function-section.xml + docs/fr/designers/language-custom-functions/language-function-popup-init.xml + docs/fr/designers/language-modifiers/language-modifier-escape.xml + docs/fr/programmers/api-functions/api-display.xml + docs/fr/programmers/plugins/plugins-inserts.xml: + sync with EN + +2006-10-14 Fernando Correa da Conceição + + * docs/pt_BR/programmers/api-variables/variable-error-reporting.xml: + New Translation + + * docs/pt_BR/designers/language-basic-syntax/language-escaping.xml + docs/pt_BR/designers/language-basic-syntax/language-syntax-variables.xml: + New Translations + + * docs/pt_BR/translation.xml: + Used in revcheck + + * docs/pt_BR/getting-started.xml + docs/pt_BR/language-snippets.ent + docs/pt_BR/make_chm_index.html + docs/pt_BR/preface.xml + docs/pt_BR/appendixes/resources.xml + docs/pt_BR/appendixes/troubleshooting.xml + docs/pt_BR/designers/language-modifiers/language-modifier-capitalize.xml + docs/pt_BR/designers/language-modifiers/language-modifier-cat.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-characters.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-sentences.xml + docs/pt_BR/designers/language-modifiers/language-modifier-count-words.xml + docs/pt_BR/designers/language-modifiers/language-modifier-date-format.xml + docs/pt_BR/designers/language-modifiers/language-modifier-default.xml + docs/pt_BR/designers/language-modifiers/language-modifier-escape.xml + docs/pt_BR/designers/language-modifiers/language-modifier-indent.xml + docs/pt_BR/designers/language-modifiers/language-modifier-lower.xml + docs/pt_BR/designers/language-modifiers/language-modifier-nl2br.xml + docs/pt_BR/designers/language-modifiers/language-modifier-regex-replace.xml + docs/pt_BR/designers/language-modifiers/language-modifier-replace.xml + docs/pt_BR/designers/language-modifiers/language-modifier-spacify.xml + docs/pt_BR/designers/language-modifiers/language-modifier-string-format.xml + docs/pt_BR/designers/language-modifiers/language-modifier-strip-tags.xml + docs/pt_BR/designers/language-modifiers/language-modifier-strip.xml + docs/pt_BR/designers/language-modifiers/language-modifier-truncate.xml + docs/pt_BR/designers/language-modifiers/language-modifier-upper.xml + docs/pt_BR/designers/language-modifiers/language-modifier-wordwrap.xml + docs/pt_BR/designers/language-variables/language-assigned-variables.xml + docs/pt_BR/designers/language-variables/language-config-variables.xml + docs/pt_BR/designers/language-variables/language-variables-smarty.xml + docs/pt_BR/programmers/advanced-features.xml + docs/pt_BR/programmers/api-functions.xml + docs/pt_BR/programmers/api-variables.xml + docs/pt_BR/programmers/caching.xml + docs/pt_BR/programmers/plugins.xml + docs/pt_BR/programmers/smarty-constants.xml + docs/pt_BR/programmers/advanced-features/advanced-features-objects.xml + docs/pt_BR/programmers/advanced-features/advanced-features-outputfilters.xml + docs/pt_BR/programmers/advanced-features/advanced-features-postfilters.xml + docs/pt_BR/programmers/advanced-features/advanced-features-prefilters.xml + docs/pt_BR/programmers/advanced-features/section-template-cache-handler-func.xml + docs/pt_BR/programmers/advanced-features/template-resources.xml + docs/pt_BR/programmers/api-functions/api-append-by-ref.xml + docs/pt_BR/programmers/api-functions/api-append.xml + docs/pt_BR/programmers/api-functions/api-assign-by-ref.xml + docs/pt_BR/programmers/api-functions/api-assign.xml + docs/pt_BR/programmers/api-functions/api-clear-all-assign.xml + docs/pt_BR/programmers/api-functions/api-clear-all-cache.xml + docs/pt_BR/programmers/api-functions/api-clear-assign.xml + docs/pt_BR/programmers/api-functions/api-clear-cache.xml + docs/pt_BR/programmers/api-functions/api-clear-compiled-tpl.xml + docs/pt_BR/programmers/api-functions/api-clear-config.xml + docs/pt_BR/programmers/api-functions/api-config-load.xml + docs/pt_BR/programmers/api-functions/api-display.xml + docs/pt_BR/programmers/api-functions/api-fetch.xml + docs/pt_BR/programmers/api-functions/api-get-config-vars.xml + docs/pt_BR/programmers/api-functions/api-get-registered-object.xml + docs/pt_BR/programmers/api-functions/api-get-template-vars.xml + docs/pt_BR/programmers/api-functions/api-is-cached.xml + docs/pt_BR/programmers/api-functions/api-load-filter.xml + docs/pt_BR/programmers/api-functions/api-register-block.xml + docs/pt_BR/programmers/api-functions/api-register-compiler-function.xml + docs/pt_BR/programmers/api-functions/api-register-function.xml + docs/pt_BR/programmers/api-functions/api-register-modifier.xml + docs/pt_BR/programmers/api-functions/api-register-object.xml + docs/pt_BR/programmers/api-functions/api-register-outputfilter.xml + docs/pt_BR/programmers/api-functions/api-register-postfilter.xml + docs/pt_BR/programmers/api-functions/api-register-prefilter.xml + docs/pt_BR/programmers/api-functions/api-register-resource.xml + docs/pt_BR/programmers/api-functions/api-template-exists.xml + docs/pt_BR/programmers/api-functions/api-trigger-error.xml + docs/pt_BR/programmers/api-functions/api-unregister-block.xml + docs/pt_BR/programmers/api-functions/api-unregister-compiler-function.xml + docs/pt_BR/programmers/api-functions/api-unregister-function.xml + docs/pt_BR/programmers/api-functions/api-unregister-modifier.xml + docs/pt_BR/programmers/api-functions/api-unregister-object.xml + docs/pt_BR/programmers/api-functions/api-unregister-outputfilter.xml + docs/pt_BR/programmers/api-functions/api-unregister-postfilter.xml + docs/pt_BR/programmers/api-functions/api-unregister-prefilter.xml + docs/pt_BR/programmers/api-functions/api-unregister-resource.xml + docs/pt_BR/programmers/api-variables/variable-autoload-filters.xml + docs/pt_BR/programmers/api-variables/variable-cache-dir.xml + docs/pt_BR/programmers/api-variables/variable-cache-handler-func.xml + docs/pt_BR/programmers/api-variables/variable-cache-lifetime.xml + docs/pt_BR/programmers/api-variables/variable-cache-modified-check.xml + docs/pt_BR/programmers/api-variables/variable-caching.xml + docs/pt_BR/programmers/api-variables/variable-compile-check.xml + docs/pt_BR/programmers/api-variables/variable-compile-dir.xml + docs/pt_BR/programmers/api-variables/variable-compile-id.xml + docs/pt_BR/programmers/api-variables/variable-compiler-class.xml + docs/pt_BR/programmers/api-variables/variable-config-booleanize.xml + docs/pt_BR/programmers/api-variables/variable-config-dir.xml + docs/pt_BR/programmers/api-variables/variable-config-fix-newlines.xml + docs/pt_BR/programmers/api-variables/variable-config-overwrite.xml + docs/pt_BR/programmers/api-variables/variable-config-read-hidden.xml + docs/pt_BR/programmers/api-variables/variable-debug-tpl.xml + docs/pt_BR/programmers/api-variables/variable-debugging-ctrl.xml + docs/pt_BR/programmers/api-variables/variable-debugging.xml + docs/pt_BR/programmers/api-variables/variable-default-modifiers.xml + docs/pt_BR/programmers/api-variables/variable-default-resource-type.xml + docs/pt_BR/programmers/api-variables/variable-default-template-handler-func.xml + docs/pt_BR/programmers/api-variables/variable-force-compile.xml + docs/pt_BR/programmers/api-variables/variable-global-assign.xml + docs/pt_BR/programmers/api-variables/variable-left-delimiter.xml + docs/pt_BR/programmers/api-variables/variable-php-handling.xml + docs/pt_BR/programmers/api-variables/variable-plugins-dir.xml + docs/pt_BR/programmers/api-variables/variable-request-use-auto-globals.xml + docs/pt_BR/programmers/api-variables/variable-request-vars-order.xml + docs/pt_BR/programmers/api-variables/variable-right-delimiter.xml + docs/pt_BR/programmers/api-variables/variable-secure-dir.xml + docs/pt_BR/programmers/api-variables/variable-security-settings.xml + docs/pt_BR/programmers/api-variables/variable-security.xml + docs/pt_BR/programmers/api-variables/variable-template-dir.xml + docs/pt_BR/programmers/api-variables/variable-trusted-dir.xml + docs/pt_BR/programmers/api-variables/variable-undefined.xml + docs/pt_BR/programmers/api-variables/variable-use-sub-dirs.xml + docs/pt_BR/programmers/caching/caching-cacheable.xml + docs/pt_BR/programmers/caching/caching-groups.xml + docs/pt_BR/programmers/caching/caching-multiple-caches.xml + docs/pt_BR/programmers/caching/caching-setting-up.xml + docs/pt_BR/programmers/plugins/plugins-block-functions.xml + docs/pt_BR/programmers/plugins/plugins-compiler-functions.xml + docs/pt_BR/programmers/plugins/plugins-functions.xml + docs/pt_BR/programmers/plugins/plugins-howto.xml + docs/pt_BR/programmers/plugins/plugins-inserts.xml + docs/pt_BR/programmers/plugins/plugins-modifiers.xml + docs/pt_BR/programmers/plugins/plugins-naming-conventions.xml + docs/pt_BR/programmers/plugins/plugins-outputfilters.xml + docs/pt_BR/programmers/plugins/plugins-prefilters-postfilters.xml + docs/pt_BR/programmers/plugins/plugins-resources.xml + docs/pt_BR/programmers/plugins/plugins-writing.xml: + Big update. Revision tag for all files. Some updates. Now I can update it + +2006-10-09 Peter 'Mash' Morgan + + * docs/en/getting-started.xml + docs/en/designers/language-basic-syntax.xml + docs/en/designers/language-custom-functions/language-function-popup-init.xml + docs/en/designers/language-modifiers/language-modifier-escape.xml + docs/en/programmers/api-functions/api-display.xml + docs/en/programmers/plugins/plugins-inserts.xml: + Minor changes and corrections + + * docs/en/designers/language-basic-syntax.xml + docs/en/designers/language-builtin-functions.xml + docs/en/designers/language-basic-syntax/language-syntax-attributes.xml + docs/en/designers/language-basic-syntax/language-syntax-comments.xml + docs/en/designers/language-basic-syntax/language-syntax-quotes.xml + docs/en/designers/language-modifiers/language-modifier-escape.xml: + Minor formatting and error correction + + * docs/en/designers/language-builtin-functions/language-function-capture.xml + docs/en/designers/language-builtin-functions/language-function-php.xml + docs/en/designers/language-builtin-functions/language-function-section.xml: + minor formatting and changes + + * docs/en/getting-started.xml: + Tidied up formatting so more readable, tidied up the install to the paths + are more clear (ta jj) + +2006-10-09 Yannick Torres + + * docs/fr/designers/language-builtin-functions/language-function-section.xml: + sync with EN + +2006-10-08 Yannick Torres + + * docs/fr/designers/language-builtin-functions/language-function-php.xml + docs/fr/designers/language-modifiers/language-modifier-escape.xml + docs/fr/designers/language-variables/language-variables-smarty.xml + docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml: + fix build + + * docs/fr/designers/language-builtin-functions/language-function-strip.xml + docs/fr/programmers/caching.xml + docs/fr/programmers/smarty-constants.xml + docs/fr/programmers/api-variables/variable-autoload-filters.xml + docs/fr/programmers/api-variables/variable-cache-dir.xml + docs/fr/programmers/api-variables/variable-cache-handler-func.xml + docs/fr/programmers/api-variables/variable-cache-lifetime.xml + docs/fr/programmers/api-variables/variable-cache-modified-check.xml + docs/fr/programmers/api-variables/variable-caching.xml + docs/fr/programmers/api-variables/variable-compile-check.xml + docs/fr/programmers/api-variables/variable-compile-dir.xml + docs/fr/programmers/api-variables/variable-compile-id.xml + docs/fr/programmers/api-variables/variable-compiler-class.xml + docs/fr/programmers/api-variables/variable-config-booleanize.xml + docs/fr/programmers/api-variables/variable-config-dir.xml + docs/fr/programmers/api-variables/variable-config-fix-newlines.xml + docs/fr/programmers/api-variables/variable-config-overwrite.xml + docs/fr/programmers/api-variables/variable-config-read-hidden.xml + docs/fr/programmers/api-variables/variable-debug-tpl.xml + docs/fr/programmers/api-variables/variable-debugging-ctrl.xml + docs/fr/programmers/api-variables/variable-debugging.xml + docs/fr/programmers/api-variables/variable-default-modifiers.xml + docs/fr/programmers/api-variables/variable-default-resource-type.xml + docs/fr/programmers/api-variables/variable-default-template-handler-func.xml + docs/fr/programmers/api-variables/variable-error-reporting.xml + docs/fr/programmers/api-variables/variable-force-compile.xml + docs/fr/programmers/api-variables/variable-left-delimiter.xml + docs/fr/programmers/api-variables/variable-php-handling.xml + docs/fr/programmers/api-variables/variable-plugins-dir.xml + docs/fr/programmers/api-variables/variable-request-use-auto-globals.xml + docs/fr/programmers/api-variables/variable-request-vars-order.xml + docs/fr/programmers/api-variables/variable-right-delimiter.xml + docs/fr/programmers/api-variables/variable-secure-dir.xml + docs/fr/programmers/api-variables/variable-security-settings.xml + docs/fr/programmers/api-variables/variable-security.xml + docs/fr/programmers/api-variables/variable-template-dir.xml + docs/fr/programmers/api-variables/variable-trusted-dir.xml + docs/fr/programmers/api-variables/variable-use-sub-dirs.xml + docs/fr/programmers/caching/caching-cacheable.xml + docs/fr/programmers/caching/caching-groups.xml + docs/fr/programmers/caching/caching-multiple-caches.xml + docs/fr/programmers/caching/caching-setting-up.xml + docs/fr/programmers/plugins/plugins-block-functions.xml + docs/fr/programmers/plugins/plugins-compiler-functions.xml + docs/fr/programmers/plugins/plugins-functions.xml + docs/fr/programmers/plugins/plugins-inserts.xml + docs/fr/programmers/plugins/plugins-modifiers.xml + docs/fr/programmers/plugins/plugins-naming-conventions.xml + docs/fr/programmers/plugins/plugins-outputfilters.xml + docs/fr/programmers/plugins/plugins-prefilters-postfilters.xml + docs/fr/programmers/plugins/plugins-resources.xml + docs/fr/programmers/plugins/plugins-writing.xml: + sync with EN + +2006-10-07 Yannick Torres + + * docs/fr/programmers/advanced-features/advanced-features-objects.xml + docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml + docs/fr/programmers/advanced-features/advanced-features-postfilters.xml + docs/fr/programmers/advanced-features/advanced-features-prefilters.xml + docs/fr/programmers/advanced-features/section-template-cache-handler-func.xml + docs/fr/programmers/advanced-features/template-resources.xml + docs/fr/programmers/api-functions/api-append-by-ref.xml + docs/fr/programmers/api-functions/api-append.xml + docs/fr/programmers/api-functions/api-assign-by-ref.xml + docs/fr/programmers/api-functions/api-assign.xml + docs/fr/programmers/api-functions/api-clear-all-assign.xml + docs/fr/programmers/api-functions/api-clear-all-cache.xml + docs/fr/programmers/api-functions/api-clear-assign.xml + docs/fr/programmers/api-functions/api-clear-cache.xml + docs/fr/programmers/api-functions/api-clear-compiled-tpl.xml + docs/fr/programmers/api-functions/api-clear-config.xml + docs/fr/programmers/api-functions/api-config-load.xml + docs/fr/programmers/api-functions/api-display.xml + docs/fr/programmers/api-functions/api-fetch.xml + docs/fr/programmers/api-functions/api-get-config-vars.xml + docs/fr/programmers/api-functions/api-get-registered-object.xml + docs/fr/programmers/api-functions/api-get-template-vars.xml + docs/fr/programmers/api-functions/api-is-cached.xml + docs/fr/programmers/api-functions/api-load-filter.xml + docs/fr/programmers/api-functions/api-register-block.xml + docs/fr/programmers/api-functions/api-register-compiler-function.xml + docs/fr/programmers/api-functions/api-register-function.xml + docs/fr/programmers/api-functions/api-register-modifier.xml + docs/fr/programmers/api-functions/api-register-object.xml + docs/fr/programmers/api-functions/api-register-outputfilter.xml + docs/fr/programmers/api-functions/api-register-postfilter.xml + docs/fr/programmers/api-functions/api-register-prefilter.xml + docs/fr/programmers/api-functions/api-register-resource.xml + docs/fr/programmers/api-functions/api-template-exists.xml + docs/fr/programmers/api-functions/api-trigger-error.xml + docs/fr/programmers/api-functions/api-unregister-block.xml + docs/fr/programmers/api-functions/api-unregister-compiler-function.xml + docs/fr/programmers/api-functions/api-unregister-function.xml + docs/fr/programmers/api-functions/api-unregister-modifier.xml + docs/fr/programmers/api-functions/api-unregister-object.xml + docs/fr/programmers/api-functions/api-unregister-outputfilter.xml + docs/fr/programmers/api-functions/api-unregister-postfilter.xml + docs/fr/programmers/api-functions/api-unregister-prefilter.xml + docs/fr/programmers/api-functions/api-unregister-resource.xml: + sync with EN + +2006-10-03 Yannick Torres + + * docs/fr/designers/language-custom-functions/language-function-html-select-time.xml + docs/fr/designers/language-custom-functions/language-function-html-table.xml + docs/fr/designers/language-custom-functions/language-function-mailto.xml + docs/fr/designers/language-custom-functions/language-function-math.xml + docs/fr/designers/language-custom-functions/language-function-popup-init.xml + docs/fr/designers/language-custom-functions/language-function-popup.xml + docs/fr/designers/language-custom-functions/language-function-textformat.xml + docs/fr/designers/language-modifiers/language-modifier-capitalize.xml + docs/fr/designers/language-modifiers/language-modifier-cat.xml + docs/fr/designers/language-modifiers/language-modifier-count-characters.xml + docs/fr/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/fr/designers/language-modifiers/language-modifier-count-sentences.xml + docs/fr/designers/language-modifiers/language-modifier-count-words.xml + docs/fr/designers/language-modifiers/language-modifier-date-format.xml + docs/fr/designers/language-modifiers/language-modifier-default.xml + docs/fr/designers/language-modifiers/language-modifier-escape.xml + docs/fr/designers/language-modifiers/language-modifier-indent.xml + docs/fr/designers/language-modifiers/language-modifier-lower.xml + docs/fr/designers/language-modifiers/language-modifier-nl2br.xml + docs/fr/designers/language-modifiers/language-modifier-regex-replace.xml + docs/fr/designers/language-modifiers/language-modifier-replace.xml + docs/fr/designers/language-modifiers/language-modifier-spacify.xml + docs/fr/designers/language-modifiers/language-modifier-string-format.xml + docs/fr/designers/language-modifiers/language-modifier-strip-tags.xml + docs/fr/designers/language-modifiers/language-modifier-strip.xml + docs/fr/designers/language-modifiers/language-modifier-truncate.xml + docs/fr/designers/language-modifiers/language-modifier-upper.xml + docs/fr/designers/language-modifiers/language-modifier-wordwrap.xml + docs/fr/designers/language-variables/language-assigned-variables.xml + docs/fr/designers/language-variables/language-config-variables.xml + docs/fr/designers/language-variables/language-variables-smarty.xml: + sync with EN + +2006-10-01 Yannick Torres + + * docs/fr/designers/language-builtin-functions/language-function-include-php.xml + docs/fr/designers/language-builtin-functions/language-function-include.xml + docs/fr/designers/language-builtin-functions/language-function-insert.xml + docs/fr/designers/language-builtin-functions/language-function-ldelim.xml + docs/fr/designers/language-builtin-functions/language-function-literal.xml + docs/fr/designers/language-builtin-functions/language-function-php.xml + docs/fr/designers/language-custom-functions/language-function-assign.xml + docs/fr/designers/language-custom-functions/language-function-counter.xml + docs/fr/designers/language-custom-functions/language-function-cycle.xml + docs/fr/designers/language-custom-functions/language-function-debug.xml + docs/fr/designers/language-custom-functions/language-function-eval.xml + docs/fr/designers/language-custom-functions/language-function-fetch.xml + docs/fr/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/fr/designers/language-custom-functions/language-function-html-image.xml + docs/fr/designers/language-custom-functions/language-function-html-options.xml + docs/fr/designers/language-custom-functions/language-function-html-radios.xml + docs/fr/designers/language-custom-functions/language-function-html-select-date.xml: + sync with EN + +2006-09-30 Yannick Torres + + * docs/fr/getting-started.xml: + fix build + + * docs/fr/designers/chapter-debugging-console.xml + docs/fr/designers/config-files.xml + docs/fr/designers/language-builtin-functions.xml + docs/fr/designers/language-modifiers.xml + docs/fr/designers/language-variables.xml + docs/fr/designers/language-basic-syntax/language-escaping.xml + docs/fr/designers/language-basic-syntax/language-math.xml + docs/fr/designers/language-basic-syntax/language-syntax-comments.xml + docs/fr/designers/language-basic-syntax/language-syntax-functions.xml + docs/fr/designers/language-basic-syntax/language-syntax-quotes.xml + docs/fr/designers/language-basic-syntax/language-syntax-variables.xml + docs/fr/designers/language-builtin-functions/language-function-capture.xml + docs/fr/designers/language-builtin-functions/language-function-config-load.xml + docs/fr/designers/language-builtin-functions/language-function-foreach.xml + docs/fr/designers/language-builtin-functions/language-function-if.xml: + sync with EN + + * docs/fr/getting-started.xml + docs/fr/language-snippets.ent + docs/fr/appendixes/resources.xml + docs/fr/appendixes/tips.xml + docs/fr/appendixes/troubleshooting.xml: + sync with EN + +2006-09-27 Peter 'Mash' Morgan + + * docs/en/designers/language-builtin-functions/language-function-section.xml: + Minor tweaks and corrections + + * docs/en/getting-started.xml + docs/en/designers/chapter-debugging-console.xml + docs/en/designers/language-basic-syntax/language-syntax-comments.xml + docs/en/designers/language-custom-functions/language-function-html-image.xml + docs/en/designers/language-custom-functions/language-function-html-options.xml + docs/en/designers/language-custom-functions/language-function-html-radios.xml + docs/en/designers/language-custom-functions/language-function-html-select-date.xml + docs/en/designers/language-custom-functions/language-function-html-select-time.xml + docs/en/designers/language-custom-functions/language-function-html-table.xml + docs/en/designers/language-custom-functions/language-function-mailto.xml + docs/en/designers/language-custom-functions/language-function-popup-init.xml + docs/en/designers/language-custom-functions/language-function-textformat.xml + docs/en/designers/language-variables/language-config-variables.xml + docs/en/designers/language-variables/language-variables-smarty.xml: + Add literal tags to html, general formatting + + * docs/en/getting-started.xml + docs/en/appendixes/resources.xml + docs/en/appendixes/tips.xml + docs/en/appendixes/troubleshooting.xml + docs/en/designers/config-files.xml + docs/en/programmers/caching.xml + docs/en/programmers/smarty-constants.xml + docs/en/programmers/advanced-features/advanced-features-objects.xml + docs/en/programmers/advanced-features/advanced-features-outputfilters.xml + docs/en/programmers/advanced-features/advanced-features-postfilters.xml + docs/en/programmers/advanced-features/advanced-features-prefilters.xml + docs/en/programmers/advanced-features/section-template-cache-handler-func.xml + docs/en/programmers/advanced-features/template-resources.xml + docs/en/programmers/api-variables/variable-autoload-filters.xml + docs/en/programmers/api-variables/variable-cache-dir.xml + docs/en/programmers/api-variables/variable-cache-handler-func.xml + docs/en/programmers/api-variables/variable-cache-lifetime.xml + docs/en/programmers/api-variables/variable-cache-modified-check.xml + docs/en/programmers/api-variables/variable-caching.xml + docs/en/programmers/api-variables/variable-compile-check.xml + docs/en/programmers/api-variables/variable-compile-dir.xml + docs/en/programmers/api-variables/variable-compile-id.xml + docs/en/programmers/api-variables/variable-config-booleanize.xml + docs/en/programmers/api-variables/variable-config-dir.xml + docs/en/programmers/api-variables/variable-config-fix-newlines.xml + docs/en/programmers/api-variables/variable-config-overwrite.xml + docs/en/programmers/api-variables/variable-config-read-hidden.xml + docs/en/programmers/api-variables/variable-debug-tpl.xml + docs/en/programmers/api-variables/variable-debugging-ctrl.xml + docs/en/programmers/api-variables/variable-debugging.xml + docs/en/programmers/api-variables/variable-default-modifiers.xml + docs/en/programmers/api-variables/variable-default-resource-type.xml + docs/en/programmers/api-variables/variable-error-reporting.xml + docs/en/programmers/api-variables/variable-force-compile.xml + docs/en/programmers/api-variables/variable-left-delimiter.xml + docs/en/programmers/api-variables/variable-php-handling.xml + docs/en/programmers/api-variables/variable-plugins-dir.xml + docs/en/programmers/api-variables/variable-request-use-auto-globals.xml + docs/en/programmers/api-variables/variable-request-vars-order.xml + docs/en/programmers/api-variables/variable-right-delimiter.xml + docs/en/programmers/api-variables/variable-secure-dir.xml + docs/en/programmers/api-variables/variable-security-settings.xml + docs/en/programmers/api-variables/variable-security.xml + docs/en/programmers/api-variables/variable-template-dir.xml + docs/en/programmers/api-variables/variable-trusted-dir.xml + docs/en/programmers/api-variables/variable-use-sub-dirs.xml + docs/en/programmers/caching/caching-cacheable.xml + docs/en/programmers/caching/caching-groups.xml + docs/en/programmers/caching/caching-multiple-caches.xml + docs/en/programmers/caching/caching-setting-up.xml: + Tidy up of formatting + + * docs/entities/global.ent: + Adding some more resources + + * docs/en/programmers/plugins/plugins-block-functions.xml + docs/en/programmers/plugins/plugins-compiler-functions.xml + docs/en/programmers/plugins/plugins-functions.xml + docs/en/programmers/plugins/plugins-inserts.xml + docs/en/programmers/plugins/plugins-modifiers.xml + docs/en/programmers/plugins/plugins-naming-conventions.xml + docs/en/programmers/plugins/plugins-outputfilters.xml + docs/en/programmers/plugins/plugins-prefilters-postfilters.xml + docs/en/programmers/plugins/plugins-resources.xml + docs/en/programmers/plugins/plugins-writing.xml: + Tidy up some formatting + +2006-09-26 Peter 'Mash' Morgan + + * docs/en/programmers/api-functions/api-append-by-ref.xml + docs/en/programmers/api-functions/api-append.xml + docs/en/programmers/api-functions/api-assign-by-ref.xml + docs/en/programmers/api-functions/api-assign.xml + docs/en/programmers/api-functions/api-clear-all-assign.xml + docs/en/programmers/api-functions/api-clear-all-cache.xml + docs/en/programmers/api-functions/api-clear-assign.xml + docs/en/programmers/api-functions/api-clear-cache.xml + docs/en/programmers/api-functions/api-clear-compiled-tpl.xml + docs/en/programmers/api-functions/api-clear-config.xml + docs/en/programmers/api-functions/api-config-load.xml + docs/en/programmers/api-functions/api-display.xml + docs/en/programmers/api-functions/api-fetch.xml + docs/en/programmers/api-functions/api-get-config-vars.xml + docs/en/programmers/api-functions/api-get-registered-object.xml + docs/en/programmers/api-functions/api-get-template-vars.xml + docs/en/programmers/api-functions/api-is-cached.xml + docs/en/programmers/api-functions/api-load-filter.xml + docs/en/programmers/api-functions/api-register-block.xml + docs/en/programmers/api-functions/api-register-compiler-function.xml + docs/en/programmers/api-functions/api-register-function.xml + docs/en/programmers/api-functions/api-register-modifier.xml + docs/en/programmers/api-functions/api-register-object.xml + docs/en/programmers/api-functions/api-register-outputfilter.xml + docs/en/programmers/api-functions/api-register-postfilter.xml + docs/en/programmers/api-functions/api-register-prefilter.xml + docs/en/programmers/api-functions/api-register-resource.xml + docs/en/programmers/api-functions/api-template-exists.xml + docs/en/programmers/api-functions/api-trigger-error.xml + docs/en/programmers/api-functions/api-unregister-block.xml + docs/en/programmers/api-functions/api-unregister-compiler-function.xml + docs/en/programmers/api-functions/api-unregister-function.xml + docs/en/programmers/api-functions/api-unregister-modifier.xml + docs/en/programmers/api-functions/api-unregister-object.xml + docs/en/programmers/api-functions/api-unregister-outputfilter.xml + docs/en/programmers/api-functions/api-unregister-postfilter.xml + docs/en/programmers/api-functions/api-unregister-prefilter.xml + docs/en/programmers/api-functions/api-unregister-resource.xml: + Tidy up formatting and examples + + * docs/en/language-snippets.ent: + Moved recurring para for register_* + + * docs/en/designers/language-modifiers.xml: + Spelling on modifiers + + * docs/en/designers/language-builtin-functions.xml + docs/en/designers/language-modifiers.xml + docs/en/designers/language-custom-functions/language-function-html-options.xml + docs/en/designers/language-modifiers/language-modifier-capitalize.xml + docs/en/designers/language-modifiers/language-modifier-cat.xml + docs/en/designers/language-modifiers/language-modifier-count-characters.xml + docs/en/designers/language-modifiers/language-modifier-count-paragraphs.xml + docs/en/designers/language-modifiers/language-modifier-count-sentences.xml + docs/en/designers/language-modifiers/language-modifier-count-words.xml + docs/en/designers/language-modifiers/language-modifier-date-format.xml + docs/en/designers/language-modifiers/language-modifier-default.xml + docs/en/designers/language-modifiers/language-modifier-escape.xml + docs/en/designers/language-modifiers/language-modifier-indent.xml + docs/en/designers/language-modifiers/language-modifier-lower.xml + docs/en/designers/language-modifiers/language-modifier-nl2br.xml + docs/en/designers/language-modifiers/language-modifier-regex-replace.xml + docs/en/designers/language-modifiers/language-modifier-replace.xml + docs/en/designers/language-modifiers/language-modifier-spacify.xml + docs/en/designers/language-modifiers/language-modifier-string-format.xml + docs/en/designers/language-modifiers/language-modifier-strip-tags.xml + docs/en/designers/language-modifiers/language-modifier-strip.xml + docs/en/designers/language-modifiers/language-modifier-truncate.xml + docs/en/designers/language-modifiers/language-modifier-upper.xml + docs/en/designers/language-modifiers/language-modifier-wordwrap.xml: + Tidying up some markup + + * docs/en/designers/language-variables.xml: + typo + + * docs/en/designers/language-variables.xml + docs/en/designers/language-variables/language-assigned-variables.xml + docs/en/designers/language-variables/language-config-variables.xml + docs/en/designers/language-variables/language-variables-smarty.xml: + Tidy up formatting on variables + + * docs/en/designers/language-basic-syntax/language-escaping.xml + docs/en/designers/language-basic-syntax/language-math.xml + docs/en/designers/language-basic-syntax/language-syntax-comments.xml + docs/en/designers/language-basic-syntax/language-syntax-functions.xml + docs/en/designers/language-basic-syntax/language-syntax-quotes.xml + docs/en/designers/language-basic-syntax/language-syntax-variables.xml: + Formatting of the basic-syntax dir + + * docs/en/designers/language-custom-functions/language-function-assign.xml + docs/en/designers/language-custom-functions/language-function-counter.xml + docs/en/designers/language-custom-functions/language-function-cycle.xml + docs/en/designers/language-custom-functions/language-function-debug.xml + docs/en/designers/language-custom-functions/language-function-eval.xml + docs/en/designers/language-custom-functions/language-function-fetch.xml + docs/en/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/en/designers/language-custom-functions/language-function-html-image.xml + docs/en/designers/language-custom-functions/language-function-html-options.xml + docs/en/designers/language-custom-functions/language-function-html-radios.xml + docs/en/designers/language-custom-functions/language-function-html-select-date.xml + docs/en/designers/language-custom-functions/language-function-html-select-time.xml + docs/en/designers/language-custom-functions/language-function-html-table.xml + docs/en/designers/language-custom-functions/language-function-mailto.xml + docs/en/designers/language-custom-functions/language-function-math.xml + docs/en/designers/language-custom-functions/language-function-popup-init.xml + docs/en/designers/language-custom-functions/language-function-popup.xml + docs/en/designers/language-custom-functions/language-function-textformat.xml: + More formatting and cleaning up examples + +2006-09-25 Peter 'Mash' Morgan + + * docs/en/designers/language-builtin-functions/language-function-foreach.xml + docs/en/designers/language-builtin-functions/language-function-section.xml: + Doh! removing tabs + + * docs/en/designers/language-builtin-functions/language-function-capture.xml + docs/en/designers/language-builtin-functions/language-function-config-load.xml + docs/en/designers/language-builtin-functions/language-function-foreach.xml + docs/en/designers/language-builtin-functions/language-function-if.xml + docs/en/designers/language-builtin-functions/language-function-include-php.xml + docs/en/designers/language-builtin-functions/language-function-include.xml + docs/en/designers/language-builtin-functions/language-function-insert.xml + docs/en/designers/language-builtin-functions/language-function-ldelim.xml + docs/en/designers/language-builtin-functions/language-function-literal.xml + docs/en/designers/language-builtin-functions/language-function-php.xml + docs/en/designers/language-builtin-functions/language-function-section.xml + docs/en/designers/language-builtin-functions/language-function-strip.xml: + A lot of formatting, tagging and tidy up. Some consistency at last + + * docs/en/designers/language-builtin-functions/language-function-section.xml: + Major tidy up + + * docs/en/designers/language-builtin-functions/language-function-foreach.xml: + Major tidy up, added index property and some examples + +2006-09-03 Yannick Torres + + * docs/fr/designers/language-custom-functions/language-function-popup-init.xml + docs/fr/programmers/advanced-features/advanced-features-outputfilters.xml + docs/fr/programmers/advanced-features/advanced-features-postfilters.xml + docs/fr/programmers/advanced-features/advanced-features-prefilters.xml: + sync with EN + +2006-09-01 George Miroshnikov + + * docs/ru/programmers/api-functions/api-append-by-ref.xml + docs/ru/programmers/api-functions/api-append.xml + docs/ru/programmers/api-functions/api-assign-by-ref.xml + docs/ru/programmers/api-functions/api-assign.xml + docs/ru/programmers/api-functions/api-clear-all-assign.xml + docs/ru/programmers/api-functions/api-clear-all-cache.xml + docs/ru/programmers/api-functions/api-clear-assign.xml + docs/ru/programmers/api-functions/api-clear-cache.xml + docs/ru/programmers/api-functions/api-clear-compiled-tpl.xml + docs/ru/programmers/api-functions/api-clear-config.xml + docs/ru/programmers/api-functions/api-config-load.xml + docs/ru/programmers/api-functions/api-display.xml: + sync with EN + +2006-08-25 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed wrong handling of name attribute in {insert} + thanks to Ivan Kravets for reporting this + + * libs/Smarty_Compiler.class.php: + fixed typo + +2006-08-21 George Miroshnikov + + * docs/ru/designers/language-custom-functions/language-function-popup-init.xml + docs/ru/programmers/advanced-features/advanced-features-objects.xml + docs/ru/programmers/advanced-features/advanced-features-outputfilters.xml + docs/ru/programmers/advanced-features/advanced-features-postfilters.xml + docs/ru/programmers/advanced-features/advanced-features-prefilters.xml + docs/ru/programmers/advanced-features/section-template-cache-handler-func.xml + docs/ru/programmers/advanced-features/template-resources.xml: + sync with EN + + * docs/en/programmers/advanced-features/advanced-features-prefilters.xml: + another missing dot + + * docs/en/programmers/advanced-features/advanced-features-postfilters.xml: + missing dot + + * docs/en/programmers/advanced-features/advanced-features-outputfilters.xml: + missing comma + +2006-08-19 Peter 'Mash' Morgan + + * docs/en/designers/language-custom-functions/language-function-popup-init.xml: + avoid dupes and added remote paths + +2006-08-06 Yannick Torres + + * docs/fr/designers/language-custom-functions/language-function-html-table.xml + docs/fr/designers/language-custom-functions/language-function-mailto.xml: + sync with EN + +2006-08-03 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix false replacement of "$t" inside double quotes + thanks to checat for reporting this + +2006-07-20 George Miroshnikov + + * docs/ru/designers/language-custom-functions/language-function-html-table.xml + docs/ru/designers/language-custom-functions/language-function-mailto.xml: + incrementing EN-Revision + + * docs/ru/designers/language-custom-functions/language-function-assign.xml + docs/ru/designers/language-custom-functions/language-function-eval.xml + docs/ru/designers/language-custom-functions/language-function-fetch.xml + docs/ru/designers/language-custom-functions/language-function-html-checkboxes.xml + docs/ru/designers/language-custom-functions/language-function-html-image.xml + docs/ru/designers/language-custom-functions/language-function-html-options.xml + docs/ru/designers/language-custom-functions/language-function-html-radios.xml + docs/ru/designers/language-custom-functions/language-function-html-table.xml + docs/ru/designers/language-custom-functions/language-function-mailto.xml + docs/ru/designers/language-custom-functions/language-function-popup-init.xml + docs/ru/designers/language-custom-functions/language-function-popup.xml + docs/ru/designers/language-modifiers/language-modifier-date-format.xml + docs/ru/designers/language-modifiers/language-modifier-default.xml + docs/ru/designers/language-modifiers/language-modifier-escape.xml + docs/ru/designers/language-modifiers/language-modifier-indent.xml + docs/ru/designers/language-modifiers/language-modifier-lower.xml + docs/ru/designers/language-modifiers/language-modifier-nl2br.xml + docs/ru/designers/language-modifiers/language-modifier-strip.xml + docs/ru/designers/language-modifiers/language-modifier-truncate.xml + docs/ru/designers/language-modifiers/language-modifier-upper.xml + docs/ru/designers/language-modifiers/language-modifier-wordwrap.xml + docs/ru/designers/language-variables/language-variables-smarty.xml: + sync with EN + + * docs/en/designers/language-custom-functions/language-function-mailto.xml: + typo + +2006-07-10 boots + + * libs/plugins/function.html_table.php: + fixed email address in comments + + * NEWS + libs/plugins/function.html_table.php: + html_table: fixed th/tr output, added hdir support for column + headings,update docs to reflect new features + +2006-07-08 Messju Mohr + + * libs/plugins/function.html_table.php: + fix occasional notices on undefined variables + +2006-07-08 boots + + * libs/plugins/function.html_table.php: + Added ability to specify column headings in {html_table} + + Added th_attrs attribute which works similary to td_attr and tr_attr but + for TH elements. Changes the cols attribute to allow mixed values; a + numeric still specifies the number of columns to render but now an array + of values can be used to specify TH column values. The number of columns + is determine from the size of the array. Further, a comma-separated + string of column names can be used which is internally coverted to an + array and used as if it was specified as a normal array. + + Thanks for lynlyn for the feature request. + +2006-06-23 boots + + * libs/plugins/outputfilter.trimwhitespace.php: + fix comments in outputfilter.trimwhitespace + + * NEWS + libs/plugins/outputfilter.trimwhitespace.php: + fixed ordering of replacements in trimwhitespace output filter + + Thanks to Getty from IRC for reporting this. + +2006-06-20 boots + + * NEWS + libs/plugins/function.mailto.php: + update mailto function plugin to work around a firefox/thunderbird escaping + bug + + Thanks to elijahlofgren from the forums for reporting this and providing + the necessary patch + + * NEWS + libs/plugins/modifier.date_format.php: + emulate %l in the date_format modifier on windows + + thanks to Gibberish from the forums for reporting this + +2006-06-14 boots + + * NEWS + libs/plugins/modifier.capitalize.php: + Fix handling of apostrophes in the capitalize modifier. + + Thanks to asmecher from the forums for reporting this and providing a + partial solution. + +2006-05-28 Monte Ohrt + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + +2006-05-25 boots + + * NEWS + libs/Smarty_Compiler.class.php: + un-hide hidden xml open tags + +2006-05-09 boots + + * NEWS + libs/Smarty_Compiler.class.php: + separate handling of comment blocks from "special blocks" + + * NEWS + libs/plugins/function.popup_init.php: + reverted {popup_init} as proposed change to insertion behviour was not BC + +2006-05-04 boots + + * NEWS + libs/plugins/function.popup_init.php: + changed {popup_init} to only emit code once during a request + + Thanks to TGKnIght from forums + +2006-04-22 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix handling of block-methods of registered objects + thanks to El Hombre Gris + +2006-04-04 Monte Ohrt + + * libs/plugins/function.html_select_date.php: + fix typo + +2006-03-09 Monte Ohrt + + * (Smarty_2_6_13) + NEWS: + update for release + +2006-03-08 Monte Ohrt + + * libs/plugins/modifier.regex_replace.php: + remove delim quote + + * libs/plugins/modifier.regex_replace.php: + fix delimiter issue + +2006-03-03 Monte Ohrt + + * libs/plugins/modifier.regex_replace.php: + use preg_replace to cover any space chars + + * libs/plugins/modifier.regex_replace.php: + fix problem with allowing "e" modifier + +2006-01-29 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed possiblity for E_NOTICE on an undefined variable in + Smarty_Compiler::_compile_if_tag() - thanks to sbeh + +2006-01-18 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + + * (Smarty_2_6_12) + NEWS: + commit 2.6.12 release + +2006-01-15 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed use of references $cache_attrs and $repeat in Smarty_Compiler. + + php does not allow to pass an assigned by reference to a function. since + php-5.1.2 + the reference to the lval gets lost when passing an assignment. + +2005-12-31 Messju Mohr + + * NEWS + libs/Smarty.class.php: + fixed incompatible use of fread() in Smarty::_read_file() + it choke on php-5.1.1 and later. + thanks to andig for pointing this out. + +2005-12-21 boots + + * NEWS + libs/Smarty_Compiler.class.php: + Fix improper tokenization of certain inline math expressions. + + Thanks to gerard at forums for reporting this. + +2005-12-19 Messju Mohr + + * libs/plugins/function.math.php: + fixed problem with math in certain LC_NUMERIC locales. + thanks to wiebren for providing problem+solution. + +2005-12-14 Messju Mohr + + * NEWS: + fixed iso-latin1 special chars + +2005-12-14 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + + * (Smarty_2_6_11) + NEWS: + commit NEWS file for 2.6.11 + +2005-12-08 Messju Mohr + + * docs/de/getting-started.xml: + sync with en + +2005-11-29 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed code generation of non-cacheable blocks to play well with php's + "Alternative syntax" used for example in compiled {if}..{else}..{/if} + blocks. + + (see: http://php.net/manual/en/control-structures.alternative-syntax.php + on "Alternative syntax") + + thanks to kihara from the forum. + +2005-11-26 Messju Mohr + + * NEWS: + fixed handling of multiple identical calls to {insert}. + + the function was called multiple times, but all inserts where replaced + by the results of the first call to the insert function. + + * libs/plugins/compiler.assign.php + libs/plugins/function.config_load.php: + added credits + + * libs/plugins/function.popup.php: + added "closeclick" from + http://www.bosrup.com/web/overlib/?Command_Reference + +2005-11-23 boots + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/modifier.escape.php: + replace {} string access with equivalent substr() to avoid E_STRICT + warnings in PHP 5.1 + +2005-11-09 boots + + * NEWS + libs/Smarty.class.php: + return valid reference in get_config_vars() when given var is non-existant + +2005-10-11 Monte Ohrt + + * libs/plugins/block.textformat.php + libs/plugins/compiler.assign.php + libs/plugins/function.assign_debug_info.php + libs/plugins/function.config_load.php + libs/plugins/function.counter.php + libs/plugins/function.eval.php + libs/plugins/function.fetch.php + libs/plugins/function.html_options.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php + libs/plugins/function.math.php + libs/plugins/function.popup.php + libs/plugins/function.popup_init.php + libs/plugins/modifier.capitalize.php + libs/plugins/modifier.count_characters.php + libs/plugins/modifier.count_paragraphs.php + libs/plugins/modifier.count_sentences.php + libs/plugins/modifier.count_words.php + libs/plugins/modifier.date_format.php + libs/plugins/modifier.debug_print_var.php + libs/plugins/modifier.default.php + libs/plugins/modifier.escape.php + libs/plugins/modifier.indent.php + libs/plugins/modifier.lower.php + libs/plugins/modifier.regex_replace.php + libs/plugins/modifier.replace.php + libs/plugins/modifier.spacify.php + libs/plugins/modifier.string_format.php + libs/plugins/modifier.strip_tags.php + libs/plugins/modifier.truncate.php + libs/plugins/modifier.upper.php + libs/plugins/modifier.wordwrap.php + libs/plugins/shared.escape_special_chars.php + libs/plugins/shared.make_timestamp.php: + Added author title to plugins where they don't exist. I put my name where I + was the original or co-author. If there needs to be more credit given + somewhere, speak up! + +2005-10-10 Monte Ohrt + + * NEWS + libs/plugins/function.html_image.php: + add path_prefix to html_image, fix incorrect secure_dir error when image + file is missing + +2005-10-04 Monte Ohrt + + * demo/templates/index.tpl: + remove popup example, update section var syntax + +2005-09-16 Nuno Lopes + + * docs/de/getting-started.xml: + more fixes + + * docs/de/getting-started.xml: + fix php bug #34520: broken example display (de only) + +2005-08-30 Monte Ohrt + + * libs/plugins/modifier.escape.php: + change default charset from utf8 to iso-8859-1 + + * NEWS + libs/plugins/modifier.escape.php: + add char_set param + +2005-08-17 Monte Ohrt + + * NEWS: + fix notice in debug security check + + * libs/Smarty.class.php: + fix typo + + * NEWS + libs/Smarty.class.php: + return valid reference in get_template_vars() when given var is + non-existant + +2005-08-12 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + add "urlpathinfo" escape type to escape modifier. (apache does not like %2F + in the PATH_INFO) + +2005-08-05 Monte Ohrt + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + +2005-08-04 Monte Ohrt + + * NEWS: + update secure_dir notes + + * NEWS: + allow debug.tpl to work from arbitrary dir + +2005-08-04 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed proper escaping for literal strings passed to + Smarty_Compiler::_expand_quoted_text() by + Smarty_Compiler::_parse_var_props() + +2005-07-27 Messju Mohr + + * NEWS + libs/plugins/shared.make_timestamp.php: + removed ambiguity for numeric values passed to smarty_make_timestamp(). + numeric values are *always* treated as timestamps now. + +2005-07-18 Messju Mohr + + * libs/Config_File.class.php: + removed E_NOTICE from Config_File::get() + + * libs/Smarty.class.php: + removed E_NOTICE + +2005-07-10 Yannick Torres + + * docs/fr/getting-started.xml: + sync with EN + +2005-07-08 Monte Ohrt + + * NEWS: + correct username in NEWS file + + * NEWS + libs/plugins/function.html_select_date.php: + added passthru attribute feature to html_select_date + +2005-07-03 Yannick Torres + + * docs/fr/language-snippets.ent + docs/fr/preface.xml: + sync with EN + +2005-06-16 Messju Mohr + + * docs/de/preface.xml + docs/de/preface.xml: + sync with en + +2005-06-13 Monte Ohrt + + * NEWS + libs/plugins/modifier.truncate.php: + add "middle" parameter to truncate modifier + +2005-06-10 Messju Mohr + + * docs/de/livedocs.ent: + added german livedocs.ent + + * docs/de/language-snippets.ent + docs/de/preface.xml: + sync with en + +2005-06-09 Messju Mohr + + * docs/de/bookinfo.xml + docs/de/getting-started.xml + docs/de/getting-started.xml: + sync with en + +2005-05-24 Yannick Torres + + * docs/fr/getting-started.xml + docs/fr/language-snippets.ent: + sync with EN + +2005-05-20 Monte Ohrt + + * libs/plugins/function.html_radios.php: + fix allowable label id characters + +2005-05-06 Monte Ohrt + + * NEWS + libs/plugins/function.html_radios.php: + make form input label ids optional (monte) + +2005-05-02 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + add error message for empty if/elseif statements + +2005-04-15 Monte Ohrt + + * NEWS + libs/plugins/function.html_radios.php: + cast selected value to string for comparison in html_radios + +2005-04-07 Messju Mohr + + * NEWS + libs/plugins/function.html_select_date.php: + added xhtml compliance to html_select_date's year_as_text-feature + thanks to Mark West + + * NEWS + libs/plugins/function.html_select_date.php: + fixed handling of selected month html_select_date + thanks to Yuri Weseman for providing problem+solution + +2005-04-07 Nuno Lopes + + * docs/configure.in: + sync configure and file-entities scripts with phpdoc, for better + windows/cygwin support + +2005-03-31 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers + + * (Smarty_2_6_9) + NEWS: + update NEWS file + +2005-03-30 Messju Mohr + + * libs/plugins/function.math.php: + re-enabled hex-constant. i hope in a sane way this time. + +2005-03-30 Monte Ohrt + + * libs/plugins/function.math.php: + fix function testing logic + + * libs/Smarty_Compiler.class.php: + disable variable func calls completely + + * libs/Smarty_Compiler.class.php: + disallow variable func calls when security is enabled + +2005-03-22 Messju Mohr + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + bumped version-number to 2.6.9-dev + added headline of 2.6.6 release to NEWS file + +2005-03-21 Messju Mohr + + * (Smarty_2_6_8) + NEWS: + maybe even better this way. thanks monte :) + + * NEWS: + little more clear news-entry + +2005-03-21 Monte Ohrt + + * NEWS: + update NEWS with e-modifier removal + + * (Smarty_2_6_8) + libs/plugins/modifier.regex_replace.php: + remove e-modifier + +2005-03-19 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + objects don't get casted to arrays anymore in {foreach} + +2005-02-26 Messju Mohr + + * NEWS + libs/Smarty.class.php: + add "null" as a valid token for {if} when security is enabled + +2005-02-25 Monte Ohrt + + * NEWS + libs/plugins/function.mailto.php: + add javascript_charcode option to mailto + +2005-02-24 Monte Ohrt + + * NEWS: + update NEWS file + + * QUICK_START + libs/plugins/function.html_radios.php: + add label ids to html_radios + +2005-02-10 Monte Ohrt + + * QUICK_START: + update with directory structure + +2005-02-10 Nuno Lopes + + * docs/Makefile.in: + fix chm generation + +2005-02-10 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed too agressive {strip} around delimiters inside strip-blocks + +2005-02-10 Monte Ohrt + + * QUICK_START: + fix a couple errors + +2005-02-10 Nuno Lopes + + * docs/Makefile.in + docs/README: + commiting the new tools to make the CHM manual. + +2005-02-09 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of strip-tags with non-default delimiters + +2005-02-04 Messju Mohr + + * libs/plugins/function.html_radios.php: + fixed syntax error. shame on me. + +2005-02-03 Monte Ohrt + + * QUICK_START: + fix example + + * QUICK_START: + initial commit + + * RELEASE_NOTES + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers in cvs + + * (Smarty_2_6_7) + NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + commit version numbers for new release + +2005-02-03 Messju Mohr + + * (Smarty_2_6_7) + libs/plugins/function.html_image.php: + fixed comment (thanks to CirTap) + +2005-02-01 Monte Ohrt + + * libs/plugins/function.html_image.php: + remove border tag + +2005-02-01 Messju Mohr + + * libs/Smarty.class.php: + fixed serialization of values containing newlines (like _cache_attrs) + in core_write_cache_file() + + bumped version to 2.6.6-dev-3 to indicate that the fileformat of cache + has changed + +2005-01-30 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of hashed opening php-tags inside strip-blocks + (reported by titi_rafa) + +2005-01-30 Nuno Lopes + + * docs/fr/language-snippets.ent: + fix build + +2005-01-28 Messju Mohr + + * NEWS + libs/plugins/modifier.escape.php: + escape:url now uses the (RFC 1738 compliant) rawurlencode() + +2005-01-23 Messju Mohr + + * libs/Smarty.class.php: + replaced ? true : false and removed intermediate $_cookie_var in the + handling of the SMARTY_DEBUG-cookie + +2005-01-22 Yannick Torres + + * docs/fr/bookinfo.xml: + update EN-Revision tag + +2005-01-21 Monte Ohrt + + * README + RELEASE_NOTES + docs/de/bookinfo.xml + docs/fr/bookinfo.xml + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.cycle.php + libs/plugins/function.debug.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_table.php + libs/plugins/function.mailto.php + libs/plugins/modifier.cat.php + libs/plugins/modifier.nl2br.php + libs/plugins/modifier.strip.php + libs/plugins/outputfilter.trimwhitespace.php: + de-spammify e-mails + + * README + RELEASE_NOTES + docs/de/bookinfo.xml + docs/fr/bookinfo.xml + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.cycle.php + libs/plugins/function.debug.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_table.php + libs/plugins/function.mailto.php + libs/plugins/modifier.cat.php + libs/plugins/modifier.nl2br.php + libs/plugins/modifier.strip.php + libs/plugins/outputfilter.trimwhitespace.php: + update copyright notices, e-mail addresses + +2005-01-06 Messju Mohr + + * libs/Smarty_Compiler.class.php: + reduced the code that is generated on a {foreach}-block that has a + name. + + instead of pre-computing all foreach-properties (like first, last, + show) on each iteration, they are computed on demand as soon as + {$smarty.foreach.*}-variables are used. + + * NEWS + libs/Smarty_Compiler.class.php: + slight optimization in the compilation of $smarty.const.FOO . + + more complex consts like $smarty.const.$name still compile to + constant($this->_tpl_vars['name']) + +2005-01-05 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + make block functions and registered objects' block methods use a + local variable for block_content instead of $this->_block_content + + it's not necessary to have $smarty->_block_content accessible. + +2005-01-04 Yannick Torres + + * docs/fr/bookinfo.xml: + sync with EN + +2005-01-01 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + Happy new year from germany. + +2004-12-28 Monte Ohrt + + * libs/Smarty.class.php: + fix _read_file comments + +2004-12-26 Yannick Torres + + * docs/fr/getting-started.xml + docs/fr/preface.xml: + typo + + * docs/fr/language-defs.ent + docs/fr/language-snippets.ent + docs/fr/livedocs.ent: + sync with EN & typo + +2004-12-21 Yannick Torres + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/translation.xml: + sync with EN + +2004-12-17 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed escaping of template-filenames in the generated code that loads + needed plugins + +2004-12-15 Monte Ohrt + + * NEWS + libs/plugins/function.popup.php: + fix invalid HTML issue with popup + +2004-12-06 boots + + * NEWS + libs/plugins/function.popup.php: + - fixed {popup} to properly handle inarray and function parameters and + added support for mouseoff and followmouse options + +2004-11-21 Mehdi Achour + + * docs/fr/livedocs.ent: + add livedocs specific entities files + +2004-11-16 Messju Mohr + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + cleaned up typecasting + +2004-11-15 Messju Mohr + + * libs/plugins/function.html_options.php: + fixed semantically misleading check for $options (use isset() instead + of is_array() because it is always an array). + + thanks to albert almeida. + +2004-11-08 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed unused code + +2004-10-25 Mehdi Achour + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml: + sync with en + +2004-10-13 Monte Ohrt + + * NEWS: + update header + +2004-10-02 Messju Mohr + + * NEWS: + fixed nocache-handling with nested includes. there was a logical error + in the replacement of internal nocache-tags to dynamic content that + lead to false results with deeply nested includes or with + nocache-blocks inside nocache-blocks. + + many thanks to Lars Jankowfsky for providing big help on reproducing + and tracking down this bug! + +2004-10-01 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + - better header for compiled includes (more in line with compiled + templates) + + - reuse cache_serials if a file is compiled more than once in one + process (force_compile) + + - don't print nocache-delimiters wenn already inside + process_cached_inserts() + +2004-09-29 Messju Mohr + + * libs/Smarty.class.php: + switched from @count() to !empty() . this was pointed out a few times + by a few people with buggy error-handlers + + * libs/Smarty_Compiler.class.php: + added some property declarations + +2004-09-28 Messju Mohr + + * libs/Smarty.class.php: + bumped up version number to reflect incompatibility in tempfiles of + 'core' vs. 'internals' + +2004-09-24 Messju Mohr + + * libs/plugins/function.html_select_date.php: + fixed $start_year when no value for the year in $time is given. + +2004-09-21 Messju Mohr + + * libs/plugins/function.html_table.php: + fixed handling of "inner"-attribute + + * libs/Smarty_Compiler.class.php: + fixed handling of object derefence inside backticks + +2004-09-20 Monte Ohrt + + * libs/debug.tpl: + add tags + +2004-09-18 boots + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.config_load.php + libs/plugins/function.debug.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + Fixed \\r\\n line endings mistakenly introduced in last commit. d'oh. + +2004-09-16 boots + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.display_debug_console.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.process_cached_inserts.php + libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include_php.php + libs/core/core.write_cache_file.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php + libs/plugins/function.config_load.php + libs/plugins/function.debug.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + Moved /libs/core to /libs/internals and created new constant, + SMARTY_CORE_DIR which defaults to SMARTY_DIR/internals. This should help + CVS and rsynch users butupgrades will require changes and this may affect + 3rd party plugins that use the /core dir. + +2004-09-15 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + moved $this->_num_const_regexp out of $this->_var_regexp and added it + to the places that affect $this->_var_regexp + + this should fix some problems parsing plugin-names endings with digits + +2004-09-14 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update files to 2.6.6-dev + +2004-09-13 Messju Mohr + + * NEWS: + fixed typo + +2004-09-13 Monte Ohrt + + * (Smarty_2_6_5) + NEWS: + update NEWS file with parsing correction note + +2004-09-11 Messju Mohr + + * libs/plugins/function.debug.php: + removed notice from {debug} + thanks to Peter Billen for pointing this one out! + +2004-09-11 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix more object calling syntax issues + +2004-09-10 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added $smarty->security_settings['ALLOW_CONSTANTS'] + including test-cases for them + +2004-09-09 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + break down regex to digestable chunks, fix multiple param problem with + method calls, + add object method testing to unit_test cases + + * libs/Smarty_Compiler.class.php: + update code comment with more examples + + * libs/Smarty_Compiler.class.php: + allow objects in arbitrary param positions + + * libs/Smarty_Compiler.class.php: + fix object parameter regex, allow one level of object indirection + + * libs/Smarty_Compiler.class.php: + fix compile problem with numeric constants and math operator matching + +2004-09-07 Monte Ohrt + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update files to 2.6.5-dev + + * (Smarty_2_6_4) + NEWS: + update NEWS file with 2.6.4 header + +2004-08-31 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix preg_quote + + * libs/Smarty_Compiler.class.php: + fix math in object params, clean up some regex on the way, change + preg_ delimiters to ~ to avoid character clashes with ! and % + +2004-08-30 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + add $smarty.ldelim and $smarty.rdelim to smarty special var + +2004-08-29 Messju Mohr + + * NEWS + libs/core/core.write_file.php: + tempnam() seems to be borken on many installation. + + now we try tempnam first and if that fails we generate our own + temp-filename with uniqid() + +2004-08-23 Monte Ohrt + + * libs/plugins/modifier.capitalize.php: + dont use constant, use static var instead + + * libs/plugins/modifier.capitalize.php: + implement optional param to capitalize for digit behavior + + * libs/plugins/modifier.capitalize.php: + another commit to capitalize, taking special chars into account + +2004-08-23 Messju Mohr + + * libs/Smarty_Compiler.class.php: + cleaned up attribute-handling in Smarty_Compiler::_compile_foreach_start() + +2004-08-23 Monte Ohrt + + * NEWS + libs/plugins/function.html_select_date.php + libs/plugins/modifier.capitalize.php: + fix capitalize modifier to not rely on buggy ucwords() func + +2004-08-20 Monte Ohrt + + * libs/plugins/function.html_select_date.php: + update version + + * NEWS + libs/plugins/function.html_select_date.php: + make time param work with negative timestamps, force year range to include + given date unless explicitly set + +2004-08-19 Monte Ohrt + + * NEWS + libs/plugins/function.fetch.php: + fix bug with fetch, passing user/pass in url did not work + +2004-08-13 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed handling of {foreachelse} and {sectionelse} that got borked with + the latest commit (v 1.330) + +2004-08-12 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed occasional wrong error messages on mismatched tags when + {else}, {elseif}, {foreachelse} or {sectionelse} is involved + + thanks to Ooypunk for pointing me on this + +2004-08-12 Nuno Lopes + + * docs/.cvsignore + docs/Makefile.in + docs/configure.in: + enable russian PDF builds + +2004-07-30 Nuno Lopes + + * docs/configure.in: + typo + + * docs/Makefile.in + docs/README + docs/configure.in: + add make test_xml + this is usefull to detect XML problems + +2004-07-29 Nuno Lopes + + * docs/configure.in: + avoid warnings in head + + * docs/.cvsignore + docs/Makefile.in + docs/README + docs/configure.in: + build pdf files + just type make pdf + +2004-07-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of methods arguments. + + thanks to Manfred Wischin for finding this one and providing the + conceptual fix. + +2004-07-23 Messju Mohr + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + there was little flaw in smarty_function_html_radios() and + smarty_function_html_checkboxes(): + + the newly introduced assign-attribute was still added to the + tag-output as an extra-attribute. + + fixed. + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php + libs/plugins/modifier.date_format.php: + backed out renaming of _get_plugin_filepath() to get_plugin_filepath() + + we'll stick to _get_plugin_filepath() and look for a more viable + solution to be exposed to plugin-writers. + +2004-07-20 Messju Mohr + + * libs/Smarty_Compiler.class.php + libs/core/core.is_trusted.php + libs/plugins/compiler.assign.php: + Some fixes on PhpDocumentor comments. Thanks go to Ruben Vermeersch. + +2004-07-16 andreas halter + + * docs/de/bookinfo.xml + docs/de/getting-started.xml + docs/de/language-defs.ent + docs/de/language-snippets.ent + docs/de/preface.xml: + - updated for 2.6.3 + - updates for new build system + - added missing files + - corrections from users + - revcheck comments for all files + - big up to didou and nuno, brilliant work + - make test: ok + - make: ok + +2004-07-16 Nuno Lopes + + * docs/de/getting-started.xml: + fix the revision tracking tag + the revision number might not be right. just check it, please + +2004-07-16 andreas halter + + * docs/de/getting-started.xml: + - updated version (incl revcheck comment) for revcheck testing + +2004-07-14 Monte Ohrt + + * libs/Smarty.class.php: + replace " with ' where literal strings are quoted (ever so slight speedup) + +2004-07-12 Messju Mohr + + * libs/plugins/modifier.date_format.php: + changed call from $smarty->_get_plugin_filepath() to + $smarty->get_plugin_filepath() + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php: + renamed calls to $smarty->_get_plugin_filepath() to + $smarty->get_plugin_filepath() + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php: + renamed Smarty::_get_plugin_filepath() to Smarty::get_plugin_filepath() + + * NEWS + libs/Smarty.class.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php: + removed touch() call. changing the timestamp of the compiled-template + to the source template's may be irritating for certain + source-code-caches. now a newly compiled template gets the current + time as timestamp. + +2004-07-02 gerald croes + + * docs/fr/getting-started.xml + docs/fr/preface.xml: + Fixed missing tags to be able to make doc again + + * docs/fr/preface.xml: + added the "is a good thing [TM]" as in en docs + + * docs/fr/getting-started.xml: + added ctags, updated screen => programm listing. + added the technical note founded on the en doc + +2004-07-02 Monte Ohrt + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php + libs/plugins/function.mailto.php: + add assign attribute to html_checkboxes and html_radios + +2004-07-01 Messju Mohr + + * NEWS + libs/Smarty.class.php: + removed use of get_include_filepath() inside + get_auto_filename(). thanks go to c960657 + + * NEWS + libs/Smarty_Compiler.class.php: + enhanced error-reporting for {foreach} + + * NEWS + libs/Smarty_Compiler.class.php: + fixed handling of digits inside tagnames. this problem slipped into + the regexps by adding support for numeric contants next to string + constants as variables. + +2004-06-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed escaping of backslashes in Smarty_Compiler::_quote_replace() + +2004-06-23 Monte Ohrt + + * libs/plugins/modifier.date_format.php: + display date_format %e, %T and %D as expected for windows + +2004-06-17 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + changed version-number to 2.6.4-dev + +2004-06-16 Monte Ohrt + + * (Smarty_2_6_3) + NEWS: + update NEWS file with version number + +2004-06-09 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + added escapement of ' + + * docs/fr/translation.xml: + Add other translators. + +2004-06-08 Messju Mohr + + * libs/Smarty.class.php: + made the correct value of "use_sub_dirs" available to the compiler. + (not worth a NEWS-entry, i think) + +2004-06-01 Messju Mohr + + * libs/plugins/function.fetch.php: + fix: proper initialistaion of $content. + thanks to Dmitry Koteroff for pointing this out. + +2004-05-29 Mehdi Achour + + * docs/fr/translation.xml: + oups :) + + * docs/fr/translation.xml: + added translation file + +2004-05-28 Nuno Lopes + + * docs/Makefile.in: + clean also file-entities.php + +2004-05-28 Messju Mohr + + * NEWS + libs/plugins/function.mailto.php: + added obfuscation of protocol-string in {mailto} when using + hex-encoding (thanks to bharat) + +2004-05-26 Messju Mohr + + * NEWS + libs/Smarty.class.php: + enhanced auto-generated filenames for templates_c and cache + + incremented Smarty::_version because the tempfiles' structure changed + a little + +2004-05-23 Mehdi Achour + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/preface.xml: + WS and added revcheck + +2004-05-21 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed typo in error-messages + + * docs/de/language-snippets.ent + docs/fr/language-snippets.ent: + added empty language-snippets.ent to fix "make web" + +2004-05-12 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + add 'nonstd' escape modifier + +2004-05-07 Monte Ohrt + + * NEWS + libs/plugins/block.textformat.php: + update textformat to not output wrap chars after last para + +2004-05-06 Messju Mohr + + * NEWS + libs/core/core.write_file.php: + use tempnam() instead of unqid() to create better temporary files in + smarty_core_write_file(). + + (thanks to xces for finding this race-condition and his work on + fixing it) + +2004-05-04 Messju Mohr + + * libs/Smarty.class.php: + added check if for file_exists() to Smarty::_read_file() + +2004-04-30 Monte Ohrt + + * NEWS + libs/plugins/modifier.escape.php: + add 'mail' attribute to escape modifier + +2004-04-20 Mehdi Achour + + * docs/manual.xml.in: + added the language-snippets.ent file and started using entities for notes + under en/programmers/api-functions + +2004-04-18 Mehdi Achour + + * docs/de/getting-started.xml + docs/fr/getting-started.xml: + new global entity for zend and php-accelerator + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/preface.xml: + added myself as translator and added vim comments and xml tags + +2004-04-16 Messju Mohr + + * NEWS: + added entry for numeric constants + + * libs/Smarty_Compiler.class.php: + removed unused 2nd param in call to _parse_var() + + * libs/Smarty_Compiler.class.php: + added explanation for $this->_num_const_regexp + + * NEWS + libs/plugins/modifier.escape.php: + added escape type "decentity" to smarty_modifier_escape() + + * libs/Smarty_Compiler.class.php: + enabled numerical constants be parsed as statements. + (like {10} or {10|@range:12} ) + + * libs/Smarty_Compiler.class.php: + removed unused $smarty_compiler->_dvar_num_var_regexp + + * libs/Smarty.class.php: + reverted Stuff + + * libs/debug.tpl + libs/core/core.assemble_plugin_filepath.php + libs/core/core.read_cache_file.php + libs/core/core.write_file.php + libs/plugins/function.eval.php + libs/plugins/function.popup.php + libs/plugins/modifier.escape.php + libs/plugins/shared.make_timestamp.php: + reverted stuff + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/debug.tpl + libs/core/core.assemble_plugin_filepath.php + libs/core/core.read_cache_file.php + libs/core/core.write_file.php + libs/plugins/function.eval.php + libs/plugins/function.popup.php + libs/plugins/modifier.escape.php + libs/plugins/shared.make_timestamp.php: + Smarty_Compiler.class.php + +2004-04-15 Messju Mohr + + * NEWS + libs/core/core.write_compiled_include.php: + made smarty_core_write_compiled_include() php5-aware + + if someone knows a better way than patching the source with the + tokenizer, please stand up! + +2004-04-14 Nuno Lopes + + * docs/Makefile.in: + remove file-entities.ent also + + * docs/.cvsignore + docs/Makefile.in + docs/README: + allow make revcheck + +2004-04-13 Nuno Lopes + + * docs/configure.in: + do not need inipath + +2004-04-13 Mehdi Achour + + * docs/TODO: + done + + * docs/configure.in + docs/manual.xml.in: + now the files entites are generated dynamically + +2004-04-12 Messju Mohr + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php: + removed unused functionality to load a subset of lines from a file in + Smarty::_read_file() + + additionally removed a warning that is emitted since php-4.3.5 when + fread() is called on an empty file (with filesize()==0). thanks to + Andreas Streichardt who pointed this out. + + * NEWS + libs/core/core.is_secure.php: + smarty_core_is_secure() only checks the file for readability now, not + the directory where is in. + + * libs/Smarty.class.php: + removed unused security_setting 'ALLOW_CONSTANTS' + +2004-04-07 Messju Mohr + + * libs/plugins/function.assign_debug_info.php + libs/plugins/function.cycle.php + libs/plugins/function.mailto.php: + removed trailing spaces + + * libs/Smarty.class.php: + removed unused $smarty->_error_msg + +2004-04-04 Nuno Lopes + + * docs/configure.in: + fixing my crap + put build_date back on-line + +2004-04-03 Nuno Lopes + + * docs/Makefile.in + docs/configure.in + docs/manual.xml.in: + trying to fix ru problems + +2004-03-30 Monte Ohrt + + * libs/core/core.display_debug_console.php: + fix problem with debug_tpl path and security + + * NEWS + libs/core/core.display_debug_console.php: + fix problem displaying debug console when $default_resource_type is not + "file:" + +2004-03-29 Mehdi Achour + + * docs/TODO: + and finally, add a TODO here + + * docs/de/bookinfo.xml + docs/de/manual.sgml + docs/fr/bookinfo.xml + docs/fr/manual.xml: + translate bookinfo.xml and put back the translators + +2004-03-28 Mehdi Achour + + * docs/manual.xml.in: + add global.ent and define some general entities + + * docs/de/bookinfo.xml + docs/de/getting-started.xml + docs/de/language-defs.ent + docs/de/preface.xml: + add new de files + + * docs/de/appendixes.sgml + docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/html-common.dsl + docs/de/preface.sgml + docs/de/programmers.sgml: + drop old de files + + * docs/fr/bookinfo.xml + docs/fr/getting-started.xml + docs/fr/manual.xml + docs/fr/preface.xml: + add ommited files + + * docs/fr/language-defs.ent: + split the french dir + + * docs/fr/appendixes.sgml + docs/fr/designers.sgml + docs/fr/getting-started.sgml + docs/fr/html-common.dsl + docs/fr/manual.sgml + docs/fr/preface.sgml + docs/fr/programmers.sgml: + drop old french files + + * docs/manual.xml.in: + let's put the new build system + +2004-03-26 Mehdi Achour + + * docs/de/common.dsl + docs/de/html.dsl + docs/fr/common.dsl + docs/fr/html.dsl + docs/fr/php.dsl: + not needed anymore + +2004-03-24 Nuno Lopes + + * docs/Makefile.in: + updated stylesheets + highlight PHP automatically + + * docs/Makefile.in + docs/html.dsl: + remove unneeded file + +2004-03-23 Nuno Lopes + + * docs/version.ent.in: + remove this also + + * docs/getting-started.sgml: + remove this one too + + * docs/appendixes.sgml + docs/common.dsl + docs/designers.sgml + docs/html-common.dsl + docs/manual.sgml + docs/php.dsl + docs/preface.sgml + docs/programmers.sgml: + removing uneeded files + + * docs/.cvsignore: + commiting missing files for docbook + + * docs/.cvsignore + docs/Makefile.in + docs/configure.in + docs/manual.xml.in: + bundling docbook 4 + now make and make web works + +2004-03-23 Messju Mohr + + * NEWS + libs/plugins/function.config_load.php: + unrolled call to the is_compiled()-check to be able to supply the + correct resource_base_path for config_load. this avoids errors when + config-files are accessed where security is enabled. + + thanks to shuther for pointing out this bug. + +2004-03-20 Nuno Lopes + + * docs/manual.xml.in: + fix build date + +2004-03-18 Messju Mohr + + * libs/core/core.is_secure.php: + removed merging of $smarty->template_dir into $smarty->secure_dir + + the resource_base_path is considerd secure instead. this change should + have absolutely no impact on smarty's security's behaviour + +2004-03-18 Nuno Lopes + + * docs/configure.in: + correcting non-existent var + + * docs/.cvsignore + docs/Makefile.in + docs/configure.in + docs/manual.xml.in + docs/version.ent.in: + generate build date + + * docs/.cvsignore + docs/Makefile.in + docs/README + docs/configure.in + docs/manual.xml.in: + new build/test system + +2004-03-18 Messju Mohr + + * libs/Smarty.class.php: + moved setting of a default resource_base_path from + Smarty::_parse_resource_name() to Smarty::_fetch_resource_info() + + this shouldn't affect anything, since all calls to + _parse_resource_name() that are not done from within + _fetch_resource_info() all pass their own resource_base_path + +2004-03-17 Messju Mohr + + * NEWS + libs/Smarty.class.php: + removed '.' from the list of default resource_base_paths in + _parse_resource_name() + + this should only affect _parse_resource_name() for templates, not for + php-resources and not for config_files. the latter pass two their own + resource_base_path. + +2004-03-16 Mehdi Achour + + * docs/appendixes.sgml + docs/getting-started.sgml + docs/preface.sgml: + adding editor comments + + * docs/appendixes.sgml + docs/getting-started.sgml: + cleaning words spacing, killing tabulations, using roles for + programlisting.. + +2004-03-15 Messju Mohr + + * libs/Smarty.class.php: + simplified Smarty::clear_all_cache(); + +2004-03-12 boots + + * docs/programmers.sgml: + Updated is_cached prototype to indicate proper return type. (thanks to + Geoffrey Hoffman) + +2004-03-11 Messju Mohr + + * libs/core/core.assemble_plugin_filepath.php: + fixed little bug that prevented plugins filepaths that are found in + php's include_path (and not in one of the plugins_dirs) from being + cached in the internal plugins-filepath-cache + +2004-03-01 Monte Ohrt + + * docs/designers.sgml: + update include_php docs:wq + :q + + * docs/appendixes.sgml: + update componentized template example to something useful + +2004-02-24 Messju Mohr + + * NEWS + libs/Smarty.class.php: + _parse_resource_name() returned true on non-existant absolute + paths. This caused a warning on _fetch_resource_info() when used in + conjunction with template_exists(). It should be fixed now without + negative effects. + +2004-02-24 Monte Ohrt + + * docs/designers.sgml: + one more typo + + * docs/designers.sgml: + fix typo + +2004-02-24 Messju Mohr + + * NEWS + libs/core/core.is_secure.php: + smarty_resource_*_secure got &$smarty passed errornously as 3rd + parameter and not as 2nd. this is fixed. + +2004-02-23 Messju Mohr + + * NEWS: + fix handling of integer values like width and delay im + smarty_function_popup() + + * libs/plugins/function.popup.php: + fixed handling of integer-attributes + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + updated version to 2.6.3-dev + +2004-02-22 Messju Mohr + + * libs/plugins/function.html_select_date.php: + removed notice on html_select_date with the month_empty-attribute + + * libs/plugins/function.mailto.php: + removed 2 notices of undefined vars (thanks Cit) + +2004-02-17 Monte Ohrt + + * NEWS: + add header + + * (Smarty_2_6_2) + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + change some info in headers, remove fluff + +2004-02-13 Messju Mohr + + * NEWS + libs/plugins/function.html_select_date.php: + correctly handle partially empty dates (like "2004--" or "-12-"). + + * docs/programmers.sgml: + learned something about and sgml and applied this to the + use.sub.dirs-section :) + + * docs/designers.sgml: + changed attribute-name "checked" to "selected" in the docs for + html_radios and html_checkboxes. "checked" is deprecated for ages + AFAIK and selected is recommended for consistency with {html_options} + + * docs/programmers.sgml: + added note about use_sub_dirs and Smarty-2.6.2 . + fixed markup for section about clear_compiled_tpl() . + +2004-02-12 Messju Mohr + + * NEWS + libs/Config_File.class.php: + YES and NO should not be booleanized inside triple-quotes in a + config-file. this behaviour changed by accident in 2.6.1 and is now + reverted to pre-2.6.1 behaviour + +2004-02-10 Messju Mohr + + * NEWS + libs/Config_File.class.php: + fixed slurping of a the next line following a triple-quoted value in a + config-file + +2004-02-07 Messju Mohr + + * libs/Config_File.class.php: + avoid @-operator for handling empty lines in Config_File.class.php + + * libs/Smarty_Compiler.class.php: + removed two notices from Smarty_Compiler::_parse_is_expr() + (thanks shuther!) + + * NEWS + libs/Smarty.class.php: + changed default for use_sub_dirs to false + + * libs/plugins/function.mailto.php: + removed notice of undefined variable. (thanks shuther!) + +2004-01-29 Messju Mohr + + * libs/Smarty_Compiler.class.php: + added file and line-number-information to error-messages regarding + assigned objects an an error messages regarding modifiers with + security. + +2004-01-27 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed use of temporary var $_params in compiled code of block-plugins + + * NEWS + libs/plugins/function.popup.php: + fixed quoting of values in smarty_function_popup() + +2004-01-25 Messju Mohr + + * docs/programmers.sgml: + documented parameters of Smarty::clear_compiled_tpl() + + * libs/Smarty_Compiler.class.php: + Smarty_Compiler::_syntax_error() uses Smarty::_trigger_fatal_error() now + instead of the trigger_error()-function + + * libs/Smarty.class.php: + Smarty::_trigger_fatal_error() uses Smarty::trigger_error() now, + instead of the native trigger_error()-function + + * libs/Smarty_Compiler.class.php: + unrecognized custom-functions trigger an error at compile now, not at + display-time. + +2004-01-23 Monte Ohrt + + * docs/getting-started.sgml: + reword a paragraph + +2004-01-22 Messju Mohr + + * libs/plugins/function.config_load.php: + removed emission of unnecessary notices for unavailable config-files + in config_load() + + * NEWS + libs/Config_File.class.php: + fixed handling of hidden sections in Config_File + +2004-01-21 Messju Mohr + + * NEWS + libs/plugins/function.config_load.php: + added handling of resources for {config_load} + +2004-01-19 Messju Mohr + + * NEWS + libs/plugins/function.html_table.php: + fixed bug when using arrays with tr_attr and td_attr in {html_table} + +2004-01-16 Monte Ohrt + + * NEWS: + add unit testing + + * NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers, add initial unit test directory + + * (Smarty_2_6_1) + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers for 2.6.1 release + +2004-01-16 Messju Mohr + + * (Smarty_2_6_1) + NEWS + docs/programmers.sgml + libs/Smarty.class.php: + renamed $smarty->tpl_rror_reporting to $smarty->error_reporting + "tpl_" is a bit redundant here (it's a TemPLate-engine overall :) + +2004-01-15 Messju Mohr + + * libs/plugins/function.html_image.php: + forgot to remove duplicate is_secure()-check + + * NEWS + libs/plugins/function.html_image.php: + fix: $smarty->security is now correctly handled + + minor optimizations: + core/core.is_secure.php is only included when needed + $dpi_default is only determined when needed + +2004-01-14 Messju Mohr + + * docs/appendixes.sgml + docs/programmers.sgml: + removed suggestions to use extract() from the manual + + * docs/designers.sgml: + fixed typo + +2004-01-12 Messju Mohr + + * docs/designers.sgml: + mention SCRIPT_NAME below {$smarty} reserved variable because it got + lost in the docs for $smarty->global_assign + + * docs/designers.sgml: + added docs for {$smarty.version} special variable + + * docs/programmers.sgml: + removed docs for $global_assign + + * docs/programmers.sgml: + added docs for tpl_error_reporting + + * docs/designers.sgml: + added docs for year_empty-, month_empty- and day_emtpy-attributes of + html_select_date. maybe an example is needed to better explain empty + values in YYY-MM-DD. + +2004-01-10 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed handling of {php}-tags + +2004-01-10 Monte Ohrt + + * docs/designers.sgml: + fix html_checkboxes examples + +2004-01-08 Messju Mohr + + * NEWS + libs/core/core.assemble_plugin_filepath.php: + added caching of requested paths to smarty_core_assemble_plugin_filepath() + + * NEWS: + fix handling of comments inside {php}- and {literal}-blocks + + * libs/Smarty_Compiler.class.php: + fixed handling of comments inside {php} and {literal} + +2004-01-06 Messju Mohr + + * NEWS + libs/Config_File.class.php: + fixed bug handling triple-quotes in config-files + + * libs/Config_File.class.php: + fixed bugs with triple-quotes in config-files + thanks BRDude for finding them testing! + +2004-01-02 Messju Mohr + + * libs/Smarty.class.php: + removed unnecessary param in call to _fetch_resource_info() + +2003-12-30 Messju Mohr + + * libs/Smarty.class.php: + oops! removed tabs. + +2003-12-27 Messju Mohr + + * NEWS + libs/Smarty.class.php: + made $SCRIPT_NAME available again + changes default for request_use_auto_global to prefer autoglobals + + * libs/Smarty.class.php: + removed tabs and trailing spaces + + * NEWS + libs/Smarty_Compiler.class.php: + readded default_modifiers. who removed that? + +2003-12-23 Monte Ohrt + + * NEWS: + add portuguese docs + +2003-12-22 Monte Ohrt + + * docs/designers.sgml: + fix counter example + +2003-12-19 Monte Ohrt + + * libs/Smarty.class.php: + add debug console persistance feature + +2003-12-19 Messju Mohr + + * libs/plugins/block.textformat.php + libs/plugins/function.html_table.php + libs/plugins/function.popup.php: + removed extract(). enhanced parameter parsing. + + * libs/plugins/function.counter.php + libs/plugins/function.fetch.php + libs/plugins/function.popup_init.php + libs/plugins/modifier.capitalize.php + libs/plugins/modifier.cat.php + libs/plugins/modifier.date_format.php + libs/plugins/modifier.debug_print_var.php + libs/plugins/modifier.escape.php + libs/plugins/modifier.indent.php + libs/plugins/modifier.lower.php + libs/plugins/modifier.nl2br.php + libs/plugins/modifier.strip.php + libs/plugins/modifier.upper.php + libs/plugins/modifier.wordwrap.php + libs/plugins/outputfilter.trimwhitespace.php + libs/plugins/shared.escape_special_chars.php: + removed tabs. fixed indentiation. + + * libs/plugins/modifier.truncate.php: + removed tabs + + * libs/plugins/function.counter.php + libs/plugins/function.cycle.php: + removed extract() from parameter-parsing + +2003-12-17 Messju Mohr + + * libs/plugins/function.html_select_date.php: + fix plugin-name in error message + + * libs/plugins/function.html_select_time.php: + remove extract-call from {html_select_time} + + * NEWS + libs/plugins/function.html_select_date.php: + allow single-digit days and months without smarty_make_timestamp() + this makes dates like "1968-11-6" work correctly since no strtotime() + is involved + + add warning when unknown parameter is passed + +2003-12-16 Messju Mohr + + * NEWS + libs/Smarty.class.php: + fix headers sent erroneously with cache_modified_check and fetch() + +2003-12-12 Monte Ohrt + + * libs/plugins/function.config_load.php: + move set_path() call below the conditional bracket + + * NEWS + libs/plugins/function.config_load.php: + fix config_load filepath bug + +2003-12-12 boots + + * docs/designers.sgml: + Updated language.function.if with additional annotation and to fix error + that broke docs build process + +2003-12-11 Messju Mohr + + * libs/Smarty_Compiler.class.php: + little optimization for "is odd" and "is even" + +2003-12-11 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + fix 'is even by' and 'is odd by' logic + +2003-12-11 Messju Mohr + + * docs/designers.sgml: + update example-output of {mailto} + + * libs/plugins/function.mailto.php: + removed extract-call -> cleaner parameter-handling + + * libs/plugins/function.mailto.php: + fixed indentiation + + * TODO: + removed two done topics + +2003-12-11 boots + + * docs/designers.sgml: + Updated language.function.if to describe qualifiers (thanks andre) + +2003-12-10 Messju Mohr + + * NEWS + libs/plugins/function.html_select_date.php: + added day_empty, month_empty, year_empty and all_empty attributes + to pass an undefined date use {html_select_date time="--" ...} + + * libs/plugins/function.html_select_date.php: + removed extract()-call + + * libs/plugins/function.html_select_date.php: + fixed indetiation + +2003-12-10 boots + + * NEWS + docs/designers.sgml: + Added table to language.function.if to describe qualifiers + +2003-12-09 Messju Mohr + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php: + strict comparason didn't work in all cases. use type-casting now. + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php: + fix bug when comparing array-keys to "selected" in html_options and + html_checkboxes + + in_array() uses "strict" comparason now. + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php: + removed tabs, fixed indentiation + +2003-12-08 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + add better checks for correctly nested tags when compiling + +2003-12-04 Messju Mohr + + * libs/Smarty.class.php + libs/plugins/function.html_image.php: + fix: check $smarty->request_use_auto_globals at the last occurences of + HTTP_*_VARS + +2003-12-03 Messju Mohr + + * NEWS + libs/Smarty.class.php: + remove $global_assign property from Smarty and $global_assign-handling + from the constructor. the only visible change is, that $SCRIPT_NAME is + not available in the tempates anymore. $smarty.server.SCRIPT_NAME has + to be used from now. + +2003-12-03 boots + + * docs/designers.sgml: + Fixed example for count_characters + +2003-12-01 boots + + * docs/designers.sgml: + Added section "Escaping Smarty Parsing" under Basic Syntax. + +2003-12-01 Messju Mohr + + * libs/core/core.create_dir_structure.php: + thought again about my latest commit and backed it out. + + * libs/core/core.create_dir_structure.php: + fix root-dir-handling on windows filepath + +2003-11-29 boots + + * libs/plugins/function.config_load.php: + really make the fixes the last patch was supposed to do + + * libs/plugins/function.config_load.php: + removed tabs and killed trailing white-space + + * libs/plugins/function.config_load.php: + changed $smarty->_syntax_error to $smarty->trigger_error + +2003-11-27 Messju Mohr + + * NEWS + libs/plugins/modifier.debug_print_var.php: + remove warning in debug_print_var on php-resources + + * README: + fix version number + +2003-11-26 Messju Mohr + + * libs/Smarty_Compiler.class.php: + raise max_level for $smarty.config... to 3 to allow arrays of config-vars + +2003-11-25 Messju Mohr + + * libs/Smarty.class.php: + changed version-tag to indicate incompatibility to older compiled + templates + +2003-11-24 Messju Mohr + + * NEWS + libs/plugins/compiler.assign.php + libs/plugins/function.assign.php: + move function.assign.php to compiler.assign.php + + * libs/core/core.get_include_path.php: + silence occasional warnings of open_basedir- and + safe_mode-restrictions in core.get_include_path.php + +2003-11-23 Messju Mohr + + * libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php: + avoid touch()-ing of recently unlinked files by touch()-ing the + tempfile before rename instead of touch()-ing the resulting file after + rename. + + * NEWS + libs/Smarty.class.php: + add property $tpl_error_reporting + +2003-11-22 Messju Mohr + + * libs/plugins/function.assign.php: + remove use of extract() in smarty_function_assign() + + * NEWS + libs/Smarty.class.php: + remove property $undefined. "null" is used literally instead + +2003-11-21 Messju Mohr + + * libs/Smarty_Compiler.class.php: + remove two E_NOTICES + +2003-11-20 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + change version to 2.6.1-dev + +2003-11-19 Monte Ohrt + + * (Smarty_2_6_0) + NEWS: + update NEWS file + + * (Smarty_2_6_0) + docs/designers.sgml + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + change version numbers to 2.6.0 + +2003-11-19 Messju Mohr + + * docs/designers.sgml + docs/de/designers.sgml + docs/fr/designers.sgml: + fix examples of escape-modifier (in docs, docs/de and docs/fr !) + +2003-11-18 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + move Smarty::quote_replace() to Smarty_Compiler::_quote_replace() + + * libs/Smarty.class.php: + removed extract-calls from _include()- and _eval()-wrappers + variables passed with {include_php} have to accessed as members of $params + now + +2003-11-17 Messju Mohr + + * docs/designers.sgml: + fixed typo + +2003-11-13 Messju Mohr + + * libs/Config_File.class.php: + fix occasional notice + +2003-11-13 andreas halter + + * docs/de/designers.sgml: + - added cat modifier, thanks messju :-) + +2003-11-13 Monte Ohrt + + * (Smarty_2_6_0-RC3) + NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + commit RC3 tags + +2003-11-13 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix handling of $var.key inside [] + + * libs/Smarty.class.php: + fix unnecessary loading of core.load_resource_plugin.php + + * (Smarty_2_6_0-RC3) + docs/fr/designers.sgml: + fixed example of html_table + +2003-11-11 Messju Mohr + + * NEWS + libs/core/core.process_cached_inserts.php: + fix handling of assign inside {insert}-tags + +2003-11-06 Messju Mohr + + * libs/core/core.read_cache_file.php: + added $exp_time-parameter + + * docs/programmers.sgml: + added $exp_time to cache_handler_func-example + + * libs/Smarty.class.php + libs/core/core.write_cache_file.php: + added $exp_time-parameter of clear_cache() and clear_all_cache() to + cache_handler_func. + +2003-11-05 Messju Mohr + + * NEWS + libs/Config_File.class.php: + fix handling if [...] inside triple-quotes in config-files + +2003-11-04 Messju Mohr + + * libs/Smarty.class.php: + fixed little bug in _parse_resource_name() (jlgunter, messju) + +2003-11-03 andreas halter + + * docs/designers.sgml + docs/de/designers.sgml + docs/fr/designers.sgml: + - changed Smarty.php.class occurences to Smarty.class.php + +2003-10-29 boots + + * docs/appendixes.sgml + docs/designers.sgml + docs/manual.sgml + docs/programmers.sgml + docs/de/appendixes.sgml + docs/de/designers.sgml + docs/de/programmers.sgml + docs/fr/appendixes.sgml + docs/fr/designers.sgml + docs/fr/getting-started.sgml + docs/fr/manual.sgml + docs/fr/preface.sgml + docs/fr/programmers.sgml: + Fixes to documentation syntax so that all content can be processed used + xsltproc docbook-xsl tools. In particular, fixes unescaped entities, + broken tags, unquoted attributes. + +2003-10-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fix handling of simple-math-operators inside modifiers + +2003-10-25 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed unused property _output_type + removed unused param $tag_attrs of _parse_var_props() + cleaned up alignment of class-properties + +2003-10-23 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed notice in php-tag handling in Smarty_Compiler::_compile_file() + + * libs/Smarty_Compiler.class.php: + removed two occasional E_NOTICES from + Smarty_Compiler::_compile_include_php_tag() + + * NEWS + libs/core/core.create_dir_structure.php: + fix handling of trailing-slashes in open_basedir in + smarty_core_create_dir_structure() + +2003-10-20 Messju Mohr + + * libs/Smarty_Compiler.class.php: + elements inside `` are bracketed now inside the compiled-tpl. this + fixes some issues with simple-math inside backticks. + +2003-10-16 Monte Ohrt + + * docs/designers.sgml: + update overlib docs, no working examples + +2003-10-12 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.is_secure.php: + move check for template_dir in secure_dir-array into core.is_secure.php + + this makes template_exists() work correctly with security=true even if + template_dir is not inside the secure_dir-array + +2003-10-11 Messju Mohr + + * libs/plugins/shared.make_timestamp.php: + tightened check for YYYYMMDDHHMMSS-format. thanks konstantin for + pointing this out. + + removed a few tabs. + + * libs/Smarty_Compiler.class.php: + fix precedence of simple-math-operators before modifiers. + thanks dominik! + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.display_debug_console.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.process_cached_inserts.php + libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include_php.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php: + removed tabs from the main and the core/*.php files + +2003-10-08 Monte Ohrt + + * (Smarty_2_6_0-RC2) + NEWS + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + update version numbers to RC2 + +2003-09-18 Messju Mohr + + * docs/designers.sgml + docs/de/designers.sgml: + fixed description of cycle's advance-attribute + +2003-09-16 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + apply modifiers only once to section-loop and foreach-from attributes + +2003-09-15 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.write_cache_paths_file.php: + backed out _smarty_cached_paths-file-handling + + * libs/Smarty.class.php + libs/core/core.rm_auto.php: + fixed clear_compiled_tpl with explicit $tpl_file given + fixed return value of smarty_core_rm_auto() + Smarty::_unlink() + + * libs/Smarty.class.php: + little fix in _get_auto_filename() + +2003-09-14 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php: + removed auto-filenames from path-cache. merged assemble_auto_filename + back into Smarty::_get_auto_filename() + +2003-09-12 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed quoting of modifier parameters + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.get_php_resource.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php: + remove Smarty::_plugin_implementation_exists() - use php's native + is_callable() + +2003-09-11 Messju Mohr + + * libs/Smarty.class.php: + silenced two notices acces HTTP_SERVER_VARS + +2003-09-10 andreas halter + + * docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/programmers.sgml: + - minor fixes (2 rep), slight wording changes + - jade transform problem fixed + +2003-09-08 andreas halter + + * docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/manual.sgml + docs/de/preface.sgml + docs/de/programmers.sgml: + all updated for 2.6.0 release, translated everything from 2_5_0 branch to + 20030908 + +2003-09-04 Messju Mohr + + * libs/Smarty.class.php: + proper checking for files in _fetch_resource_info() + +2003-09-02 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + ignore {strip}/{/strip) inside {strip}-blocks + + * libs/plugins/function.mailto.php: + fixed 2 notices in smarty_function_mailto() + +2003-09-01 Messju Mohr + + * libs/Smarty.class.php: + re-include cache_paths on multiple calls to fetch() to avoid + inconsistencies + at multiple calls to fetch() in one script + + * libs/Smarty_Compiler.class.php: + fixed handling of \r in {strip} + renamed $_trailing_lf to $_additional_newline + + * libs/Smarty_Compiler.class.php: + the weekly fix for {strip} :) + + * docs/designers.sgml: + fixed example for simple math. + +2003-08-29 Messju Mohr + + * libs/core/core.assign_smarty_interface.php + libs/core/core.display_debug_console.php + libs/plugins/function.assign.php + libs/plugins/function.html_options.php + libs/plugins/function.html_table.php: + fixed PHPDocumentor-comments (thanks Konstantin) + + * libs/core/core.rmdir.php: + made rmdir a bit more optimistic. especially it now removes + directories correctly that where created accidently by "safe_mode=On + && $use_sub_dirs=true" + +2003-08-27 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed removal of leading/trailing newlines in {strip}-blocks + +2003-08-25 Messju Mohr + + * INSTALL: + added note emphasizing the introduction of "libs/" with 2.5.0 + + * NEWS + libs/plugins/modifier.escape.php: + fixed proper escaping of " and ' with escape:javascript + +2003-08-22 Messju Mohr + + * NEWS + libs/core/core.assemble_plugin_filepath.php: + fixed bug in traversal of $smarty->plugins_dir-array in + smarty_core_assemble_plugin_filepath(). the first matching plugin in + the path should be used, not the last one. + + * libs/core/core.read_cache_file.php: + discard $_cache_info when the cache should be regenerated + +2003-08-20 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php + libs/plugins/block.strip.php: + reverted {strip} from a block-plugin back into the compiler + + * docs/programmers.sgml: + fixed examples for register_function() and register_block() + + * libs/Smarty.class.php: + made template_exists() quiet when the template does not exist (thanks + to konstatin for pointing this out) + +2003-08-18 Monte Ohrt + + * docs/getting-started.sgml: + fix example title + + * docs/README + docs/getting-started.sgml: + change installation wording confusion + +2003-08-18 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.read_cache_file.php: + fixed unnecessary load of source in template_exists() and the + compile-check of smarty_core_read_cache_file() + + * libs/Smarty_Compiler.class.php: + allow section-, array- and object-dereference in $smarty-references + +2003-08-15 Messju Mohr + + * docs/designers.sgml: + added parameter-descriptions for count_characters (thanks Konstantin + A. Pelepelin) + + fixed docs for {html_checkboxes} + +2003-08-14 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.read_cache_file.php: + fixed timestamp-check of config-files in smarty_core_read_cache_file() + + * libs/Smarty.class.php: + fixed typecasting for arrays in _parse_resource_name() + + * NEWS + libs/plugins/function.config_load.php: + fixes in config_load: + - handling of section-attribute + - reusing the same config-file multiple times + - serialization of config-data for php<4.2.0 (no var_export) + + many thanks to atu for pointing this out and for testing + +2003-08-13 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.smarty_include_php.php: + fixed problem with vars as attributes in {include_php} + +2003-08-13 Monte Ohrt + + * docs/README: + commit README file for documentation compiling + +2003-08-13 Messju Mohr + + * libs/debug.tpl + libs/plugins/modifier.debug_print_var.php: + removed '\r' from debug_print_vars' output + properly escape vars in javascript-version of debug.tpl + +2003-08-11 Monte Ohrt + + * (Smarty_2_6_0_RC1) + NEWS + docs/designers.sgml + docs/html.dsl + docs/php.dsl + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + get ready for 2.6.0-RC1 release + +2003-08-10 Messju Mohr + + * NEWS + libs/Smarty.class.php: + fixed status-header for cache_modified_check under cgi-sapi + +2003-08-09 Messju Mohr + + * libs/core/core.is_secure.php + libs/core/core.is_trusted.php: + synced secure_dir-checking with trusted_dir-checking + + * libs/core/core.is_secure.php: + tightenend path checking in smarty_core_is_secure() + +2003-08-08 Messju Mohr + + * libs/Smarty.class.php: + fix: proper nesting of $smarty->_cache_including flag in cascaded + cached/not-cached/fetched/inserted/foo-templates + + * libs/debug.tpl: + better escaping for $_debug_tpls[templates].filenames + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + removed redundant $smarty from Smarty::_smarty_include() + + * libs/debug.tpl: + proper escaping of filenames in debug-console (thanks to prossel). + +2003-08-07 Messju Mohr + + * docs/programmers.sgml: + added docs for block-methods of registered objects + + * docs/programmers.sgml: + fixed typo in example for registered objects + + * docs/designers.sgml: + fixed exampls of html_image and html_checkboxes + + * libs/plugins/function.debug.php: + fixed {debug} and removed tabs in function.debug.php + + * docs/programmers.sgml: + fixed example for register_object + + * docs/designers.sgml + docs/programmers.sgml: + updated docs for capture, html_table, html_image and register_object + +2003-08-07 Monte Ohrt + + * docs/designers.sgml + docs/programmers.sgml: + add math and default_resource_type to docs + + * docs/getting-started.sgml: + add core to example, add tech note + +2003-08-07 Messju Mohr + + * docs/manual.sgml + docs/fr/manual.sgml: + upd copyright in the docs + +2003-08-07 Monte Ohrt + + * docs/getting-started.sgml: + added core directory to install instructions + +2003-08-07 Messju Mohr + + * docs/designers.sgml + docs/programmers.sgml: + added docs for php-functions as modifiers + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + better caching of attributes for $cacheable=false-plugins + + * docs/programmers.sgml: + added section "caching.cacheable" to the docs, explaining the usage of + the $cacheable-flag of the register_(block|compiler|function)-functions + + * libs/Smarty_Compiler.class.php: + fixed output of custom-functions with cached attributes + + * docs/programmers.sgml: + docs update on callbacks to the register_*-functions + +2003-08-06 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.process_compiled_include.php: + 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. + + * libs/Smarty.class.php: + fixed bug in _run_mod_handler + + * libs/Smarty_Compiler.class.php: + fixed bug with autoload-handling of modifiers. thanks ándre. + +2003-08-05 Messju Mohr + + * libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + updated copyright notice + + * libs/Smarty.class.php + libs/core/core.load_plugins.php: + fixed bug that occurred when using the same not-cacheable plugin in + multiple includes + + * docs/programmers.sgml: + docs-update for plugins.writing + +2003-08-04 Messju Mohr + + * docs/designers.sgml + docs/programmers.sgml: + updated docs for register_block_function(), block-functions, + $request_use_auto_globals and html_checkboxes + +2003-07-31 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + enabled registration of class-methods as callbacks for the + register_*-functions + + use: array('classname', 'method_name')) as callback + +2003-07-29 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + modifiers are resolved at compile-time now. _run_mod_handler() is + still used for modifiers with map_array=true (== no preceeding '@') + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.smarty_include.php: + moved _smarty_include() back into Smarty.class.php + + * libs/Smarty.class.php + libs/core/core.load_plugins.php: + prevent unnecessary calls to _read_file() in _is_compiled() + converted method-call to internal function-call in + smarty_core_load_plugins() + +2003-07-28 Messju Mohr + + * libs/Smarty_Compiler.class.php: + quote smarty-header properly to prevent resource-names from escaping from + the comment + +2003-07-25 Messju Mohr + + * libs/core/core.create_dir_structure.php: + weakend race-condition and removed bogus error-message caused by that + in smarty_core_create_dir_structure(). + +2003-07-23 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_php_resource.php + libs/core/core.parse_resource_name.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/plugins/function.eval.php: + moved _fetch_resource_info and _parse_resource_name back into + Smarty.class.php + renamed smarty_include and smarty_eval wrappers to _include and _eval + +2003-07-17 Messju Mohr + + * libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php: + improved checking of compiled_include against cached-template with + non-cached-chunks + + * libs/core/core.write_compiled_include.php: + fixed too short open-tag + + * libs/plugins/function.eval.php: + fixed assign parameter for eval (must have gotton lost on its way to 2.5.0) + cleaned up indentiation + +2003-07-03 Messju Mohr + + * libs/Smarty_Compiler.class.php: + resurrected $foo->$bar syntax + + * libs/Smarty_Compiler.class.php: + i'm so stupid. kick me. + + * libs/Smarty_Compiler.class.php: + fixed initialisation of $this->_plugins in compile_block_tag() + +2003-07-03 Monte Ohrt + + * libs/Config_File.class.php: + add preg_quote delimiter + +2003-07-03 Messju Mohr + + * libs/Smarty_Compiler.class.php: + applied fix for {$var1->p1|modifier:$var2->p2}-syntax - thanks Dominik + +2003-07-02 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed duplicate generation of arg-list in _compile_block_tag() + + * libs/Smarty_Compiler.class.php: + fixed off-by-one-error in nocache-tag-handling + +2003-06-30 Messju Mohr + + * libs/Smarty_Compiler.class.php: + backed out errornously committed support for $foo->$bar + + * libs/core/core.write_file.php: + fixed indentiation, silenced occasional warning + + * libs/plugins/function.html_image.php: + match first character of file-attribute against "/" instead of + DIRECTORY_SEPARATOR since it is a url-path and not a file-path. + + * libs/Smarty_Compiler.class.php + libs/core/core.write_file.php + libs/plugins/function.html_image.php: + libs/plugins/function.html_image.php + + * libs/Smarty_Compiler.class.php: + re-fixed cacheable_state-handling + + * libs/core/core.display_debug_console.php + libs/core/core.process_cached_inserts.php + libs/core/core.process_compiled_include.php + libs/core/core.run_insert_handler.php: + extincting $this out of smarty_core_*-functions + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + fixed handling of nocache-state + +2003-06-29 Messju Mohr + + * libs/Smarty.class.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/plugins/function.eval.php: + removed $this from smarty_include and smarty_include_php + added cleaner handling of $this to {eval} + + * libs/core/core.load_resource_plugin.php: + fixed inlude_once-call + + * docs/de/designers.sgml + docs/fr/designers.sgml: + fixed examples of html_radios and html_checkboxes in german and french docs + +2003-06-25 Monte Ohrt + + * libs/core/core.assemble_auto_filename.php + libs/core/core.write_cache_paths_file.php: + fix typo, fix write_cache_paths logic + + * libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php: + fix SMARTY_COMPILE_DIR_SEP problem, make local var + +2003-06-24 Monte Ohrt + + * libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php + libs/core/core.write_cache_paths_file.php: + fixed cache_paths bug, simplified filename assembly logic + +2003-06-24 Messju Mohr + + * libs/plugins/function.html_image.php: + added parsing of forgotton param "basedir" + + * libs/Smarty_Compiler.class.php: + fixed $smarty.get-reference + + * libs/plugins/block.textformat.php: + removed warning + + * libs/Smarty_Compiler.class.php: + fixed value of _cacheable_state on compiler-startup + +2003-06-23 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.write_cache_paths_file.php: + make cache_path per resource, fix a couple directory path issues + +2003-06-23 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed warning when compiling empty template + + * libs/core/core.write_compiled_include.php: + fixed bug in write_compiled_include + + * libs/core/core.assemble_plugin_filepath.php: + fixed warning + +2003-06-22 Messju Mohr + + * libs/plugins/function.eval.php: + fixed propagation of $this into evald code in smarty_function_eval() + + * libs/core/core.write_cache_paths_file.php + libs/core/core.write_compiled_include.php: + fix in compiled-include-handling + + * libs/core/core.assemble_auto_filename.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.parse_resource_name.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.write_cache_file.php + libs/core/core.write_cache_paths_file.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php + libs/plugins/modifier.date_format.php: + started moving from $this to $smarty in core.*.php + +2003-06-21 Monte Ohrt + + * libs/core/core.create_dir_structure.php + libs/core/core.write_file.php + libs/plugins/function.config_load.php: + fix more dir paths + + * NEWS + libs/Smarty.class.php + libs/core/core.assemble_auto_filename.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_php_resource.php + libs/core/core.parse_resource_name.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/core/core.write_cache_file.php + libs/core/core.write_cache_paths_file.php + libs/core/core.write_compiled_include.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_file.php + libs/plugins/function.config_load.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + fix filepaths to core files to use DIRECTORY_SEPARATOR + +2003-06-21 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed {plugin|modifier} syntax + + * libs/Smarty.class.php + libs/core/core.write_compiled_include.php: + fixed compiled include handling + +2003-06-21 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assemble_auto_filename.php + libs/core/core.assemble_plugin_filepath.php + libs/core/core.write_cache_paths_file.php: + added filepath caching + +2003-06-20 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + update more varnames + + * libs/Smarty.class.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_file_info.php + libs/core/core.fetch_resource_info.php + libs/core/core.get_php_resource.php + libs/core/core.parse_file_path.php + libs/core/core.parse_resource_name.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/core/core.write_compiled_resource.php + libs/core/core.write_compiled_template.php + libs/plugins/function.config_load.php: + refactored var naming to better reflect "resource" instead of "file" where + appropriate + +2003-06-19 Messju Mohr + + * libs/Smarty.class.php: + updated version-number to 2.5.0-cvs + + * libs/core/core.write_cache_file.php: + omit is-cache_dir-writable-check if a cache_handler_function is in use + + * libs/core/core.smarty_include_php.php: + fixed comments in smarty_include_php + +2003-06-19 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.display_debug_console.php + libs/core/core.smarty_include.php + libs/plugins/function.eval.php: + split up _compile_template to _compile_file and _compile_source, fix eval + function + VS: ---------------------------------------------------------------------- + + * libs/plugins/function.config_load.php: + fix logic for _is_compiled() + +2003-06-19 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + added optional assign-attribute to {capture}-tag + + * NEWS + libs/Smarty.class.php: + added $cacheable-parameter to register_compiler_function() + +2003-06-18 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.load_plugins.php + libs/core/core.process_compiled_include.php + libs/core/core.read_cache_file.php + libs/core/core.write_cache_file.php + libs/core/core.write_compiled_include.php: + added $cacheable-parameter to register_function() and register_block() + + * libs/Smarty.class.php: + append '.php' to all compiled templates regardless of the settings of + $use_sub_dirs + + * libs/Smarty.class.php + libs/core/core.read_cache_file.php: + fixed $file_path-parameters passed to smarty_core_fetch_file_info() + +2003-06-17 Monte Ohrt + + * NEWS: + fix name + + * libs/Smarty_Compiler.class.php: + change varnames to follow coding methods + + * NEWS + libs/Smarty_Compiler.class.php: + add math patch to core + +2003-06-17 Messju Mohr + + * libs/core/core.smarty_include.php: + switched _process_template() to _is_compiled()-logic + +2003-06-17 Monte Ohrt + + * libs/Smarty.class.php: + fix _is_compiled logic + + * NEWS: + update news file + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + fix _run_mod_handler routine + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_file_info.php + libs/core/core.parse_file_path.php + libs/core/core.write_compiled_template.php + libs/plugins/function.config_load.php: + fix path problems, rename some varibles from "template" to "file" + +2003-06-16 Monte Ohrt + + * libs/core/core.fetch_file_info.php + libs/core/core.fetch_template_info.php: + rename file, commit + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.parse_file_path.php + libs/core/core.read_cache_file.php + libs/plugins/block.strip.php + libs/plugins/block.textformat.php + libs/plugins/compiler.config_load.php + libs/plugins/function.config_load.php + libs/plugins/function.eval.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + fix config_load, compile fetched arrays to compile_dir, switch display + back to runtime. clean up var names and function names, split up compile + testing and compiling to separate funcs, rename some template_* functions + to + file_* functions and update logic so they can be used for file resources + other than templates. + +2003-06-16 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed little bug in _compile_custom_tag() + +2003-06-16 Monte Ohrt + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/core/core.assign_smarty_interface.php + libs/core/core.create_dir_structure.php + libs/core/core.display_debug_console.php + libs/core/core.fetch_template_info.php + libs/core/core.get_include_path.php + libs/core/core.get_microtime.php + libs/core/core.get_php_resource.php + libs/core/core.is_secure.php + libs/core/core.is_trusted.php + libs/core/core.load_plugins.php + libs/core/core.load_resource_plugin.php + libs/core/core.parse_file_path.php + libs/core/core.process_cached_inserts.php + libs/core/core.read_cache_file.php + libs/core/core.rm_auto.php + libs/core/core.rmdir.php + libs/core/core.run_insert_handler.php + libs/core/core.smarty_include.php + libs/core/core.smarty_include_php.php + libs/core/core.write_cache_file.php + libs/core/core.write_compiled_template.php + libs/core/core.write_file.php + libs/plugins/core.assign_smarty_interface.php + libs/plugins/core.create_dir_structure.php + libs/plugins/core.display_debug_console.php + libs/plugins/core.fetch_template_info.php + libs/plugins/core.get_include_path.php + libs/plugins/core.get_microtime.php + libs/plugins/core.get_php_resource.php + libs/plugins/core.is_secure.php + libs/plugins/core.is_trusted.php + libs/plugins/core.load_plugins.php + libs/plugins/core.load_resource_plugin.php + libs/plugins/core.parse_file_path.php + libs/plugins/core.process_cached_inserts.php + libs/plugins/core.read_cache_file.php + libs/plugins/core.rm_auto.php + libs/plugins/core.rmdir.php + libs/plugins/core.run_insert_handler.php + libs/plugins/core.smarty_include.php + libs/plugins/core.smarty_include_php.php + libs/plugins/core.write_cache_file.php + libs/plugins/core.write_compiled_template.php + libs/plugins/core.write_file.php: + move core files into their own directory under SMARTY_DIR, + remove abstraction function _execute_core_function + + * libs/Smarty_Compiler.class.php: + fix newline handling for template for all template tags + +2003-06-11 Monte Ohrt + + * libs/plugins/compiler.config_load.php: + add compiler function to cvs repository + +2003-06-11 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added config-option "request_use_auto_globals" to make auto-globals be + used as request vars instead of HTTP_*_VARS + +2003-06-11 Monte Ohrt + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/function.config_load.php: + make config vars compile statically + +2003-06-11 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + backed out newlines patch + + * NEWS + libs/Smarty_Compiler.class.php: + removed newlines in compiled templates after closing tags + +2003-06-10 Messju Mohr + + * docs/de/designers.sgml: + fixed german note on html_image and disk-access + +2003-06-10 Monte Ohrt + + * libs/plugins/core.parse_file_path.php: + fix bug with resource_type resolving + +2003-06-09 Monte Ohrt + + * docs/designers.sgml: + replace example with more practical one + +2003-06-08 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added block-methods for registered objects + +2003-06-07 Messju Mohr + + * docs/programmers.sgml: + fixed bug in documentation for $smarty->default_modifiers + +2003-06-06 Monte Ohrt + + * libs/plugins/core.parse_file_path.php: + fix problem with new default_resource_type changes + + * NEWS: + update NEWS file info + + * NEWS + libs/Smarty.class.php + libs/plugins/core.parse_file_path.php: + add default_resource_type, ignore 1 char resource names + + * NEWS + libs/Config_File.class.php: + fix bug where config file starts with hidden section + +2003-06-04 Monte Ohrt + + * NEWS + libs/Smarty.class.php: + -** empty log message *** + +2003-06-03 Monte Ohrt + + * libs/plugins/function.html_image.php: + fix example in code comments + +2003-06-03 Messju Mohr + + * NEWS + libs/plugins/function.counter.php: + fixed behaviour of start=... for {counter} + +2003-06-02 Messju Mohr + + * NEWS + libs/plugins/function.counter.php: + fixed assign for {counter} + +2003-05-30 Monte Ohrt + + * libs/plugins/core.write_cache_file.php + libs/plugins/core.write_compiled_template.php: + add discrete error checking pertaining to $cache_dir + and $compile_dir, their existance and writability + +2003-05-28 Messju Mohr + + * NEWS + libs/plugins/function.html_table.php: + added params vdir, hdir and inner to html_table to allow looping over + the data in various directions + +2003-05-28 Monte Ohrt + + * libs/plugins/core.compile_template.php + libs/plugins/core.display_debug_console.php: + fix problem with security and debug.tpl file + +2003-05-23 Monte Ohrt + + * NEWS: + upd NEWS file + + * libs/Smarty_Compiler.class.php: + allow spaces in literal tags + +2003-05-22 Monte Ohrt + + * docs/fr/programmers.sgml: + fix special chars + +2003-05-19 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + speed up compiled templates, hardcode plugin filepaths instead of + recalculate at runtime + +2003-05-19 Messju Mohr + + * docs/designers.sgml: + fixed example of {html_image} + + * docs/designers.sgml: + fixed typo + +2003-05-12 Messju Mohr + + * libs/Smarty.class.php + libs/plugins/core.read_cache_file.php + libs/plugins/core.smarty_include.php + libs/plugins/function.config_load.php: + fixed multiple redundant occurrences for 'config' and 'template' in + $smarty->_cache_info + +2003-05-10 Messju Mohr + + * libs/plugins/core.create_dir_structure.php: + refurbished create_dir_structure to use '/' internally + + * libs/plugins/core.create_dir_structure.php: + fixed windows absolute-paths in smarty_core_create_dir_structure() + + * libs/plugins/core.create_dir_structure.php: + fixed error-message + +2003-05-09 Messju Mohr + + * libs/Smarty_Compiler.class.php: + fixed warning due to missing param to _execute_core_function() + + * libs/Smarty_Compiler.class.php: + fixed quoting in _compile_include_php + + * libs/Smarty_Compiler.class.php: + fixed quoting of "file"-parameter in _compile_include_tag() + +2003-05-08 Monte Ohrt + + * docs/programmers.sgml: + fix typo + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/core.compile_template.php + libs/plugins/core.create_dir_structure.php + libs/plugins/core.fetch_template_info.php + libs/plugins/core.get_include_path.php + libs/plugins/core.get_microtime.php + libs/plugins/core.get_php_resource.php + libs/plugins/core.is_secure.php + libs/plugins/core.is_trusted.php + libs/plugins/core.load_plugins.php + libs/plugins/core.load_resource_plugin.php + libs/plugins/core.parse_file_path.php + libs/plugins/core.process_cached_inserts.php + libs/plugins/core.read_cache_file.php + libs/plugins/core.rm_auto.php + libs/plugins/core.rmdir.php + libs/plugins/core.run_insert_handler.php + libs/plugins/core.smarty_include.php + libs/plugins/core.smarty_include_php.php + libs/plugins/core.write_cache_file.php + libs/plugins/core.write_compiled_template.php + libs/plugins/core.write_file.php + libs/plugins/function.config_load.php + libs/plugins/function.fetch.php + libs/plugins/function.html_image.php: + abstract more private functions to plugin directory + + * libs/Config_File.class.php: + only add DIRECTORY_SEPARATOR if it isn't already present + + * libs/Config_File.class.php: + fix directory separator code, use DIRECTORY_SEPARATOR + +2003-05-08 Messju Mohr + + * docs/designers.sgml: + fixed example of html_checkboxes + + * NEWS + libs/Smarty.class.php: + fixed bug in _create_dir_structure() when used with + open_basedir-restriction and relative paths + + * docs/designers.sgml: + fixed example for html_radios + +2003-05-07 Monte Ohrt + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php + libs/plugins/core.assign_smarty_interface.php + libs/plugins/core.display_debug_console.php + libs/plugins/function.display_debug_console.php: + abstracted display_debug_console and assign_smarty_interface to plugin dir + as a test + + * libs/Smarty.class.php + libs/plugins/function.display_debug_console.php: + correct misc varnames, abstract debug console display to plugin function + + * libs/plugins/modifier.escape.php: + fix typo + +2003-05-05 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + add % to math + + * libs/Smarty.class.php: + clean up comments, formatting + + * NEWS + libs/Smarty.class.php: + keep DIR_SEP for 3rd party compatability + + * NEWS + libs/Smarty.class.php: + remove DIR_SEP, use DIRECTORY_SEPARATOR exclusively + + * libs/Smarty_Compiler.class.php: + remove ++ and -- math operators on template vars + +2003-05-04 Messju Mohr + + * libs/Smarty_Compiler.class.php: + removed unused parameter $quote from Smarty_Compiler::_parse_attrs() + + * libs/plugins/function.html_image.php: + fixed DIR_SEP in html_image-plugin + +2003-05-04 Monte Ohrt + + * NEWS + libs/Smarty.class.php: + rename DIR_SEP to SMARTY_DIR_SEP to avoid varname collisions + +2003-05-04 Messju Mohr + + * NEWS + libs/plugins/function.html_image.php: + changed "link" to "href" in html_image. "link" is still working but + deprecated + html_image always renders an alt-tag now (default alt="") + cleaned up indentiation of function.html_image.php + +2003-05-03 Monte Ohrt + + * libs/debug.tpl: + fix typo + +2003-05-02 Messju Mohr + + * NEWS + libs/plugins/function.counter.php: + fixed assign attribute for multiple counters + +2003-05-02 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + allow math on negative number + + * NEWS + libs/Smarty_Compiler.class.php: + added simple math operators to variables + +2003-05-02 Messju Mohr + + * docs/designers.sgml: + fixed typos + +2003-04-30 Monte Ohrt + + * docs/fr/appendixes.sgml + docs/fr/common.dsl + docs/fr/designers.sgml + docs/fr/getting-started.sgml + docs/fr/html-common.dsl + docs/fr/html.dsl + docs/fr/manual.sgml + docs/fr/php.dsl + docs/fr/preface.sgml + docs/fr/programmers.sgml: + add frech docs to cvs repository + +2003-04-29 Messju Mohr + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + reverted patch for case-insensitive tag-names + +2003-04-28 Messju Mohr + + * docs/programmers.sgml: + reverted back to humerous redundancy in the docs :). although we all + know we are here to generate template-based output, and not to have + fun ;-) + + * docs/getting-started.sgml: + fixed default user and group for max os x installation + + * libs/Smarty.class.php: + made $function[2] and $function[3] options for register_resource + + * libs/Smarty.class.php: + fixed issue with object-callback when fetching a php-resource + + * NEWS + libs/Smarty.class.php: + enabled array(&$obj. 'source', 'timestamp', 'secure', 'trusted') as + callback for register_resource() + + enabled array(&$obj, 'method') as callback for + $default_template_handler_func + +2003-04-27 Messju Mohr + + * docs/designers.sgml + docs/programmers.sgml: + fixed some typos, thank to mehdi + + * libs/plugins/function.counter.php: + prevent assign from overruling print-attribute in function.counter.php + + * libs/plugins/function.counter.php: + fixed problem with counter and assign + + * libs/Smarty.class.php: + fixed notice in _load_plugins() + + * NEWS + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + made plugin-names case-insensitive. this affects + compiler/block/custom-functions and modifers. + +2003-04-26 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + remove unnecessary close/open tags from compiled templates + +2003-04-26 Messju Mohr + + * docs/designers.sgml: + added documentation for foreach.property.* + +2003-04-24 Messju Mohr + + * docs/designers.sgml: + fixed example table_attr and tr_attr in html_table-example + +2003-04-21 Greg Beaver + + * libs/Smarty.class.php: + fixed small bug in doc comments + +2003-04-21 Messju Mohr + + * NEWS + libs/plugins/function.html_image.php: + fixed errornous creation of '//' in image_path in html_image + +2003-04-21 Monte Ohrt + + * libs/plugins/modifier.debug_print_var.php: + fix htmlspecialchars() conflict + + * NEWS + libs/plugins/modifier.debug_print_var.php: + fix escapement of special chars in key values of debug console + + * NEWS + libs/plugins/function.config_load.php: + fixed debug timing logic for config_load + + * docs/designers.sgml: + fix example text + + +2003-04-20 Greg Beaver + * plugins/* + Smarty.class.php + Smarty_Compiler.class.php + Config_File.class.php: + updated all doc comments to phpDocumentor format (whew!) + +2003-04-06 Messju Mohr + + * libs/plugins/function.math.php: + allowed "_" in the name of variable-parameters to {math}-function + +2003-04-04 Monte Ohrt + + * NEWS + docs/designers.sgml + libs/Smarty_Compiler.class.php: + change backtic syntax from $`foo` to `$foo` + + * NEWS + libs/Smarty_Compiler.class.php: + recognize $foo[][] syntax in embedded quotes without backticks + +2003-04-03 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + name=123 is passed as an integer (not a string) to plugins now + +2003-04-01 Messju Mohr + + * libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + added CVS $Id: ChangeLog 2746 2007-09-28 01:32:05Z changelog $ + +2003-03-31 Messju Mohr + + * libs/Smarty.class.php: + added missing compile_id inside Smarty_Compiler + + * libs/Smarty_Compiler.class.php: + fixed flaw when generating an error for missing postfilter + +2003-03-31 Monte Ohrt + + * docs/getting-started.sgml + docs/programmers.sgml: + fix typos + +2003-03-27 Messju Mohr + + * NEWS + libs/plugins/modifier.debug_print_var.php: + $length is now propagated to sub-values in debug_print_var + +2003-03-26 Monte Ohrt + + * NEWS: + update header + + * RELEASE_NOTES: + commit changes to release notes + + * (Smarty_2_5_0_RC2) + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + committing RC2 + +2003-03-24 Messju Mohr + + * NEWS + libs/Smarty.class.php: + made clear_cache() ignore compile_id when clearing cache_groups + + * libs/plugins/function.popup.php: + made onmouseout XHTML-compatible in function.popup.php + +2003-03-21 Messju Mohr + + * NEWS + libs/Smarty.class.php: + applied new var-names to fetch() + + * NEWS + libs/Smarty.class.php: + renamed $localvars to $_localvars in cache-file-handling-functions, + added _get_auto_id()-function + +2003-03-21 Monte Ohrt + + * libs/plugins/function.mailto.php + libs/plugins/function.popup.php: + update functions for XHTML compatability + +2003-03-21 Messju Mohr + + * libs/Smarty.class.php: + fixed wrong $auto_id in _read_cache_file() + + * NEWS + libs/Smarty.class.php: + swapped compile_id and cache_id in read_cache_file and write_cache_file + + * libs/Smarty.class.php: + reverted patch for ignoring compile-id back to -r1.364, due to problems + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + html_radios and html_checkboxes accept "selected" instead of "checked" + optionally now + + * NEWS + libs/Smarty.class.php: + swapped compile_id and cache_id for cache-file-handling again + +2003-03-20 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + fix notice when no parameter is passed to default + +2003-03-20 Messju Mohr + + * NEWS + libs/Smarty.class.php: + removed notice of undefined var in _rm_auto() + +2003-03-19 Monte Ohrt + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_table.php: + fix a few error messages, follow consistancy format plugin_name: errormsg + + * libs/plugins/function.html_radios.php: + update error messages + + * NEWS + libs/plugins/function.html_radios.php: + add a warning when an array is passed as the 'checked' value of html_radios + +2003-03-19 Messju Mohr + + * NEWS + libs/Smarty_Compiler.class.php: + fixed errormessage in _compile_smarty_ref() + + * NEWS + docs/designers.sgml: + updated docs for html_image + +2003-03-18 Messju Mohr + + * NEWS + libs/Smarty.class.php: + cleaned up calls to readdir() + + * libs/plugins/function.html_options.php: + fixed label for optgroup in html_options + +2003-03-18 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + fix (newly introduced) bug with passing multiple modifiers to a parameter + +2003-03-18 Messju Mohr + + * NEWS + docs/designers.sgml: + updated docs for html_checkboxes, html_options and html_radios + + * libs/plugins/function.html_options.php: + fixed wrong default-"name" in function.html_options.php + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + renamed "checkbox" and "radios" to "options" in {html_checkboxes} and + {html_radios} + + * libs/plugins/outputfilter.trimwhitespace.php: + tried to optimize re-replacement in outputfilter.trimwhitespace.php a + little + + * libs/plugins/outputfilter.trimwhitespace.php: + fixed greedy str_replace in outputfilter.trimwhitespace.php + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php: + html_options, html_checkboxes and html_radios now pass-thru all unknown + paramters + +2003-03-17 Messju Mohr + + * NEWS + libs/plugins/function.html_options.php: + html_options passthru all unknown paramters now + +2003-03-17 Monte Ohrt + + * NEWS + libs/plugins/function.html_image.php: + Fix link bug in html_image function, also make output XHTML compatible + + * libs/Smarty_Compiler.class.php: + fix issue of embedded var and escaped double quotes + +2003-03-15 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + back out "@" logic, apply only to default modifier special case + + * libs/Smarty_Compiler.class.php: + fix @ logic, only use upon an echo + + * NEWS + libs/Smarty_Compiler.class.php: + append "@" to template var echoes to supress possible notices + + * NEWS + libs/Smarty_Compiler.class.php: + append "@" to _run_mod_handler to supress warnings + +2003-03-14 Monte Ohrt + + * NEWS + libs/Smarty_Compiler.class.php: + fix problem with escaped double quotes + + * NEWS + libs/plugins/function.html_radios.php: + fixed html_options to not return an array + +2003-03-12 Messju Mohr + + * NEWS + libs/plugins/modifier.truncate.php: + fixed length in modifier.truncate.php + + * NEWS + libs/plugins/outputfilter.trimwhitespace.php: + fixed handling of '$'-signs in trimwhitespace outputfilter (messju) + +2003-03-12 Monte Ohrt + + * docs/programmers.sgml: + update technical explanation of assign_by_ref and append_by_ref + +2003-03-11 Monte Ohrt + + * NEWS + libs/Smarty.class.php: + fix config file recompiling code + +2003-03-07 Monte Ohrt + + * libs/plugins/function.html_image.php: + change E_USER_ERROR to E_USER_NOTICE + + * libs/plugins/function.html_image.php: + suppress warning in html_image + + * NEWS + libs/plugins/function.html_image.php: + update changes to html_image + +2003-03-06 Monte Ohrt + + * docs/designers.sgml + docs/de/appendixes.sgml + docs/de/common.dsl + docs/de/designers.sgml + docs/de/getting-started.sgml + docs/de/html-common.dsl + docs/de/html.dsl + docs/de/manual.sgml + docs/de/preface.sgml + docs/de/programmers.sgml: + add german docs to dist + + * NEWS: + update news file + + * libs/plugins/function.html_image.php: + fix width/height parameter index + + * NEWS + libs/Smarty.class.php: + get rid of unsetting name and script attributes to insert tags + +2003-03-05 Monte Ohrt + + * NEWS + RELEASE_NOTES: + update NEWS file + + * libs/plugins/modifier.string_format.php: + fix argument order, erroneously swapped a while back + + * (Smarty_2_5_0_RC1) + NEWS + README + RELEASE_NOTES + libs/Config_File.class.php + libs/Smarty.class.php + libs/Smarty_Compiler.class.php: + commit final changes for 2.5.0-RC1 + +2003-03-04 Monte Ohrt + + * docs/programmers.sgml: + remove $show_info_header and $show_info_include property vars from docs + +2003-03-03 Monte Ohrt + + * NEWS + libs/plugins/function.popup.php: + fixed PHP notice + +2003-02-28 Monte Ohrt + + * libs/Smarty_Compiler.class.php: + simplify smarty.const.foo and smarty.const.$foo logic + + * libs/Smarty_Compiler.class.php: + only allow $foo syntax in embedded quotes, unless escaped with backticks + then allow any dollar var + + * NEWS + libs/Smarty_Compiler.class.php: + fix "once" var compiling to work with new attr compiling methods for + include_php + + * FAQ + NEWS + README + docs/designers.sgml + docs/getting-started.sgml + libs/Smarty_Compiler.class.php + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/function.html_select_date.php + libs/plugins/function.html_select_time.php + libs/plugins/function.html_table.php: + fix $smarty.const.foo compiling, clean up double quoted strings, + allow full dollar var syntax in quotes again + +2003-02-27 Monte Ohrt + + * docs/designers.sgml + docs/programmers.sgml + libs/Smarty_Compiler.class.php: + update docs, fix smarty var compiling, allow any $smarty.*.$foo syntax, + add $`foobar` for embedded variables + + * libs/plugins/function.html_image.php: + update functionality + +2003-02-26 Monte Ohrt + + * NEWS + libs/plugins/modifier.nl2br.php: + add nl2br modifier + + * libs/plugins/function.html_image.php: + add link parameter + +2003-02-24 Monte Ohrt + + * libs/Smarty.class.php + libs/plugins/function.html_image.php: + fix rename problem in windows, unlink first + + * libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_image.php + libs/plugins/function.html_options.php + libs/plugins/function.html_radios.php + libs/plugins/shared.escape_special_chars.php: + update functions with separate escape_special_chars routine + + * NEWS + libs/plugins/function.html_checkboxes.php + libs/plugins/function.html_radios.php: + commit checkboxes, update radios + + * NEWS + libs/Smarty.class.php + libs/plugins/function.html_image.php: + fix bug with get_registered_object + + * NEWS + libs/plugins/modifier.cat.php: + added cat modifier to distribution + + * NEWS + libs/Smarty_Compiler.class.php: + added << >> <> support to IF statements + + * libs/plugins/function.html_radios.php: + apply patch to initial html_radios function + + * NEWS + libs/Smarty.class.php: + fix _assign_smarty_interface to not overwrite keys other than 'request' + + * NEWS + libs/plugins/function.html_radios.php: + added html_radios to distribution + + * NEWS + libs/plugins/modifier.string_format.php: + fixed arg order of string_format + + * NEWS + libs/Smarty.class.php: + use tmp file for file writes, avoid race condition + + * NEWS + libs/Smarty_Compiler.class.php: + add $smarty.config.foo var, handle embedded smarty var correctly + + * NEWS + libs/plugins/function.fetch.php: + silence warnings in fetch plugin + +2003-02-21 Monte Ohrt + + * INSTALL: + update wording + + * INSTALL: + update install instructions + + * AUTHORS + BUGS + CREDITS + QUICKSTART + README + RESOURCES + TESTIMONIALS: + remove some files already in docs or elsewhere + + * demo/index.php: + add templates_c to repository + + * index.php: + move demo files to demo directory + + * Config_File.class.php + Smarty.class.php + Smarty_Compiler.class.php + debug.tpl: + moved lib files under libs directory + +2003-02-20 Monte Ohrt + + * NEWS + Smarty.class.php: + add get_config_vars() method, update get_template_vars() functionality + + * NEWS + Smarty.class.php: + fix minor logic in _fetch_template_info() + + * NEWS + Smarty.class.php: + support merging appended vars + + * NEWS + Smarty.class.php: + fix cache groups behavior with compile_id set + +2003-02-19 Monte Ohrt + + * Smarty.class.php: + back out third parameter, extend functionality of append + + * NEWS + Smarty_Compiler.class.php: + update imbedded vars, allow special $smarty vars + + * plugins/function.html_table.php: + add plugin html_table + + * NEWS + Smarty.class.php: + support appending key=>val pairs + + * NEWS + Smarty_Compiler.class.php: + change embedded variable logic to only recognize $foo and $foo[0][bar] + syntax + + * NEWS + Smarty_Compiler.class.php: + allow null as function attribute value + +2003-02-18 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + support foo->bar[index] syntax + + * Smarty_Compiler.class.php: + allow $foo->bar[0] syntax + +2003-02-17 Monte Ohrt + + * plugins/modifier.escape.php: + fix syntax error from previous commit + + * NEWS + Smarty.class.php: + add error msgs to get_registered_object + + * Smarty.class.php: + add function for getting reference to registered object + + * Smarty_Compiler.class.php: + back out patches for object and objref calls on $smarty var + + * NEWS + Smarty_Compiler.class.php: + treat unrecognized param attribute syntax as a string + + * NEWS + Smarty_Compiler.class.php: + support $smarty.const.$foo syntax + + * NEWS + debug.tpl + plugins/modifier.count_words.php + plugins/modifier.escape.php: + fix E_NOTICE messages + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + add @ and === to if tokens, few param cleanups + +2003-02-16 Greg Beaver + + * ChangeLog + Smarty.class.php + Smarty_Compiler.class.php: + many more phpdoc comment upgrades + +2003-02-15 Greg Beaver + * Smarty.class.php + Smarty_Compiler.class.php + continue cleaning of phpdoc comments. All that is needed is the + addition of @return tags and perhaps a bit more verbose comments + and they are finished. + +2003-02-14 Monte Ohrt + + * NEWS + Smarty.class.php: + enable config_load error messages + + * NEWS + plugins/function.html_options.php: + fix html_options to not escape already escaped entities + + * NEWS + Smarty.class.php: + send Last-Modified header on cache creation, misc tab/spacing cleanup + +2003-02-13 Monte Ohrt + + * Smarty_Compiler.class.php + docs/designers.sgml: + allow dash in plain text + + * NEWS + Smarty_Compiler.class.php: + check strict syntax of function attributes + +2003-02-12 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php: + dropped support for modifiers on object parameters, + added support for objects as modifier parameters + + * NEWS + Smarty_Compiler.class.php + docs/designers.sgml: + fix bug with decimal numbers in if statements, misc doc updates + +2003-02-11 Monte Ohrt + + * (Smarty_2_4_2) + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: + update version numbers + +2003-02-10 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php: + add support for $foo->$bar syntax + + * NEWS: + update NEWS file + + * NEWS + Smarty_Compiler.class.php: + support full var syntax in quoted text, fix problem with const var access, + clean up some more regex code, fix object problem with no properties + +2003-02-06 Monte Ohrt + + * (Smarty_2_4_1) + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: + committed 2.4.1 changes + + * NEWS + Smarty_Compiler.class.php: + ignore case in IF statements + +2003-02-05 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php: + treat undefined constants as null + + * NEWS + Smarty.class.php: + fix problem with inserts and nested fetches + + * Smarty_Compiler.class.php: + fix "if" regex for math tokens + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs/getting-started.sgml: + added support for extracting params to include_php + +2003-02-04 Monte Ohrt + + * RELEASE_NOTES: + reformat text + +2003-02-03 Monte Ohrt + + * NEWS: + update news file + +2003-02-03 Greg Beaver + + * ChangeLog + Smarty.class.php: + begin fixing phpdoc comments in Smarty.class.php + + * ChangeLog + Config_File.class.php: + fixed phpdoc comments + +2003-02-03 Monte Ohrt + + * Smarty_Compiler.class.php: + allow $foo->bar[$x].foo syntax + + * Smarty_Compiler.class.php + index.php + configs/test.conf + templates/index.tpl: + fix accidental commit + + * index.php + configs/test.conf + templates/index.tpl: + allow $foo->bar[$j].blah type of syntax + +2003-02-02 Greg Beaver + + * Smarty.class.php + begin fixing of phpdoc comments + + * Config_File.class.php + fix phpdoc comments, add phpDocumentor docblock templates + +2003-02-02 Monte Ohrt + + * Smarty.class.php + docs/html.dsl + docs/php.dsl: + fix version number + + * (Smarty_2_4_0) + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php + docs/appendixes.sgml + docs/designers.sgml + docs/programmers.sgml: + update Smarty version numbers + +2003-01-30 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php + TODO: + fix order of php tag comparisons + + * NEWS + Smarty_Compiler.class.php: + fix known php tag handling problems + +2003-01-29 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + change comments to phpdoc style + +2003-01-28 Monte Ohrt + + * Smarty.class.php + docs/programmers.sgml: + make separate var for compiler file + + * plugins/function.fetch.php: + fix error call + +2003-01-25 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + add support for restriction to registered methods + + * plugins/outputfilter.trimwhitespace.php: + update with textarea support + +2003-01-24 Monte Ohrt + + * Smarty_Compiler.class.php: + fix compiling problem with {foreach} tags + + * Smarty.class.php + Smarty_Compiler.class.php: + put objects in own array, add object param format support, change + object syntax from foo.bar to foo->bar + +2003-01-23 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + add support for object registration + +2003-01-22 Monte Ohrt + + * Smarty.class.php: + add file & line number of calling error to error message + +2003-01-21 Monte Ohrt + + * Smarty_Compiler.class.php: + put php style object syntax back in + +2003-01-20 Monte Ohrt + + * Smarty.class.php: + move security settings to fetch function for template_dir + + * NEWS + Smarty.class.php: + fix debug template and security, add template_dir to secure_dir at runtime + +2003-01-17 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + added new object support without new template syntax + +2003-01-15 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + fix if statement syntax for negative integers, fix issue with directories + named '0' + +2003-01-08 Monte Ohrt + + * Smarty.class.php + plugins/function.counter.php + plugins/function.cycle.php + plugins/function.debug.php + plugins/function.eval.php + plugins/function.fetch.php + plugins/function.html_options.php + plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/function.mailto.php + plugins/function.math.php + plugins/function.popup.php + plugins/function.popup_init.php: + update plugins to return values instead of echo, fix config file cache + to include global config variables in cache file + + * Smarty_Compiler.class.php: + fix bug with >= tests in if statements, comment out full object support + +2003-01-06 Monte Ohrt + + * NEWS + docs/html.dsl + plugins/modifier.escape.php: + add javascript escape parameter to escape modifier + +2003-01-02 Monte Ohrt + + * templates/header.tpl: + move the title into head where it should be + +2002-12-24 Monte Ohrt + + * Smarty_Compiler.class.php: + added correct line numbers to smarty syntax error messages + + * docs/programmers.sgml: + update append documentation, make more clear on its function + + * Smarty_Compiler.class.php: + fix modifier matching regexp + +2002-12-23 Monte Ohrt + + * Smarty_Compiler.class.php: + support nested function calls in IF statements + +2002-12-20 Monte Ohrt + + * Smarty_Compiler.class.php: + few more fixes, spaces around function parameters + + * Smarty_Compiler.class.php: + fix misc syntax issues with {if} tags + +2002-12-20 Monte Ohrt + + * Smarty_Compiler.class.php: + fix misc syntax issues with {if} tags + +2002-12-19 Monte Ohrt + + * Smarty_Compiler.class.php: + commit updates, passes all smoke tests + + * NEWS: + update NEWS file + + * Smarty_Compiler.class.php: + fixed literal string not in quotes as parameters + + * NEWS + Smarty_Compiler.class.php: + fix misc syntax issues, add ability to pass modifiers to functions + +2002-12-18 Monte Ohrt + + * NEWS: + update NEWS + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + update compiler code, clean up regex, add new syntax features + +2002-12-16 Monte Ohrt + + * NEWS: + update NEWS file + + * Smarty_Compiler.class.php: + commit updates for objects + +2002-12-14 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + fix bug with compiling config files with caching on + +2002-12-13 Monte Ohrt + + * Smarty_Compiler.class.php: + fix problem with matching single quoted strings + + * Smarty_Compiler.class.php: + update embedded variable logic, get rid of ."" at end of output + + * NEWS + docs/designers.sgml + plugins/function.html_select_date.php: + add day_value_format to html_select_date + +2002-12-12 Monte Ohrt + + * plugins/modifier.debug_print_var.php: + fix bug, double escaped values in display + + * Smarty.class.php: + move debug test back into fetch() + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + plugins/outputfilter.trimwhitespace.php: + assigned vars are no longer in global name space, few debug cleanups + +2002-12-11 Monte Ohrt + + * plugins/function.popup.php: + fix error in newline code + + * plugins/function.popup.php: + fix popup to allow newlines in text data + +2002-12-10 Monte Ohrt + + * Smarty.class.php: + fix plugin error logic + + * docs/designers.sgml + docs/programmers.sgml: + edit examples, make more verbose + + * NEWS + plugins/function.html_options.php: + escape html entities in the option values and output + + * NEWS + plugins/function.html_options.php: + fixed bug with label of html_options + +2002-12-09 Monte Ohrt + + * Smarty.class.php: + add support for var_export() + + * Config_File.class.php + Smarty.class.php: + clean up code, respect force_compile and compile_check flags + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs/designers.sgml + plugins/function.mailto.php: + add caching feature to config loading, document update, add mailto plugin + +2002-12-08 Monte Ohrt + + * plugins/function.fetch.php: + fix query part of URL + +2002-12-05 Monte Ohrt + + * docs/designers.sgml: + fix typos + +2002-11-22 Monte Ohrt + + * Smarty_Compiler.class.php: + patch for warning message + +2002-11-21 Monte Ohrt + + * RELEASE_NOTES + Smarty.class.php: + get rid of testing for a set value with assign function, just set to + whatever is passed into the template + + * docs/programmers.sgml: + fix typo + +2002-11-19 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: + commit changes, ready for 2.3.1 release + +2002-11-01 Monte Ohrt + + * plugins/function.html_options.php: + added label attribute to all option outputs, cover w3c spec. + + * NEWS: update NEWS file + + * docs/designers.sgml: update docs for optgroup output + + * plugins/function.html_options.php: + make html_options work with optgroup, make func modular and recursive. + +2002-10-29 Monte Ohrt + + * NEWS + Smarty.class.php: set mtime on compile files so they match source files + +2002-10-18 Monte Ohrt + + * NEWS + Smarty.class.php: added proper support for open_basedir setting + + * docs/designers.sgml: clear up docs on index, iteration and rownum + +2002-10-16 Monte Ohrt + + * plugins/modifier.default.php: fix warning message in default modifier + +2002-09-25 Monte Ohrt + + * docs/designers.sgml + plugins/modifier.strip.php + NEWS: added strip variable modifier + +2002-09-24 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: + Fix to be able to use $smarty.x variables as arrays. + +2002-09-23 Monte Ohrt + + * Config_File.class.php: + add support for mac/dos formatted config files (fix newlines) + + * docs/programmers.sgml: add optional tags to clear_cache parameters + + * docs/designers.sgml: + fix error with include_php description, add $this to description + +2002-09-20 Monte Ohrt + + * NEWS + docs/getting-started.sgml: fixed errors with example setup docs + +2002-09-16 Monte Ohrt + + * plugins/block.textformat.php + docs/designers.sgml + NEWS: add textformat block function + +2002-09-10 Monte Ohrt + + * docs/designers.sgml: + add assign attribute to cycle function documentation + + * docs/designers.sgml + docs/programmers.sgml: fix typos + +2002-09-09 Monte Ohrt + + * plugins/function.debug.php + templates/header.tpl: + fix header in debug template, fix typo in header.tpl example + +2002-08-15 mohrt + + * docs/programmers.sgml: fix typos + +2002-08-08 mohrt + + * RELEASE_NOTES + Smarty.class.php: + supress warnings from unlink() and is_dir(), let error handler deal with it + +2002-08-07 mohrt + + * docs/appendixes.sgml + docs/designers.sgml + docs/programmers.sgml + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: update files with new version numbers + +2002-08-02 mohrt + + * NEWS: update NEWS file with credits + + * NEWS + Smarty.class.php: added assign_by_ref() and append_by_ref() functions + +2002-08-01 mohrt + + * TODO + NEWS + Smarty.class.php: + changed default warning type for plugin errors from E_USER_WARNING to E_USER_ERROR + +2002-07-29 mohrt + + * plugins/function.html_select_time.php + docs/designers.sgml + NEWS: added paramters to html_select_time plugin + +2002-07-25 Andrei Zmievski + + * TODO: *** empty log message *** + +2002-07-24 mohrt + + * QUICKSTART: update QUICKSTART guide + + * NEWS + debug.tpl + plugins/modifier.debug_print_var.php: + update debug console to show objects, fix warning in debug.tpl + +2002-07-23 mohrt + + * docs/programmers.sgml: fix load_filter examples + + * Config_File.class.php + NEWS: fix error when there are no sections in config file + +2002-07-19 mohrt + + * docs/getting-started.sgml: fix error in install guide + +2002-07-18 mohrt + + * Smarty_Compiler.class.php: + correct the expression match for smarty:nodefaults + +2002-07-17 mohrt + + * Smarty_Compiler.class.php: fix default modifier to work with config vars + + * Smarty_Compiler.class.php: got args to strstr backwards... + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + change default modifiers to array instead of string + + * Smarty_Compiler.class.php + docs/designers.sgml + Smarty.class.php: add default modifier logic, minor doc updates + + * NEWS + Smarty.class.php + plugins/function.popup_init.php: + make popup_init xhtml compliant, minor variable name changes for consistancy + +2002-07-16 mohrt + + * NEWS: update NEWS file + + * plugins/function.debug.php + Smarty.class.php + debug.tpl + NEWS: + fix problem with filenames on windows, add ability to supply expire time in seconds when clearing cache or compiled files + +2002-07-15 mohrt + + * Smarty.class.php: + fixed problem with insert tags when loading function from script attribute + and caching enabled (Monte) + +2002-07-14 mohrt + + * NEWS + Smarty.class.php: fix bug with debug_tpl file path for Windows + +2002-07-12 Monte Ohrt + + * Smarty.class.php: fix append function with array/string issue + +2002-07-11 Monte Ohrt + + * RELEASE_NOTES: update release notes + + * NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php + Config_File.class.php: update files to 2.2.0 tags, get ready for release + +2002-07-09 Monte Ohrt + + * NEWS + Smarty.class.php: make debug.tpl work with any delimiter + + * NEWS + Smarty.class.php: + change tests in append and assign to != '' instead of empty(), which is more accurate + +2002-07-08 Monte Ohrt + + * docs/designers.sgml: minor doc update + + * Smarty.class.php: + cast var as an array, simplify and get rid of PHP warning messages + +2002-07-03 Monte Ohrt + + * Smarty.class.php: one more N + + * Smarty.class.php: + prepend "N" to filenames to avoid possible OS issues with dir names starting with "-" + + * Smarty.class.php: only set $debug_tpl in constructor if empty + + * Smarty.class.php + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml: + make use_sub_dirs go back to crc32 for subdir separation + +2002-06-29 Monte Ohrt + + * plugins/function.eval.php: do nothing if $val is empty + + * TODO + plugins/function.eval.php + plugins/function.popup_init.php: + add zindex to popup init, fix error message for eval. + +2002-06-27 Monte Ohrt + + * Smarty.class.php: + only loop through relative paths for PHP include_path, remove $_relative variable + + * Smarty_Compiler.class.php: added {$smarty.version} variable + +2002-06-26 Monte Ohrt + + * docs/appendixes.sgml + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml + Smarty.class.php: + update plugin loading logic, look in SMARTY_DIR, then cwd. If all fail, then retry all with include_path + + * templates/header.tpl + Smarty.class.php: update get_include_path, get _path_array only once + + * Smarty.class.php: fix get_include_path function for windows + + * Smarty.class.php: update plugin search logic + + * Smarty.class.php: only search include_path if relative path + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php + Smarty_Compiler.class.php + NEWS + Smarty.class.php: allow plugins_dir to be an array of directories + +2002-06-25 Monte Ohrt + + * docs/programmers.sgml + docs/getting-started.sgml: update installation docs + + * debug.tpl + docs/getting-started.sgml + templates/debug.tpl + NEWS + Smarty.class.php: move debug.tpl to SMARTY_DIR, add to constructor + +2002-06-24 Monte Ohrt + + * plugins/function.assign_debug_info.php + NEWS: fixed warning message in function.assign_debug_info + + * Smarty.class.php: update include_path fixes + + * NEWS: + fixed $template_dir, $compile_dir, $cache_dir, $config_dir to respect include_path + +2002-06-23 Monte Ohrt + + * plugins/shared.make_timestamp.php: + update timestamp plugin to work when passed a timestamp + +2002-06-19 Monte Ohrt + + * NEWS: update NEWS file + + * plugins/modifier.date_format.php + docs/designers.sgml: + update date_format, allow optional 2nd paramater as default date if passed date is empty. update docs. + + * plugins/modifier.date_format.php: + fix date_format modifier, return nothing if given empty string + +2002-06-18 Monte Ohrt + + * NEWS + plugins/function.cycle.php: + gave $reset a default value in cycle function + + * plugins/function.html_select_date.php + plugins/shared.make_timestamp.php + NEWS: + corrected warnings in html_select_time function, made make timestamp always return a timestamp + +2002-06-17 Monte Ohrt + + * Smarty.class.php: swapped around cache_id and compile_id order + +2002-06-14 Monte Ohrt + + * docs/programmers.sgml + plugins/function.popup_init.php + Smarty.class.php: + change directory delimiter to "^" for cache and compile files + +2002-06-13 Andrei Zmievski + + * TODO: done. + + * Smarty_Compiler.class.php: + Optimize the calculation of section 'total' property. + +2002-06-11 Monte Ohrt + + * NEWS + Smarty.class.php: + added support for subdir exclusion, deletion by full or partial cache_id and compile_id, change file format to urlencoded values instead of crc32 + +2002-06-07 Monte Ohrt + + * Smarty.class.php: fix bug with last_modified_check code + + * NEWS + Smarty.class.php: + updated $GLOBALS refererence for HTTP_IF_MODIFIED_SINCE + +2002-06-06 Monte Ohrt + + * docs/designers.sgml + overlib.js: + remove overlib.js file from distribution, update plugin and docs + +2002-06-05 Monte Ohrt + + * docs/designers.sgml + NEWS + Smarty.class.php: fix 304 Not Modified, don't send content + +2002-06-03 Monte Ohrt + + * plugins/function.cycle.php: update version number + + * plugins/function.cycle.php + NEWS: + fixed cycle function to respect delimiter setting after initial setting + + * Smarty.class.php + NEWS: + update $GLOBALS references to work properly with track_globals settings + + * plugins/function.math.php: fixed bug with call $assign + + * docs/appendixes.sgml + docs/designers.sgml + plugins/function.html_options.php + plugins/function.html_select_time.php + NEWS + Smarty.class.php + Smarty_Compiler.class.php: + optimized for loops with count() function calls + +2002-06-01 Andrei Zmievski + + * TODO: *** empty log message *** + +2002-05-21 Monte Ohrt + + * NEWS: update NEWS file + + * plugins/function.html_select_date.php + RESOURCES + docs/designers.sgml + Config_File.class.php: + update html_select_date with month_value_format attribute for controlling the format of the month values. + +2002-05-17 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: + Made it possible to use simple variables inside [] for indexing. + +2002-05-16 Monte Ohrt + + * docs/designers.sgml + docs/getting-started.sgml + NEWS + Smarty.class.php + Smarty_Compiler.class.php + TESTIMONIALS: add "once" attribute to php_include, update docs + +2002-05-09 Andrei Zmievski + + * NEWS + TODO: *** empty log message *** + +2002-05-07 Monte Ohrt + + * plugins/function.cycle.php: remove \n from cycle function + + * docs/designers.sgml + plugins/function.cycle.php + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php + NEWS: + update cycle function to handle array as input, update files to 2.1.1 + +2002-05-06 Monte Ohrt + + * plugins/function.fetch.php: + update fetch function with more error checking + +2002-05-03 Monte Ohrt + + * docs/designers.sgml + plugins/function.counter.php: + update counter to use name instead of id (id still works though) + + * plugins/function.cycle.php + docs/designers.sgml: rename id to name for cycle function + + * plugins/function.cycle.php: + update cycle function to allow blank values parameter after initialized + + * plugins/function.cycle.php: fix syntax error + +2002-05-02 Monte Ohrt + + * plugins/function.cycle.php: ugh, another typo + + * plugins/function.cycle.php: update comments + + * docs/designers.sgml + plugins/function.cycle.php + NEWS: added function cycle + + * FAQ + Smarty.class.php: fix register_outputfilter function + +2002-05-01 Monte Ohrt + + * docs/designers.sgml + NEWS + Smarty.class.php: fixed bug with resource testing and include_path + +2002-04-30 Monte Ohrt + + * NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: update files for 2.1.0 release + +2002-04-30 Andrei Zmievski + + * plugins/function.fetch.php + docs/programmers.sgml + Smarty.class.php: Fix. + +2002-04-29 Andrei Zmievski + + * docs/programmers.sgml + docs/designers.sgml: A whole bunch of docs. + +2002-04-26 Monte Ohrt + + * FAQ + QUICKSTART + docs/programmers.sgml: update FAQ, QUICKSTART, small doc syntax fix + +2002-04-24 Monte Ohrt + + * docs/programmers.sgml + templates/debug.tpl + Smarty.class.php: changed doc structure a bit + +2002-04-16 Andrei Zmievski + + * Smarty.class.php: Add register/unregister API for output filters. + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + TODO: + Changed the way filters are loaded, which now has to be done explicitly, + either through load_filter() API or by filling in $autoload_filters variable. + Also renamed internal variable to avoid namespace pollution. + +2002-04-15 Andrei Zmievski + + * Smarty.class.php: + Fixed _get_php_resource() to take include_path into account. + +2002-04-15 Monte Ohrt + + * docs/designers.sgml: + update docs, get modifiers and functions into index for easy access + + * docs/programmers.sgml + NEWS + Smarty.class.php: update caching documentation + +2002-04-15 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.class.php: Only turn down error notices if $debugging is false. + +2002-04-15 Monte Ohrt + + * NEWS: update NEWS file + + * plugins/function.html_select_date.php: + fixed logic so this works right when field_separator = "/" + + * plugins/function.html_select_date.php: + fix regular expression for matching date + +2002-04-13 Monte Ohrt + + * docs/designers.sgml: updated html_select_date docs to reflect changes + + * NEWS + plugins/function.html_select_date.php: + added YYYY-MM-DD support to html_select_date + +2002-04-12 Andrei Zmievski + + * TESTIMONIALS: New entry. + +2002-04-12 Monte Ohrt + + * plugins/modifier.strip_tags.php: back out changes to strip_tags + + * docs/programmers.sgml: update docs regarding cache_lifetime + + * plugins/modifier.strip_tags.php + Smarty.class.php: + update cache_lifetime logic: -1 = never expire, 0 = always expire + +2002-04-11 Andrei Zmievski + + * BUGS + FAQ + INSTALL + NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs/getting-started.sgml: + Fixed directory separtor issue. Requiring PHP 4.0.6 now. + + * NEWS + Smarty_Compiler.class.php: + Added ability to use simple variables for array indices or object properties. + + * TESTIMONIALS: Another one. + + * TESTIMONIALS: Adding one from Mark P. + +2002-04-05 Andrei Zmievski + + * Smarty_Compiler.class.php + NEWS + Smarty.class.php: Make it possible to unregister pre/postfilter plugins. + +2002-04-05 Monte Ohrt + + * INSTALL: Remove addons file from INSTALL instructions + +2002-04-04 Monte Ohrt + + * docs/designers.sgml: update doc error + + * docs/designers.sgml + plugins/modifier.escape.php + NEWS + Smarty.class.php: added htmlall attribute to escape modifier + +2002-04-03 Andrei Zmievski + + * Smarty_Compiler.class.php: Fixed undefined offset warning in {if} tag. + + * Smarty.class.php + NEWS: Added template_exists() API. + + * Smarty.class.php + Smarty_Compiler.class.php + NEWS: + - Added $smarty.template variable. + - Fixed {include_php} tag when dynamic values were used for 'file' attribute. + + * Config_File.class.php: Separator setting fix. + +2002-03-28 Monte Ohrt + + * FAQ + README: add digest address + + * FAQ + README + Smarty.class.php: update mailing list addresses + +2002-03-28 Andrei Zmievski + + * NEWS: *** empty log message *** + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: + Fix for when plugins directory is not the default one. + +2002-03-28 Andrei Zmievski + + * NEWS: *** empty log message *** + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: + Fix for when plugins directory is not the default one. + +2002-03-27 Monte Ohrt + + * FAQ: update FAQ page + +2002-03-26 Andrei Zmievski + + * CREDITS + NEWS + Smarty.class.php + Smarty_Compiler.class.php + TODO: Block functions changes. + + * Config_File.class.php: *** empty log message *** + +2002-03-25 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php: Initial implementation of block functions. + +2002-03-22 Monte Ohrt + + * docs/designers.sgml: fix documentation error in capture + +2002-03-22 Andrei Zmievski + + * Smarty.class.php: *** empty log message *** + + * Smarty.class.php: Turn off notices. + +2002-03-21 Andrei Zmievski + + * Smarty_Compiler.class.php: Make _current_file available to prefilters. + + * NEWS + Smarty.class.php: + Made is possible to assign variables in pre/postfilters. + +2002-03-20 Andrei Zmievski + + * plugins/function.html_select_date.php: Fixed +/- functionality. + + * NEWS: *** empty log message *** + +2002-03-20 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.class.php + Smarty_Compiler.class.php: update version numbers + + * plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: + move .make_timestamp.php to shared.make_timestamp.php + + * NEWS + Smarty.class.php + docs/designers.sgml + plugins/function.fetch.php + plugins/function.html_select_date.php: + update file generation, replace crc32() '-' with 'N' + +2002-03-20 Andrei Zmievski + + * Smarty_Compiler.class.php: *** empty log message *** + +2002-03-19 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.class.php + Smarty_Compiler.class.php: + Fix plugin behavior for inserts with script attribute. + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: Fix bug with $smarty.cookies. + + * TESTIMONIALS: *** empty log message *** + +2002-03-15 Monte Ohrt + + * NEWS + docs/designers.sgml: update Changelog + + * plugins/modifier.indent.php + plugins/modifier.wordwrap.php: add wordwrap and indent to repository + +2002-03-14 Monte Ohrt + + * Smarty.class.php: + remove show_info_include and show_info_header functions + +2002-03-13 Monte Ohrt + + * plugins/function.fetch.php: update fetch function + + * plugins/function.fetch.php: update fetch function with new parameters + +2002-03-12 Monte Ohrt + + * docs/designers.sgml: update doc tables + + * docs/designers.sgml: update docs columns + + * docs/getting-started.sgml + docs/appendixes.sgml: update docs + + * TESTIMONIALS + docs/appendixes.sgml: update syntax error in docs, add to testimonials + +2002-03-04 Monte Ohrt + + * FAQ + README: update FAQ, README with digest mode info + +2002-03-02 Monte Ohrt + + * QUICKSTART: update quickstart + + * Smarty.class.php: + change behavior so cache_lifetime = 0 never expires (instead of always regenerate) + +2002-03-01 Monte Ohrt + + * docs/designers.sgml: update doc example + +2002-03-01 Andrei Zmievski + + * CREDITS + RELEASE_NOTES + TODO + NEWS: *** empty log message *** + +2002-03-01 Monte Ohrt + + * docs/appendixes.sgml + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml: update document id tags + + * docs.sgml: remove docs.sgml + + * RESOURCES + Smarty.class.php: update resources + +2002-02-28 Andrei Zmievski + + * TESTIMONIALS + docs/appendixes.sgml + docs/designers.sgml + docs/programmers.sgml: *** empty log message *** + +2002-02-27 Andrei Zmievski + + * plugins/function.eval.php + docs/designers.sgml: *** empty log message *** + +2002-02-27 Monte Ohrt + + * plugins/function.eval.php: added eval function to plugin dir + +2002-02-27 Andrei Zmievski + + * NEWS: *** empty log message *** + +2002-02-27 Monte Ohrt + + * docs/designers.sgml: fix syntax error + + * docs/appendixes.sgml + docs/designers.sgml + docs/getting-started.sgml + docs/programmers.sgml: convert technical notes to docbook format + + * NEWS + docs/designers.sgml: added "eval" plugin docs + +2002-02-26 Andrei Zmievski + + * docs/programmers.sgml + docs/designers.sgml + docs/appendixes.sgml + docs/getting-started.sgml + docs/html-common.dsl + docs/.cvsignore: *** empty log message *** + + * docs/appendixes.sgml + docs/common.dsl + docs/designers.sgml + docs/getting-started.sgml + docs/html-common.dsl + docs/html.dsl + docs/manual.sgml + docs/preface.sgml + docs/programmers.sgml: Split up docs. + +2002-02-25 Andrei Zmievski + + * docs.sgml: *** empty log message *** + +2002-02-22 Monte Ohrt + + * docs.sgml: update docs + +2002-02-22 Andrei Zmievski + + * docs.sgml + AUTHORS + NEWS: *** empty log message *** + +2002-02-21 Monte Ohrt + + * Config_File.class.php + NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: update misc changes + +2002-02-21 Andrei Zmievski + + * docs.sgml: *** empty log message *** + +2002-02-20 Monte Ohrt + + * docs.sgml: misc updates + +2002-02-20 Andrei Zmievski + + * docs.sgml: *** empty log message *** + + * Smarty.class.php + plugins/function.assign.php + plugins/function.assign_debug_info.php + plugins/function.counter.php + plugins/function.fetch.php + plugins/function.math.php + plugins/function.popup.php + plugins/function.popup_init.php + plugins/modifier.escape.php: Fixup some naming. + +2002-02-20 Monte Ohrt + + * docs.sgml: update docs + +2002-02-20 Andrei Zmievski + + * docs.sgml: *** empty log message *** + +2002-02-20 Monte Ohrt + + * NEWS + docs.sgml + plugins/modifier.escape.php: + removed global vars from fetch function, added attrs to escape modifier + + * docs.sgml: add plugin chapter outline + +2002-02-19 Monte Ohrt + + * README + RELEASE_NOTES + RESOURCES + Smarty.class.php + docs.sgml + BUGS + FAQ + INSTALL + QUICKSTART: update docs + +2002-02-19 Andrei Zmievski + + * docs.sgml: Updated resources docs. + + * README: *** empty log message *** + + * docs.sgml: Updated description of {$smarty} variable. + + * BUGS + FAQ + INSTALL + QUICKSTART + RELEASE_NOTES + docs.sgml: Remove PEAR notes. + +2002-02-18 Andrei Zmievski + + * Config_File.class.php + NEWS: Removed dependency on PEAR. + +2002-02-18 Monte Ohrt + + * NEWS + docs.sgml + plugins/function.popup_init.php: add src attribute to popup_init + +2002-02-15 Andrei Zmievski + + * Smarty_Compiler.class.php + plugins/modifier.debug_print_var.php + NEWS + Smarty.class.php: Performance enhancements. + +2002-02-06 Andrei Zmievski + + * plugins/function.html_options.php: + Fix html_options output to be XHTML compatible. + +2002-02-05 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php: Fix up plugin inclusion. + + * Smarty.class.php + Smarty_Compiler.class.php + TODO + plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/modifier.date_format.php: Fix plugin directory access. + +2002-02-04 Andrei Zmievski + + * .cvsignore + Smarty_Compiler.class.php: *** empty log message *** + +2002-01-31 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + TODO + plugins/function.assign.php + plugins/function.assign_debug_info.php + plugins/function.counter.php + plugins/function.fetch.php + plugins/function.html_options.php + plugins/function.html_select_date.php + plugins/function.html_select_time.php + plugins/function.math.php + plugins/function.popup.php + plugins/function.popup_init.php + plugins/modifier.capitalize.php + plugins/modifier.count_characters.php + plugins/modifier.count_paragraphs.php + plugins/modifier.count_sentences.php + plugins/modifier.count_words.php + plugins/modifier.date_format.php + plugins/modifier.debug_print_var.php + plugins/modifier.default.php + plugins/modifier.escape.php + plugins/modifier.lower.php + plugins/modifier.regex_replace.php + plugins/modifier.replace.php + plugins/modifier.spacify.php + plugins/modifier.string_format.php + plugins/modifier.strip_tags.php + plugins/modifier.truncate.php + plugins/modifier.upper.php + plugins/shared.make_timestamp.php + templates/index.tpl + AUTHORS + CREDITS + Config_File.class.php + README: Implemented plugin architecture. + + * NEWS: *** empty log message *** + +2002-01-30 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + docs.sgml: added modifiers wordwrap and indent + +2002-01-28 Monte Ohrt + + * Smarty.class.php + docs.sgml: + add support for is-modified-since headers, adjust a doc example + +2002-01-24 Monte Ohrt + + * Smarty.class.php: cleanup formatting + + * NEWS + Smarty.class.php + docs.sgml: update ChangeLog, remove insert_tag_check parameter + +2002-01-24 Andrei Zmievski + + * plugins/standard.plugin.php: *** empty log message *** + +2002-01-24 Monte Ohrt + + * Smarty.class.php: fix syntax error + + * Smarty.class.php: removed unneccesary test from fetch() + +2002-01-23 Monte Ohrt + + * Smarty.addons.php: update overlib fixes + + * NEWS: update changelog + + * FAQ + NEWS + RESOURCES + Smarty.addons.php: updated overlib fixes + +2001-12-31 Andrei Zmievski + + * NEWS + Smarty.class.php: Fixed compile_id problem. + +2001-12-28 Monte Ohrt + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + fixed problem with using assigned var with include_php filepath + +2001-12-21 Monte Ohrt + + * RESOURCES: update RESOURCES + +2001-12-20 Monte Ohrt + + * FAQ + README: update FAQ + +2001-12-18 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php: update version numbers + +2001-12-18 Andrei Zmievski + + * NEWS + Smarty.class.php: Fixed clear_cache(). + +2001-12-14 Monte Ohrt + + * NEWS + Smarty.addons.php: + fixed bug in smarty_make_timestamp introduced in PHP 4.1.0 + +2001-12-13 Monte Ohrt + + * NEWS + Smarty.class.php + docs.sgml: update default function args, fix cached insert debug timing + +2001-12-12 Monte Ohrt + + * docs.sgml: fix syntax error in documentation + + * Smarty.class.php: update default template handling functionality + +2001-12-11 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: update file fetching logic + +2001-12-11 Andrei Zmievski + + * NEWS + Smarty.class.php: Added 'script' attribute to {insert..}. + +2001-12-10 Monte Ohrt + + * NEWS + Smarty.class.php: added default template function handler + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update version numbers in files to 1.5.1 + +2001-12-10 Andrei Zmievski + + * NEWS + Smarty.class.php: Removed error message from the _read_file() method. + + * Smarty.class.php: Fix check for compile and cache IDs. + +2001-12-06 Monte Ohrt + + * QUICKSTART: fix spelling error in QUICKSTART + + * docs.sgml: fixed spelling errors in documenation + + * Smarty_Compiler.class.php + docs.sgml + Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php: commit 1.5.0 release + + * RESOURCES + docs.sgml: added RESOURCES file + +2001-12-05 Andrei Zmievski + + * Smarty_Compiler.class.php: Refactor. + +2001-12-05 Monte Ohrt + + * NEWS + Smarty_Compiler.class.php + docs.sgml: added assign to include and php_include + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: *** empty log message *** + +2001-12-04 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Formatting. + +2001-12-04 Monte Ohrt + + * Smarty_Compiler.class.php + NEWS + Smarty.class.php: update ChangeLog + +2001-12-04 Andrei Zmievski + + * NEWS + Smarty.class.php: Formatting. + +2001-12-04 Monte Ohrt + + * Smarty.class.php: removed SMARTY_DIR setting in constructor + + * Smarty.class.php: fix Smarty.class.php indention error + + * Smarty.class.php: update trusted logic + +2001-12-03 Monte Ohrt + + * Smarty.class.php: + fix up is_secure, is_trusted, make _parse_tpl_path function + + * Smarty.class.php: fix problem with testing SMARTY_DIR as empty + + * NEWS + docs.sgml: update documentation, change log + + * Smarty.class.php: + update constructor to check for SMARTY_DIR before assigning + +2001-12-03 Andrei Zmievski + + * NEWS + Smarty.class.php: *** empty log message *** + +2001-12-03 Monte Ohrt + + * FAQ + INSTALL + RELEASE_NOTES: update a few files + + * NEWS + QUICKSTART + Smarty.class.php + docs.sgml: added trusted_dir functionality, cleaned up secure_dir logic + +2001-12-03 Andrei Zmievski + + * NEWS: *** empty log message *** + + * NEWS + Smarty.class.php: - Introduced $compile_id class variable. + - Fixed a situation where if $cache_id and $compile_id were both null + they were passed to auto functions as empty string instead of null. + +2001-11-30 Monte Ohrt + + * NEWS + Smarty.class.php: + change variable names in fetch() fuction to smarty_* to avoid namespace conflicts + + * NEWS + Smarty.class.php: fixed bug in _rm_auto with catenated null values + +2001-11-29 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Added $smarty.section.* syntax. + + * Smarty_Compiler.class.php: Made 'name' attribute optional for {foreach}. + +2001-11-29 Monte Ohrt + + * Smarty.class.php + index.php: remove assign "now" in index.tpl + +2001-11-29 Andrei Zmievski + + * NEWS + Smarty.addons.php + Smarty.class.php: Fix formatting. + +2001-11-28 Monte Ohrt + + * NEWS + Smarty.class.php + docs.sgml: + removed return statements from _read_cache_file (how did they get in there?) + +2001-11-27 Monte Ohrt + + * docs.sgml + NEWS + Smarty.addons.php + Smarty.class.php: + fixed bugs and added assign attribute to several functions + +2001-11-27 Andrei Zmievski + + * NEWS: Some rewording. + + * Smarty_Compiler.class.php: Fix $smarty.capture access. + + * TODO: *** empty log message *** + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + Made {config_load ..} merge globals from each config file only once per scope. + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: - Added {foreach ...}. + - Made certain $smarty.* references handled at compilation time. + +2001-11-26 Monte Ohrt + + * Config_File.class.php + NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: commit cache handler functionality + +2001-11-20 Andrei Zmievski + + * NEWS + Smarty.addons.php + Smarty_Compiler.class.php: Various fixes and additions. + + * NEWS + index.php: *** empty log message *** + +2001-11-05 Monte Ohrt + + * Smarty.class.php: changed _read_file parameter from $end to $lines + + * NEWS + Smarty.class.php: fixed is_cache, make cache reading more efficient + +2001-11-02 Monte Ohrt + + * FAQ + NEWS: update FAQ with mailing list Reply-To header FAQ + + * NEWS + Smarty.class.php + index.php: supress fopen errors, return false if cache file won't load + +2001-11-01 Monte Ohrt + + * QUICKSTART + docs.sgml + index.php: update QUICKSTART guide with index key example + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: commit all updates for 1.4.6 + +2001-11-01 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-10-30 Monte Ohrt + + * Smarty.addons.php: fix assign function problem with empty value passed + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + templates/debug.tpl: + fixed bug in assign function when passing an empty value + +2001-10-26 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php + index.php: fix minor typo in debug code + +2001-10-26 Andrei Zmievski + + * Smarty.class.php: Typo. + +2001-10-26 Monte Ohrt + + * Smarty.addons.php: + update debug console output, handle html encoding correctly + +2001-10-26 Andrei Zmievski + + * Smarty.addons.php + templates/debug.tpl: Debug formatting. + + * Smarty.class.php: Disable rmdir warning. + +2001-10-26 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php + templates/debug.tpl: update debugging to expand array variables + + * Smarty.class.php + docs.sgml: + update docs for fetching only timestamp with custom template source functions + + * Smarty.addons.php: fix debug console error + +2001-10-26 Andrei Zmievski + + * docs.sgml: Typos. + + * Smarty.addons.php: Cleanup whitespace. + + * Smarty_Compiler.class.php: Clean up whitespace. + + * Smarty.class.php: Cleaning up code, formatting mostly. + + * NEWS: *** empty log message *** + +2001-10-25 Monte Ohrt + + * NEWS + docs.sgml: update documentation to current version + + * NEWS + Smarty.addons.php: + updated fetch to give proper warning when fetching unreadable or nonexistant files + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + fixed problem with newline at the end of compiled templates + + * NEWS + Smarty.class.php: recompile cache if config file gets modified too. + + * NEWS + Smarty.class.php: + added feature to regenerate cache if compile_check is enabled and an + involved template is modified + +2001-10-23 Monte Ohrt + + * Smarty.class.php: fix indent for insert tags in debug console + + * templates/debug.tpl: update debug.tpl file format + + * NEWS + Smarty.addons.php + Smarty.class.php + templates/debug.tpl: + update execution time debugging, move into include list + +2001-10-10 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: + fixed up execution time output in debug console + +2001-10-09 Andrei Zmievski + + * Config_File.class.php + NEWS + Smarty.class.php + TODO: Added support for hidden config vars. + +2001-10-04 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + templates/debug.tpl: added execution times to debug console + +2001-10-02 Andrei Zmievski + + * Smarty_Compiler.class.php: Add space. + +2001-10-01 Andrei Zmievski + + * Smarty.class.php: Fix reference to compile_id. + +2001-09-28 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: Added postfilter functions. + +2001-09-26 Andrei Zmievski + + * NEWS + Smarty.class.php + docs.sgml: Rename to clear_compiled_tpl(). + +2001-09-25 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: + Fixed line number reporting when removing comments. + +2001-09-20 Monte Ohrt + + * NEWS + RELEASE_NOTES + Smarty.addons.php: made html_options output xhtml compatible + +2001-09-19 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + templates/debug.tpl: updated version numbers + +2001-09-16 Monte Ohrt + + * FAQ + NEWS + docs.sgml: fix doc error with insert function + +2001-09-06 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-08-31 Monte Ohrt + + * NEWS: update ChangeLog + + * overlib.js + Smarty.addons.php + Smarty.class.php + docs.sgml: + update overlib to 3.50, adjust addon code so that the overlib.js file isn't modified + +2001-08-31 Andrei Zmievski + + * Smarty.class.php: - compile_id changes + + * NEWS + Smarty.addons.php: - compile_id support + - new options for html_select_date + +2001-08-23 Andrei Zmievski + + * TODO: *** empty log message *** + +2001-08-10 Andrei Zmievski + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: + Modified to pass Smarty object as second parameter to insert functions. + Also moved _smarty_mod_handler() and _smarty_insert_handler() into the class. + + * NEWS + Smarty_Compiler.class.php: + Passing Smarty as second parameter to prefilter functions. + +2001-08-09 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-08-09 Monte Ohrt + + * templates/index.tpl + Smarty.class.php: add smarty.now variable to template + +2001-08-06 Monte Ohrt + + * templates/index.tpl: change config_load section back to setup + +2001-08-06 Andrei Zmievski + + * Smarty.addons.php: Optimize a bit. + +2001-08-04 Monte Ohrt + + * docs.sgml: update capture documentation + +2001-08-03 Monte Ohrt + + * FAQ + NEWS + Smarty.class.php: + fix bug with URL controlled debugging, works now (Monte) + +2001-08-01 Andrei Zmievski + + * Config_File.class.php: *** empty log message *** + + * Smarty_Compiler.class.php + Smarty.class.php: - Fixed some E_NOTICE stuff in compiler. + - Generalized assign_smarty_interface() a bit. + +2001-07-24 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php + TODO: See ChangeLog for details. + +2001-07-20 Andrei Zmievski + + * Config_File.class.php: Booleanize case-insensitively. + +2001-07-17 Monte Ohrt + + * NEWS: update ChangeLog + + * Smarty.class.php + docs.sgml: put SMARTY_DIR on Config_File require + +2001-07-11 Monte Ohrt + + * docs.sgml + FAQ + NEWS + Smarty.class.php: + updated security to not include insecure docs, only warning + +2001-07-10 Andrei Zmievski + + * Smarty.class.php: Adding 'sizeof' as an allowed {if} function. + +2001-07-06 Andrei Zmievski + + * NEWS: *** empty log message *** + +2001-07-06 Monte Ohrt + + * Config_File.class.php + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update version number to 1.4.4 + + * NEWS + Smarty.addons.php + Smarty_Compiler.class.php + docs.sgml + templates/header.tpl + templates/index.tpl: update documenatation, template examples + +2001-07-03 Andrei Zmievski + + * NEWS + Smarty.class.php: Implemented access to request vars via $smarty var. + + * NEWS + Smarty_Compiler.class.php: + Fixed a bug with parsing function arguments in {if} tags. + +2001-06-30 Monte Ohrt + + * NEWS: update ChangeLog + +2001-06-29 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php + docs.sgml + overlib.js: + moved overlib to separate file, added SMARTY_DIR, documented. added much documentation + +2001-06-29 Andrei Zmievski + + * NEWS + RELEASE_NOTES + TODO: *** empty log message *** + +2001-06-29 Monte Ohrt + + * NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + docs.sgml + index.php + templates/debug.tpl + templates/header.tpl + templates/index.tpl: update release notes + +2001-06-27 Andrei Zmievski + + * Smarty_Compiler.class.php: *** empty log message *** + + * NEWS + Smarty_Compiler.class.php: Implemented 'step' section attribute. + + * Smarty_Compiler.class.php: Negative values of 'max' will mean no max. + + * AUTHORS + NEWS: *** empty log message *** + +2001-06-26 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + index.php: Added 'max' and 'start' section attributes. + Added 'total' and 'iteration' section properties. + +2001-06-25 Andrei Zmievski + + * Config_File.class.php + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: Update version numbers. + +2001-06-23 Andrei Zmievski + + * TODO: *** empty log message *** + +2001-06-21 Andrei Zmievski + + * Config_File.class.php + NEWS: Fixed booleanization bug. + +2001-06-20 Monte Ohrt + + * docs.sgml: + update documents to reflect changes to cached content & debugging + +2001-06-20 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php: Remove debug output for cached and fetched cases. + +2001-06-20 Monte Ohrt + + * Smarty.class.php: update include_info to false + + * Smarty.class.php + docs.sgml + index.php + templates/footer.tpl: + moved debug logic into Smarty completely, created flags for it + +2001-06-19 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php + templates/debug.tpl: *** empty log message *** + + * NEWS + Smarty.class.php: Remove unneeded debug functions. + +2001-06-19 Monte Ohrt + + * NEWS + Smarty.addons.php + Smarty.class.php + docs.sgml + templates/debug.tpl + templates/footer.tpl: commit updates, add debug template + +2001-06-19 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php + TODO: + Moved config loading code inside main class, the compiled template now + simply calls that method. + +2001-06-15 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + templates/index.tpl: * moved config array into class itself + * added 'scope' attribute for config_load + + * Smarty_Compiler.class.php + Smarty.addons.php + Smarty.class.php: Finishing up secure mode. + +2001-06-15 Monte Ohrt + + * NEWS: update ChangeLog + + * Smarty_Compiler.class.php: cleaned up logic of if statement security + + * Smarty_Compiler.class.php: update if logic to cover more situations + + * Smarty_Compiler.class.php + docs.sgml: update if statement security feature + +2001-06-14 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php: *** empty log message *** + + * NEWS + Smarty_Compiler.class.php: + Fixed a bug with quoted strings inside if statements. + +2001-06-13 Monte Ohrt + + * Smarty.addons.php + Smarty.class.php: added secure_dir array for multiple secure directories + + * Smarty.addons.php: update fetch funtion to respect security setting + + * NEWS + Smarty.addons.php + Smarty.class.php + docs.sgml: update documentation, changelog + + * Smarty.addons.php + Smarty.class.php: moved _extract setting to assign functions + + * Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: + added assign/unassign custom functions, ability to re-extract tpl_vars + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + index.php: commit security features + +2001-06-11 Andrei Zmievski + + * Smarty.class.php: Version variable typo. + +2001-06-05 Andrei Zmievski + + * Smarty.class.php: + Create config object in fetch() or just set the config path if it already + exists. + +2001-06-04 Andrei Zmievski + + * Smarty.class.php: *** empty log message *** + + * NEWS + Smarty_Compiler.class.php: + Fixed a problem with $ inside strip tags. + +2001-05-31 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Config_File.class.php: Allow empty config_path. + +2001-05-29 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php: update version numbers + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: moved version variable to internal variable + +2001-05-22 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php: + Moved $_smarty_sections and $_smarty_conf_obj into Smarty class. + +2001-05-18 Monte Ohrt + + * NEWS: update ChangeLog + + * FAQ + QUICKSTART: update FAQ, QUICKSTART for windows include_path setup + + * configs/test.conf: added configs directory to cvs + +2001-05-18 Andrei Zmievski + + * Smarty.class.php: Use compiler_class for including the file. + +2001-05-18 Monte Ohrt + + * docs.sgml: fix typo + +2001-05-16 Monte Ohrt + + * README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update files to version 1.4.1 + + * NEWS: update ChangeLog + +2001-05-15 Andrei Zmievski + + * NEWS: *** empty log message *** + + * index.php: forget that! + + * NEWS + Smarty_Compiler.class.php + index.php: Fixed a few E_NOTICE warnings. + +2001-05-09 Monte Ohrt + + * NEWS + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + docs.sgml: update dates versions + +2001-05-09 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty.class.php: + Use absolute paths when requiring/including Smart components. + + * NEWS: *** empty log message *** + + * Smarty.class.php: Use write mode instead of append. + +2001-05-02 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Fix indexing by section properties. + +2001-05-02 Monte Ohrt + + * NEWS: update changelog + + * Smarty.class.php: remove period from syntax error + +2001-05-02 Andrei Zmievski + + * Smarty_Compiler.class.php: Double-quote the attribute values by default. + +2001-04-30 Monte Ohrt + + * Smarty_Compiler.class.php + NEWS: added simple {capture} logic + +2001-04-30 Andrei Zmievski + + * TODO: *** empty log message *** + + * Smarty_Compiler.class.php + Smarty.class.php: Fix passing config vars to included files. + + * Smarty.class.php + Smarty_Compiler.class.php: Fix inclusion again. + +2001-04-30 Monte Ohrt + + * FAQ + RELEASE_NOTES + Smarty.class.php + misc/fix_vars.php + NEWS: update paths for windows (c:) + +2001-04-28 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php: Fix passing variables to included files. + + * templates/index.tpl: *** empty log message *** + +2001-04-27 Andrei Zmievski + + * Smarty_Compiler.class.php: Fix includes. + +2001-04-26 Andrei Zmievski + + * Smarty_Compiler.class.php + docs.sgml + Smarty.class.php: Formatting mostly. + + * Smarty_Compiler.class.php + Config_File.class.php: *** empty log message *** + +2001-04-26 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + FAQ + NEWS + QUICKSTART + RELEASE_NOTES + Smarty.class.php: update docs with new changes + +2001-04-26 Andrei Zmievski + + * RELEASE_NOTES: *** empty log message *** + + * docs.sgml + templates/index.tpl + NEWS + Smarty_Compiler.class.php: Added ability to reference object properties. + +2001-04-25 Andrei Zmievski + + * README + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + AUTHORS + Config_File.class.php + CREDITS + RELEASE_NOTES + NEWS: *** empty log message *** + + * docs.sgml: Docs on new parameter to custom functions. + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: + Changing the way tpl vars are referenced and passing smarty object + to custom functions. + + * RELEASE_NOTES + docs.sgml: Fixing docs a bit. + +2001-04-24 Andrei Zmievski + + * docs.sgml: Docs for $compiler_class and compiler functions. + + * templates/index.tpl: *** empty log message *** + + * Smarty_Compiler.class.php: Remove debugging. + +2001-04-24 Monte Ohrt + + * docs.sgml: update compiler function docs + +2001-04-24 Andrei Zmievski + + * NEWS + Smarty.class.php + Smarty_Compiler.class.php + templates/index.tpl: Added compiler function support. + +2001-04-24 Monte Ohrt + + * RELEASE_NOTES + Smarty.class.php: + update notes, change show_info_header to false by default + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + CREDITS + FAQ + NEWS + README + RELEASE_NOTES: update documenation, bug fixes + +2001-04-24 Andrei Zmievski + + * misc/fix_vars.php: Hopefully fix for sure. + +2001-04-23 Monte Ohrt + + * misc/fix_vars.php: uncomment copy/unlink + +2001-04-23 Andrei Zmievski + + * misc/fix_vars.php: Do it more thoroughly. + + * misc/fix_vars.php: check for } + +2001-04-22 Andrei Zmievski + + * misc/fix_vars.php: Fix variable parsing. + +2001-04-20 Monte Ohrt + + * misc/fix_vars.php: fix problem with 4.0.5-dev and preg_replace_callback + +2001-04-19 Monte Ohrt + + * Smarty_Compiler.class.php + docs.sgml + misc/fix_vars.php + NEWS + RELEASE_NOTES + Smarty.class.php: update notes/documentation + + * NEWS + README + RELEASE_NOTES + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + docs.sgml: update files for 1.4.0 release + +2001-04-16 Andrei Zmievski + + * misc/fix_vars.php: Added fix_vars.php script. + +2001-04-16 Monte Ohrt + + * QUICKSTART + RELEASE_NOTES + docs.sgml + templates/index.tpl: + update RELEASE_NOTES & scripts with new section var syntax + +2001-04-13 Andrei Zmievski + + * Smarty_Compiler.class.php: * Implement new variable format parser. + * Optimizing config load a bit. + +2001-04-13 Monte Ohrt + + * FAQ + NEWS + RELEASE_NOTES + Smarty.class.php: + added $check_cached_insert_tags to speed up cached pages if + {insert ...} is not used (Monte) + +2001-04-12 Andrei Zmievski + + * NEWS + Smarty.class.php + RELEASE_NOTES: *** empty log message *** + + * Smarty_Compiler.class.php: Remove redundant functions. + + * Smarty.class.php: Formatting. + +2001-04-12 Monte Ohrt + + * Smarty.class.php: update file: parsing + + * Smarty.class.php + docs.sgml: update documentation + +2001-04-12 Andrei Zmievski + + * Smarty.class.php + Smarty_Compiler.class.php + TODO: *** empty log message *** + +2001-04-11 Monte Ohrt + + * FAQ + QUICKSTART + RELEASE_NOTES: added RELEASE_NOTES file to cvs + + * NEWS + docs.sgml: update ChangeLog, update documentation + + * Smarty.class.php + Smarty_Compiler.class.php + templates/index.tpl: + update Smarty to compile at run-time. added ability to get files from + absolute paths, added work around for LOCK_EX and windows, changed a few + file permissions to be more secure. + +2001-03-29 Monte Ohrt + + * NEWS + Smarty.addons.php: + allow arbitrary date strings instead of just timestamps + +2001-03-28 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php + docs.sgml + FAQ + NEWS + README + Smarty.addons.php: + update version in class, update docs for count_ and new vars + + * templates/index.tpl + docs.sgml: update docs, example template + +2001-03-28 Andrei Zmievski + + * Smarty_Compiler.class.php: Some variable renaming. + +2001-03-23 Andrei Zmievski + + * Smarty_Compiler.class.php + NEWS: Fixed nested include infinite repeat bug. + +2001-03-23 Monte Ohrt + + * Smarty.class.php: fix version number + + * Smarty.class.php + NEWS: added optional HTML header to output + +2001-03-22 Andrei Zmievski + + * Smarty_Compiler.class.php: Fixed inclusion of dynamic files. + +2001-03-16 Andrei Zmievski + + * Smarty_Compiler.class.php: Fixing the config_load scoping. + + * Smarty_Compiler.class.php: making config variables global for now. + +2001-03-15 Andrei Zmievski + + * NEWS: *** empty log message *** + + * Smarty_Compiler.class.php: + * Includes are now always done via generated function call to protect + namespace. + * config_load now always uses global config object to improve + performance. + +2001-03-13 Monte Ohrt + + * docs.sgml: update math documentation with format attribute + +2001-03-11 Monte Ohrt + + * docs.sgml + NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update math function with format attribute + +2001-03-10 Andrei Zmievski + + * Smarty.addons.php: *** empty log message *** + + * NEWS + Smarty.addons.php + Smarty.class.php: Added html_select_time custom function. + +2001-03-08 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php + NEWS + README + Smarty.addons.php: rename 1.3.1b to 1.3.1pl1 + + * NEWS + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php: update version numbers, changelog + + * Smarty.class.php + Smarty_Compiler.class.php: + moved _syntax_error to Smarty_Compiler.class.php + + * Smarty.class.php + docs.sgml: + missing _syntax_error function recovered. fixed minor syntax in docs + +2001-03-07 Monte Ohrt + + * QUICKSTART + README + Smarty.addons.php + Smarty.class.php + Smarty_Compiler.class.php + BUGS + INSTALL + NEWS: update everything to 1.3.1 + +2001-03-03 Monte Ohrt + + * Smarty_Compiler.class.php + Smarty.class.php: fixed bug with cached insert tags + +2001-03-02 Monte Ohrt + + * Smarty.class.php + Smarty_Compiler.class.php: + fix cache fuctions with separated compiled class + + * FAQ + NEWS + docs.sgml: update changelog + +2001-03-02 Andrei Zmievski + + * NEWS + Smarty_Compiler.class.php: Added 'first' and 'last' section properties. + +2001-03-02 Monte Ohrt + + * TODO: remove compiling separation TODO + + * Smarty_Compiler.class.php + Smarty.addons.php + Smarty.class.php: update function headers + + * templates/index.tpl + NEWS + Smarty.class.php + Smarty_Compiler.class.php + index.php: split out compiling code for faster execution + + * Smarty.class.php: fixed a few warning messages + + * Smarty.addons.php + Smarty.class.php + docs.sgml + NEWS: added fetch, unregister mod/fun, updated docs + +2001-03-01 Monte Ohrt + + * Smarty.addons.php: added "int" to available list + + * docs.sgml + FAQ + Smarty.class.php: update FAQ, add math functions & update documetation + + * index.php + Smarty.addons.php + Smarty.class.php + docs.sgml: fixed literal tags and other optional delimiters + +2001-02-26 Andrei Zmievski + + * NEWS + Smarty.class.php: + Added index_prev, index_next section properties and ability to + index by them. + + * NEWS + Smarty.addons.php + Smarty.class.php: Reverting the plugins patch - needs more thought. + + * Smarty.class.php: Fixing plugin loading. + +2001-02-23 Andrei Zmievski + + * Smarty.addons.php + Smarty.class.php + plugins/standard.plugin.php + NEWS: Added plugin functionality. + +2001-02-22 Monte Ohrt + + * docs.sgml + templates/index.tpl + NEWS + README + Smarty.class.php: fixed issue with php tags executed in literal blocks + +2001-02-21 Monte Ohrt + + * NEWS: update changelog for LGPL change + + * Smarty.class.php + docs.sgml + README + Smarty.addons.php: updated version numbers to 1.3.0 + + * NEWS + templates/index.tpl: update changelog, rearrange index.tpl file + +2001-02-21 Andrei Zmievski + + * NEWS + Smarty.class.php: *** empty log message *** + +2001-02-21 Monte Ohrt + + * docs.sgml: update parameters for is_cached and fetch + +2001-02-21 Andrei Zmievski + + * NEWS + Smarty.class.php: *** empty log message *** + +2001-02-21 Monte Ohrt + + * NEWS + Smarty.addons.php + docs.sgml: update docs, remove header function from addons + +2001-02-20 Monte Ohrt + + * FAQ + NEWS: update changelog + + * TODO: update todo + + * TODO: update todo list + + * Smarty.class.php: update php tag handling logic + +2001-02-19 Monte Ohrt + + * index.php + Config_File.class.php + FAQ + Smarty.class.php + docs.sgml: fixed + + * Smarty.addons.php: *** empty log message *** + +2001-02-13 Andrei Zmievski + + * TODO: *** empty log message *** + +2001-02-12 Andrei Zmievski + + * templates/index.tpl + Smarty.class.php: *** empty log message *** + +2001-02-10 Monte Ohrt + + * Smarty.class.php: remove unneeded preg_match + + * Smarty.class.php: remove comment + + * Smarty.class.php: updated php escape to handle +{/if} \ No newline at end of file diff --git a/gui/bacula-web/classes/external/smarty/libs/internals/core.assemble_plugin_filepath.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.assemble_plugin_filepath.php new file mode 100644 index 0000000000..690d3ddbc2 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.assemble_plugin_filepath.php @@ -0,0 +1,67 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.assign_smarty_interface.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.assign_smarty_interface.php new file mode 100644 index 0000000000..7e65a73ec2 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.assign_smarty_interface.php @@ -0,0 +1,43 @@ + + * Name: assign_smarty_interface
+ * 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/gui/bacula-web/classes/external/smarty/libs/internals/core.create_dir_structure.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.create_dir_structure.php new file mode 100644 index 0000000000..3eecc49723 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.create_dir_structure.php @@ -0,0 +1,79 @@ +_dir_perms) && !is_dir($_new_dir)) { + $smarty->trigger_error("problem creating directory '" . $_new_dir . "'"); + return false; + } + $_new_dir .= '/'; + } + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/internals/core.display_debug_console.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.display_debug_console.php new file mode 100644 index 0000000000..1a80f39096 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.display_debug_console.php @@ -0,0 +1,61 @@ + + * Name: display_debug_console
+ * 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/gui/bacula-web/classes/external/smarty/libs/internals/core.get_include_path.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.get_include_path.php new file mode 100644 index 0000000000..43432412b8 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.get_include_path.php @@ -0,0 +1,44 @@ + diff --git a/gui/bacula-web/classes/external/smarty/libs/internals/core.get_microtime.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.get_microtime.php new file mode 100644 index 0000000000..f1a28e0425 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.get_microtime.php @@ -0,0 +1,23 @@ + diff --git a/gui/bacula-web/classes/external/smarty/libs/internals/core.get_php_resource.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.get_php_resource.php new file mode 100644 index 0000000000..786d4e78e8 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.get_php_resource.php @@ -0,0 +1,80 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.is_secure.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.is_secure.php new file mode 100644 index 0000000000..d54abd4322 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.is_secure.php @@ -0,0 +1,59 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.is_trusted.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.is_trusted.php new file mode 100644 index 0000000000..429973158d --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.is_trusted.php @@ -0,0 +1,47 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.load_plugins.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.load_plugins.php new file mode 100644 index 0000000000..6db1dc51d2 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.load_plugins.php @@ -0,0 +1,125 @@ +_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/gui/bacula-web/classes/external/smarty/libs/internals/core.load_resource_plugin.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.load_resource_plugin.php new file mode 100644 index 0000000000..a7d37d1afc --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.load_resource_plugin.php @@ -0,0 +1,74 @@ +_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/gui/bacula-web/classes/external/smarty/libs/internals/core.process_cached_inserts.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.process_cached_inserts.php new file mode 100644 index 0000000000..1d78edd937 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.process_cached_inserts.php @@ -0,0 +1,71 @@ +_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/gui/bacula-web/classes/external/smarty/libs/internals/core.process_compiled_include.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.process_compiled_include.php new file mode 100644 index 0000000000..904d597452 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.process_compiled_include.php @@ -0,0 +1,37 @@ +_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/gui/bacula-web/classes/external/smarty/libs/internals/core.read_cache_file.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.read_cache_file.php new file mode 100644 index 0000000000..c60e113a71 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.read_cache_file.php @@ -0,0 +1,101 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.rm_auto.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.rm_auto.php new file mode 100644 index 0000000000..b251f64911 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.rm_auto.php @@ -0,0 +1,71 @@ + $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/gui/bacula-web/classes/external/smarty/libs/internals/core.rmdir.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.rmdir.php new file mode 100644 index 0000000000..2166c44d28 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.rmdir.php @@ -0,0 +1,54 @@ + 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/gui/bacula-web/classes/external/smarty/libs/internals/core.run_insert_handler.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.run_insert_handler.php new file mode 100644 index 0000000000..71c3845080 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.run_insert_handler.php @@ -0,0 +1,71 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.smarty_include_php.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.smarty_include_php.php new file mode 100644 index 0000000000..30c6e76549 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.smarty_include_php.php @@ -0,0 +1,50 @@ + $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/gui/bacula-web/classes/external/smarty/libs/internals/core.write_cache_file.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_cache_file.php new file mode 100644 index 0000000000..fa3cdd746d --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_cache_file.php @@ -0,0 +1,96 @@ +_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/gui/bacula-web/classes/external/smarty/libs/internals/core.write_compiled_include.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_compiled_include.php new file mode 100644 index 0000000000..c14adb5f42 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_compiled_include.php @@ -0,0 +1,91 @@ +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 = "_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 .= "= 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('\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/gui/bacula-web/classes/external/smarty/libs/internals/core.write_compiled_resource.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_compiled_resource.php new file mode 100644 index 0000000000..b902eff3cb --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_compiled_resource.php @@ -0,0 +1,35 @@ +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/gui/bacula-web/classes/external/smarty/libs/internals/core.write_file.php b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_file.php new file mode 100644 index 0000000000..8a3a3b3984 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/internals/core.write_file.php @@ -0,0 +1,54 @@ + $_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/gui/bacula-web/classes/external/smarty/libs/plugins/block.textformat.php b/gui/bacula-web/classes/external/smarty/libs/plugins/block.textformat.php new file mode 100644 index 0000000000..8cd010acb4 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/block.textformat.php @@ -0,0 +1,103 @@ + + * Name: textformat
+ * Purpose: format text a certain way with preset styles + * or custom wrap/indent settings
+ * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * @param array + *
+ * Params:   style: string (email)
+ *           indent: integer (0)
+ *           wrap: integer (80)
+ *           wrap_char string ("\n")
+ *           indent_char: string (" ")
+ *           wrap_boundary: boolean (true)
+ * 
+ * @author Monte Ohrt + * @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) +{ + if (is_null($content)) { + return; + } + + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string)$_val; + break; + + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int)$_val; + break; + + case 'wrap_cut': + $$_key = (bool)$_val; + break; + + default: + $smarty->trigger_error("textformat: unknown attribute '$_key'"); + } + } + + if ($style == 'email') { + $wrap = 72; + } + + // split into paragraphs + $_paragraphs = preg_split('![\r\n][\r\n]!',$content); + $_output = ''; + + for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) { + if ($_paragraphs[$_x] == '') { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]); + // indent first line + if($indent_first > 0) { + $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x]; + } + // wordwrap sentences + $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut); + // indent lines + if($indent > 0) { + $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + + return $assign ? $smarty->assign($assign, $_output) : $_output; + +} + +/* vim: set expandtab: */ + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/plugins/compiler.assign.php b/gui/bacula-web/classes/external/smarty/libs/plugins/compiler.assign.php new file mode 100644 index 0000000000..abef377f8c --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/compiler.assign.php @@ -0,0 +1,40 @@ + + * Name: assign
+ * 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 (initial author) + * @author messju mohr (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/gui/bacula-web/classes/external/smarty/libs/plugins/function.assign_debug_info.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.assign_debug_info.php new file mode 100644 index 0000000000..654049876a --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.assign_debug_info.php @@ -0,0 +1,40 @@ + + * Name: assign_debug_info
+ * Purpose: assign debug info to the template
+ * @author Monte Ohrt + * @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/gui/bacula-web/classes/external/smarty/libs/plugins/function.config_load.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.config_load.php new file mode 100644 index 0000000000..db89f638c2 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.config_load.php @@ -0,0 +1,142 @@ + + * Name: config_load
+ * 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 + * @author messju mohr (added use of resources) + * @param array Format: + *
+ * 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)
+ * 
+ * @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 = ''; + } else { + $_output = ''\\\'', '\\'=>'\\\\')) . '\'); ?>'; + } + $_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/gui/bacula-web/classes/external/smarty/libs/plugins/function.counter.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.counter.php new file mode 100644 index 0000000000..1f26db5fb6 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.counter.php @@ -0,0 +1,80 @@ + + * Name: counter
+ * Purpose: print out a counter value + * @author Monte Ohrt + * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * @param array parameters + * @param Smarty + * @return string|null + */ +function smarty_function_counter($params, &$smarty) +{ + static $counters = array(); + + $name = (isset($params['name'])) ? $params['name'] : 'default'; + if (!isset($counters[$name])) { + $counters[$name] = array( + 'start'=>1, + 'skip'=>1, + 'direction'=>'up', + 'count'=>1 + ); + } + $counter =& $counters[$name]; + + if (isset($params['start'])) { + $counter['start'] = $counter['count'] = (int)$params['start']; + } + + if (!empty($params['assign'])) { + $counter['assign'] = $params['assign']; + } + + if (isset($counter['assign'])) { + $smarty->assign($counter['assign'], $counter['count']); + } + + if (isset($params['print'])) { + $print = (bool)$params['print']; + } else { + $print = empty($counter['assign']); + } + + if ($print) { + $retval = $counter['count']; + } else { + $retval = null; + } + + if (isset($params['skip'])) { + $counter['skip'] = $params['skip']; + } + + if (isset($params['direction'])) { + $counter['direction'] = $params['direction']; + } + + if ($counter['direction'] == "down") + $counter['count'] -= $counter['skip']; + else + $counter['count'] += $counter['skip']; + + return $retval; + +} + +/* vim: set expandtab: */ + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/plugins/function.cycle.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.cycle.php new file mode 100644 index 0000000000..fe78bb87da --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.cycle.php @@ -0,0 +1,102 @@ + + * Name: cycle
+ * Date: May 3, 2002
+ * Purpose: cycle through given values
+ * 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. + * + * Examples:
+ *
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * 
+ * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle} + * (Smarty online manual) + * @author Monte Ohrt + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat + * @version 1.3 + * @param array + * @param Smarty + * @return string|null + */ +function smarty_function_cycle($params, &$smarty) +{ + 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($cycle_vars[$name]['values'])) { + $smarty->trigger_error("cycle: missing 'values' parameter"); + return; + } + } else { + if(isset($cycle_vars[$name]['values']) + && $cycle_vars[$name]['values'] != $params['values'] ) { + $cycle_vars[$name]['index'] = 0; + } + $cycle_vars[$name]['values'] = $params['values']; + } + + $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['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']]); + } + + if($print) { + $retval = $cycle_array[$cycle_vars[$name]['index']]; + } else { + $retval = null; + } + + if($advance) { + if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { + $cycle_vars[$name]['index'] = 0; + } else { + $cycle_vars[$name]['index']++; + } + } + + return $retval; +} + +/* vim: set expandtab: */ + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/plugins/function.debug.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.debug.php new file mode 100644 index 0000000000..43452307bc --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.debug.php @@ -0,0 +1,35 @@ + + * Name: debug
+ * Date: July 1, 2002
+ * Purpose: popup debug window + * @link http://smarty.php.net/manual/en/language.function.debug.php {debug} + * (Smarty online manual) + * @author Monte Ohrt + * @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/gui/bacula-web/classes/external/smarty/libs/plugins/function.eval.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.eval.php new file mode 100644 index 0000000000..ff0472de25 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.eval.php @@ -0,0 +1,49 @@ + + * Name: eval
+ * Purpose: evaluate a template variable as a template
+ * @link http://smarty.php.net/manual/en/language.function.eval.php {eval} + * (Smarty online manual) + * @author Monte Ohrt + * @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/gui/bacula-web/classes/external/smarty/libs/plugins/function.fetch.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.fetch.php new file mode 100644 index 0000000000..81b1bfc6b9 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.fetch.php @@ -0,0 +1,221 @@ + + * Name: fetch
+ * Purpose: fetch file, web or ftp data and display results + * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} + * (Smarty online manual) + * @author Monte Ohrt + * @param array + * @param Smarty + * @return string|null if the assign parameter is passed, Smarty assigns the + * result to a template variable + */ +function smarty_function_fetch($params, &$smarty) +{ + if (empty($params['file'])) { + $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty"); + 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); + } + fclose($fp); + } else { + $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $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."'"); + 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; + } + break; + default: + $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'"); + 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; + } 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, "\r\n"); + while(!feof($fp)) { + $content .= fgets($fp,4096); + } + fclose($fp); + $csplit = split("\r\n\r\n",$content,2); + + $content = $csplit[1]; + + if(!empty($params['assign_headers'])) { + $smarty->assign($params['assign_headers'],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; + } + } + + } + + + if (!empty($params['assign'])) { + $smarty->assign($params['assign'],$content); + } else { + return $content; + } +} + +/* vim: set expandtab: */ + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_checkboxes.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_checkboxes.php new file mode 100644 index 0000000000..ed8ad7f33d --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_checkboxes.php @@ -0,0 +1,143 @@ + + * Type: function
+ * Name: html_checkboxes
+ * Date: 24.Feb.2003
+ * Purpose: Prints out a list of checkbox input types
+ * Input:
+ * - name (optional) - string default "checkbox" + * - values (required) - array + * - options (optional) - associative array + * - checked (optional) - array default not set + * - separator (optional) - ie
or   + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable + * Examples: + *
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='
' output=$names} + * {html_checkboxes values=$ids checked=$checked separator='
' output=$names} + *
+ * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt + * @version 1.0 + * @param array + * @param Smarty + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_checkboxes($params, &$smarty) +{ + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + + $name = 'checkbox'; + $values = null; + $options = null; + $selected = null; + $separator = ''; + $labels = true; + $output = null; + + $extra = ''; + + foreach($params as $_key => $_val) { + switch($_key) { + case 'name': + case 'separator': + $$_key = $_val; + break; + + case 'labels': + $$_key = (bool)$_val; + break; + + case 'options': + $$_key = (array)$_val; + break; + + case 'values': + case 'output': + $$_key = array_values((array)$_val); + break; + + case 'checked': + case 'selected': + $selected = array_map('strval', array_values((array)$_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; + break; + + case 'assign': + break; + + 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); + } + break; + } + } + + 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); + + + } 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); + } + + } + + if(!empty($params['assign'])) { + $smarty->assign($params['assign'], $_html_result); + } else { + return implode("\n",$_html_result); + } + +} + +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) { + $_output = ''; + if ($labels) $_output .= ''; + $_output .= $separator; + + return $_output; +} + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_image.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_image.php new file mode 100644 index 0000000000..9abae72ef7 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_image.php @@ -0,0 +1,142 @@ + + * Name: html_image
+ * Date: Feb 24, 2003
+ * Purpose: format HTML tags for the image
+ * Input:
+ * - 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: + * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} + * (Smarty online manual) + * @author Monte Ohrt + * @author credits to Duda - wrote first image function + * in repository, helped with lots of functionality + * @version 1.0 + * @param array + * @param Smarty + * @return string + * @uses smarty_function_escape_special_chars() + */ +function smarty_function_html_image($params, &$smarty) +{ + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); + + $alt = ''; + $file = ''; + $height = ''; + $width = ''; + $extra = ''; + $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'] : ''; + foreach($params as $_key => $_val) { + switch($_key) { + case 'file': + case 'height': + case 'width': + case 'dpi': + case 'path_prefix': + case 'basedir': + $$_key = $_val; + break; + + case 'alt': + 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); + } + break; + + case 'link': + case 'href': + $prefix = ''; + $suffix = ''; + break; + + default: + 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); + } + break; + } + } + + if (empty($file)) { + $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE); + return; + } + + if (substr($file,0,1) == '/') { + $_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); + return; + } else if(!is_readable($_image_path)) { + $smarty->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); + 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'])) { + $width = $_image_data[0]; + } + if(!isset($params['height'])) { + $height = $_image_data[1]; + } + + } + + if(isset($params['dpi'])) { + if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) { + $dpi_default = 72; + } else { + $dpi_default = 96; + } + $_resize = $dpi_default/$params['dpi']; + $width = round($width * $_resize); + $height = round($height * $_resize); + } + + return $prefix . ''.$alt.'' . $suffix; +} + +/* vim: set expandtab: */ + +?> diff --git a/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_options.php b/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_options.php new file mode 100644 index 0000000000..cebadde479 --- /dev/null +++ b/gui/bacula-web/classes/external/smarty/libs/plugins/function.html_options.php @@ -0,0 +1,122 @@ + + * Name: html_options
+ * Input:
+ * - 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