commit a68630bf3523414f97344e7e93058a54aef42ce7 Author: real_nowhereman Date: Tue Oct 30 10:30:07 2007 +0000 First revision of FlatPress Crescendo+1 ( 0.703+n :) ) diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..2359310 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,80 @@ +0703.1 Crescendo (July 10, 2007) +=============================== + +Small bug fixes +FIXED: bbcode: [u] tag missing +FIXED: bbcode/syntaxhighlighter: [code=MY_SYNTAX] works again +FIXED: fixed error handling with missing categories + + +0.703 Crescendo Final (June 27, 2007) +===================================== + +UPDATED: jsUtils : Mootools 1.11 +FIXED: URL issues with BBCODE +FIXED: small issues with thumb plugin + + +Crescendo RC2 (June 3, 2007) +============================ + +FIXED: spaces in file names are escaped as dashes "-" when uploaded +FIXED: various bbcode issues +FIXED: scale/width bbcode/thumb issues +MDFD: now thumb creates a .thumb dir for each subdir of images/ +FIXED: leggero CSS +FIXED: double entity encoding +ADDED: (since RC1): when loggedin trying to open a non-existent + static page will bring you to the "add new static" panel + + +Crescendo RC1 (May 29, 2007) +============================ + +FIXED: plugin/bbcode: broken non-local urls +FIXED: core/FPDB archive function: /?y=nn didn't work if a month wasn't specified +FIXED: core/entry/cache : buggy workarounded function (see previous) is now fixed +FIXED: core/users : session was not kept if user IP changed +FIXED: core/rss : template now works, fixed core accordingly +ADDED: core/rss : full content support +UPDATED: plugin/jsUtils, upgraded to mootools 1.1 +UPDATED: plugin/lightbox updated accordingly to slimbox 1.4 +RMVD: temporarily removed prettyurls plugin + (todo: remove from default config); + I'm working to a newer cooler version, but + it will require probably some changes in core, so no-go for this + release + +ADDED: Lang/it-it: added some strings I forgot + +Crescendo beta1 (May 17, 2007) +============================ + +added: some entry/cache hooks +added: many plugin translations thanx to cimangi (http://luielei.altervista.org/) +added: panel notifications for plugins +added: new theme, new icons (updated old admin css) +fixed: lightbox updated and fixed +fixed: removed quote escaping in entries (removed and added fix for old versions) +fixed: directory deletion under php5 (thx cimangi) +fixed: entry_delete did not remove visit counter (cimangi) +fixed: session retaining in control panel under certain conditions (smartyvalidate) +changed: some behaviours in cache; need some rework as introduced a little bug... d'oh! + + +Crescendo alpha +=============== + +fixed: utils_mail() +fixed: bbcode url trim +fixed: bbcode remote image timeouts +changed: WHOLE new POST behaviour (no longer "POSTDATA" messages) +changed: new theme tags (almost finished). support for old themes; soon deprecated +changed: graphics for the old theme (almost finished) +changed: a whole bunch of graphic thingies +changed: plugin organization +added: [video] tag support http://flatpress.nowhereland.it/index.php?entry=entry070210-211548 +added: update checker (experimental) +added: error/success notification system with fancy graphics :P + +NOTE: italian language is still there until the wiki is ready diff --git a/COPYING b/COPYING new file mode 100755 index 0000000..1a7a09e --- /dev/null +++ b/COPYING @@ -0,0 +1,300 @@ + + FlatPress, flat-file based blog platform + Copyright (C) 2006 Edoardo Vacchi (NoWhereMan) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/README b/README new file mode 100755 index 0000000..8b97df2 --- /dev/null +++ b/README @@ -0,0 +1,132 @@ + + +FLATPRESS README (or "the file that nobody reads except who writes") (draft 1) +============================================================================== + + + +## 1. WHAT THE FLATPRESS? + +First of all, let me thank you for choosing my FlatPress. I hope you'll +enjoy using it as I (almost) enjoyed writing it :) + +FlatPress is a brand new blogging platform under heavy development. + +Now, you may be like: «Another blog?? Who the heck would need that?». + + + +## 2. WHO THE HECK NEED THAT? + +Oh-kay, FP is flat-file based. This means *it doesn't require databases*. +Actually all the content in stored in text files, so you don't need +MySQL if you can't afford an hosting service which can provide that to you. + + + +## 3. COOL. I STILL DON'T SEE WHY I SHOULD USE IT + +«...as I could use SimplePHPBlog, Pivot, etc...». +Good question. FlatPress was born as an extension to SPB. +But let's clear the things out + +1. This is not a _fork_: we didn't take the SPB code and edited it; +2. This is not a rewrite: we didn't take SPB concept and reinvented its wheel + +This is a *new* project, which inherits from SPB just its *storing system*. +This means you can take your content/, images/ dirs from your SPB installation, +put them in FP's fp-content/ dir as they are, and, once installed, it should +almost work out-of-the-box. This is the aim. + +Note that we don't want every single SPB user to switch to FP, it's just +that, as a SPB user myself, I wanted an easy way to switch from that to my project +and by the way its storing system is not bad at all :) + + + +## 4. IF IT'S NOT THAT BAD, WHY THIS REWRITE? + +As I said, this *IS NOT* a rewrite. This is a new blog. +At the time we (I) started this project SPB lacked some features, it +wasn't W3C standard-compliant and, above all, it was obviously a pain +to upgrade if you had made many changes to the code. + +So the most important lacks were a plugin system and a little more +flexible theming engine. + +FlatPress uses the same plugin system of WordPress. +Beware: this doesn't mean you will be able to use any of the WordPress +plugins without any effort. Only a few of the plugin "hooks" have been +implemented (search the sources for apply_filters and do_action to know which ones). + +Also FlatPress uses the famous Smarty template engine for the themes (the +same of PhpBB). + +Of course, this now will sound great (and quite conceited), then remember +1. This is my first complete work in PHP +2. It's unfinished :) + + + +## 5. ANYWAY, IT SOUNDS PRETTY DECENT, HOW DO I GET IT TO WORK? + +OK, let's see what it will take you to run the fruit of my sweat +(sounds juicy, doesn't it? Yech!). + +A basic Apache+PHP system as a server should work. It has been small tested on IIS, +too. If you experience any problem, just let me know (be detailed describing the problem). +As I said, no need for databases. Anyway I must ask for a +version of PHP >= 4.3.0. I can't tell if it will work on older versions +so if it something is going wrong, first check this :) + +Unpack the .tar.bz2 you downloaded from the main site (probably +http://flatpress.nowhereland.it/) and http://flatpress.nowhereland.it/downloads/) +and then upload it on your webserver (or test it locally). + +Point your browser to http://yoursite.com/flatpress/ and just follow +*carefully* the istructions :p + + + +## 6. FINAL WARNING AND GOODBYE + +This you're using (or you're about to use) is intended as a TEST version; +it should be very stable, but it if it ever blew your PC up, just +remember you'd been told. + +Kidding. + +People tell me I'm quite unprofessional presenting this project. +You'll see why when you'll install FlatPress for the first time... +If that won't make your day, I just hope to make you smile :) + +Once you're ready tell us what you think on the main site; any +feedback is appreciated! + + + +## CREDITS + +I want to thank here some people that helped (and are helping) me with +this project. + +Hydra, betatester, small-coder, and official cheerleader :D +drudo, theme designer, supporter, space and time provider + +Other thanks to giulio and alcor for their precious advice. + +As an additional note, I'd like to thank also Tychondriax +another friend of mine who occasionally helps me with betasting +and bug-discovering :) + +Thank you all, guys, without you I would have already given up. + + + +Edoardo Vacchi (NoWhereMan), August, 2 2006 + +email: real_nowhereman at users dot sf dot net +www: http://www.nowhereland.it +flatpress home: http://flatpress.nowhereland.it + + diff --git a/TESTING b/TESTING new file mode 100755 index 0000000..701a938 --- /dev/null +++ b/TESTING @@ -0,0 +1 @@ +This is a test version and it's not intended for production. diff --git a/admin.php b/admin.php new file mode 100755 index 0000000..80194b9 --- /dev/null +++ b/admin.php @@ -0,0 +1,8 @@ + diff --git a/admin/admin-inline.tpl b/admin/admin-inline.tpl new file mode 100644 index 0000000..648f24a --- /dev/null +++ b/admin/admin-inline.tpl @@ -0,0 +1,33 @@ + + + + {$flatpress.title}{$pagetitle} + + {action hook=wp_head} + + + + + {if $submenu} + + {/if} + + + {include file=$admin_resource|default:"admin:$panel/$action"} + + + diff --git a/admin/imgs/config.png b/admin/imgs/config.png new file mode 100755 index 0000000..df9b2dc Binary files /dev/null and b/admin/imgs/config.png differ diff --git a/admin/imgs/entries.png b/admin/imgs/entries.png new file mode 100755 index 0000000..54d9eed Binary files /dev/null and b/admin/imgs/entries.png differ diff --git a/admin/imgs/maintain.png b/admin/imgs/maintain.png new file mode 100755 index 0000000..6d0e32b Binary files /dev/null and b/admin/imgs/maintain.png differ diff --git a/admin/imgs/newentry.png b/admin/imgs/newentry.png new file mode 100755 index 0000000..478ca69 Binary files /dev/null and b/admin/imgs/newentry.png differ diff --git a/admin/imgs/plugins.png b/admin/imgs/plugins.png new file mode 100755 index 0000000..632b872 Binary files /dev/null and b/admin/imgs/plugins.png differ diff --git a/admin/imgs/widgets.png b/admin/imgs/widgets.png new file mode 100755 index 0000000..3acb221 Binary files /dev/null and b/admin/imgs/widgets.png differ diff --git a/admin/includes/panels.prototypes.php b/admin/includes/panels.prototypes.php new file mode 100644 index 0000000..011677a --- /dev/null +++ b/admin/includes/panels.prototypes.php @@ -0,0 +1,251 @@ +false); + var $defaultaction = 'default'; + + var $actionpanel = null; + + + function AdminPanel(&$smarty) { + $this->smarty =& $smarty; + if (!$this->panelname) + trigger_error("Variable \$panelname is not defined!", E_USER_ERROR); + + + + /* get plugin panels */ + $plugactions = admin_getpanelactions($this->panelname); + + /* add plugged actions to system-defined */ + $this->actions = array_merge($this->actions, $plugactions); + + /* if # actions > 1 we won't show it in the submenu bar */ + /* this is just for aesthetics ;) */ + if ((count($this->actions) > 1) && in_array(true, $this->actions)) + $this->smarty->assign('submenu', $this->actions); + + + } + + + + function &get_action(&$action) { + + if (!$action) + $action = $this->defaultaction; + + $obj = null; + + if (!isset($this->actions[$action])) { + // trigger_error("$action: + // No such an action was defined", E_USER_ERROR); + $action = $this->defaultaction; + } + + $this->smarty->assign('actionname', $action); + + $class = get_class($this) . "_$action"; + + if (!class_exists($class)) { + + $f = str_replace('_','.',$class); + + $fname = ADMIN_DIR . "panels/{$this->panelname}/$f.php"; + + + if (file_exists($fname)) { + include($fname); + + if (!class_exists($class)) { + trigger_error("No classes for action $action.", E_USER_ERROR); + } + + $obj =& new $class($this->smarty); + return $obj; + + } else trigger_error("No script found for action $action", E_USER_ERROR); + + } else { + $obj =& new $class($this->smarty); + } + + return $obj; + } + + } + + class AdminPanelAction { + + var $actionname = null; + var $smarty = null; + var $events = array(); + var $commands = array(); + + var $langres = ''; + + function AdminPanelAction(&$smarty) { + $this->smarty =& $smarty; + $the_action_panel = get_class($this); + $this->smarty->assign('admin_panel_id', $the_action_panel); + if (!$this->langres) + $this->langres = 'admin.' . ADMIN_PANEL ; + } + + function exec() { + + $this->setup(); + $result = 0; // if !=0, defaultaction for this panel is called + + if (empty($_POST)) { + if ($this->commands) { + foreach($this->commands as $cmd) { + if (isset($_GET[ $cmd ])) { + return $this->docommand($cmd, $_GET[ $cmd ]); + } + } + } + + $result = $this->main(); + lang_load($this->langres); + + } else { + $result = $this->onsubmit(); + } + + return $result; + + + } + + function setup() { + + } + + function main() { + return 0; + } + + /** + * Method onsubmit
+ * + * @return int values: + * 1. if you want main() method to be called; + * 2. if you want main() method of the defaultaction + * 0. if you don't want any further action to be called + * + */ + + function onsubmit() { + + $returnvalue = 1; + $valid_evts = array_intersect(array_keys($_POST), $this->events); + + if ($the_event=array_pop($valid_evts)) { + $event = "on{$the_event}"; + if (method_exists($this, $event)) + $returnvalue = call_user_func(array(&$this, $event)); + } + + return $returnvalue; + + } + + function docommand($the_cmd, $the_val) { + + global $panel, $action; + + check_admin_referer("admin_{$panel}_{$action}_{$the_cmd}_{$the_val}"); + $cmd = "do{$the_cmd}"; + + if (method_exists($this, $cmd)) + return call_user_func(array(&$this, $cmd), $the_val); + + return 1; + } + + + } + + class AdminPanelActionValidated extends AdminPanelAction { + + var $validators = array(); + + function exec() { + + if (empty($_POST)) + SmartyValidate::disconnect($this->smarty); + + $form_id = get_class($this); + + SmartyValidate::connect($this->smarty); + if (!SmartyValidate::is_registered_form($form_id)) + SmartyValidate::register_form($form_id); + + $this->setup(); + + $retval = 0; + + if (empty($_POST)) { + if ($validators =& $this->validators) { + foreach ($validators as $validator) { + $validator[6]=$form_id; + call_user_func_array(array('SmartyValidate', 'register_validator'), $validator); + } + } + + if ($this->commands) { + foreach($this->commands as $cmd) { + if (isset($_GET[ $cmd ])) { + return $this->docommand($cmd); + } + } + } + + lang_load($this->langres); + $retval = $this->main(); + } else { + $retval = $this->onsubmit(); + } + + return $retval; + + } + + + function onsubmit() { + $result = 0; + + if(SmartyValidate::is_valid($_POST, get_class($this))) { + $result = parent::onsubmit(); + } else $result = $this->onerror(); + + return $result; + + } + + function onerror() { + return true; + } + + + } + + + +?> \ No newline at end of file diff --git a/admin/index.php b/admin/index.php new file mode 100755 index 0000000..db0b4f9 --- /dev/null +++ b/admin/index.php @@ -0,0 +1,20 @@ + + + + + + FlatPress + + + + +

Not Authorized

+

You're not allowed to browse this folder.

+

Back to home page.

+ + + diff --git a/admin/main.php b/admin/main.php new file mode 100755 index 0000000..ff2d499 --- /dev/null +++ b/admin/main.php @@ -0,0 +1,193 @@ +assign('panel', $panel); + + if (!admin_panelexists($panel)) + trigger_error('Requested panel does not exists!', E_USER_ERROR); + + + $panelprefix = "admin.$panel"; + $panelpath = ADMIN_DIR."panels/$panel/$panelprefix.php"; + + + $fp_admin = null; + + if (file_exists($panelpath)) { + + include($panelpath); + $panelclass = "admin_$panel"; + + if (!class_exists($panelclass)) + trigger_error("No class defined for requested panel", E_USER_ERROR); + + $fp_admin =& new $panelclass($smarty); + + } + + $action = isset($_GET['action'])? $_GET['action'] : 'default'; + if (!$fp_admin) + return; + + $fp_admin_action =& $fp_admin->get_action($action); + + + define('ADMIN_PANEL_ACTION', $action); + $smarty->assign('action', $action); + $panel_url = BLOG_BASEURL . "admin.php?p={$panel}"; + $action_url = $panel_url . "&action={$action}"; + $smarty->assign('panel_url', $panel_url); + $smarty->assign('action_url', $action_url); + + /* check if user is loggedin */ + + if (!user_loggedin()) { + utils_redirect("login.php"); + die(); + } + + if (!empty($_POST)) + check_admin_referer("admin_{$panel}_{$action}"); + + + + + $smarty->assign('success', sess_remove("success_{$panel}")); + $retval = $fp_admin_action->exec(); + + if ($retval > 0) { + // clear postdata by a redirect + + sess_add("success_{$panel}", $smarty->get_template_vars('success')); + $smarty->get_template_vars('success'); + + $to_action = $retval > 1 ? ('&action=' . $action) : ''; + $with_mod = isset($_GET['mod'])? ('&mod=' . $_GET['mod']) : ''; + + utils_redirect("admin.php?p={$panel}{$to_action}{$with_mod}"); + + } + + $smarty->register_modifier('action_link', 'admin_filter_action'); + $smarty->register_modifier('cmd_link', 'admin_filter_command'); + + } + + function admin_filter_action($string, $action) { + if (strpos($string, '?')===false) + return $string .= "?action={$action}"; + else + return $string .= wp_specialchars("&action={$action}"); + } + + function admin_filter_command($string, $cmd, $val) { + + global $panel, $action; + + $arg = $cmd? "&{$cmd}" : $cmd; + + return wp_nonce_url("{$string}{$arg}={$val}", "admin_{$panel}_{$action}_{$cmd}_{$val}"); + + } + + + function admin_panelstrings($panelprefix) { + + global $lang, $smarty; + + lang_load('admin'); + lang_load($panelprefix); + + $smarty->assign('subject', $lang['admin']['head']); + $smarty->assign('menubar', admin_getpanels()); + + add_filter('wp_title', 'admin_panel_title', 10, 2); + } + + function admin_panel_title($title, $sep) { + + global $lang, $panel; + + $t = @$lang['admin']['panels'][$panel]; + $title = "$title $sep $t"; + return $title; + } + + + + function showcontrolpanel($params, &$smarty) { + $smarty->display(ABS_PATH. ADMIN_DIR . 'main.tpl'); + } + + // html header + + function admin_title($title, $sep) { + global $lang; + return $title = "$title $sep {$lang['admin']['head']}"; + } + + add_filter('wp_title', 'admin_title', 10, 2); + + + $fp_config = config_load(); + system_init(); + main(); + admin_panelstrings('admin.'.ADMIN_PANEL); + theme_init($smarty); + $smarty->register_function('controlpanel', 'showcontrolpanel'); + + $v =& $lang['admin'][$panel][$action]; + + + $smarty->assign_by_ref('panelstrings', $v); + $smarty->assign_by_ref('plang', $v); + + + if (isset($_GET['mod'])) { + + switch ($_GET['mod']) { + case 'inline' : + $smarty->display(ABS_PATH . ADMIN_DIR . 'admin-inline.tpl'); + break; + case 'ajax' : + echo $smarty->get_template_vars('success'); + } + + } else { + $smarty->display('admin.tpl'); + } + + +?> diff --git a/admin/main.tpl b/admin/main.tpl new file mode 100755 index 0000000..d932613 --- /dev/null +++ b/admin/main.tpl @@ -0,0 +1,39 @@ + + + + {if $submenu} + + {/if} + +
+ {include file=$admin_resource|default:"admin:$panel/$action"} + +
diff --git a/admin/panels/admin.defaultpanels.php b/admin/panels/admin.defaultpanels.php new file mode 100755 index 0000000..eeb213c --- /dev/null +++ b/admin/panels/admin.defaultpanels.php @@ -0,0 +1,24 @@ + diff --git a/admin/panels/config/admin.config.php b/admin/panels/config/admin.config.php new file mode 100755 index 0000000..88ab315 --- /dev/null +++ b/admin/panels/config/admin.config.php @@ -0,0 +1,115 @@ +smarty->assign('themes', theme_list()); + $this->smarty->assign('lang_list', lang_list()); + + $static_list = array(); + + foreach(static_getlist() as $id) { + $static_list[$id] = static_parse($id); + } + + $this->smarty->assign('static_list', $static_list); + + } + + + function onsave() { + + global $fp_config; + $l = explode(',',$_POST['lang']); + $fp_config['general'] = array( + //'BLOG_ROOT' => $_POST['blog_root'], + 'www' => $_POST['www'], + 'title' => html_entity_decode(stripslashes($_POST['title'])), + 'subtitle' => html_entity_decode(stripslashes($_POST['subtitle'])), + 'footer' => html_entity_decode(stripslashes($_POST['blogfooter'])), + 'author' => $_POST['author'], + 'email' => $_POST['email'], + 'startpage' => ($_POST['startpage'] == ':NULL:')? null : $_POST['startpage'], + 'maxentries' => $_POST['maxentries'], + // 'voting' => $_POST['voting'], + 'notify' => isset($_POST['notify']), + /* preserve the following */ + 'theme' => $fp_config['general']['theme'], + 'style' => @$fp_config['general']['style'], + 'blogid' => $fp_config['general']['blogid'], + + 'lang' => 'en-us', + 'charset'=> 'utf-8', + + ); + + $fp_config['locale'] = array( + 'timeoffset' => $_POST['timeoffset'], + 'timeformat' => $_POST['timeformat'], + 'dateformat' => $_POST['dateformat'], + 'charset' => $_POST['charset'], + 'lang' => $_POST['lang'] + ); + + + // 'LANG' => $l[0], + // 'CHARSET'=> $l[1], + + + + + + $success = config_save()? 1: -1; + + $this->smarty->assign('success', $success); + + return 1; + + } + + function onerror() { + $this->main(); + return 0; + } + + function cleartplcache() { + // if theme was switched, clear tpl cache + + $tpl =& new tpl_deleter(); + + $tpl->getList(); + + + } + + } + +?> diff --git a/admin/panels/config/admin.config.tpl b/admin/panels/config/admin.config.tpl new file mode 100755 index 0000000..227b248 --- /dev/null +++ b/admin/panels/config/admin.config.tpl @@ -0,0 +1,147 @@ + +{validate_init form=$admin_panel_id} + +{validate id="www" message=$panelstrings.error.www append="error"} + +{validate id="title" message=$panelstrings.error.title append="error"} +{validate id="email" message=$panelstrings.error.email append="error"} +{validate id="maxentries" message=$panelstrings.error.maxentries append="error"} + +{validate id="timeoffset" message=$panelstrings.error.maxentries append="error"} +{validate id="timeformat" message=$panelstrings.error.maxentries append="error"} +{validate id="dateformat" message=$panelstrings.error.maxentries append="error"} +{validate id="lang" message=$panelstrings.error.maxentries append="error"} +{validate id="charset" message=$panelstrings.error.maxentries append="error"} + +{include file='shared:errorlist.tpl'} + +{html_form} + + +
+ +
+ +

{$panelstrings.gensetts}

+ +
+
+
+
+ + +
+
+ +
+
+ +
+
+ + +
+
+ + +
+
+ +
{$panelstrings.notifications}
+
+ +
+ +
+
+
+ +
+
+ + +
+ +
+ +
+ +

{$panelstrings.intsetts}

+ +
+
{$panelstrings.utctime}
+ {assign var=temp_time value="%b %d %Y %H:%M:%S"} +
{"r"|date:$smarty.now}
+ +
+
{$panelstrings.hours} +
+ + +
+

+

{$panelstrings.output}: {$smarty.now|date_format:$fp_config.locale.dateformat}

+
+ +
+

+

{$panelstrings.output}: {$smarty.now|date_format:$fp_config.locale.timeformat}

+
+ + +
+
+ +
+ +
+

+

{$panelstrings.charsettip}

+
+ + +
+ +
+ +
+ +
+{html_submit name="save" id="save" value=$panelstrings.submit} +
+ + +{/html_form} + + diff --git a/admin/panels/entry/admin.entry.cats.php b/admin/panels/entry/admin.entry.cats.php new file mode 100755 index 0000000..e241063 --- /dev/null +++ b/admin/panels/entry/admin.entry.cats.php @@ -0,0 +1,61 @@ + + * + */ + + + class admin_entry_cats extends AdminPanelActionValidated { + + var $validators = array(array('content', 'content', 'notEmpty', false, false, 'trim,stripslashes')); + var $events = array('save'); + + + function main() { + + if (isset($_GET['do']) && $_GET['do'] == 'clear') { + $ret1 = fs_delete(CONTENT_DIR . 'categories_encoded.dat') && + $ret2 = fs_delete(CONTENT_DIR . 'categories.txt'); + + $ret = ($ret1 && $ret2) ? 2 : -2; + + $this->smarty->assign('success', $ret); + } + + if (file_exists(CONTENT_DIR . 'categories.txt')) { + $cats = io_load_file(CONTENT_DIR . 'categories.txt'); + $this->smarty->assign('catdefs', $cats); + } + + do_action('update_categories', true); + + return 0; + + + } + + + function onsave() { + + $str=(stripslashes($_POST['content'])); + $success = io_write_file(CONTENT_DIR . 'categories.txt', $str); + entry_categories_encode(); + $this->smarty->assign('success', ( $success )? 1 : -1 ); + $this->smarty->assign('catdefs', $str); + + return PANEL_REDIRECT_CURRENT; + + } + + } + + ?> diff --git a/admin/panels/entry/admin.entry.cats.tpl b/admin/panels/entry/admin.entry.cats.tpl new file mode 100755 index 0000000..899b6ac --- /dev/null +++ b/admin/panels/entry/admin.entry.cats.tpl @@ -0,0 +1,27 @@ +{validate_init form=$admin_panel_id} +{validate id="content" message=$panelstrings.error.content append="error"} + +

{$panelstrings.head}

+{include file=shared:errorlist.tpl} + + +{$panelstrings.descr} + +

{$panelstrings.clear}

+ + + +{html_form} + +

+
+

+ + +
+ + {html_submit name="save" id="save" value=$panelstrings.submit} + +
+ +{/html_form} diff --git a/admin/panels/entry/admin.entry.commentlist.php b/admin/panels/entry/admin.entry.commentlist.php new file mode 100755 index 0000000..220f51e --- /dev/null +++ b/admin/panels/entry/admin.entry.commentlist.php @@ -0,0 +1,45 @@ + + * + */ + + + class admin_entry_commentlist extends AdminPanelAction { + + var $commands = array('delete'); + + function dodelete($commentid) { + $this->smarty->assign('success', + comment_delete($_GET['entry'], $commentid)? 6 : -6 + ); + return PANEL_REDIRECT_CURRENT; + } + + function main() { + global $fpdb; + if (isset($_GET['entry'])) { + + $fpdb->query("id:{$_GET['entry']},fullparse:true"); + + return 0; + + + } + + + return 1; + + } + } + +?> diff --git a/admin/panels/entry/admin.entry.commentlist.tpl b/admin/panels/entry/admin.entry.commentlist.tpl new file mode 100755 index 0000000..26a7733 --- /dev/null +++ b/admin/panels/entry/admin.entry.commentlist.tpl @@ -0,0 +1,60 @@ + +{entry_block} +{entry} + +

{$panelstrings.head} {$subject}

+{include file=shared:errorlist.tpl} + +

{$panelstrings.descr}

+ + + +{comment_block} + +{html_form} + + + + + + + + + + + + +{comment} + +{**} + + + + + + + +{/comment} +
{$panelstrings.date}{$panelstrings.content}{$panelstrings.author}{$panelstrings.email}{$panelstrings.ip}{$panelstrings.actions}
{$date|date_format:"%D, %T"} +{$content|strip_tags|truncate:70} +{if $url}{$name}{else}{$name}{/if}{$email}{$ip_address} +{$plang.act_del} +
+{/html_form} + +{/comment_block} + +{/entry} +{/entry_block} + + + + + diff --git a/admin/panels/entry/admin.entry.conf.php b/admin/panels/entry/admin.entry.conf.php new file mode 100755 index 0000000..2b2e9c1 --- /dev/null +++ b/admin/panels/entry/admin.entry.conf.php @@ -0,0 +1,26 @@ + + * + */ + + + $admin_entry_sections = array( + 'list', + 'new', + 'edit', + 'delete', + 'comms', + 'commsdel' + ); + +?> diff --git a/admin/panels/entry/admin.entry.delete.php b/admin/panels/entry/admin.entry.delete.php new file mode 100755 index 0000000..ba52278 --- /dev/null +++ b/admin/panels/entry/admin.entry.delete.php @@ -0,0 +1,62 @@ + + * + */ + + + class admin_entry_delete extends AdminPanelAction { + + var $events = array('delete', 'cancel'); + + function main() { + global $fpdb; + + if (isset($_REQUEST['entry'])){ + $id = $_REQUEST['entry']; + if ($a = entry_parse($id)); + else + $a = draft_parse($id); + + if ($a) { + + if (THEME_LEGACY_MODE) { + theme_entry_filters($a, $id); + } + + $this->smarty->assign('entry', $a); + $this->smarty->assign('id', $id); + return 0; + + } + } + + return 1; + + } + + + function ondelete() { + $id=$_REQUEST['entry']; + $ok=draft_delete($id) || entry_delete($id); + + $success = $ok? 2 : -2; + $this->smarty->assign('success',$success); + return 1; + } + + function oncancel() { + return 1; + } + + } +?> diff --git a/admin/panels/entry/admin.entry.delete.tpl b/admin/panels/entry/admin.entry.delete.tpl new file mode 100755 index 0000000..ef5049b --- /dev/null +++ b/admin/panels/entry/admin.entry.delete.tpl @@ -0,0 +1,19 @@ +

{$panelstrings.head}

+ +

{$panelstrings.descr}

+ + {entry_block} + {html_form} +
{$panelstrings.preview} + {include file=preview.tpl} +
+

{$panelstrings.confirm}

+ + +
+ {html_submit name="delete" id="delete" value=$panelstrings.ok} + {html_submit name="cancel" id="cancel" value=$panelstrings.cancel} +
+ {/html_form} + {/entry_block} + diff --git a/admin/panels/entry/admin.entry.list.php b/admin/panels/entry/admin.entry.list.php new file mode 100755 index 0000000..7462b99 --- /dev/null +++ b/admin/panels/entry/admin.entry.list.php @@ -0,0 +1,92 @@ + + * + */ + + + //require (ADMIN_DIR . 'panels/entry/shared.entry.form.php'); + + + // --------------------------------------------------------------------- + // utils + // --------------------------------------------------------------------- + + + function smarty_function_flag_classes($params, &$smarty) { + $flags = entry_flags_get(); + ($active_flags = array_intersect( + $smarty->get_template_vars('categories'), $flags)); + return implode(' ', $active_flags); + } + + + class admin_entry_list extends AdminPanelActionValidated { + + + var $actionname = 'list'; + + + function setup() { + $this->smarty->register_function('flag_classes', 'smarty_function_flag_classes'); + + } + + function main() { + parent::main(); + //$smarty =& $this->smarty; + + // parameters for the list + // start offset and count (now defaults to 8...) + + $this->smarty->assign('categories_all', entry_categories_get('defs')); + $this->smarty->assign('saved_flags', entry_flags_get()); + + $defcount = 8; // <-- no magic numbers! todo: add config option? + + global $fpdb; + + if (!empty($_REQUEST['entry'])) + utils_redirect('admin.php?p=entry&action=write&entry='.$_REQUEST['entry']); + + isset($_REQUEST['m'])? $params['m'] = $_REQUEST['m'] : null; + isset($_REQUEST['y'])? $params['y'] = $_REQUEST['y'] : null; + // $params['start'] = isset($_REQUEST['start'])? $_REQUEST['start'] : 0; + $params['count'] = isset($_REQUEST['count'])? $_REQUEST['count'] : $defcount; + $params['page'] = isset($_REQUEST['paged'])? $_REQUEST['paged'] : 1; + isset($_REQUEST['category'])? $params['category'] = $_REQUEST['category'] : $params['category'] = 'all'; + $params['fullparse']=true; + $fpdb->query($params); + + return 0; + } + + + function onsubmit() { + parent::onsubmit(); + return $this->main(); + } + + + function onfilter() { + return $this->main(); + } + + function onerror() { + return $this->main(); + } + + + } + + +?> diff --git a/admin/panels/entry/admin.entry.list.tpl b/admin/panels/entry/admin.entry.list.tpl new file mode 100755 index 0000000..e89427e --- /dev/null +++ b/admin/panels/entry/admin.entry.list.tpl @@ -0,0 +1,95 @@ + +

{$panelstrings.head}

+ + + +{draft_block} +
+

Your drafts:

+ +
+ +{/draft_block} + + + +{include file=shared:errorlist.tpl} + +

{$panelstrings.descr}

+ +{html_form} + + +
{$panelstrings.filter} + + {html_submit name='filter' id='filter' class="alignright" value=$panelstrings.filterbtn} +
+ + +{entry_block} + + +{**} + + + + + + +{entry} + + + + + + + + + +{/entry} + +
{$panelstrings.sel}{$panelstrings.date}{$panelstrings.title}{$panelstrings.author}{$panelstrings.comms}{$panelstrings.action}
{$date|date_format:"%D, %T"} +{if in_array('draft',$categories)} +({$lang.entry.flags.short.draft}) +{/if} +{$subject|truncate:70} +{$author} +{* Compatibility with pre-0.702 *} +{$commentcount|default:$comments} + +{$panelstrings.act_view} + + +{$panelstrings.act_edit} + + +{$panelstrings.act_del} + + +
+ + +{/entry_block} + + +{/html_form} \ No newline at end of file diff --git a/admin/panels/entry/admin.entry.php b/admin/panels/entry/admin.entry.php new file mode 100755 index 0000000..c23a11c --- /dev/null +++ b/admin/panels/entry/admin.entry.php @@ -0,0 +1,36 @@ + + * + */ + + + class admin_entry extends AdminPanel { + + var $panelname = "entry"; + var $actions = array( + 'list' => true, + 'write' => true, + 'commentlist' => false, + 'delete' => false, + 'cats' => true, + 'stats' => false + ); + var $defaultaction = 'list'; + + } + + + + + +?> diff --git a/admin/panels/entry/admin.entry.stats.php b/admin/panels/entry/admin.entry.stats.php new file mode 100644 index 0000000..4267406 --- /dev/null +++ b/admin/panels/entry/admin.entry.stats.php @@ -0,0 +1,138 @@ + + * + */ + + class admin_entry_stats extends AdminPanelAction { + + function format_number($num, $sep) { + $ss = $sep*$sep; + $i = 0; + while ( $num > $ss ) { + $num = (float) $num / $sep; + $i++; + } + + return array(number_format((int)$num), $i); + + } + + function main() { + + global $fpdb; + + $fpdb->query(array( + 'count' => -1, // show all + 'fullparse' => true + )); + + $q = $fpdb->getQuery(); + + $comments = + $entries = array( + 'count' => 0, + 'words' => 0, + 'chars' => 0, + 'size' => 0, + 'topten' => array() + ); + + $entries['comments'] = 0; + + $toplist = array(); + + while ($q->hasMore()) { + + list($id, $e) = $q->getEntry(); + + $entries['count']++; + $entries['words'] += str_word_count($e['subject']) + + str_word_count($e['content']); + + $entries['chars'] += strlen($e['subject']) + + strlen($e['content']); + + $entries['size'] += filesize(entry_exists($id)); + + $cc = $q->hasComments(); + $entries['comments'] += $cc; + $toplist[$id] = $cc; + $toplistsubj[$id] = $e['subject']; + + $comments['count']+= $cc; + + while ($q->comments->hasMore()) { + list($cid, $c) = $q->comments->getComment(); + $comments['words'] += str_word_count($c['content']); + $comments['chars'] += strlen($c['content']); + $comments['size'] += filesize(comment_exists($id, $cid)); + } + + } + + arsort($toplist); + + $i = 0; + foreach($toplist as $k=>$v) { + if ($i>=10 || $v < 1) + break; + + $entries['topten'][$k] = array( + 'subject' => $toplistsubj[$k], + 'comments' => $v + ); + $i++; + } + + $decunit = array('', 'Thousand', 'Million', 'Billion', 'Trillion', 'Zillion', 'Gazillion'); + $binunit = array('Bytes', 'KiloBytes', 'MegaBytes', 'GigaBytes', 'TeraBytes', 'Many', 'ManyBytes'); + + + list($count, $approx) = $this->format_number($entries['count'], 1000); + $entries['count'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($entries['words'], 1000); + $entries['words'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($entries['chars'], 1000); + $entries['chars'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($entries['comments'], 1000); + $entries['comments'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($entries['size'], 1024); + $entries['size'] = $count .' '. $binunit[$approx]; + + + $this->smarty->assign('entries', $entries); + + + + list($count, $approx) = $this->format_number($comments['count'], 1000); + $comments['count'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($comments['words'], 1000); + $comments['words'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($comments['chars'], 1000); + $comments['chars'] = $count .' '. $decunit[$approx]; + + list($count, $approx) = $this->format_number($comments['size'], 1024); + $comments['size'] = $count .' '. $binunit[$approx]; + + + $this->smarty->assign('comments', $comments); + + } + + } diff --git a/admin/panels/entry/admin.entry.stats.tpl b/admin/panels/entry/admin.entry.stats.tpl new file mode 100644 index 0000000..bf4d9bf --- /dev/null +++ b/admin/panels/entry/admin.entry.stats.tpl @@ -0,0 +1,29 @@ +

{"Statistics"}

+ +

{"Entries"}

+{"

You have %s +entries using %s characters +in %s words.

+

Total disk space is +%s.

"|sprintf:$entries.count:$entries.chars:$entries.words:$entries.size} + +

{"Comments"}

+{"

You have %s +comments using %s characters +in %s words.

+

Total disk space is +%s.

"|sprintf:$comments.count:$comments.chars:$comments.words:$comments.size} + + +{if $entries.topten} + +

{$entries.topten|@count} {"most commented entries"}

+ +
    +{foreach from=$entries.topten key=id item=this_entry} +
  1. {$this_entry.subject} ({$this_entry.comments})
  2. +{/foreach} +
+ +{/if} + diff --git a/admin/panels/entry/admin.entry.tpl b/admin/panels/entry/admin.entry.tpl new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/admin/panels/entry/admin.entry.tpl @@ -0,0 +1 @@ + diff --git a/admin/panels/entry/admin.entry.write.php b/admin/panels/entry/admin.entry.write.php new file mode 100755 index 0000000..ddd6c3a --- /dev/null +++ b/admin/panels/entry/admin.entry.write.php @@ -0,0 +1,176 @@ + + * + */ + + + + + class admin_entry_write extends AdminPanelActionValidated { + + var $validators = array( + array('subject', 'subject', 'notEmpty', false, false, 'trim,stripslashes'), + array('content', 'content', 'notEmpty', false, false, 'stripslashes'), + ); + + var $events = array('save', 'preview', 'savecontinue'); + + function _makePreview($arr, $id=null) { + + $arr['subject'] = apply_filters('title_save_pre', $arr['subject']); + $arr['content'] = apply_filters('content_save_pre', $arr['content']); + + + $this->smarty->assign('post', $arr); + + if (THEME_LEGACY_MODE) { + theme_entry_filters($arr, $id); + } + + $arr = array_change_key_case($arr, CASE_LOWER); + + $this->smarty->assign('entry', $arr); + $this->smarty->assign('preview', true); + + } + + function makePageTitle($title, $sep) { + global $lang; + return "$title $sep {$lang['admin']['entry']['write']['head']}"; + } + + function _getCatsFlags() { + + //$this->smarty->assign('saved_categories', entry_categories_format()); + $this->smarty->assign('saved_flags', entry_flags_get()); + + } + + function setup() { + + $this->id = @$_REQUEST['entry']; + $this->smarty->assign('id', $this->id); + + + } + + function main() { + + global $lang; + + $id = $this->id; + + if (isset($_REQUEST['entry'])) { + + $arr = draft_parse($id); + + if (!$arr) + $arr = entry_parse($id); + else + $this->smarty->assign('draft', true); + + // if entry does not exists + if ($arr) { + $this->_makePreview($arr, $id); + } + + } + + $this->_getCatsFlags(); + add_filter('wp_title', array(&$this, 'makePageTitle'), 10, 2); + + } + + function _getposteddata() { + + $arr['version'] = system_ver(); + $arr['subject'] = ($_POST['subject']); + $arr['content'] = ($_POST['content']); + $author = user_get(); + $arr['author'] = $author['userid']; + $arr['date'] = !empty($_POST['timestamp'])?$_POST['timestamp']:date_time(); + + $cats = !empty($_POST['cats'])?$_POST['cats']:array(); + $flags = !empty($_POST['flags'])?$_POST['flags']:array(); + + $catids = array_merge(array_keys($flags), array_keys($cats)); + + if ($catids) + $arr['categories'] = $catids; + + return $arr; + + } + + function onsave($do_preview = false) { + + $id = $this->id; + $data = $this->_getposteddata(); + + if (isset($data['categories']) && in_array('draft', $data['categories'])) { + + $success=draft_save($data, $id); + } else { + + /* anyway issued */ + + draft_to_entry($id); + $success=entry_save($data, $id); + + } + + if ($success) sess_remove('entry'); + + $this->smarty->assign('success',$success? 1:-1); + + if ($do_preview) + $this->_makePreview($data); + + return 1; + } + + + function onpreview() { + global $lang; + + $this->_makePreview($this->_getposteddata()); + + + $this->_getCatsFlags(); + + add_filter('wp_title', array(&$this, 'makePageTitle'), 10, 2); + + return 0; + + + } + + function onsavecontinue() { + global $lang; + $this->onsave(true); + + $this->_getCatsFlags(); + + add_filter('wp_title', array(&$this, 'makePageTitle'), 10, 2); + + } + + + function onerror() { + $this->main(); + return 0; + } + + } + +?> diff --git a/admin/panels/entry/admin.entry.write.tpl b/admin/panels/entry/admin.entry.write.tpl new file mode 100755 index 0000000..2a1dd58 --- /dev/null +++ b/admin/panels/entry/admin.entry.write.tpl @@ -0,0 +1,101 @@ +

{$panelstrings.head}

+ +{html_form} + {validate_init form=$admin_panel_id} + {validate id="subject" message=$panelstrings.error.subject append="error"} + {validate id="content" message=$panelstrings.error.content append="error"} + + {include file='shared:errorlist.tpl'} + + {entry_block} + {if $preview} +
{$panelstrings.preview} + {include file=preview.tpl} +
+ {/if} + + + + {entry content=$post alwaysshow=true} + +
+


+
+ + +

+

+ +

+ {toolbar} +

+
+ {*here will go a plugin hook*} + {action hook=simple_edit_form} + +

+
+ +
+ + {* let's disable this for now... *} + + {* + +
{$panelstrings.uploader} + +
+ *} + + {* end of inline form *} + +
{$panelstrings.archive} + {list_categories type=form} +
+ +
{$panelstrings.saveopts} + +

+ {foreach from=$saved_flags item=flag} +
+ {/foreach} +

+ +
+
+ + +
+ {html_submit name="save" id="save" value=$panelstrings.submit accesskey=s} + {html_submit name="savecontinue" id="savecontinue" value=$panelstrings.savecontinue accesskey=c} + {html_submit name="preview" id="preview" value=$panelstrings.preview accesskey=p} +
+ + + {/entry} + {/entry_block} +{/html_form} + +{if $smarty.get.entry } + +
+ +

{$panelstrings.otheropts}

+ + +
+ +{/if} + + + diff --git a/admin/panels/entry/shared.entry.form.php b/admin/panels/entry/shared.entry.form.php new file mode 100755 index 0000000..18a4962 --- /dev/null +++ b/admin/panels/entry/shared.entry.form.php @@ -0,0 +1,51 @@ + + * + */ + + + function shared_entry_form_setup(&$smarty) { + $smarty->assign('form', ABS_PATH.ADMIN_DIR."panels/entry/shared.entry.form.tpl"); + admin_entry_cats_flags($smarty); + + } + + function shared_entry_form_main() { + + SmartyValidate::register_validator('subject', 'subject', 'notEmpty', false, false, 'trim'); + SmartyValidate::register_validator('content', 'content', 'notEmpty', false, false); + } + + + function shared_entry_form_onsubmit() { + + $arr['version'] = system_ver(); + $arr['subject'] = stripslashes($_POST['subject']); + $arr['content'] = stripslashes($_POST['content']); + $author = user_get(); + $arr['author'] = $author['NAME']; + $arr['date'] = !empty($_POST['timestamp'])?$_POST['timestamp']:time(); + + $cats = !empty($_POST['cats'])?$_POST['cats']:array(); + $flags = !empty($_POST['flags'])?$_POST['flags']:array(); + + $arr['categories'] = array_merge(array_keys($flags), array_keys($cats)); + + //sess_add('entry', $arr); + + + return $arr; + + } + +?> diff --git a/admin/panels/entry/shared.entry.form.tpl b/admin/panels/entry/shared.entry.form.tpl new file mode 100755 index 0000000..86e7cf4 --- /dev/null +++ b/admin/panels/entry/shared.entry.form.tpl @@ -0,0 +1,54 @@ +{validate id="subject" message=$panelstrings.error.subject append="error"} +{validate id="content" message=$panelstrings.error.content append="error"} + + + {if $error} + + {/if} + +
{$panelstrings.fieldset1} +


+
+ +

+ {toolbar} +

+
+
+ {*here will go a plugin hook*} +

+ +
{$panelstrings.fieldset2} + +


+

+ {html_submit name="save" id="save" value=$panelstrings.submit accesskey=s} + {html_submit name="preview" id="preview" value=$panelstrings.preview accesskey=p} + +
+ + + {/static} + + +{/html_form} + {/static_block} + + + + + + diff --git a/admin/panels/themes/admin.themes.php b/admin/panels/themes/admin.themes.php new file mode 100644 index 0000000..72a4b67 --- /dev/null +++ b/admin/panels/themes/admin.themes.php @@ -0,0 +1,159 @@ + true); + + function admin_themes(&$smarty) { + global $theme; + + if ($theme['version'] > 0.703) + $this->actions['style'] = true; + + parent::AdminPanel($smarty); + + } + + } + + function admin_theme_data( $theme_file, $theme_id, $defprev ) { + + + $theme_data = io_load_file($theme_file); + $theme_data = str_replace ( '\r', '\n', $theme_data ); + preg_match( '/(Theme|Style) Name:(.*)/i', $theme_data, $theme_name ); + preg_match( '/(Theme|Style) URI:(.*)/i', $theme_data, $theme_uri ); + preg_match( '|Description:(.*)|i', $theme_data, $description ); + preg_match( '|Author:(.*)|i', $theme_data, $author_name ); + preg_match( '|Author URI:(.*)|i', $theme_data, $author_uri ); + preg_match( '|Template:(.*)|i', $theme_data, $template ); + if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) ) + $version = trim( $version[1] ); + else + $version =''; + if ( preg_match('|Status:(.*)|i', $theme_data, $status) ) + $status = trim($status[1]); + else + $status = 'publish'; + + $description = @wptexturize( trim( $description[1] ) ); + + $name = @$theme_name[1]? $theme_name[2] : $theme_id; + $name = trim( $name ); + $theme = $name; + $theme_uri = trim( @$theme_uri[2] ); + + if ( '' == @$author_uri[1] ) { + $author = trim( @$author_name[1] ); + } else { + $author = '' . + trim( $author_name[1] ) . ''; + } + + if (file_exists($f = dirname($theme_file). '/preview.png')) + $prev = $f; + else + $prev = $defprev; + + //$theme['name'] = isset($theme['name'])? $theme['name'] : ($thm); + + return + array( 'name' => $name, + 'id' => $theme_id, + 'title' => $theme, + 'www' => $theme_uri, + 'description' => $description, + 'author' => $author, + 'version' => $version, + 'template' => $template, + 'status' => $status, + 'preview' => $prev + ); + } + + + + class admin_themes_default extends AdminPanelAction { + + var $defprev = ''; + var $commands = array('select'); + + function theme_list() { + global $fp_config; + $list = theme_list(); + $info = array(); + foreach ($list as $thm) { + + // don't show current theme + if ($fp_config['general']['theme'] == $thm) + continue; + + $theme = array(); + $d = THEMES_DIR . $thm; + + + $f = $d . '/theme.conf.php'; + + $theme = admin_theme_data($d . '/theme.conf.php', $thm, $this->defprev); + + $info[] = $theme; + } + + return $info; + } + + function setup() { + $this->defprev = BLOG_BASEURL . ADMIN_DIR . 'panels/'. ADMIN_PANEL .'/preview-default.png'; + + $current_theme = admin_theme_data(THEMES_DIR . THE_THEME . '/theme.conf.php', THE_THEME, $this->defprev); + $this->smarty->assign('current_theme', $current_theme); + + $this->smarty->assign('available_themes', $this->theme_list()); + } + + + function doselect($id) { + global $fp_config; + //$id = isset($_GET['select'])? $_GET['select'] : null; + if ($id) { + $id = sanitize_title($id); + if (theme_exists($id)) { + $fp_config['general']['theme'] = $id; + + unset($fp_config['general']['style']); + + //$t = theme_loadsettings(); + //$fp_config['general']['style'] = $t['default_style']; + + $return = config_save() ? 1 : -1; + } else { + $return = -2; + + } + + $this->smarty->assign('success', $return); + + return 1; + + } + + } + + function onerror() { + $this->main(); + return 0; + } + + function cleartplcache() { + // if theme was switched, clear tpl cache + + $tpl =& new tpl_deleter(); + + $tpl->getList(); + + + } + + } + +?> \ No newline at end of file diff --git a/admin/panels/themes/admin.themes.style.php b/admin/panels/themes/admin.themes.style.php new file mode 100644 index 0000000..705721a --- /dev/null +++ b/admin/panels/themes/admin.themes.style.php @@ -0,0 +1,99 @@ +_directory = THEMES_DIR . THE_THEME; + parent::fs_filelister(); + } + + function _checkFile($d, $f) { + $p = "$d/$f"; + if (is_dir($p) && file_exists($p.'/style.conf.php')) + $this->_list[] = $f; + } + + } + + + class admin_themes_style extends AdminPanelAction { + + var $defprev = ''; + var $commands = array('select'); + + function style_list() { + global $fp_config; + + $o =& new admin_themes_obj_style_idx; + + $list = $o->getList(); + $info = array(); + $based = THEMES_DIR . THE_THEME; + + foreach ($list as $sty) { + + // don't show current theme + //if ($fp_config['general']['theme'] == $thm) + // continue; + + $style = array(); + $d = "$based/$sty"; + + + $f = $d . '/style.conf.php'; + + $style = admin_theme_data($f, $sty, $this->defprev); + + $info[] = $style; + } + + return $info; + } + + function setup() { + global $fp_config; + $this->defprev = BLOG_BASEURL . ADMIN_DIR . 'panels/'. ADMIN_PANEL .'/preview-default.png'; + + $this->smarty->assign('current_style', + admin_theme_data(THEMES_DIR . THE_THEME . '/' .$fp_config['general']['style'] .'/style.conf.php', THE_THEME, $this->defprev)); + $this->smarty->assign('available_styles', $this->style_list()); + } + + function doselect($id) { + global $fp_config; + + if ($id) { + $id = sanitize_title($id); + if (theme_style_exists($id)) { + $fp_config['general']['style'] = $id; + + $return = config_save() ? 1 : -1; + } else { + $return = -2; + } + + $this->smarty->assign('success', $return); + + return 2; + } + } + + + function onerror() { + $this->main(); + return 0; + } + + function cleartplcache() { + // if theme was switched, clear tpl cache + + $tpl =& new tpl_deleter(); + + $tpl->getList(); + + + } + + } + +?> \ No newline at end of file diff --git a/admin/panels/themes/admin.themes.style.tpl b/admin/panels/themes/admin.themes.style.tpl new file mode 100644 index 0000000..5b03f47 --- /dev/null +++ b/admin/panels/themes/admin.themes.style.tpl @@ -0,0 +1,33 @@ +{include file=shared:errorlist.tpl} + +
+ +

{$panelstrings.head1}

+{$current_style.name} +
{$current_style.title} — {$current_style.author|default:$panelstrings.noauthor}
+{$current_style.description|default:$panelstrings.nodescr} +
+ + +
+ +

{$panelstrings.head2}

+

{$panelstrings.descr}

+ +{if $available_styles} + +
    +{foreach from=$available_styles item=thm} +
  • +
    {$thm.title}
    + {$thm.name} + +

    {$thm.description|default:$panelstrings.nodescr}

    + +
  • +{/foreach} +
+ +{/if} + +
\ No newline at end of file diff --git a/admin/panels/themes/admin.themes.tpl b/admin/panels/themes/admin.themes.tpl new file mode 100644 index 0000000..3814521 --- /dev/null +++ b/admin/panels/themes/admin.themes.tpl @@ -0,0 +1,33 @@ +{include file=shared:errorlist.tpl} + +
+ +

{$panelstrings.head1}

+{$current_theme.name} +
{$current_theme.title} — {$current_theme.author|default:$panelstrings.noauthor}
+{$current_theme.description|default:$panelstrings.nodescr} +
+ + +
+ +

{$panelstrings.head2}

+

{$panelstrings.descr}

+ +{if $available_themes} + +
    +{foreach from=$available_themes item=thm} +
  • +
    {$thm.title}
    + {$thm.name} + +

    {$thm.description|default:$panelstrings.nodescr}

    + +
  • +{/foreach} +
+ +{/if} + +
\ No newline at end of file diff --git a/admin/panels/themes/preview-default.png b/admin/panels/themes/preview-default.png new file mode 100644 index 0000000..9d96214 Binary files /dev/null and b/admin/panels/themes/preview-default.png differ diff --git a/admin/panels/uploader/admin.uploader.browse.php b/admin/panels/uploader/admin.uploader.browse.php new file mode 100644 index 0000000..661d3ef --- /dev/null +++ b/admin/panels/uploader/admin.uploader.browse.php @@ -0,0 +1,146 @@ + + * + */ + + class uploader_lister extends fs_filelister { + + var $_dirlist = array(); + var $_filelist = array(); + + function uploader_lister($d, $pd) { + $this->urldir = $pd; + $this->basepanelurl = + BLOG_BASEURL . + "admin.php?p=uploader&action=browse&dir="; + $this->thumburl = + BLOG_BASEURL . + 'admin.php?p=uploader&action=thumb&f='; + return parent::fs_filelister($d); + } + + function _checkFile($d, $f) { + + $p = "{$d}{$f}"; + + if (is_dir($p)) { + $this->_dirlist[$f]="{$this->basepanelurl}$f"; + } else { + $lbl = $f; + $this->_filelist[$f]="{$this->thumburl}{$this->urldir}$f"; + } + + return parent::_checkFile($d,$f); + + + } + + function getDirs() { + + ksort($this->_dirlist); + return $this->_dirlist; + + } + + function getFiles() { + ksort($this->_filelist); + return $this->_filelist; + } + + } + + class admin_uploader_browse extends AdminPanelAction { + + var $events = array('upload'); + + function main() { + + if (!empty($_GET['dir'])) { + + $dir = $_GET['dir']; + if (substr($_GET['dir'], -1)!= '/') + $dir.= '/'; + } else { + $dir = './'; + } + + $pd = $dir; + $dir = ABS_PATH.IMAGES_DIR.$dir; + $o = new uploader_lister($dir, $pd); + + if ($dir != '') + $this->smarty->assign('parent', $o->basepanelurl.dirname($dir)); + $this->smarty->assign('dirs', $o->getDirs()); + $this->smarty->assign('files', $o->getFiles()); + + } + + function onupload() { + + $success = false; + + if (!file_exists(IMAGES_DIR)) + fs_mkdir(IMAGES_DIR); + + if (!file_exists(ATTACHS_DIR)) + fs_mkdir(ATTACHS_DIR); + + + $imgs = array('.jpg','.gif','.png', '.jpeg'); + + //intentionally + //I've not put BMPs + + $uploaded_files=array(); + + foreach ($_FILES["upload"]["error"] as $key => $error) { + + if ($error == UPLOAD_ERR_OK) { + $tmp_name = $_FILES["upload"]["tmp_name"][$key]; + $name = $_FILES["upload"]["name"][$key]; + + $dir = ATTACHS_DIR; + + $ext = strtolower(strrchr($name,'.')); + + if (in_array($ext,$imgs)) { + $dir = IMAGES_DIR; + } + + $name = sanitize_title(substr($name, 0, -strlen($ext))) . $ext; + + $target = "$dir/$name"; + @umask(022); + $success = move_uploaded_file($tmp_name, $target); + @chmod($target,0766); + + $uploaded_files[] = $name; + + $success &= $success; + + + } + + } + + if ($uploaded_files) { + $this->smarty->assign('success', $success? 1 : -1); + sess_add('admin_uploader_files', $uploaded_files); + } + + return 1; + + } + } + + ?> diff --git a/admin/panels/uploader/admin.uploader.browse.tpl b/admin/panels/uploader/admin.uploader.browse.tpl new file mode 100644 index 0000000..0da6b04 --- /dev/null +++ b/admin/panels/uploader/admin.uploader.browse.tpl @@ -0,0 +1,59 @@ +

{$panelstrings.head}

+

{$panelstrings.descr}

+ +{include file='shared:errorlist.tpl'} + + + +
+ + + {*
{$panelstrings.fset1} + + +
+ {html_submit name="upload" id="upload" value=$panelstrings.submit} +
+
+ *} + +
+ + {foreach from=$dirs item=dirpath key=dirname} + + {/foreach} + + + {if $files} +
    + {foreach from=$files item=filepath key=filename} +
  • +
    {$filename}
    + {$filename} +
  • + {/foreach} +
+ {/if} + +
+ + {* + + + + + + {foreach from=$dirs item=dirpath key=dirname} + + {/foreach} + + {foreach from=$files item=filepath key=filename} + + {/foreach} + +
name date
.. ...
{$dirname} ...
{$filename} ...
+ *} + +
diff --git a/admin/panels/uploader/admin.uploader.php b/admin/panels/uploader/admin.uploader.php new file mode 100755 index 0000000..0c627bf --- /dev/null +++ b/admin/panels/uploader/admin.uploader.php @@ -0,0 +1,89 @@ + + * + */ + class admin_uploader extends AdminPanel { + var $panelname = 'uploader'; + var $actions = array('default'=>true); + } + + + class admin_uploader_default extends AdminPanelAction { + + var $events = array('upload'); + + function main() { + if ($f = sess_remove('admin_uploader_files')) + $this->smarty->assign('uploaded_files', $f); + } + + function onupload() { + + $success = false; + + if (!file_exists(IMAGES_DIR)) + fs_mkdir(IMAGES_DIR); + + if (!file_exists(ATTACHS_DIR)) + fs_mkdir(ATTACHS_DIR); + + + $imgs = array('.jpg','.gif','.png', '.jpeg'); + + //intentionally + //I've not put BMPs + + $uploaded_files=array(); + + foreach ($_FILES["upload"]["error"] as $key => $error) { + + if ($error == UPLOAD_ERR_OK) { + $tmp_name = $_FILES["upload"]["tmp_name"][$key]; + $name = $_FILES["upload"]["name"][$key]; + + $dir = ATTACHS_DIR; + + $ext = strtolower(strrchr($name,'.')); + + if (in_array($ext,$imgs)) { + $dir = IMAGES_DIR; + } + + $name = sanitize_title(substr($name, 0, -strlen($ext))) . $ext; + + $target = "$dir/$name"; + @umask(022); + $success = move_uploaded_file($tmp_name, $target); + @chmod($target,0766); + + $uploaded_files[] = $name; + + // one failure will make $success == false :) + $success &= $success; + + + } + + } + + if ($uploaded_files) { + $this->smarty->assign('success', $success? 1 : -1); + sess_add('admin_uploader_files', $uploaded_files); + } + + return 1; + + } + } + + ?> diff --git a/admin/panels/uploader/admin.uploader.thumb.php b/admin/panels/uploader/admin.uploader.thumb.php new file mode 100644 index 0000000..6011e30 --- /dev/null +++ b/admin/panels/uploader/admin.uploader.thumb.php @@ -0,0 +1,84 @@ +$h) { + + $ratio = $w/$h; + $new_width = $MAX; + $new_height = (int)($MAX/$ratio); + + } else { + $ratio = $h/$w; + $new_height = $MAX; + $new_width = (int)($MAX/$ratio); + } + + $scaled = imagecreatetruecolor($new_width, $new_height); + imagecopyresampled($scaled, $image, 0, 0, 0, 0, $new_width, $new_height, $infos[0], $infos[1]); + + + header('Content-Type: image/jpeg'); + imagejpeg($scaled); + + +} + + if (isset($_GET['f'])) { + + $f = ABS_PATH . IMAGES_DIR . $_GET['f']; + if ( strpos ($f, '..') !== false) + return; + + if (file_exists($f)) { + thumb_send($f); + } + } + + exit(); + +?> \ No newline at end of file diff --git a/admin/panels/uploader/admin.uploader.tpl b/admin/panels/uploader/admin.uploader.tpl new file mode 100755 index 0000000..70d7a99 --- /dev/null +++ b/admin/panels/uploader/admin.uploader.tpl @@ -0,0 +1,46 @@ +{if $smarty.request.mod != 'inline'} +

{$panelstrings.head}

+

{$panelstrings.descr}

+{/if} + +{include file='shared:errorlist.tpl'} + + +{if $success} + +{/if} + +{html_form} + + + {if $smarty.request.mod != 'inline'} +
{$panelstrings.fset1} + {/if} + + + + + + + + + + {if $smarty.request.mod != 'inline'} +
+ {/if} + +
+ {html_submit name="upload" id="upload" value=$panelstrings.submit} +
+ +{/html_form} \ No newline at end of file diff --git a/admin/panels/widgets/admin.widgets.default.php b/admin/panels/widgets/admin.widgets.default.php new file mode 100644 index 0000000..6e2579d --- /dev/null +++ b/admin/panels/widgets/admin.widgets.default.php @@ -0,0 +1,119 @@ +'; + } + add_action('wp_footer', 'admin_widgets_head'); + + + class admin_widgets_default extends AdminPanelAction { + + //var $validators = array(array('content', 'content', 'notEmpty', false, false)); + var $events = array('save'); + + + function get_widget_lists($wlist, $wpos, &$widget_list, $registered_w, $add_empties) { + + if (!isset($wlist[$wpos])) + return; + + $widget_list[$wpos] = array(); + + foreach($wlist[$wpos] as $idx => $wdg) { + + $widget_list[$wpos][$idx] = array(); + + @list($newid, $params) = explode(":", $wdg); + + $widget_list[$wpos][$idx]['id'] = $newid; + + + if (isset($registered_w[$newid])){ + $thiswdg =& $registered_w[$newid]; + + $widget_list[$wpos][$idx]['name'] = $thiswdg['name']; + + if ($thiswdg['nparams'] > 0) { + $widget_list[$wpos][$idx]['params'] = $params; + } + + /* + * here should go the check for + * limited parameters: parameters limited to a + * particular set would mean using a
+

+ + +
+ {html_submit name="save" id="save" value=$panelstrings.submit} +
+ + diff --git a/admin/panels/widgets/admin.widgets.tpl b/admin/panels/widgets/admin.widgets.tpl new file mode 100755 index 0000000..1b1a956 --- /dev/null +++ b/admin/panels/widgets/admin.widgets.tpl @@ -0,0 +1,107 @@ +

{$panelstrings.head}

+

{$panelstrings.descr}

+ +{include file='shared:errorlist.tpl'} + + +{html_form} + +
+

{$panelstrings.availwdgs}

+ +
+ {$panelstrings.trashcan} +
+ +
    + {foreach from=$fp_registered_widgets key=widgetid item=widget} +
  • + {* those are actually dummies just to have two inputs ready, but they might come handy *} + + {if $widget.nparams > 0} + {* class is for javascript: this input will be converted into a type="text" :) *} + + {/if} +

    {$widget.name}

    +
  • + {/foreach} +
+ +
+ +
+ +
+ +
+ +

{$panelstrings.themewdgs}

+

{$panelstrings.themewdgsdescr}

+ +
    + {foreach from=$widgetlist key=widgetset item=widgetarr} +
  • +

    + {$panelstrings.stdsets[$widgetset]|default:$widgetset} +

    + +
      + {foreach from=$widgetarr item=widget} +
    • + + {if $widget.params} + {* this will be hooked from javascript *} + + {/if} +

      {$widget.name}

      +
    • + {foreachelse} +
    • Drop here
    • + {/foreach} +
    +
  • + {/foreach} + + +
+ + {if $oldwidgetlist} + +

{$panelstrings.oldwdgs}

+

{$panelstrings.oldwdgsdescr}

+ + {foreach from=$oldwidgetlist key=widgetset item=widgetarr} +
  • +

    + {$panelstrings.stdsets[$widgetset]|default:$widgetset} +

    + +
      + {foreach from=$widgetarr item=widget} +
    • + + {if $widget.params} + {* this will be hooked from javascript *} + + {/if} +

      {$widget.name}

      +
    • + {foreachelse} +
    • Drop here
    • + {/foreach} +
    +
  • + {/foreach} + {/if} + +
    + +
    + {html_submit name="save" id="save" value=$panelstrings.submit} +
    + +{/html_form} diff --git a/admin/res/admin.css b/admin/res/admin.css new file mode 100755 index 0000000..de58216 --- /dev/null +++ b/admin/res/admin.css @@ -0,0 +1,197 @@ +/* + + + compatibility for old themes, soon + this hackish and ugly css will be + DROPPED + +*/ + +#admin-tabmenu { + text-align: left; + + padding-right: 0px; + padding-left: 0px; + z-index: 1; + padding-bottom: 0px; + margin: 12px 0px 0px; + padding-top: 0px; + + border-bottom: black 2px solid; + + + font-size: 80%; + _font-size: 90%; + font-weight: normal; + +} + + +#admin-tabmenu li { + display: inline; + overflow: hidden; + list-style-type: none; + padding-left: -10px +} + + +#admin-tabmenu a { + border-right: black 2px solid; + padding-right: 5px; + border-top: black 2px solid; + padding-left: 5px; + background: #f9f9f9; + padding-bottom: 0px; + margin: 0px; + border-left: black 2px solid; + padding-top: 2px; + border-bottom: black 2px solid; + text-decoration: none +} + +#cpmain ul, #main li{ + list-style-type:none; +} + +#cpmain ul li:before { + content: none; +} + + +#admin-tabmenu a#admin-tab-current { + background: #f9f9f9; + color: black; + border-bottom: #f9f9f9 3px solid; +} + +.admin-mainmenu-item { + clear:both; + display:block; + padding:1em; +} + + + + +#admin-content { + border-right: black 2px solid; + padding-right: 20px; + border-top: black 2px; + padding-left: 20px; + z-index: 2; + padding-bottom: 20px; + border-left: black 2px solid; + padding-top: 20px; + border-bottom: black 2px solid; + _font-size: 1em; +} + +#admin-content table { + border-collapse: collapse; + width: 100%; + _width: 470px; + _font-size:100%; + +} + +#admin-content td { + border-bottom: solid 1px black; + width: 8px; + font-size: 0.8em; + _font-size:1em; + padding: 4px; +} + +#admin-content td.main_cell { + text-align: left; + font-weight: bold; + width: 20%; + +} + +#admin-content th { + border-bottom: solid 2px black; + + padding: 4px; + font-size: 0.75em; + _font-size: 100%; + font-style: italic; + +} + +#subject { + font-size: 18px; + font-weight: bold; + width: 99%; +} + +.underOpt { + font-size: 80%; + font-style: oblique; + margin: .5em 0 0 0 +} + +.maxsize { + width: 99%; +} + +input.maxsize { width: 99% } + +.msg { + font-weight: bold; +} + +.error { + color: red; + padding-left: 10px; +} + +.disabled { + background-color: red; +} + +.enabled { + background-color: green; +} + +.locked { + background-color: grey; +} + +.draft { + background-color: lightgrey; +} + + +/* ===== NOTIFICATION ===== */ +#main ul.msgs, ul.msgs { + margin-top: 1em; + margin-left: 0em; + padding: 1em 2em +} + +.errors { + color: #901d1d; + border-top: 1px solid; + border-bottom: 1px solid; + border-color: #ffbbbb; + background: #ffdddd +} + +.errors a { + color: #901d1d; + text-decoration: underline; + font-weight: normal +} + +.notifications { + color : #1d901d; + border-top: 1px solid #bbffbb; + border-bottom: 1px solid #bbffbb; + background: #ddffdd +} + +.field-error { + border: red 1px solid; + background: #fdd +} diff --git a/blog.php b/blog.php new file mode 100755 index 0000000..0b24a67 --- /dev/null +++ b/blog.php @@ -0,0 +1,10 @@ + diff --git a/comments.php b/comments.php new file mode 100644 index 0000000..c0a3417 --- /dev/null +++ b/comments.php @@ -0,0 +1,223 @@ +getQuery(); + + list($id, $entry) = $q->peekEntry(); + + if (!empty($_GET['feed'])){ + + switch($_GET['feed']) { + + case 'atom': + header('Content-type: application/atom+xml'); + $module = SHARED_TPLS . 'comment-atom.tpl'; + break; + case 'rss2': + default: + header('Content-type: application/rss+xml'); + $module = SHARED_TPLS . 'comment-rss.tpl'; + } + + + } elseif (!in_array('commslock', $entry['categories'])) { + + commentform(); + } + + return $module; + + } + + function comment_feed() { + echo "\n"; + echo "\n\n"; + } + add_action('wp_head', 'comment_feed'); + + function comment_validate() { + + + $arr['version'] = system_ver(); + $arr['name'] = $_POST['name']; + + $loggedin = false; + + if (user_loggedin()) { + $loggedin = $arr['loggedin']=true; + } + + if (!$loggedin) + setcookie('comment_author_' . COOKIEHASH, + $arr['name'], time() + 30000000, COOKIEPATH, COOKIE_DOMAIN); + + + if (!empty($_POST['email'])) { + ($arr['email'] = $_POST['email']); + if (!$loggedin) + setcookie('comment_author_email_' . COOKIEHASH, + $arr['email'], time() + 30000000, COOKIEPATH, COOKIE_DOMAIN); + + } + if (!empty($_POST['url'])) { + ($arr['url'] = ( $_POST['url'] )) ; + if (!$loggedin) + setcookie('comment_author_url_' . COOKIEHASH, + $arr['url'], time() + 30000000, COOKIEPATH, COOKIE_DOMAIN); + + + } + $arr['content'] = $_POST['content']; + + $arr['ip-address'] = utils_ipget(); + + if (apply_filters('comment_validate', true, $arr)) + return $arr; + else return false; + + + } + + function commentform() { + + global $smarty, $lang, $fpdb; + + $comment_formid = 'fp-comments'; + $smarty->assign('comment_formid', $comment_formid); + + + if(empty($_POST)) { + + if(!SmartyValidate::is_registered_form($comment_formid)) { + + // new form, we (re)set the session data + + SmartyValidate::connect($smarty, true); + SmartyValidate::register_form($comment_formid, true); + + + // register our validators + + SmartyValidate::register_validator('name', 'name', 'notEmpty', false, false, 'trim,stripslashes', $comment_formid); + SmartyValidate::register_validator('email','email', 'isEmail', true, false, 'trim,stripslashes', $comment_formid); + SmartyValidate::register_validator('www', 'url', 'isURL', true, false, 'trim,stripslashes', $comment_formid); + SmartyValidate::register_validator('comment', 'content', 'notEmpty', false, false, 'stripslashes', $comment_formid); + } + + } else { + utils_nocache_headers(); + // validate after a POST + SmartyValidate::connect($smarty, true); + + // add http to url + if (!empty($_POST['url']) && strpos($_POST['url'], 'http://')===false) + $_POST['url'] = 'http://'.$_POST['url']; + + + // custom hook here!! + if( SmartyValidate::is_valid($_POST, $comment_formid) && ($arr=comment_validate())) { + //SmartyValidate::disconnect(); + + global $fp_config; + + + $id = comment_save($_GET['entry'], $arr); + + do_action('comment_post', $_GET['entry'], array($id, $arr)); + + + if ($fp_config['general']['notify'] && !user_loggedin()) { + $comm_mail = isset($arr['email'])? "<{$arr['email']}>" : ''; + $from_mail = $comm_mail? $arr['email'] : $fp_config['general']['email']; + $q =& new FPDB_Query(array('entry'=>$_GET['entry'],'fullparse'=>false), null); + list($id, $e) = $q->getEntry(); + + + $lang = lang_load('comments'); + + $mail = str_replace( + array( + '%toname%', + '%fromname%', + '%frommail%', + '%entrytitle%', + '%commentlink%', + '%content%', + '%blogtitle%' + ), + + array( + $fp_config['general']['author'], + $arr['name'], + $comm_mail, + $e['subject'], + get_comments_link($_GET['entry']) . '#'.$id, + $arr['content'], + $fp_config['general']['title'] + ), + + $lang['comments']['mail'] + ); + + + @utils_mail($from_mail, "New comment on {$fp_config['general']['title']}", + $mail); + + } + + // if comment is valid, this redirect will clean the postdata + $location = str_replace( + '&', '&', + apply_filters( + 'comments_link', + '', + $_GET['entry']) + ) . '#'.$id; + + utils_redirect($location,true); + exit(); + + } else { + $smarty->assign('values', $_POST); + } + + } + + + // Cookies + $smarty->assign('cookie', array( + 'name' => @$_COOKIE['comment_author_' . COOKIEHASH], + 'email' => @$_COOKIE['comment_author_email_' . COOKIEHASH], + 'url' => @$_COOKIE['comment_author_url_' . COOKIEHASH] + )); + + + + + } + + + + + + +?> diff --git a/contact.php b/contact.php new file mode 100755 index 0000000..43e01de --- /dev/null +++ b/contact.php @@ -0,0 +1,111 @@ +assign('notifications',system_geterr('contact')); + + if(empty($_POST)) { + // new form, we (re)set the session data + SmartyValidate::connect($smarty, true); + // register our validators + SmartyValidate::register_validator('name', 'name', 'notEmpty', false, false, 'trim'); + SmartyValidate::register_validator('email', 'email', 'isEmail', true, false, 'trim'); + SmartyValidate::register_validator('www', 'url', 'isURL', true, false, 'trim'); + SmartyValidate::register_validator('content', 'content', 'notEmpty', false, false); + } else { + utils_nocache_headers(); + // validate after a POST + SmartyValidate::connect($smarty); + + if (!empty($_POST['url']) && strpos($_POST['url'], 'http://')===false) $_POST['url'] = 'http://'.$_POST['url']; + + + // custom hook here!! + // we'll use comment actions, anyway + if(SmartyValidate::is_valid($_POST) && $arr=contact_form_validate()) { + + $msg = "Name: \n{$arr['name']} \n\n"; + + if (isset($arr['email'])) + $msg .= "Email: {$arr['email']}\n\n"; + if (isset($arr['url'])) + $msg .= "WWW: {$arr['url']}\n\n"; + $msg .= "Content:\n{$arr['content']}\n"; + + @utils_mail( + ( + isset($arr['email'])? + $arr['email'] + : + $this->config['EMAIL'] + ), + "Contact sent through {$fp_config['general']['title']} ", $msg ); + + system_seterr('contact', 1); + utils_redirect(); + } else { + $smarty->assign('values', $_POST); + } + } + } + + + function contact_main() { + global $smarty; + + $lang = lang_load('contact'); + + $smarty->assign('subject', $lang['contact']['head']); + $smarty->assign('content', 'shared:contact.tpl'); + contact_form(); + + } + + function contact_display() { + global $smarty; + + contact_main(); + + theme_init($smarty); + + $smarty->display('default.tpl'); + + unset($smarty); + + do_action('shutdown'); + + } + + + system_init(); + contact_display(); + +?> diff --git a/defaults.php b/defaults.php new file mode 100755 index 0000000..4525d92 --- /dev/null +++ b/defaults.php @@ -0,0 +1,108 @@ + diff --git a/docs/README-SmartyValidate b/docs/README-SmartyValidate new file mode 100755 index 0000000..e75656e --- /dev/null +++ b/docs/README-SmartyValidate @@ -0,0 +1,1089 @@ +NAME: + + SmartyValidate: a class/plugin for validating form variables + within the Smarty template environment. + +AUTHOR: + Monte Ohrt (monte [AT] ohrt [DOT] com) + +VERSION: + 2.6 + +DATE: + February 7th, 2005 + +WEBSITE: + http://www.phpinsider.com/php/code/SmartyValidate/ + +DOWNLOAD: + http://www.phpinsider.com/php/code/SmartyValidate/SmartyValidate-current.tar.gz + +ANONYMOUS CVS: (leave password empty) + cvs -d :pserver:anonymous@cvs.phpinsider.com:/export/CVS login + cvs -d :pserver:anonymous@cvs.phpinsider.com:/export/CVS checkout SmartyValidate + +SYNOPSIS: + + index.php + --------- + + session_start(); + require('Smarty.class.php'); + require('SmartyValidate.class.php'); + + $smarty =& new Smarty; + + + if(empty($_POST)) { + SmartyValidate::connect($smarty, true); + SmartyValidate::register_validator('fname','FullName','notEmpty'); + SmartyValidate::register_validator('fdate','Date','isDate'); + $smarty->display('form.tpl'); + } else { + SmartyValidate::connect($smarty); + // validate after a POST + if(SmartyValidate::is_valid($_POST)) { + // no errors, done with SmartyValidate + SmartyValidate::disconnect(); + $smarty->display('success.tpl'); + } else { + // error, redraw the form + $smarty->assign($_POST); + $smarty->display('form.tpl'); + } + } + + form.tpl + -------- + +
    + + {validate id="fname" message="Full Name cannot be empty"} + Full Name: + + {validate id="fdate" message="Date is not valid"} + Date: + + +
    + +DESCRIPTION: + + What is SmartyValidate? + + SmartyValidate is a form validation class. Its design goals are to + leverage the Smarty templating environment and make form validation + as easy and flexible as possible. + +BACKGROUND: + + Form validation is one of the most frequently performed tasks when + it comes to web application programming. Developing form validation + can be a tedious and time consuming task. SmartyValidate simplifies + this effort by abstracting the validation process. You basically + provide the validation criteria and error messages, SmartyValidate + does the rest! + + On the application side, you call SmartyValidate::connect($smarty) first, + passing your smarty object as the parameter. Then you register your + validators with the SmartyValidate::register_validator() function, once for + each validation criteria on the form. Once the form is posted, you call + SmartyValidate::is_valid($_POST) and depending on the outcome, you either + continue with a valid form or begin a form redraw cycle until all the + validation criteria is met. This keeps the form validation process to a bare + minimum on the application side. + + In the form template, you put {validate ...} tags which handle error + messages that get displayed upon a validation error. + + +FEATURES: + + Supplied validation criteria includes empty, integer, float, price, + email syntax, credit card checksums, credit card exp dates, valid + date syntax, equality between fields, ranges, lengths, regular expression + matching and custom function calls. Create your own through Smarty plugins, + PHP functions or class methods. + + Transform functions can be applied to form values prior to validation, + such as trimming, upper-casing, etc. Create your own through Smarty Plugins, + PHP functions or class methods. + + {validate ...} tags can be located anywhere in your template, regardless of + where the corresponding fields are located. + + Multiple validators may be used for one field. Once one validator fails, + the remaining validators for that field are ignored. A "halt" parameter can + also stop validation on remaining fields. + + +CAVEATS: + + Smarty supports validation on single-level array values such as foo[] and + foo[bar], but does not (currently) support nested array validation such as + foo[bar][blah]. So you can do this: + + {validate field="foo[bar]" criteria="notEmpty" ...} + + + But not this: + + {validate field="foo[bar][blah]" criteria="notEmpty" ...} + + + +REQUIREMENTS: + + You must enable session management prior to using SmartyValidate. Do this + by calling session_start() at the top of your PHP application. + SmartyValidate also requires the Smarty template environment. + +INSTALLATION: + + It is assumed that you are familiar with the Smarty templating + installation and setup, so I will not explain Smarty template + directories and such. Please refer to the Smarty documentation for + that information. + + To install SmartyValidate: + + * Copy the 'SmartyValidate.class.php' file to a place within your + php_include path (or use absolute pathnames when including.) + * Copy all of the plugins to your Smarty plugin directory. (located + in the plugins/ directory of the distribution.) + +EXAMPLE: + + Here is a full working example of how to use SmartyValidate. Put the + form.tpl and success.tpl files in your Smarty template directory. + + + index.php + --------- + + display('form.tpl'); + } else { + // validate after a POST + SmartyValidate::connect($smarty); + if(SmartyValidate::is_valid($_POST)) { + // no errors, done with SmartyValidate + SmartyValidate::disconnect(); + $smarty->display('success.tpl'); + } else { + // error, redraw the form + $smarty->assign($_POST); + $smarty->display('form.tpl'); + } + } + + ?> + + form.tpl + -------- + +
    + {validate id="fullname" message="Full Name Cannot Be Empty"} + Full Name:
    + {validate id="phone" message="Phone Number Must be a Number"} + Phone :
    + {validate id="expdate" message="Exp Date not valid"} + Exp Date:
    + {validate id="email" message="Email not valid"} + Email:
    + {validate id="date" message="Date not valid"} + Date:
    + {validate id="password" message="passwords do not match"} + password:
    + password2:
    + + +
    + + success.tpl + ----------- + + Your form submission succeeded. + + +PUBLIC METHODS: + + function connect(&$smarty, $reset = false) + ------------------------------------------ + + examples: + SmartyValidate::connect($smarty); + SmartyValidate::connect($smarty, true); + + connect() is required on every invocation of SmartyValidate. Pass your + $smarty object as the parameter. This sets up SmartyValidate with $smarty + and auto-registers the default form. Passing the optional second param as + true, the default form registration will get reset. + + function disconnect() + --------------------- + + examples: + SmartyValidate::disconnect(); + + This clears the SmartyValidate session data. Call this after you are + completely finished with SmartyValidate (eg. do NOT call between form + submissions.) + + + function register_object($obj_name,&$object) + -------------------------------------------- + + examples: + SmartyValidate::register_object('myobj',$myobj); + + Register an object with SmartyValidate for use with transform and criteria + functions. Typically do this right after issuing connect(). See the + register_criteria() method for more details. + + + function is_registered_object($obj_name) + ---------------------------------------- + + examples: + if(!SmartyValidate::is_registered_object('myobj')) { ... do something ... } + + Test if an object has been registered. + + + function register_form($form, $reset = false) + --------------------------------------------- + + examples: + SmartyValidate::register_form('myform'); + SmartyValidate::register_form('myform', true); + + Register a form to be validated. Each form must be registered before it can + be validated. You do not have to register the 'default' form, that is done + automatically by SmartyValidate. If you register a form that is already + registered, nothing will happen (returns false). If you have the optional + reset parameter set to true, the form will get reset (essentially + unregistering and reregistering the form.) + + + function is_registered_form($form) + ---------------------------------- + + examples: + if(!SmartyValidate::is_registered_form('myform')) { ... do something ... } + + Test if a form has been registered for validation. + + + function is_valid(&$formvars, $form = 'default') + ------------------------------------------------ + + examples: + SmartyValidate::is_valid($_POST); + SmartyValidate::is_valid($_POST, 'myform'); + + Tests if the current form is valid. You MUST supply the form variable array + to this function, typically $_POST. You can optionally pass a form name as + the second parameter, otherwise the 'default' form is used. Call this after + the form is submitted. + + + function register_criteria($name, $func_name, $form = 'default') + ---------------------------------------------------------------- + + examples: + SmartyValidate::register_criteria('isPass', 'test_password'); + SmartyValidate::register_criteria('isPass', 'test_password','myform'); + SmartyValidate::register_criteria('isPass', 'myobj::test_password'); + SmartyValidate::register_criteria('isPass', 'myobj->test_password'); + + Registers a new criteria function. All functions must be registered before + they can be used (or exist as a plugin.) You can optionally pass a form + name in the case you are not using the 'default' form. Static method calls + are also supported such as foo::bar. You can also register a method of an + object instance such as foo->bar, but you must first register the object + with SmartyValidate. See the register_object() method. Then use your new + criteria within the template: + + {validate field="Password" criteria="isPass" ... } + + Note: the "isCustom" criteria type is no longer supported (or necessary.) + See the "BUILDING YOUR OWN" section. + + function is_registered_criteria($func_name, $form = 'default') + -------------------------------------------------------------- + + examples: + if(SmartyValidate::is_registered_criteria('isPass')) { ... } + + Tests to see if a criteria function has been registered. + + + function register_transform($name, $func_name, $form = 'default') + ----------------------------------------------------------------- + + examples: + SmartyValidate::register_transform('upper','strtoupper'); + SmartyValidate::register_transform('upper','strtoupper','myform'); + + Registers a function to use with "transform" parameter. All functions must + be registered before they can be used (or exist as a plugin.) You can + optinally pass a form name in the case you are not using the 'default' + form. 'trim' is already registered by default. + + + function is_registered_transform($func_name, $form = 'default') + --------------------------------------------------------------- + + examples: + if(SmartyValidate::is_registered_transform('upper')) { ... } + + Tests to see if a transform function has been registered. + + + function register_validator($id, $field, $criteria, $empty = false, $halt = + false, $transform = null, $form = 'default') + --------------------------------------------------------------------------- + + examples: + + SmartyValidate::register_validator('fullname', 'FullName', 'notEmpty'); + SmartyValidate::register_validator('fullname', 'FullName', 'notEmpty', true); + SmartyValidate::register_validator('fullname', 'FullName', 'notEmpty', true, + false, 'trim', 'myform'); + + Register a validator with the form. You must register at least one + validator. If you specify multiple fields, separate them with a colon and + they will be passed into the validator as params field2, field3, etc. + + Example: + + SmartyValidate::register_validator('passcheck', 'pass1:pass2', 'isEqual'); + + {validator id="passcheck" message="your passwords must match"} + + + function set_page($page, $form = 'default') + --------------------------------------------------------------- + + examples: + SmartyValidate::set_page('1')); + + When doing multi-page forms, this value must be set proir to drawing each + page. Each validator must have a page="1" attribute for the given page. + + +SMARTYVALIDATE TEMPLATE VARS: + + For each form, the variable {$validate.formname.is_error} is a boolean set + to true or false indicating whether the form had any failed validators from + the last is_valid() call. is_error is initialized to "false". The default + form is denoted as {$validate.default.is_error}. + + +SMARTYVALIDATE FUNCTION SYNTAX: + + The basic syntax of the {validate ...} function is as follows: + + {validate field="foo" criteria="isNumber" message="foo must be a number"} + + Those are the three required attributes to a {validate ...} + function call. "field" is the form field the validation will + validate, "criteria" is the validation criteria, and "message" is + the message that will be displayed when an error occurs. + + +OPTIONAL FUNCTION ATTRIBUTES: + + FORM + ---- + + {validate form="foo" ...} + + If you are using a registered form other than the "default" form, + you must supply the form name with each corresponding validate tag. + + + TRANSFORM + --------- + + Note: This attribute has been deprecated, please set your transform functions with + the register_validator() function. + + {validate field="foo" ... transform="trim"} + {validate field="foo" ... transform="trim,upper"} + + "transform" is used to apply a transformation to a form value prior to + validation. For instance, you may want to trim off extra whitespace from + the form value before validating. + + You can apply multiple transform functions to a single form value by + separating them with commas. You must register all transformation functions + with the register_transform() method. By default, 'trim' is registered. + + Transformations will apply to every value of an array. If you want the + transformation applied to the array itself, you must specify with an "@" + symbol in front of each transform function: + + {validate field="foo" ... transform="@notEmpty"} + + If you want only a particular array element transformed, you must specify: + + {validate field="foo[4]" ... transform="notEmpty"} + {validate field="foo[bar]" ... transform="notEmpty"} + + + TRIM + ---- + + Note: the "trim" attribute has been deprecated, set your "trim" behavior + with a transform parameter of 'trim' in the register_validator() function. + Trim will trim whitespace from the form value before being validated, and + before the "empty" or "default" parameters are tested. + + + EMPTY + ----- + + Note: This attribute has been deprecated, please set your "empty" behavior with + the register_validator() function. + + {validate id="foo" ... empty="yes"} + + "empty" determines if the field is allowed to be empty or not. If + allowed, the validation will be skipped when the field is empty. + Note this is ignored with the "notEmpty" criteria. + + + HALT + ---- + + Note: This attribute has been deprecated, please set your "halt" behavior with + the register_validator() function. + + {validate id="foo" ... halt="yes"} + If the validator fails, "halt" determines if any remaining validators for + this form will be processed. If "halt" is yes, validation will stop at this + point. + + + ASSIGN + ------ + + {validate id="foo" ... assign="error"} + + "assign" is used to assign the error message to a template variable + instead of displaying the value. Use this when you don't want the + error message displayed right where the {validate ...} function is + called. + + + APPEND + ------ + + {validate id="foo" ... append="error"} + + "append" is used to append the error message to a template variable as an + array. This is an alternate to "assign". Use this when you want to loop over + multiple validation error messages and display them in one place. Example: + + {foreach from=$error key="key" item="val"} + field: {$key} error: {$val} + {/foreach} + + + PAGE + ---- + + {validate id="foo" page="1" ... message="fooError"} + + When doing multi-page forms, each validator must have a page attribute to + identify the page that it belongs to. The SmartyValidator::set_page('1') + function must be called prior to displaying the given page. + + + +TRANSFORM FUNCTIONS BUNDLED WITH SMARTYVALIDATE: + + + trim + ---- + + example: + + SmartyValidate::register_validator('fullname','FullName','notEmpty',false,false,'trim'); + + "trim": this trims whitespace from the beginning and end of the field. This + is useful to avoid confusing errors just because extra space was typed into + a field. + + default + ------- + + example: + + + SmartyValidate::register_validator('value','Value','isInt',false,false,'default:0'); + + {validate id="value" message="..."} + + "default": This sets the form value to the given default value in the case + it is empty. You can pass the default value as a parameter in the + register_validator() function (see above), or in the template as default="0". + + + makeDate + -------- + + example: + + SmartyValidate::register_validator('start','StartDate','isDate',false,false,'makeDate'); + SmartyValidate::register_validator('start','StartDate:year:month:day','isDate',false,false,'makeDate'); + + {validate id="start" message="..."} + + "makeDate": this creates a date from three other form fields constructed by + using the "field" parameter as the prefix, such as StartDateYear, + StartDateMonth, StartDateDay in the first example. This is the common format + used with date fields generated by {html_select_date}. You can supply three + specific form fields separated by colons as in the second example above. + + Here is a full example of how you might use "makeDate" transform function + and "isDateOnOrAfter" criteria function to compare two dates: + + // in PHP script, setup validators + SmartyValidate::register_validator('setdate', 'EndDate', 'dummyValid', false, false, 'makeDate'); + SmartyValidate::register_validator('compdate', 'StartDate:EndDate', 'isDateOnOrBefore'); + + + // template + {* generate the EndDate value from EndDateYear, EndDateMonth, EndDateDay *} + {validate id="setdate"} + {* generate StartDate, then compare to EndDate *} + {validate is="compdate" message="start date must be on or after end date"} + {html_select_date prefix="StartDate"} + {html_select_date prefix="EndDate"} + {* we need these two hidden form fields to hold the values generated by makeDate *} + + + + +CRITERIA BUNDLED WITH SMARTYVALIDATE: + + This is a list of the possible criteria you can use with + SmartyValidate. Some of them require their own special attributes. + + Note: setting criteria in the template is deprecated, use the + register_validator() function instead. + + notEmpty + -------- + + Tests if a field is empty (zero length). NOTE: using the "empty" flag with + this validator has no effect, it is ignored. + + example: + + PHP: + SmartyValidate::register_validator('v_fullname','FullName','notEmpty'); + + TEMPLATE: + {validate id="v_fullname" message="..."} + + + + isInt + ----- + + Tests if a field is an integer value. + + example: + + PHP: + SmartyValidate::register_validator('v_age','age','isInt'); + + TEMPLATE: + {validate id="v_age" message="..."} + + + + isFloat + ------- + + Tests if a field is a float value. + + example: + + PHP: + SmartyValidate::register_validator('v_fraction','fraction','isFloat'); + + TEMPLATE: + {validate id="v_fraction" message="..."} + + + + isNumber + -------- + + Tests if a field is either an int or float value. + + example: + + PHP: + SmartyValidate::register_validator('v_total','total','isNumber'); + + TEMPLATE: + {validate id="v_total" message="..."} + + + + isPrice + ------- + + Tests if a field has number with two decimal places. + + example: + + PHP: + SmartyValidate::register_validator('v_price','price','isPrice'); + + TEMPLATE: + {validate id="v_price" message="..."} + + + + + isEmail + ------- + + Tests if field is valid Email address syntax. + + example: + + PHP: + SmartyValidate::register_validator('v_email','email','isEmail'); + + TEMPLATE: + {validate id="v_email" message="..."} + + + + + isCCNum + ------- + + Tests if field is a checksummed credit card number. + + example: + + PHP: + SmartyValidate::register_validator('v_ccnum','ccnum','isCCNum'); + + TEMPLATE: + {validate id="v_ccnum" message="..."} + + + + isCCExpDate + ----------- + + Tests if field is valid credit card expiration date. + + example: + + PHP: + SmartyValidate::register_validator('v_ccexp','ccexp','isCCExpDate'); + + TEMPLATE: + + {validate id="v_ccexp" message="..."} + + + isDate + ------ + + Tests if field is valid Date (parsible by strtotime()). + + example: + + PHP: + SmartyValidate::register_validator('v_startDate','startDate','isDate'); + + TEMPLATE: + {validate id="v_startDate" message="..."} + + + + + isURL + ------ + + Tests if field is valid URL (http://www.foo.com/) + + + example: + + PHP: + SmartyValidate::register_validator('v_URL','URL','isURL'); + + TEMPLATE: + {validate id="v_URL" message="..."} + + + + + isEqual + ------- + + Tests if two fields are equal in value. + + + example: + + PHP: + SmartyValidate::register_validator('v_pass','pass:pass2','isEqual'); + + TEMPLATE: + {validate id="v_pass" message="..."} + + + + + + isRange + ------- + + Tests if field is within a given range. Must give low and high params. + + + example: + + PHP: + SmartyValidate::register_validator('v_mynum','num:1:5','isRange'); + + TEMPLATE: + {validate id="v_mynum" message="..."} + + + + isLength + -------- + + Tests if field is a given length. parameters 1 and 2 are min and max. use + -1 for no min or no max. + + example: + + PHP: + SmartyValidate::register_validator('v_username','username:3:10','isLength'); + + TEMPLATE: + {validate id="isLength" message="..."} + + + + isRegExp + -------- + + Tests a field against a regular expression. Expression must be fully + qualified preg_* expression. Note: it is recommended to use a custom plugin + instead of this validator, otherwise syntax limits may be a problem. + + + example: + + PHP: + SmartyValidate::register_validator('v_username','username:!^\w+$!','isLength'); + + TEMPLATE: + {validate id="v_username" message="..."} + + + + + isFileType + ---------- + + Tests if an uploaded file is a given type (just checks the extention + name.) Note: This function is not backward compatible prior to version 2.4. + + example: + + PHP: + SmartyValidate::register_validator('v_myfile','myfile:jpg,gif,png','isFileType'); + + TEMPLATE: + {validate id="v_myfile" message="..."} + + + + isFileSize + ---------- + + Tests if an uploaded file is under a given size. Size param can be suffixed + with "b" for bytes (default), "k" for kilobytes, "m" for megabytes and "g" + for gigabytes (kb, mb, and gb also work.) Note: This function is not + backward compatible prior to version 2.4. + + example: + + PHP: + SmartyValidate::register_validator('v_myimage','myimage:50k','isFileSize'); + + {validate id="v_myimage" message="..."} + + + + dummyValid + ---------- + + This is a dummy criteria that always validates to true. This is useful to + apply a transformation to a field without actually applying a validation. + NOTE: Using the "empty" flag with this validator is ignored, dummyValid + always validates true anyways. + + + example: + + PHP: + + SmartyValidate::register_validator('v_initdate','StartDate','dummyValid',false,false,'makeDate'); + + TEMPLATE: + {validate id="v_initdate"} + + + + isDateEqual + ----------- + + Tests if a date is equal to another. The dates must be parsible by strtotime(). + + + example: + + PHP: + SmartyValidate::register_validator('date_equal', 'StartDate:EndDate', 'isDateEqual'); + + TEMPLATE: + {validate id="date_equal" message="..."} + + + + + isDateBefore + ------------ + isDateAfter + ----------- + isDateOnOrBefore + ---------------- + isDateOnOrAfter + --------------- + + These all work similar to "isDateEqual" example above, but testing the dates + according to their respective function. + + + isCustom + -------- + + "isCustom" HAS BEEN REMOVED. Please see BUILDING YOUR OWN directly below. + +VALIDATE INIT +------------- + + Note: validate_init is deprecated now that we have register_validator(), + it shouldn't be necessary any more with no criteria in the templates. + + example: + {validate_init form="foobar" halt="yes" assign="error_msg"} + {validate field="name" criteria="notEmpty" message="name cannot be empty"} + {validate field="pass" criteria="notEmpty" message="pass cannot be empty"} + + {validate_init ... } sets parameter values that are implicitly passed to + each {validate ... } tag thereafter. This keeps the repeated verbosity of + {validate ... } tags to a minimum. Any initialized parameter can be + overridden in each {validate ... } tag. You can re-initialize the + parameters by calling {validate_init ... } again. + + +BUILDING YOUR OWN CRITERIA/TRANSFORM FUNCTIONS: + + Building your own custom functions has never been easier. First, we'll make + up a couple of new functions in the template. We'll make one criteria + function and one transform function. + + "isValidPassword" and "upper" are names we are using in the validator + registration reference your new custom functions. These are not necessarily + real PHP function names, it just the names used by the validator. + + You can do one of two things: make Smarty plugins so the new functions are + automatically found and used, or write PHP functions and register them + directly. + + SMARTY_PLUGIN METHOD: + + In your Smarty plugin directory, create a new file named + validate_TYPE.NAME.php where TYPE is either 'criteria' or 'transform', and + NAME is the name of the new function. The corresponding function names in + the plugin files must follow the convention smarty_validate_TYPE_NAME() + where TYPE and NAME are the same TYPE and NAME from the filename. The NAME + is the criteria/transform name that will be used in the template. In our + example, the filenames will be validate_criteria.isValidPassword.php, and + validate_transform.upper.php. (The template will be calling + criteria="isValidPassword" and transform="upper") + + + validate_criteria_isValidPassword.php + ------------------------------------- + + + + validate_transform_upper.php + ---------------------------- + + + + Your criteria functions must contain the four parameters given in the + example above. The first parameter is the form field value being validated. + The second is the boolean "empty" value given as a parameter to the + validator (or false if none was given). $params contains all the parameters + passed to the validator, and $formavars contains all the form information. + The last two are passed by reference so you can edit the original values if + need be. + + All custom criteria should return a boolean "true" or "false" value to + indicate to SmartyValidate that the validation passed or failed. You do NOT + print error messages inside the function, except for errors dealing with a + misconfiguration of the validator such as a missing parameter. If the + validator fails, the error message for the person filling out the form + should already be set in the template {validator ... message="error!"} + + Transform functions have three parameters, the first being the field value + being transformed, and the second is all the parameters passed to the + validator, and the third is the form variables. The last two are passed by + reference so you can edit the original values if need be. The transform + function should return the transformed value of $value. + + If the file names and function names follow the above convention, no + registration of the functions are necessary, SmartyValidate will locate and + use the plugins. All of the functions that ship with SmartyValidate are plugins. + + +MANUAL REGISTER METHOD: + + You can manually register your functions instead of using plugins. This is + useful if you have a function specific to one application and a Smarty + plugin may not be the most practical place for it. You can also register + class methods this way. + + First example will be a straight forward PHP function: + + function check_pass($value, $empty, &$params, &$formvars) { + // do your logic here, check password, return true or false + } + + After your function exists, you can register it with SmartyValidate: + + SmartyValidate::register_criteria('isValidPassword','check_pass'); + + Transformation functions are done the same way: + + SmartyValidate::register_transform('upper','my_upper_func'); + + You can also register class methods. First, you must register the object + with SmartyValidate, then register the method(s): + + SmartyValidate::register_object('my_obj', $my_obj); + SmartyValidate::register_criteria('isValidPassword','myobj->check_pass'); + SmartyValidate::register_transform('upper','myobj->my_upper_method'); + + Calling PHP functions or class methods look exactly the same, you just use + the registered name(s) like so: + + SmartyValidate::register_validator('v_foo','foo','isValidPassword',false,false,'upper'); + + Just like functions that come with SmartyValidator, all functions are + applied to every element of an array coming from the form. If you want your + function to act on the array itself, you must specify that in the + registration: + + SmartyValidate::register_validator('v_foo','foo','@isValidPassword',false,false,'@upper'); + + If you want a specific array element validated, you must specify: + + SmartyValidate::register_validator('v_foo','foo[4]','isValidPassword',false,false,'upper'); + SmartyValidate::register_validator('v_foo','foo[bar]','isValidPassword',false,false,'upper'); + + + +CREDITS: + + Thanks to the many people who have submitted bug reports, suggestions, etc. + + Edwin Protomo + John Blyberg + Alexey Kuimov + boots (from forums) + xces (from forums) + electr0n (from forums) + Justin (from forums) + hristov (form forums) + + Anyone I missed, let me know! + + +COPYRIGHT: + Copyright(c) 2004-2005 New Digital Group, Inc. All rights reserved. + + 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. diff --git a/docs/spb_db.txt b/docs/spb_db.txt new file mode 100755 index 0000000..6345fe5 --- /dev/null +++ b/docs/spb_db.txt @@ -0,0 +1,35 @@ + + ========================================================== + CONSIDERATIONS AROUND SIMPLEPHPBLOG AND ITS STORING SYSTEM + ========================================================== + + - SimplePHPBlog flat "db" structure + + [$content] + | + |-- [$year] // two-digit year ID (05 stands for 2005) + | | + | |-- [$month] //two-digit month ID (01 stands for January) + | | + | |-- entryYYMMDD-HHMMSS.txt + | |-- [entryYYMMDD-HHMMSS] + | | + | |-- rating.txt + | |-- view_counter.txt + | |-- [comments] + | | + | |-- commentYYMMDD-HHMMSS.txt + | + |-- [static] + | + |-- $filename.txt + + + Due to its nature of name of a file, entryYYMMDD-HHMMSS.txt must be + univocal, and therefore it can be considered as the ID field of a DB + table. + + Comment DBs are associated to the entries using the file name (ID) of + the entry, deprived of its extension (.txt) as the name of the directory + which will contain them. + diff --git a/fp-content/delete.me b/fp-content/delete.me new file mode 100644 index 0000000..2995a4d --- /dev/null +++ b/fp-content/delete.me @@ -0,0 +1 @@ +dummy \ No newline at end of file diff --git a/fp-defaults/plugins.conf.php b/fp-defaults/plugins.conf.php new file mode 100755 index 0000000..25e871d --- /dev/null +++ b/fp-defaults/plugins.conf.php @@ -0,0 +1,32 @@ + diff --git a/fp-defaults/settings-defaults.php b/fp-defaults/settings-defaults.php new file mode 100755 index 0000000..fedc35c --- /dev/null +++ b/fp-defaults/settings-defaults.php @@ -0,0 +1,31 @@ + + array ( + 'www' => 'http://localhost', + 'title' => 'FlatPress', + 'subtitle' => 'My FlatPress blog', + 'footer' => '', + 'author' => 'admin', + 'email' => 'webmaster@localhost.com', + 'startpage' => 'about', + 'maxentries' => '5', + 'notify' => true, + 'theme' => 'leggero', + 'style' => 'leggero', + 'blogid' => 'fpdefid', + 'lang' => 'en-us', + 'charset' => 'utf-8', + ), + 'locale' => + array ( + 'timeoffset' => '2', + 'timeformat' => '%H:%M:%S', + 'dateformat' => '%A, %B %e, %Y', + 'charset' => 'utf-8', + 'lang' => 'en-us', + ) +); + +?> diff --git a/fp-defaults/widgets.conf.php b/fp-defaults/widgets.conf.php new file mode 100755 index 0000000..f41a126 --- /dev/null +++ b/fp-defaults/widgets.conf.php @@ -0,0 +1,45 @@ + + array ( + // (no widgets) + ), + + // Left side widgets. Put here blocks which will appear + // on the left side + // (Theme dependant) + + 'left' => + array ( + // (no widgets) + ), + + + // Right side widgets + 'right' => + array ( + 'adminarea', + 'blockparser:menu', + 'categories', + 'archives', + //'calendar', // quite time consuming, not really recommended + 'lastentries', + // 'lastcomments', + 'searchbox', + ), + + 'bottom' => + array ( + // (no widgets) + ), + + +); + +?> diff --git a/fp-includes/core/core.administration.php b/fp-includes/core/core.administration.php new file mode 100755 index 0000000..faf77f2 --- /dev/null +++ b/fp-includes/core/core.administration.php @@ -0,0 +1,64 @@ + diff --git a/fp-includes/core/core.blogdb.php b/fp-includes/core/core.blogdb.php new file mode 100755 index 0000000..98fc604 --- /dev/null +++ b/fp-includes/core/core.blogdb.php @@ -0,0 +1,144 @@ + + */ + + /** + * entry id prefix and identifier + */ + define('BDB_ENTRY', 'entry'); + /** + * comment id prefix and identifier + */ + define('BDB_COMMENT', 'comment'); + + /** + * default file extension + */ + define('EXT', '.txt'); + + + + + /** + * function bdb_idtofile + * + *

    Takes the id $id and returns a filepath

    + * + * @param string $id string formatted like "prefixYYMMDD-HHMMSS.EXT" + * @return string + */ + function bdb_idtofile($id,$type=null) { + + $fname = $id.EXT; + + $date = date_from_id($id); + + if (!$date) + return false; + + $path = CONTENT_DIR . $date['y'] . '/' . $date['m'] . '/'; + if ($type == null || $type == BDB_ENTRY) { + $path .= $fname; + } elseif ($type == BDB_COMMENT) { + $path .= $id . '/comments/'; + } + + return $path; + + } + + + /** + * function bdb_idfromtime + * + *

    Returns a well formatted id for entry type specified in $type + * and date eventually specified in $date;

    + * + * @param string $type one of the BDB_ constants + * @param int $timestamp UNIX timestamp + * @return string + */ + function bdb_idfromtime($type, $timestamp=null) { + if (!$timestamp) + $timestamp=time(); + + /*if (!ctype_digit($timestamp)) { + trigger_error("bdb_idfromtime(): + $timestamp Not a valid timestamp", E_USER_WARNING); + }*/ + return $type . date('ymd-His', $timestamp); + } + + + /** + * function bdb_filetoid + * + *

    Cosmetic wrapper to basename($file, EXT)

    + * + * @param string $file filepath of the blogdb entry + * @return string + * + * @todo validate returned id + */ + function bdb_filetoid($file) { + + return basename($file, EXT); + + } + + + /** + * function bdb_parse_entry + * + *

    Parses the entry file passed as parameter; returns an associative array + * of the file content

    + * Tipically, entry arrays are usually made of these keys + * - VERSION : SimplePHPBlog or compatible blogs' version identifier string + * - SUBJECT : Subject of the entry + * - CONTENT : Content of the entry + * - DATE : UNIX filestamp to format by {@link date_format()}. + * + * comments usually provide also + * - NAME : author name + * - EMAIL : author email (if any) + * - URL : author website url (if any) + * + * A common usage of the function could be + * + * + * + * + * @param string $file filepath of the blogdb entry + * @return string + * + * @todo validate returned id + */ + function bdb_parse_entry($id, $type=null) { + + if (file_exists($id)) + $file = $id; + else + $file = bdb_idtofile($id, $type); + + + if (file_exists($file)) { + $contents = io_load_file($file); + // TODO: here we must add compatibility to encoding conversion! + // if "dumb" (legacy :D) mode is enabled (set to true in default.php, then we set parsing + // to ignore array key case (defaults to true i.e. check them to be uppercase or failing otherwise + $entry = utils_kexplode($contents, '|', !DUMB_MODE_ENABLED); + + return $entry; + } else return false; + + } + +?> \ No newline at end of file diff --git a/fp-includes/core/core.cache.php b/fp-includes/core/core.cache.php new file mode 100755 index 0000000..36b539c --- /dev/null +++ b/fp-includes/core/core.cache.php @@ -0,0 +1,94 @@ +_cachefile) + trigger_error('CACHE: no cache file specified'); + + $varname = $this->_varname; + + if (file_exists($this->_cachefile)) { + //include($this->_cachefile); + $var = io_load_file($this->_cachefile); + $this->_list = unserialize($var); + } else { + parent::fs_filelister(); + + $this->save(); + } + + return $this->_list; + + } + + function checksorting() { + + list($k1) = each($this->_list); + list($k2) = each($this->_list); + + // decreasing order + + if ((FP_SORTING==SORT_DESC) & (strcmp($k1, $k2) < 0)) { + $this->save; + } + + + + + } + + function save() { + + + // TODO: re-think this :) + // reverse sorting on save is an acceptable overhead, + // still this is quite an hack + + krsort($this->_list); + $succ = io_write_file($this->_cachefile, serialize($this->_list)); + + if (!$succ){ + trigger_error("Error while saving data in {$this->_cachefile}", + E_USER_WARNING); + return false; + + + } else return $this->_list; + + } + + function getList() { + return $this->_list; + } + + function get($id) { + return isset($this->_list[$id])? $this->_list[$id] : false; + } + + function add($id, $val) { + $this->_list[$id]=$val; + + return $this->save(); + } + + function delete($entryid) { + $cache =& $this->_list; + unset($cache[$entryid]); // if id found, it is deleted + + return $this->save(); + } + + function purge() { + return fs_delete($this->_cachefile); + } + + } + +?> \ No newline at end of file diff --git a/fp-includes/core/core.comment.php b/fp-includes/core/core.comment.php new file mode 100755 index 0000000..06a74c8 --- /dev/null +++ b/fp-includes/core/core.comment.php @@ -0,0 +1,154 @@ +_directory = $f; + parent::fs_filelister(); + //substr(bdb_idtofile($id), -strlen(EXT)); + } + + function _checkFile($directory, $file) { + $f = "$directory/$file"; + if (fnmatch('comment*'.EXT, $file)) { + array_push($this->_list, basename($file,EXT)); + return 0; + } + } + + // overrides parent method to return sorted results + function getList() { + sort($this->_list); + return parent::getList(); + } + + } + + + /** + * function bdb_get_comments + * + *

    On success returns an array containing the comment IDs, associated to + * the entry ID in $id

    + *

    On failure returns false

    + * + * @param string $id string formatted like "prefixYYMMDD-HHMMSS.EXT" + * @return mixed + * + * @see bdb_idtofile() + */ + function comment_getlist($id) { + $obj =& new comment_indexer($id); //todo change syntax + return $obj->getList(); + + } + + function comment_parse($entryid, $id) { + + $f = comment_exists($entryid, $id); + + + if (!$f) return false; + + + $fc = io_load_file($f); + $arr = utils_kexplode($fc); + + //$arr['EMAIL'] = apply_filters('comment_email', $arr['EMAIL']); + // hackish: dash to underscore for ip-address :( todo: clean this up here or somewhere else + //$arr['ip_address'] = $arr['ip-address']; + return array_change_key_case($arr, CASE_LOWER); + + } + + function comment_exists($entryid, $id) { + if (!preg_match('|^comment[0-9]{6}-[0-9]{6}$|', $id)) + return false; + $f = entry_exists($entryid); + if (!$f) return false; + + $f2 = substr($f, 0, -strlen(EXT)) . '/comments/' . $id.EXT; + if (!file_exists($f2)) return false; + + return $f2; + + } + + + function comment_clean(&$arr) { + $arr['name'] = apply_filters('pre_comment_author_name', stripslashes($arr['name'])); + if (isset($arr['email'])) + $arr['email'] = apply_filters('pre_comment_author_email', $arr['email']); + if (isset($arr['url'])) + $arr['url'] = apply_filters('pre_comment_author_url', $arr['url']); + $arr['content'] = apply_filters('pre_comment_content', stripslashes($arr['content'])); + return $arr; + } + + + /** + * function bdb_save_comment + * + *

    Saves the content of the $comment array, associating it to the entry-ID $id.

    + *

    $comment must be formatted as the one returned by {@link bdb_parse_entry()}.

    + *

    Returns true on success, or false on failure

    + * + * @param string $id string formatted like "prefixYYMMDD-HHMMSS" + * @param array $comment array formatted as the one returned by {@link bdb_parse_entry()} + * @return bool + * + * @see bdb_parse_entry() + */ + function comment_save($id, $comment) { + + comment_clean($comment); + + $comment = array_change_key_case($comment, CASE_UPPER); + + $comment_dir = bdb_idtofile($id,BDB_COMMENT); + + $comment['DATE'] = date_time(); + $id = bdb_idfromtime(BDB_COMMENT, $comment['DATE']); + $f = $comment_dir . $id . EXT; + $str = utils_kimplode($comment); + if (io_write_file($f, $str)) + return $id; + + + return false; + + + } + + + + + /** + * function comment_delete + * + *

    Deletes the $id comment

    + *

    Returns true on success, or false on failure

    + * + * @param string $id string formatted like "entryYYMMDD-HHMMSS" + * @param string $comment_id string representig comment id as in "commentYYMMDD-HHMMSS" + * @return bool + * + * @see entry_delete() + */ + function comment_delete($id, $comment_id) { + $comment_dir = bdb_idtofile($id,BDB_COMMENT); + $f = $comment_dir . $comment_id .EXT; + return fs_delete($f); + } + + + function dummy_comment($val) { + return $val; + } + + add_filter('comment_validate', 'dummy_comment'); + + + +?> \ No newline at end of file diff --git a/fp-includes/core/core.config.php b/fp-includes/core/core.config.php new file mode 100755 index 0000000..e34bdc3 --- /dev/null +++ b/fp-includes/core/core.config.php @@ -0,0 +1,53 @@ + $conf_arr); + return system_save($conffile, $arr); + } + +?> \ No newline at end of file diff --git a/fp-includes/core/core.cookie.php b/fp-includes/core/core.cookie.php new file mode 100644 index 0000000..bf435e9 --- /dev/null +++ b/fp-includes/core/core.cookie.php @@ -0,0 +1,169 @@ + $_COOKIE[USER_COOKIE], 'password' => $_COOKIE[PASS_COOKIE]); +} + +endif; + +function cookie_set($username, $password, $already_md5 = false, $home = '', $siteurl = '', $remember = false) { + if ( !$already_md5 ) + $password = md5( md5($password) ); // Double hash the password in the cookie. + + if ( empty($home) ) + $cookiepath = COOKIEPATH; + else + $cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' ); + + if ( empty($siteurl) ) { + $sitecookiepath = SITECOOKIEPATH; + $cookiehash = COOKIEHASH; + } else { + $sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' ); + $cookiehash = md5($siteurl); + } + + if ( $remember ) + $expire = time() + 31536000; + else + $expire = 0; + + setcookie(USER_COOKIE, $username, $expire, $cookiepath, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, $password, $expire, $cookiepath, COOKIE_DOMAIN); + + if ( $cookiepath != $sitecookiepath ) { + setcookie(USER_COOKIE, $username, $expire, $sitecookiepath, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, $password, $expire, $sitecookiepath, COOKIE_DOMAIN); + } +} + +function cookie_clear() { + setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); +} + + +if ( !function_exists('wp_login') ) : +function wp_login($username, $password, $already_md5 = false) { + global $wpdb, $error; + + $username = sanitize_user($username); + + if ( '' == $username ) + return false; + + if ( '' == $password ) { + $error = __('ERROR: The password field is empty.'); + return false; + } + + $login = get_userdatabylogin($username); + //$login = $wpdb->get_row("SELECT ID, user_login, user_pass FROM $wpdb->users WHERE user_login = '$username'"); + + if (!$login) { + $error = __('ERROR: Invalid username.'); + return false; + } else { + // If the password is already_md5, it has been double hashed. + // Otherwise, it is plain text. + if ( ($already_md5 && md5($login->user_pass) == $password) || ($login->user_login == $username && $login->user_pass == md5($password)) ) { + return true; + } else { + $error = __('ERROR: Incorrect password.'); + $pwd = ''; + return false; + } + } +} +endif; + +if ( !function_exists('is_user_logged_in') ) : +function is_user_logged_in() { + $user = wp_get_current_user(); + + if ( $user->id == 0 ) + return false; + + return true; +} +endif; + +if ( !function_exists('auth_redirect') ) : +function auth_redirect() { + // Checks if a user is logged in, if not redirects them to the login page + if ( (!empty($_COOKIE[USER_COOKIE]) && + !wp_login($_COOKIE[USER_COOKIE], $_COOKIE[PASS_COOKIE], true)) || + (empty($_COOKIE[USER_COOKIE])) ) { + nocache_headers(); + + wp_redirect(get_option('siteurl') . '/wp-login.php?redirect_to=' . urlencode($_SERVER['REQUEST_URI'])); + exit(); + } +} +endif; + + +?> \ No newline at end of file diff --git a/fp-includes/core/core.date.php b/fp-includes/core/core.date.php new file mode 100755 index 0000000..6e1ec52 --- /dev/null +++ b/fp-includes/core/core.date.php @@ -0,0 +1,73 @@ + diff --git a/fp-includes/core/core.draft.php b/fp-includes/core/core.draft.php new file mode 100644 index 0000000..b82e57d --- /dev/null +++ b/fp-includes/core/core.draft.php @@ -0,0 +1,227 @@ +_cachefile = CACHE_DIR . 'draft_index.php'; + return parent::fs_filelister(); + } + + + function _checkFile($directory, $file) { + + $f = "$directory/$file"; + if ( is_dir($f) && ctype_digit($file)) { + return 1; + } + + if (fnmatch('entry*'.EXT, $file)) { + $id=basename($file,EXT); + $arr=draft_parse($id); + + //$this->add($id, $arr['subject']); + $this->_list[$id] = $arr['subject']; + + return 0; + } + + } + + } + + function &draft_init() { + global $draftdb; + if (!isset($draftdb)) + $draftdb =& new draft_indexer; + return $draftdb; + } + + + function draft_getlist() { + + static $list = array(); + + if (!$list) { + $obj =& draft_init(); + $list = $obj->getList(); + krsort($list); + } + + return $list; + + } + + function draft_parse($id) { + + if ($fname=draft_exists($id)) { + + $entry = io_load_file($fname); + + $entry = array_change_key_case(utils_kexplode($entry)); + if (!isset($entry['categories'])) + $entry['categories'] = array(); + else + $entry['categories'] = explode(',', $entry['categories']); + + return $entry; + } + return array(); + } + + + function draft_save($entry, $id=null, $update_date=false) { + + if (!$id) { + $id = bdb_idfromtime('entry', $entry['date']); + } + + $ed = entry_dir($id); + $dd = draft_dir($id); + + if (file_exists($ed.EXT)) { + + // move collateral files + @rename($ed, $dd); + + // delete normal entry + fs_delete($ed.EXT); + + // remove from normal flow + $o =& entry_init(); + $o->delete($id); + + } + + $entry = array_change_key_case($entry, CASE_UPPER); + if (isset($entry['CATEGORIES'])) { + + if (is_array($entry['CATEGORIES'])) + $entry['CATEGORIES'] = implode(',',$entry['CATEGORIES']); + else + trigger_error("Failed saving draft. Expected 'categories' to be + an array, found " . gettype($entry['CATEGORIES']), E_USER_ERROR); + } + + $string = utils_kimplode($entry); + + + if (!io_write_file($dd.EXT, $string)) { + return false; + } else return $id; + + return false; + + } + + function draft_dir($id) { + if (!preg_match('|^entry[0-9]{6}-[0-9]{6}$|', $id)) + return false; + //$date = date_from_id($id); + //$f = CONTENT_DIR . "{$date['y']}/{$date['m']}/$id"; + return DRAFT_DIR . $id; + //return $f; + + + } + + function draft_exists($id) { + + if (!user_loggedin()) + return false; + + $dir = draft_dir($id); + if (!$dir) + return false; + + $f = $dir .EXT; + if (file_exists($f)) + return $f; + + return false; + } + + function draft_delete($id) { + $dir = draft_dir($id); + + $f=$dir.EXT; + if (!file_exists($f)) + return false; + + //$draftdb =& draft_init(); + //$draftdb->delete($id); + fs_delete_recursive($dir); + + return fs_delete($f); + } + + /* + function draft_from_entry($entryid) { + $dir = entry_dir($entryid); + //$dir2 = str_replace('entry', 'draft', $dir); + $dir2 = draft_dir($entryid); + @rename($dir, $dir2); + @rename($dir.EXT, $dir2.EXT); + } + */ + + function draft_to_entry($draftid) { + + $dir = draft_dir($draftid); + $dir2 = entry_dir($draftid); + + @rename($dir, $dir2); + draft_delete($draftid); + } + + + function smarty_block_draftlist($params, $content, &$smarty, &$repeat) { + global $fpdb; + + if ($list = draft_getlist()) { + $smarty->assign('draft_list', $list); + return $content; + } + + } + + + function smarty_block_draft($params, $content, &$smarty, &$repeat) { + + static $list = array(); + + $smarty->assign(array( 'subject'=>'', + 'content'=>'', + 'date'=>'', + 'author'=>'', + 'version'=>'', + 'id'=>'' + ) + ); + $arr =& $smarty->get_template_vars('draft_list'); + + list($id, $subject)=each($arr); + + if ($id){ + $smarty->assign('subject', $subject); + $smarty->assign('id', $id); + } + + $repeat = (bool) $id; + + return $content; + } + + + + $smarty->register_block('draft_block', 'smarty_block_draftlist'); + $smarty->register_block('draft', 'smarty_block_draft'); + + +?> diff --git a/fp-includes/core/core.entry.php b/fp-includes/core/core.entry.php new file mode 100755 index 0000000..c85400e --- /dev/null +++ b/fp-includes/core/core.entry.php @@ -0,0 +1,508 @@ +_cachefile = CACHE_DIR . CACHE_FILE; + + return parent::cache_filelister(); + } + + function _checkFile($directory, $file) { + $f = "$directory/$file"; + if ( is_dir($f) && ctype_digit($file)) { + return 1; + } + + if (fnmatch('entry*'.EXT, $file)) { + $id=basename($file,EXT); + $arr=entry_parse($id); + + $this->addEntry($id, $arr); + + return 0; + } + } + + + function addEntry($id, $arr) { + + + if ($arr) { + // do_action('publish_post', $id, $arr); + $this->_list[$id]=array( + 'subject' => $arr['subject'], + 'categories' => + ( + isset($arr['categories'])? + $arr['categories'] + : + array() + ) + ); + + } + + } + + + function save() { + do_action('cache_save'); + return parent::save(); + } + + function add($id, $val) { + + $this->_list[$id]=array('subject' => $val['SUBJECT'], + 'categories' => + (isset($val['CATEGORIES'])? + $val['CATEGORIES'] : array())); + + return $this->save(); + } + + function get($id) { + if (isset($this->_list[$id])) + return $this->_list[$id]; + else { + //trigger_error("entry_lister: No such element \"$id\" in + //list", E_USER_WARNING); + return false; + } + } + + + } + class entry_archives extends fs_filelister { + + var $_directory = CONTENT_DIR; + var $_y = null; + var $_m = null; + var $_d = null; + + var $_count = 0; + + var $_filter = 'entry*'; + + function entry_archives($y, $m = null, $d = null) { + + $this->_y = $y; + $this->_m = $m; + $this->_d = $d; + + $this->_directory .= "$y/"; + + if ($m){ + + $this->_directory .= "$m/"; + + if ($d) { + $this->_filter = "entry$y$m$d*"; + } + + } + + return parent::fs_filelister(); + } + + function _checkFile($directory, $file) { + $f = "$directory/$file"; + if ( is_dir($f) && ctype_digit($file)) { + return 1; + } + + if (fnmatch($this->_filter.EXT, $file)) { + $id=basename($file,EXT); + $this->_count++; + array_push($this->_list, $id); + return 0; + } + } + + function getList() { + rsort($this->_list); + return parent::getList(); + } + + function getCount() { + return $this->_count; + } + + } + + /* //work in progress + class entry { + + var $_indexer; + var $id; + + function entry($id, $content) { + //$this->_indexer =& $indexer; + } + + function get($field) { + $field = strtolower($field); + if (!isset($this->$field)) { + // if it is not set + // tries to fetch from the database + $arr = entry_parse($id); + while(list($field, $val) = each($arr)) + $this->$field = $val; + + // if still is not set raises an error + if (!isset($this->$field)) + trigger_error("$field is not set", E_USER_NOTICE); + return; + + + } + + return $this->$field; + + } + + function set($field, $val) { + $field = strtolower($field); + $this->$field = $val; + } + + } + */ + + /** + * function entry_init + * fills the global array containing the entry object + */ + function &entry_init() { + + global $fpdb; + $fpdb->init(); + return $fpdb->_indexer; + + } + + /* + function entry_query($params=array()){ + + global $fpdb; + $queryid = $fpdb->query($params); + $fpdb->doquery($queryid); + + + } + + function entry_hasmore() { + global $fpdb; + return $fpdb->hasmore(); + + } + + function entry_get() { + $fpdb->get(); + } + */ + + function entry_list() { + + $obj =& entry_init(); + + $entry_arr = $obj->getList(); + + + if ($entry_arr) { + krsort($entry_arr); + return $entry_arr; + } + } + + function entry_exists($id) { + $f = entry_dir($id).EXT; + return $f;file_exists($f)? $f : false; + } + + function entry_dir($id) { + if (!preg_match('|^entry[0-9]{6}-[0-9]{6}$|', $id)) + return false; + $date = date_from_id($id); + $f = CONTENT_DIR . "{$date['y']}/{$date['m']}/$id"; + return $f; + + + } + + function entry_parse($id, $incrViews=false) { + + $f = entry_exists($id); + if (!$f) + return array(); + + $fc = io_load_file($f); + + if (!$fc) + return array(); + + $arr = utils_kexplode($fc); + + // propagates the error if entry does not exist + + + if (isset($arr['CATEGORIES']) && // fix to bad old behaviour: + (trim($arr['CATEGORIES']) != '')) { + + + $cats = (array)explode(',',$arr['CATEGORIES']); + $arr['CATEGORIES'] = (array) $cats; + + + + } else $arr['CATEGORIES'] = array(); + + // if (!is_array($arr['CATEGORIES'])) die(); + + if (!isset($arr['AUTHOR'])) { + global $fp_config; + $arr['AUTHOR'] = $fp_config['general']['author']; + } + + return array_change_key_case($arr, CASE_LOWER); + + } + + + /** + * function entry_get_comments + * + * @param string id entry id + * @param array entry entry content array by ref; 'commentcount' field is added to the array + * + * @return object comment_indexer as reference + * + */ + + function &entry_get_comments($id, &$count) { + $obj =& new comment_indexer($id); + + $count = count($obj->getList()); + + return $obj; + + } + + + function entry_categories_encode() { + + if ($string = io_load_file(CONTENT_DIR . 'categories.txt')) { + $lines = explode("\n", trim($string)); + $idstack = $result = $indentstack=array(); + + while (!empty($lines)) { + + $v = array_pop($lines); + + $vt = trim($v); + + if ($vt) { + + $text=''; + $indent = utils_countdashes($vt, $text); + + $val = explode(':', $text); + + $id = trim($val[1]); + $label = trim($val[0]); + + if (empty($indentstack)) { + array_push($indentstack,$indent); + array_push($idstack, $id); + $indent_old = $indent; + } else { + $indent_old = end($indentstack); + } + + if ($indent < $indent_old) { + array_push($indentstack, $indent); + array_push($idstack, $id); + } elseif ($indent > $indent_old) { + $idstack = array($id); + $indentstack = array($indent); + } else { + array_pop($idstack); + $idstack = array($id); + } + + + + $result['rels'][$id] = $idstack; + $result['defs'][$id] = $label; + } + + } + + ksort($result['rels']); + ksort($result['defs']); + + //print_r($result); + + return io_write_file(CONTENT_DIR . 'categories_encoded.dat', serialize($result)); + + } + + return false; + + + } + + /* + + function entry_categories_print(&$lines, &$indentstack, &$result, $params) { + + +} + +*/ + + function entry_categories_get($what=null) { + + global $fpdb; + + $categories = array(); + + if (isset($fpdb->_categories)) { + $categories = $fpdb->_categories; + } else { + + $f = CONTENT_DIR . 'categories_encoded.dat'; + if (file_exists($f)) { + if ($c = io_load_file($f)) + $categories = unserialize($c); + } + + } + + if ($categories) { + + if ($what=='defs' || $what=='rels') + return $categories[$what]; + else + return $categories; + } + return array(); + } + + /** + + flags are actually special categories + which are usually hidden. + + they can be set when editing your entries + to let flatpress perform special actions + + draft: Draft entry (hidden, awaiting publication) + static: Static entry (allows saving an alias, so you can reach it with + ?page=myentry) + commslock: Comments locked (comments disallowed for this entry) + + + */ + + function entry_flags_get() { + + return array( + 'draft', + //'static', + 'commslock' + ); + + + } + + function entry_save($entry_cont, $id=null, $update_index = true) { + + $obj =& entry_init(); + + if (!isset($entry_cont['date'])) { + $entry_cont['date']=date_time(); + } + + $entry = array_change_key_case($entry_cont, CASE_UPPER); + + if (!$id) { + $id = bdb_idfromtime(BDB_ENTRY, $entry['DATE']); + } + do_action('publish_post', $id, $entry_cont); + + $f = bdb_idtofile($id); + + $entry['CONTENT'] = apply_filters('content_save_pre', $entry['CONTENT']); + $entry['SUBJECT'] = apply_filters('title_save_pre', $entry['SUBJECT']); + + $ok = ($update_index) ? $obj->add($id, $entry) : true; + + if ($ok) { + + + if (isset($entry['CATEGORIES'])) { + + if (is_array($entry['CATEGORIES'])) + $entry['CATEGORIES'] = implode(',',$entry['CATEGORIES']); + else + trigger_error("Failed saving entry. Expected 'categories' to be + an array, found " . gettype($entry['CATEGORIES']), E_USER_ERROR); + } + + + $str = utils_kimplode($entry); + + if (!io_write_file($f, $str)) { + if ($update_index) + $obj->delete($id); + return false; + } else return $id; + + } + return false; + + } + + + function entry_delete($id) { + + if ( ! $f = entry_exists($id) ) + return; + + + /* + $d = bdb_idtofile($id,BDB_COMMENT); + fs_delete_recursive("$d"); + + // thanks to cimangi for noticing this + $f = dirname($d) . '/view_counter' .EXT; + fs_delete($f); + + + $f = bdb_idtofile($id); + */ + + $d = entry_dir($id); + fs_delete_recursive($d); + + $obj =& entry_init(); + $obj->delete($id); + + do_action('delete_post', $id); + + return fs_delete($f); + } + + function entry_purge_cache() { + $obj =& entry_init(); + $obj->purge(); + } + //add_action('init', + +?> \ No newline at end of file diff --git a/fp-includes/core/core.fileio.php b/fp-includes/core/core.fileio.php new file mode 100755 index 0000000..06bde73 --- /dev/null +++ b/fp-includes/core/core.fileio.php @@ -0,0 +1,58 @@ + diff --git a/fp-includes/core/core.filesystem.php b/fp-includes/core/core.filesystem.php new file mode 100755 index 0000000..502734f --- /dev/null +++ b/fp-includes/core/core.filesystem.php @@ -0,0 +1,285 @@ + + */ + + + class fs_filelister { + + var $_list = array(); + var $_directory = null; + + + //constructor + function fs_filelister($directory = null) { + if ($directory) $this->_directory = $directory; + $this->_listFiles($this->_directory); + } + + function _checkFile($directory, $file) { + if (!is_dir("$directory/$file")) + array_push($this->_list, $file); + return 0; + } + + function _exitingDir($directory, $file) { + + } + + function _listFiles($directory) { + + // Try to open the directory + if (!file_exists($directory)) return array(); + + if($dir = opendir($directory)) { + // Add the files + while($file = readdir($dir)) { + + if ($file != '.' && $file != '..') { + + $action = $this->_checkFile($directory,$file); + + // $action == 0: ok, go on + // $action == 1: recurse + // $action == 2: exit function + + switch ($action) { + case (1): { + $this->_listFiles("$directory/$file"); + $this->_exitingDir($directory, $file); + break; + } + case (2): { + return false; + } + } + } + + } + + // Finish off the function + closedir($dir); + return true; + } + else return false; + + } + + function getList() { + //$this->_listFiles($this->_directory); + return $this->_list; + } + + } + + class fs_pathlister extends fs_filelister { + function _checkFile($directory, $file) { + $f = "$directory/$file"; + if (!is_dir($f)) + array_push($this->_list, $f); + else + return 1; + } + + } + + // dir list + function fs_list_dirs($dir) { + $dh = opendir($dir); + while (false !== ($filename = readdir($dh))) { + if ( ($filename[0] != '.') ) { + $id = lang_id($filename); + $files[] = $filename; + } + + + } + sort($files); + return $files; + } + + + /** + * function fs_mkdir + * + *

    Function from : {@link http://www.php.net/function.mkdir.php}

    + * + *

    Recursively creates dirs.

    + *

    Returns true on success, else false

    + * + * @param string $path Directory or directories to create + * @param int $mode octal mode value; same as UNIX chmod; defaults to 0777 (rwrwrw); + * @return bool + * + * @todo cleanup & check bool return value + * + */ + function fs_mkdir($dir, $mode=0777) { + if (is_dir($dir) || (@mkdir($dir,$mode))) {@chmod($dir, $mode); return TRUE;} + if (!fs_mkdir(dirname($dir),$mode)) return FALSE; + return (@mkdir($dir,$mode) && @chmod($dir, $mode)); + } + + + + /** + * function fs_delete + * + * Deletes a file and recursively deletes dirs, if they're empty + * + */ + function fs_delete($path) { + + if (file_exists($path)) { + + $fsuccess = unlink($path); + $dsuccess = true; + + while ($dsuccess) { + + $path = dirname($path); + $dsuccess = @rmdir($path); + + } + + // unlink can return both 0 and false -__-' + return ($fsuccess); + + } + + // in our particular implementation + // you can always delete a non existent file; + // anyway, we'll return a value != true + // so that we can anyway track it back + + return 2; + + + } + + /** + * function fs_recursive_chmod + * + * Perform a recursive reset of file permission in the given $path + * and its subdirectories to 0777 + * + * @param $fpath dir path + * @return bool + * + */ + + class fs_chmodder extends fs_filelister { + + var $_chmod=0777; + + function fs_chmodder($directory, $octal=0777) { + $this->_directory = $directory; + $this->_chmod = $octal; + parent::fs_filelister(); + } + + function _checkFile($directory, $file) { + $retval = 0; + $path = "$directory/$file"; + if (is_dir($path)) + $retval = 1; + if (!@chmod($path, $this->_chmod)) + array_push($this->_list, $path); + + return $retval; + } + } + + function fs_chmod_recursive($fpath=FP_CONTENT) { + $obj = new fs_chmodder($fpath); + return $obj->getList(); + } + + + + /** + * recursive deletion + * deletes all files and directories recursively in the given $path + * @param $fpath dir path + * @return bool + */ + + /*class fs_deleter extends fs_filelister { + + function fs_deleter($directory) { + $this->_directory = $directory; + parent::fs_filelister(); + } + + function _checkFile($directory, $file) { + + $path = "$directory/$file"; + + /* + * open dir handle prevents directory deletion of php5 (and probably win) + * thanks to cimangi for noticing and + * giving a possible solution: + * + * filenames are cached and then deleted + // + + if ( is_dir($path) ) { + return 1; + } elseif ( file_exists($path) ) { + array_push($this->_list, $path); + return 0; + } else { + return 2; + } + + } + + } + + */ + + /* + * open dir handle prevents directory deletion of php5 (and probably win) + * thanks to cimangi for noticing and + * giving a possible solution; + * + * paths are now cached and then deleted + */ + + function fs_delete_recursive($path) { + if (file_exists($path)) { + + $obj =& new fs_pathlister($path); + $list = ($obj->getList()); + + unset($obj); + + $elem = null; + while($elem = array_pop($list)) { + $elem; + fs_delete($elem); + } + + + + } + + + return true; + } + + + + function fs_copy($source, $dest) { + if ($contents = io_load_file($source)) { + return io_write_file($dest, $contents); + } + return false; + } + +?> diff --git a/fp-includes/core/core.fpdb.class.php b/fp-includes/core/core.fpdb.class.php new file mode 100644 index 0000000..3d1b5fd --- /dev/null +++ b/fp-includes/core/core.fpdb.class.php @@ -0,0 +1,854 @@ +parse_string($params); + } elseif (is_array($params)) { + $this->validate_array($params); + } else { + trigger_error("FPDB_QueryParams: parameters were not in a valid form", + E_USER_ERROR); + } + + } + + function pad_date($date) { + + if (is_numeric($date) && strlen($date)<=2){ + return str_pad($date,2,'0', STR_PAD_LEFT); + } + + return null; + + } + + function validate_array($params) { + + global $fp_config; + + if (isset($params['id'])) { + + if (entry_exists($params['id'])) { + $this->id = $params['id']; + + } + + } + + if (isset($params['fullparse'])) { + $this->fullparse = + is_string($params['fullparse'])? + ($params['fullparse'] != 'false') + : + $params['fullparse']; + } + + + if (isset($params['y'])) { + $this->y = $this->pad_date($params['y']); + + if ($this->y && isset($params['m'])) { + $this->m = $this->pad_date($params['m']); + + if ($this->m && isset($params['d'])) { + $this->d = $this->pad_date($params['d']); + } + + } + + } + + if (isset($params['random'])) { + $this->random = intval($params['random']); + $this->count = $this->random; + } + + if (isset($params['page'])) { + $this->page = $params['page']; + } else { + $this->page = 1; + } + + if ($this->page<1) { + $this->page=1; + } + + if (isset($params['count'])) { + $this->count = intval($params['count']); + } else { + $this->count = intval($fp_config['general']['maxentries']); + } + + + $this->start = ($this->page - 1) * $this->count; + + + if (isset($params['start'])) { + $this->start = intval($params['start']); + } + + + if (isset($params['category'])) { + $this->category = intval($params['category']); + } + + } + + function parse_string($str) { + $params = utils_kexplode(strtolower($str), ',:', false); + $this->validate_array($params); + } + + } + + class FPDB_Query { + + var $counter = -1; + var $params = null; + var $single = false; + var $pointer = 1; /* pointer points always to NEXT element */ + var $processed = false; + var $ID = 0; /* query id */ + + + var $lastentry = array(null, array()); + var $nextid = ''; + var $previd = ''; + var $currentid = ''; + + function FPDB_Query($params, $ID) { + + global $current_query; + + + $this->params =& new FPDB_QueryParams($params); + $this->ID = $ID; + + if ($this->params->id) { + $this->single = true; + } + + $GLOBALS['current_query'] =& $this; + + } + + function prepare() { + + global $fpdb; + + + $fpdb->init(); + + $entry_index = $fpdb->entry_index; + + if ($this->single) { + $this->_prepare_single($entry_index); + } else { + $this->_prepare_list($entry_index); + if ($this->params->random>0) { + $this->_randomize_list(); + } + } + + $this->counter++; + + + } + + function _prepare_single(&$entry_index) { + + /* + * this should never happen + */ + if (!$this->params->id) + trigger_error("FPDB: no ID found for query {$this->ID}", E_USER_ERROR); + + $qp =& $this->params; + + if (!isset($entry_index[$qp->id])){ + trigger_error("FPDB: no entry found for {$qp->id}", E_USER_WARNING); + return; + } + if ($this->counter < 0) { + + $idlist = array_keys($entry_index); + $fliplist = array_flip($idlist); + + $this->local_index =& $entry_index; + $this->local_list =& $idlist; + + $qp->start = $fliplist[$qp->id]; + $qp->count = 1; + + + } + + $this->pointer = $qp->start; + + } + + function _prepare_list(&$entry_index) { + //global $blog_config; + $qp =& $this->params; + + $entry_num = 0; + + if (!$qp->y){ + + $this->local_list = array_keys($entry_index); + $this->local_index =& $entry_index; + + /* @todo MUST CACHE THIS COUNT! (MUST STRUCT CACHE)*/ + $index_count = count($entry_index); + + } else { + + $obj =& new entry_archives($qp->y, $qp->m, $qp->d); + $filteredkeys = $obj->getList(); + + $index_count = $obj->getCount(); + + $this->local_list =& $filteredkeys; + + } + + if ($qp->count < 0) { + $qp->count = $index_count; + } elseif (($qp->start + $qp->count) > $index_count) { + if ($index_count > 0) + $qp->count = $index_count - $qp->start; + else + $index_count = $qp->start = $qp->count = 0; + } + + $this->pointer = $qp->start; + + + if ($qp->category==0) + return; + + + /* category */ + /* this just SUCKS. need a separate cache... */ + + $relations = entry_categories_get('rels'); + + if (!isset($relations[$qp->category])) + return; + + $catrel = $relations[$qp->category]; + + /* need to search for one more to know if we need a nextpage link */ + $fill = $qp->start + $qp->count + 1; + $i = 0; + $tmp = array(); + + while ($i <= $fill && (list($K, $V) = each($this->local_list))) { + + if (array_intersect($catrel, $this->local_index[$V]['categories'])) { + // in_array($qp->category, $this->local_index[$V]['categories'])) + $tmp[] =& $this->local_list[$K]; + + $i++; + + } + + } + + $this->local_list =& $tmp; + + if ($qp->start + $qp->count > $i) { + $qp->count = $i - $qp->start; + } + + } + + function _randomize_list() { + $qp =& $this->params; + + $i = $qp->random - 1; + $nums = array_keys($this->local_list); + + + if ($qp->random == 1) { + $i = mt_rand(0, end($nums)); + $this->single = true; + $qp->id = $this->local_list[ $i ]; + $this->_prepare_single($this->local_index); + return; + } + + shuffle($nums); + + $newlocal = array(); + do { + $newlocal[ $i ] = $this->local_list[ $nums[$i] ]; + } while($i--); + + $this->local_list = $newlocal; + + if ($qp->count > $qp->random) { + $qp->count = $qp->random; + } + } + + /* reading functions */ + + function hasMore() { + + + $GLOBALS['current_query'] =& $this; + + + if ($this->counter < 0) + $this->prepare(); + + return $this->pointer < $this->params->start + $this->params->count; + } + + function &peekEntry() { + + global $post; + + $qp =& $this->params; + + + if ($this->counter < 0) + $this->prepare(); + + + $this->_fillPrevId(); + $this->_fillNextId(); + + $id = $this->_fillCurrentId(); + + + if ($qp->fullparse && $this->counter <= 0) { + + $cont = array(); + + $cont = entry_parse($id); + if ($cont) { + $this->comments =& new FPDB_CommentList($id, comment_getlist($id)); + + $cont['comments'] = $this->comments->getCount(); + + /* index is updated with full-parsed entry */ + $this->local_index[$id] = $cont; + } + + } else { + + $cont = $this->local_index[$id]; + + } + + + + $post = $cont; + $post['id'] = $id; + + $var = array(&$id, &$cont); + return $var; + + } + + function &getEntry() { + + if (!$this->hasMore()) + return false; + + $var =& $this->peekEntry(); + + $this->lastentry = $var; + + $this->pointer++; + + return $var; + } + + function getLastEntry() { + return $this->lastentry; + } + + function hasComments() { + return $this->comments->getCount(); + } + + + + function _getOffsetId($offset, $assume_pointer=null) { + if (is_int($assume_pointer)) + $i = $assume_pointer + $offset; + else + $i = $this->pointer + $offset; + return isset($this->local_list [ $i ])? $this->local_list [ $i ] : false; + } + + function _fillCurrentId() { + return $this->currentid = $this->_getOffsetId(0); + } + + + function _fillNextId() { + return $this->nextid = $this->_getOffsetId(1); + } + + + function _fillPrevId() { + return $this->previd = $this->_getOffsetId(-1); + } + + function getCurrentId() { + return $this->currentid; + } + + function getNextId() { + return $this->nextid; + } + + function getPrevId() { + return $this->previd; + } + + function getNextPage() { + + if ($this->single){ + $id = $this->_getOffsetId(-1, $this->params->start); + + if ($id) + $label = $this->local_index[$id]['subject']; + else + return false; + + return array($label, $id); + + } + + if ($this->params->page) { + if ($this->_getOffsetId(0, ($this->params->start + $this->params->count))) + return array($GLOBALS['lang']['main']['nextpage'], $this->params->page + 1); + + } + + + } + + function getPrevPage() { + + if ($this->single) { + $id = $this->_getOffsetId(1, $this->params->start); + + if ($id) + $label = $this->local_index[$id]['subject']; + else + return false; + + return array($label, $id); + + } + + if ($this->params->page > 1) { + return array($GLOBALS['lang']['main']['prevpage'], $this->params->page - 1); + } + + } + + + } + + + + class FPDB_CommentList { + + var $count = 0; + var $list = array(); + var $current = ''; + var $entryid = ''; + + function FPDB_CommentList($ID, $array) { + + if (is_array($array)) { + $this->list = $array; + $this->count = count($array); + $this->entryid = $ID; + } + + } + + function getCount() { + return $this->count; + } + + function hasMore() { + + if ($this->count) { + return current($this->list) !== false; + } + + return false; + + } + + function &getComment() { + + if (!$this->hasMore()) + return false; + + list($k,$id) = each($this->list); + + $comment = comment_parse($this->entryid, $id); + $couplet = array(&$id, &$comment); + return $couplet; + + } + + } + + class FPDB { + + var $_indexer = null; + var $queries = array(); + + + function FPDB() { + // constructor + } + + function init() { + if (!$this->_indexer) { + $this->_indexer =& new entry_indexer(); + $this->_categories = entry_categories_get(); + $obj =& $this->_indexer; + $this->entry_index =& $obj->getList(); + + } + } + + function reset($queryId=null) { + + switch ($queryId) { + case null: $this->_query = array(); break; + default: unset($this->_query[$queryId]); + } + + + } + + /** + * function query + * @param mixed params + * $params may be an associative array or a query string with the following syntax: + * 'key:val,key:val,key:val'; + * example: $params = 'start:0,count:5';
    + * is a convenient way to express + * $params = array('start'=>0,'count'=>5);
    + * + * Valid parameters: + * + * start (int) first entry to show (counting from 0 + * to the total number of entries). + * Defaults to 0. + * + * count (int) offset from start (e.g. for the first 5 entries, + * you'll have start=0 and count=5). + * Defaults to $blog_config['MAXENTRIES'] + * + * page (int) page number (counting from 1 to + * n=ceil(num_entries/maxentries_setting)) + * This is a shortcut for setting both start and count + * and overrides them, if they're set too + * + * id (string) entry or static page id + * + * get (string) 'entry' or 'static' defaults to 'entry'. <-- not anymore + * + * y (string) two digit year (06 means 2006) + * m (string) two digit month (06 means June); 'y' must be set + * d (string) two digit for day; 'y' and 'm' must be set + * + * + * fullparse (bool) non-full-parsed entries get their values + * right from the indexed list (or cache). + * These values are 'subject', 'content' and 'categories'. + * If you need any of the other values, you'll need to + * set fullparse=true; defaults to false. + * + */ + + function query($params=array()) { + + static $queryId=-1; + $queryId++; + + $this->queries[$queryId] =& new FPDB_Query($params, $queryId); + + + $this->init(); + + return $queryId; + + + } + + function doquery($queryId=0) { + + if (isset($this->queries[$queryId])) { + $q =& $this->queries[$queryId]; + } else { + return false; + trigger_error("FPDB: no such query ID ($queryId)", E_USER_WARNING); + } + + if (!$q) + return false; + + //$this->init(); + + /** + @todo return true/false + */ + return $q->prepare($this->entry_index); + } + + // "get" functions. todo: move out? + + function &getQuery($queryId=0) { + $o = null; + if (isset($this->queries[$queryId])) + $o =& $this->queries[$queryId]; + return $o; + } + } + + + // SMARTY FUNCTIONS ---------------------------------------------------- + + + function smarty_block_entries($params, $content, &$smarty, &$repeat) { + global $fpdb; + + return $content; + + $show = false; + + $smarty->assign('prev_entry_day', ''); + + if ($repeat) { + + if (isset($params['alwaysshow']) && $params['alwaysshow']) { + //$fpdb->doquery(); + $repeat = false; + return $content; + } + + //$show = @$fpdb->doquery(); + + } else { + + if (!isset($fpdb->queries[0]->comments) || !$fpdb->queries[0]->comments) + $fpdb->reset(0); + $show = true; + + } + + $show = true; + + + + + if ($show) + return $content; + + } + + + function smarty_block_entry($params, $content, &$smarty, &$repeat) { + global $fpdb; + + // clean old variables + + $smarty->assign(array( 'subject'=>'', + 'content'=>'', + 'categories' =>array(), + 'filed_under'=>'', + 'date'=>'', + 'author'=>'', + 'version'=>'', + 'ip-address'=>'' + ) + ); + + + if (isset($params['content']) && is_array($params['content']) && $params['content']) { + //foreach ($params['entry'] as $k => $val) + $smarty->assign(array_change_key_case($params['content'], CASE_LOWER)); + return $content; + } + + if (isset($params['alwaysshow']) && $params['alwaysshow']) { + return $content; + } + + $q =& $fpdb->getQuery(); + + if($repeat=$q->hasMore()) { + + + $couplet =& $q->getEntry() ; + + $id =& $couplet[0]; + $entry =& $couplet[1]; + + if (THEME_LEGACY_MODE) { + $entry = theme_entry_filters($entry, $id); + } + + + foreach($entry as $k=>$v) + $smarty->assign_by_ref($k, $entry[$k]); + + $smarty->assign_by_ref('id', $id); + + + do_action('entry_block'); + + } + + + return $content; + + } + + + function smarty_block_comment($params, $content, &$smarty, &$repeat) { + global $fpdb; + + // clean old variables + + $smarty->assign(array( + 'subject'=>'', + 'content'=>'', + 'date'=>'', + 'name'=>'', + 'url'=>'', + 'email'=>'', + 'version'=>'', + 'ip-address'=>'', + 'loggedin'=>'', + ) + ); + + $q =& $fpdb->getQuery(); + + if($repeat=$q->comments->hasMore()) { + + $couplet =& $q->comments->getComment(); + + $id =& $couplet[0]; + $comment =& $couplet[1]; + + + foreach($comment as $k=>$v) { + $kk = str_replace('-', '_', $k); + $smarty->assign_by_ref($kk, $comment[$k]); + } + + if (THEME_LEGACY_MODE) { + $comment = theme_comments_filters($comment, $id); + } + + $smarty->assign('id', $id); + + + + } + + + return $content; + + + + } + + function smarty_block_comments($params, $content, &$smarty, &$repeat) { + global $fpdb; + + $q =& $fpdb->getQuery(); + $show = $q->comments->getCount(); + $smarty->assign('entryid', $q->comments->entryid); + + + if ($show) { + + return $content; + } else { + + $repeat = false; + } + + } + + + function smarty_function_nextpage($params) { + + list ($caption, $link) = get_nextpage_link(); + + if (!$link) + return; + + if (isset($params['admin'])) { + $qstr=strstr($link, '?'); + $link = BLOG_BASEURL . 'admin.php' . $qstr; + } + + + return "
    "; + + } + + function smarty_function_prevpage($params) { + + list($caption, $link) = get_prevpage_link(); + + if (!$link) + return; + + if (isset($params['admin'])) { + $qstr=strstr($link, '?'); + $link = BLOG_BASEURL .'admin.php' . $qstr; + } + + + return ""; + + + } + + $_FP_SMARTY->register_block('comment','smarty_block_comment'); + $_FP_SMARTY->register_block('comments','smarty_block_comments'); + $_FP_SMARTY->register_block('comment_block','smarty_block_comments'); + + $_FP_SMARTY->register_block('entries','smarty_block_entries'); + $_FP_SMARTY->register_block('entry_block','smarty_block_entries'); + + $_FP_SMARTY->register_block('entry','smarty_block_entry'); + + $_FP_SMARTY->register_function('nextpage','smarty_function_nextpage'); + $_FP_SMARTY->register_function('prevpage','smarty_function_prevpage'); + +?> diff --git a/fp-includes/core/core.language.php b/fp-includes/core/core.language.php new file mode 100644 index 0000000..449e9aa --- /dev/null +++ b/fp-includes/core/core.language.php @@ -0,0 +1,127 @@ + my, file, name + $old_lang =& $GLOBALS['lang']; + + if (!$old_lang) + $old_lang = array(); + + if ($postfix) { + + if (strpos($postfix, 'plugin:')===0) { + $pluginpath = substr($postfix, 7); + } + + $file = "lang.$postfix.php"; + + } else { + + $postfix='default'; + $file = "lang.default.php"; + + } + + $fpath=LANG_DIR."{$fp_config['general']['lang']}/$file"; + $fallback=LANG_DIR.LANG_DEFAULT."/$file"; + + + $path = ''; + $plugin=$pluginpath; + + + if ($pluginpath) { + if (($n = strpos($pluginpath, '/'))!==false) { + $plugin = substr($plugin, 0, $n-1); + $path = substr($plugin, $n+1); + $path = str_replace('/', '.', $path); + } + + $dir = plugin_getdir($plugin); + + $fpath = $dir . "lang/lang.{$fp_config['general']['lang']}{$path}.php"; + $fallback = $dir . "lang/lang.".LANG_DEFAULT."{$path}.php"; + + } + + if (!file_exists($fpath)) { + /* if file does not exist, we fall back on English */ + if (!file_exists($fallback)) { + trigger_error("No suitable language file was found $postfix", E_USER_WARNING); + return; + } + + $fpath = $fallback; + + } + + /* load $lang from file */ + + /* + * utf encoded files may output whitespaces known as BOM, we must + * capture this chars + */ + + //ob_start(); + + include_once ($fpath); + + + if (!isset($lang)){ + return $GLOBALS['lang']; + } + + + //$v = ob_get_contents(); + //ob_end_clean(); + + // if ($v) trigger_error("[lang] $fpath produced output", E_USER_WARNING); + + + $GLOBALS['lang'] = array_merge_recursive($lang, $old_lang); + + return $GLOBALS['lang']; + + } + + function lang_getconf($id) { + global $lang; + $fpath=LANG_DIR."$id/lang.conf.php"; + if (file_exists($fpath)) { + include ($fpath); + return $langconf; + } else + trigger_error("Error loading config for language \"$file\"", E_USER_WARNING); + } + + + + class lang_indexer extends fs_filelister { + + var $_directory=LANG_DIR; + + function _checkFile($directory, $file) { + + if (is_dir("$directory/$file")) { + $this->_list[$file] = lang_getconf($file); + } + + return 0; + + } + + } + + function lang_list() { + $obj =& new lang_indexer(); + return $obj->getList(); + } + + +?> diff --git a/fp-includes/core/core.layout.php b/fp-includes/core/core.layout.php new file mode 100644 index 0000000..d1397fc --- /dev/null +++ b/fp-includes/core/core.layout.php @@ -0,0 +1,137 @@ +pagecontent = $content; + + $this->fpdb =& new FPDB; + $GLOBALS['fpdb'] =& $this->fpdb; + + $this->fp_widgets =& new widget_indexer; + $GLOBALS['fp_widgets'] =& $this->fp_widgets; + + $this->smarty =& $GLOBALS['_FP_SMARTY']; + + $GLOBALS['fp_config'] =& $this->config; + $this->config = $GLOBALS['fp_config']['general']; + + + $this->theme = theme_loadsettings(); + $GLOBALS['theme'] =& $this->theme; + + $this->lang = lang_load(); + $GLOBALS['lang'] =& $this->lang; + + // user_loggedin() or sess_setup(); + + plugin_loadall(); + + // init smarty + + $this->smarty->compile_dir = CACHE_DIR; + $this->smarty->cache_dir = SMARTY_DIR . 'cache/'; + $this->smarty->caching = 0; + + + + do_action('init'); + + } + + + function display() { + $this->main(); + theme_init($this->smarty, $this); + $this->smarty->display($this->tpl); + + unset($this->smarty); + + do_action('shutdown'); + + } + /* + + function post_message($module, $ring, $message) { + $this->message_queue[$module][$ring][]=$message; + + } + + function flush_messages($module, $ring=-1) { + + $msg_arr=array(); + if ($ring<0) + $ring_arr = + array_keys($this->message_queue[$module]); + else + $ring_arr = array($ring); + + foreach($ring_arr as $this_ring) { + $localq=& $this->message_queue[$module][$this_ring]; + foreach ($localq as $msg) { + $msg_arr[]=$msg; + } + } + + $this->smarty->append('err', $msg_arr); + return $msg_arr; + } + */ + + } + + class Abstract_LayoutIndex extends LayoutDefault { + + var $tpl = 'index.tpl'; + + } + + class Abstract_LayoutComment extends LayoutDefault { + + var $tpl = 'comments.tpl'; + + } + + class Abstract_LayoutDialog extends LayoutDefault { + + var $tpl = 'default.tpl'; + + function page($subject, $content, $rawcontent=false) { + $this->pagecontent = array( + 'subject'=>$subject, + 'content'=>$content + ); + + if ($rawcontent) $this->smarty->assign('rawcontent', true); + + } + + function pagecontent($params, $content, &$smarty, &$repeat) { + if ($this->pagecontent) { + $this->smarty->assign($this->pagecontent); + return $content; + } else return; + + } + + function display() { + $this->smarty->register_block('page', array(&$this, 'pagecontent')); + parent::display(); + } + + + } + + +?> diff --git a/fp-includes/core/core.plugins.php b/fp-includes/core/core.plugins.php new file mode 100644 index 0000000..d6ca3ef --- /dev/null +++ b/fp-includes/core/core.plugins.php @@ -0,0 +1,243 @@ +_enabledlist = CONFIG_DIR . 'plugins.conf.php'; + parent::fs_filelister(); + } + + function _checkFile($directory, $file) { + $f = "$directory/$file"; + if (is_dir($f) && file_exists("$f/plugin.$file.php")) { + array_push($this->_list, $file); + } + return 0; + } + + /* + * + * @param $checkonly bool if false will load all the plugins, + * if true will check if the plugin exist + */ + + function getEnableds($checkonly) { + + $lang =& $GLOBALS['lang']; + $errors = array(); + + if (!file_exists($this->_enabledlist)) + return false; + include($this->_enabledlist); + $var = $this->_varname; + + $this->enabledlist = $$var; + + foreach ($$var as $plugin) { + + $e = plugin_load($plugin, $checkonly); + if ($e) + $errors[] = $e; + + } + + return $errors; + + } + + } + + function plugin_loadall($check=false){ + + // this is done during init process + // all the plugin are loaded + + $pluginlister =& new plugin_indexer; + $enab = $pluginlister->getEnableds($check); + + include_once (INCLUDES_DIR . 'core.wp-pluggable-funcs.php'); + + return $enab; + + } + + function plugin_get($id=null){ + + $pluginlister =& new plugin_indexer; + return $pluginlister->getList(); + + } + + function plugin_loaded($id) { + + if (file_exists(PLUGINS_DIR . $id. '/plugin.'. $id.".php")) { + return true; + } + + return false; + } + + function plugin_load($plugin, $checkonly=true, $langload=true) { + + global $lang; + + $errno = 0; + $errors = false; + + if (file_exists($f = PLUGINS_DIR . "$plugin/plugin.$plugin.php")){ + $errno = 1; // 1 means exists + }elseif (file_exists($f = PLUGINS_DIR . "$plugin/$plugin.php")){ + $errno = 2; // 2 means exists but filename is oldstyle + } + + + if ($errno > 0){ + include_once($f); + } + + if ($langload) + @lang_load("plugin:{$plugin}"); + + if ($checkonly) { + $func = "plugin_{$plugin}_setup"; + + if (is_callable($func)){ + $errno = $func(); + } + + if ($errno<=0) { + + if (isset($lang['plugin'][$plugin]['errors'][$errno])) { + $errors = "[{$plugin}] {$lang['plugin'][$plugin]['errors'][$errno]}"; + } elseif($errno<0) { + $errors = "[$plugin] " . + sprintf($lang['admin']['plugin']['errors']['generic'], $errno); + } else { + $errors = "[$plugin] " . + $lang['admin']['plugin']['errors']['notfound']; + } + + } + } + + return $errors; + + } + + function plugin_exists($id) { + return file_exists($f = PLUGINS_DIR . $id . '/plugin.'. $id.".php"); + } + + function plugin_do($id, $type=null){ + $entry = null; + if (file_exists($f = PLUGINS_DIR . 'plugin.'. $id.".php")) { + include_once($f); + } else return false; + } + + function plugin_require($id) { + + return !plugin_loaded($id); + /* + global $_FP_SMARTY; + $_FP_SMARTY->trigger_error("A plugin required $id to be loaded to work properly, but $id ". + "does not appear to be loaded. Maybe the plugins have been loaded in the wrong sequence. ". + "Check your plugin config in the control panel"); + */ + + } + + function plugin_getdir($id) { + return PLUGINS_DIR . $id . '/'; + } + + function plugin_geturl($id) { + return BLOG_BASEURL . PLUGINS_DIR . $id . '/'; + } + + /* + * + * plugin options system might + * change + * + */ + + function plugin_getoption($plugin, $key) { + global $fp_config; + return $fp_config['plugins'][ $plugin ][ $key ]; + } + + function plugin_addoption($plugin, $key, $val) { + global $fp_config; + return $fp_config['plugins'][ $plugin ][ $key ][ $val ]; + } + + function plugin_saveoptions($null=null) { + return config_save(); + } + + + + function smarty_function_plugin_getdir($params, &$smarty) { + if (!isset($params['plugin'])) //todo complete here + $smarty->trigger_error('You must set plugin= parameter to a valid id!'); + return plugin_getdir($id); + } + + function plugin_getinfo($plugin) { + $plugin_data = io_load_file(plugin_getdir($plugin) . "plugin.$plugin.php"); + preg_match("|Plugin Name:(.*)|i", $plugin_data, $plugin_name); + preg_match("|Plugin URI:(.*)|i", $plugin_data, $plugin_uri); + preg_match("|Description:(.*)|i", $plugin_data, $description); + preg_match("|Author:(.*)|i", $plugin_data, $author_name); + preg_match("|Author URI:(.*)|i", $plugin_data, $author_uri); + if (preg_match("|Version:(.*)|i", $plugin_data, $version)) + $version = trim($version[1]); + else + $version = ''; + + $description = wptexturize(trim($description[1])); + + $name = $plugin_name[1]; + $name = trim($name); + $plugin = $name; + + + if ('' != $plugin_uri[1] && '' != $name) { + // '" title="'.__('Visit plugin homepage').'">'. + $plugin = '' . trim($author_name[1]) . ''; + } + + + global $smarty; + $smarty->assign( + array ( + 'name' => $name, + 'title' => $plugin, + 'description' => $description, + 'author' => $author, + 'version' => $version, + 'template' => $template[1] + ) + ); + + } + + $_FP_SMARTY->register_function('plugin_getdir','smarty_function_plugin_getdir'); + + +?> diff --git a/fp-includes/core/core.session.php b/fp-includes/core/core.session.php new file mode 100755 index 0000000..d239216 --- /dev/null +++ b/fp-includes/core/core.session.php @@ -0,0 +1,54 @@ +0 && $lifetime==0 ) + $lifetime = $cparams['lifetime']; + + session_set_cookie_params($lifetime); + + session_name(SESS_COOKIE); + + session_start(); + + + // echo '
    ', print_r($cparams,1), '
    '; + + } + + + function sess_add($key, $val) { + $_SESSION[$key] = $val; + } + + + function sess_remove($key) { + if (isset($_SESSION[$key])) { + $oldval=$_SESSION[$key]; + unset($_SESSION[$key]); + return $oldval; + } + } + + function sess_get($key) { + if (isset($_SESSION[$key])) + return $_SESSION[$key]; + else return false; + } + + function sess_close() { + unset($_SESSION); + if (isset($_COOKIE[session_name()])) { + setcookie(session_name(), '', time()-42000, '/'); + session_set_cookie_params(-42000); + } + session_destroy(); + } + +?> \ No newline at end of file diff --git a/fp-includes/core/core.static.php b/fp-includes/core/core.static.php new file mode 100755 index 0000000..bddb61f --- /dev/null +++ b/fp-includes/core/core.static.php @@ -0,0 +1,138 @@ +_list, basename($file,EXT)); + return 0; + } + + } + + function static_getlist() { + + $obj =& new static_indexer; + $list = $obj->getList(); + return $list; + + } + + function static_parse($id) { + if ($fname=static_exists($id)) { + $entry = io_load_file($fname); + return array_change_key_case(utils_kexplode($entry)); + } + return array(); + } + + + function static_save($entry, $id, $oldid=null) { + $fname = STATIC_DIR . $id . EXT; + + $str = utils_kimplode(array_change_key_case($entry, CASE_UPPER)); + if (io_write_file($fname, $str)) { + if ( $oldid && $id!=$oldid && $fname = static_exists($oldid)) { + $succ = static_delete($oldid) ; + return ($succ !== false && $succ !== 2); + } + return true; + } + return false; + } + + function static_exists($id) { + $fname = STATIC_DIR . $id . EXT; + + if (file_exists($fname)) + return $fname; + + return false; + } + + function static_delete($id) { + return fs_delete(STATIC_DIR . $id . EXT); + } + + + + function smarty_block_statics($params, $content, &$smarty, &$repeat) { + global $fpdb; + + /* + $show = false; + + if (isset($params['alwaysshow']) && $params['alwaysshow']) { + return $content; + } + */ + return $content; + + } + + + function smarty_block_static($params, $content, &$smarty, &$repeat) { + global $fpdb; + static $pointer = 0; + + // clean old variables + + $smarty->assign(array( 'subject'=>'', + 'content'=>'', + 'date'=>'', + 'author'=>'', + 'version'=>'', + 'id'=>'' + ) + ); + + if ($arr=$smarty->get_template_vars('static_page')){ + $smarty->assign('id', $smarty->get_template_vars('static_id')); + if (THEME_LEGACY_MODE) + theme_entry_filters($arr); + $smarty->assign($arr); + return $content; + } + + if (isset($params['content']) && is_array($params['content']) && $params['content']) { + //foreach ($params['entry'] as $k => $val) + $smarty->assign(array_change_key_case($params['content'], CASE_LOWER)); + return $content; + } + + if (isset($params['alwaysshow']) && $params['alwaysshow']) { + return $content; + } + + $list = $smarty->get_template_vars('statics'); + + + if(isset($list[$pointer])) { + //foreach ($entry as $k => $val) + $smarty->assign(static_parse($list[$pointer])); + $smarty->assign('id', $list[$pointer]); + + $pointer++; + + $repeat = true; + + } else { + $repeat = false; + } + + + return $content; + + } + + + $_FP_SMARTY->register_block('statics', 'smarty_block_statics'); + $_FP_SMARTY->register_block('static_block', 'smarty_block_statics'); + $_FP_SMARTY->register_block('static', 'smarty_block_static'); + +?> diff --git a/fp-includes/core/core.system.php b/fp-includes/core/core.system.php new file mode 100755 index 0000000..4cbafbf --- /dev/null +++ b/fp-includes/core/core.system.php @@ -0,0 +1,177 @@ + + * $my_arr); //same as: $save_arr['$my_arr'] = $my_arr); + * system_save($my_file, $my_arr); + * // now the file $my_file will contain the following lines: + * // global $my_arr; + * // $my_arr = array ( + * // '$my_arr' => val1', + * // '$my_arr' => 'val2', + * // '$my_arr' => 'val3' + * // ); + * ?> + * + * + * @param string $file file path where $array contents will be saved + * @array $var_list list of vars to be saved + * @return bool + * + * @see config_save, config_load + * + */ + function system_save($file, $array ) { + + //if ( ( $numargs = func_num_args() ) > 1) { + + $string = " $arg) { + //$vname = utils_vname ($arg); + //var_export($arg); + $s = /*" global {$key};\n*/ "\${$key} = " . + var_export($arg, true) . ";\n"; + $string .= $s; + } + + $string .= "\n?>"; + + return io_write_file($file, $string); + + //} else die('Wrong number of parameters!'); + + } + + define('SYSTEM_VER', '0.704'); + function system_ver() { + return 'fp-' . SYSTEM_VER; + } + + function system_generate_id($string) { + return 'fp-'.dechex(crc32($string) ^ mt_rand()); + } + + function system_guessblogroot() { + return substr($_SERVER['REQUEST_URI'], 0,strrpos($_SERVER['REQUEST_URI'],'/')+1); + } + + function system_guessbaseurl() { + return 'http://'.$_SERVER['HTTP_HOST']. BLOG_ROOT; + } + + function system_getindex() { + if (MOD_BLOG != INDEX) + return MOD_BLOG; + else + return 'index.php'; + } + + function system_unregister_globals() { + $v = @ini_get('register_globals'); + + // on error we unregister anyway + if ($v || is_null($v)) { + foreach ($_REQUEST as $var => $val) { + unset($GLOBALS[$var]); + } + } + + } + + function system_sanitizequery() { + $err = false; + foreach ($_GET as $k => $v) { + if (preg_match('![<>]|://!', $v)) { + $err = true; + break; + } + } + if ($err) { + // @todo add log handler + utils_redirect(); + } + } + + + function system_init() { + + system_sanitizequery(); + system_unregister_globals(); + + $GLOBALS['fpdb'] =& new FPDB; + + $GLOBALS['fp_widgets'] =& new widget_indexer; + + $GLOBALS['smarty'] =& $GLOBALS['_FP_SMARTY']; + $smarty =& $GLOBALS['smarty']; + + + $GLOBALS['fp_config'] =& config_load(); + + $GLOBALS['theme'] =& theme_loadsettings(); + + $GLOBALS['lang'] =& lang_load(); + + + cookie_setup(); + sess_setup(); + user_loggedin(); + + plugin_loadall(); + + // init smarty + $smarty->compile_dir = CACHE_DIR; + $smarty->cache_dir = SMARTY_DIR . 'cache/'; + $smarty->caching = 0; + + do_action('init'); + + } + + function system_seterr($module, $val) { + if ($module) + $elem = 'success_'.$module; + else + $elem = 'success'; + sess_add($elem, $val); + } + + function system_geterr($module='') { + if ($module) + $elem = 'success_'.$module; + else + $elem = 'success'; + return sess_remove($elem); + } + + /* delayed print */ + function system_dpr($action, $content) { + $p = print_r($content,1); + $f = create_function('', "echo '
    $p
    ';"); + add_action($action, $f); + } + + +?> diff --git a/fp-includes/core/core.theme.php b/fp-includes/core/core.theme.php new file mode 100644 index 0000000..f193a7c --- /dev/null +++ b/fp-includes/core/core.theme.php @@ -0,0 +1,596 @@ + 'theme', + // author of the theme + 'author' => 'anonymous', + // theme website + 'www' => 'http://flatpress.nowhereland.it', + // fp version + 'version' => -1, + // default style (must be in res/ dir + + 'style' => array( + + 'style_def' => 'style.css', + // default style for admin panel (usually it's the same of the theme) + 'style_admin' => 'style.css', + ), + + // if false a default css is used to style some elements of the panel + // if true, we'll suppose these elements are already styled in your own css's + 'admin_custom_interf' => false + ); + + + if (!defined('THE_THEME')) + define('THE_THEME', $fp_config['general']['theme']); + + + // backward compatibility: + $conf1 = THEMES_DIR . THE_THEME . '/theme_conf.php'; + + // new naming convention. Yeah, I know, just an underscore + // instead of the dot, so? It is more "consistent" :D + $conf2 = THEMES_DIR . THE_THEME . '/theme.conf.php'; + + if (file_exists($conf2)) { + include($conf2); + } elseif (file_exists($conf1)) { + include($conf1); + } + + + if (!defined('THEME_LEGACY_MODE')) { + if ($theme['version'] < 0.702) { + define('THEME_LEGACY_MODE', true); + theme_register_default_widgetsets(); + } else { + define('THEME_LEGACY_MODE', false); + + if ($theme['version'] > 0.704) { + if (!isset($fp_config['general']['style'])) + $fp_config['general']['style'] = $theme['default_style']; + include(THEMES_DIR . THE_THEME . "/{$fp_config['general']['style']}/style.conf.php"); + $theme['style'] = $style; + } else { + theme_register_default_widgetsets(); + } + + } + } + + return $theme; + + } + + function theme_register_default_widgetsets() { + register_widgetset('left'); + register_widgetset('right'); + register_widgetset('top'); + register_widgetset('bottom'); + } + + + function theme_exists($id) { + $f = THEMES_DIR . ($id) . '/'; + if (file_exists($f)) + return $f; + + return ''; + } + + function theme_style_exists($id, $themeid=THE_THEME) { + if ($f = theme_exists($themeid)) { + $fs = $f . ($id) . '/'; + if (file_exists($fs)) + return $fs; + } + return ''; + + } + + function theme_geturl($id = THE_THEME) { + return BLOG_BASEURL . THEMES_DIR . $id . '/'; + } + + function theme_style_geturl($style, $id=THE_THEME) { + return theme_geturl($id) . $style . '/'; + } + + + function theme_list() { + $dir = THEMES_DIR; + $dh = opendir($dir); + $i = 0; + while (false !== ($filename = readdir($dh))) { + if ( ($filename != '.') && ($filename != '..') ) { + $files[$i++] = $filename; + } + } + sort($files); + return $files; + } + + + function theme_wp_head() { + global $fp_config; + + echo "\n\n"; + + // echo "\n"; + + echo "\n\n"; + //echo "\n"; + echo "\n"; + echo "\n"; + + + echo "\n"; + } + + function theme_head_stylesheet() { + + global $fp_config, $theme; + + echo "\n\n"; + + echo ''; + + echo "\n\n"; + + + } + + function admin_head_action() { + global $theme; + if (!$theme['admin_custom_interface']) + echo ''; + } + + add_filter('admin_head', 'admin_head_action'); + + + + + add_action('wp_head', 'theme_wp_head'); + add_action('wp_head', 'theme_head_stylesheet'); + + + + + function get_wp_head() { + do_action('wp_head'); + if (class_exists('AdminPanel')) + do_action('admin_head'); + } + + $smarty->register_function('header', 'get_wp_head'); + + + function theme_wp_footer() { + global $fp_config; + echo $fp_config['general']['footer']; + } + + add_action('wp_footer', 'theme_wp_footer'); + + function get_wp_footer() { + do_action('wp_footer'); + } + + $smarty->register_function('footer', 'get_wp_footer'); + + + function theme_charset() { + global $fp_config; + header('Content-Type: text/html; charset='. $fp_config['general']['charset']); + + } + + add_action('init', 'theme_charset'); + + function theme_init(&$smarty) { /* &$mode */ + + global $fp_config; + global $lang; + global $theme; + + // avoid compiled tpl collision (i.e. change theme without this and cry) + $smarty->compile_id = md5($fp_config['general']['theme']); + $smarty->template_dir = THEMES_DIR . $fp_config['general']['theme'] . '/'; + + $loggedin = user_loggedin(); + + $flatpress = $fp_config['general']; + // retained for compatibility + // todo: ugly, clean this up + // smarty has constant facilities included ^_^ + //$flatpress['FP_INTERFACE'] = FP_INTERFACE; + //$flatpress['BLOGURL'] = BLOG_BASEURL; + + + $flatpress['loggedin'] = $loggedin; + + if ($loggedin) + $flatpress['user'] = user_get(); + + // useful shorthand for themes + // e.g. {$flatpress.themeurl}imgs/myimage.png + + if (isset($fp_config['general']['style'])) { + $themeurl = theme_style_geturl($fp_config['general']['style']); + } else { + $themeurl = theme_geturl(); + } + + $flatpress['themeurl'] = $themeurl; + + $flatpress_upper = array_change_key_case($flatpress, CASE_UPPER); + + $flatpress = array_merge($flatpress, $flatpress_upper); + + $smarty->assign('flatpress', $flatpress); + + $smarty->assign('lang', $lang); + + $smarty->assign('blogtitle', $fp_config['general']['title']); + + $smarty->assign('pagetitle', + apply_filters('wp_title', "", '»')); + + $smarty->assign_by_ref('fp_config', $fp_config); + + + $smarty->register_modifier('tag', 'theme_apply_filters_wrapper'); + $smarty->register_modifier('link', 'theme_apply_filters_link_wrapper'); + $smarty->register_modifier('filed', 'theme_entry_categories'); + + + if (!isset($_GET['feed']) || empty($_GET['feed'])) { + $smarty->register_modifier('date_format_daily', 'theme_smarty_modifier_date_format_daily'); + $smarty->register_modifier('date_format', 'theme_smarty_modifier_date_format'); + } + + $smarty->register_modifier('date_rfc3339', 'theme_smarty_modifier_date_rfc3339'); + + $smarty->register_function('action', 'theme_smarty_function_action'); + + + } + + + function smarty_block_page($params, $content) { + return $content; + } + + $smarty->register_block('page', 'smarty_block_page'); + + function theme_apply_filters_wrapper($var, $hook) { + $args = func_get_args(); + $tmp = $args[0]; + $args[0] = $args[1]; + $args[1] = $tmp; + return call_user_func_array('apply_filters', $args); + } + + + function theme_apply_filters_link_wrapper($var, $hook) { + return apply_filters($hook, '', $var); + } + + + + function theme_smarty_function_action($params, &$smarty) { + if (isset($params['hook'])) + do_action($params['hook']); + + } + + function theme_smarty_modifier_date_format( $string, + $format = null, + $default_date = '' + ) { + global $lang; + + if ($string != '') { + $timestamp = $string; // smarty_make_timestamp($string); + } elseif ($default_date != '') { + $timestamp = $default_date; // smarty_make_timestamp($default_date); + } else { + return; + } + + if (is_null($format)) { + global $fp_config; + $format = $fp_config['locale']['timeformat']; + } + + + // D l day + + if ( strpos($format, '%a') !== false ) { + $i = strftime('%u', $timestamp); + $format = str_replace('%a', $lang['date']['weekday_abbr'][$i], $format); + } + + if ( strpos($format, '%A') !== false ) { + $i = strftime('%u', $timestamp); + $format = str_replace('%A', $lang['date']['weekday'][$i], $format); + } + + + // F M month + + if ( strpos($format, '%b') !== false ) { + $i = intval(strftime('%m', $timestamp))-1; + $format = str_replace('%b', $lang['date']['month_abbr'][$i], $format); + } + + + if ( strpos($format, '%B') !== false ) { + $i = intval(strftime('%m', $timestamp))-1; + $format = str_replace('%B', $lang['date']['month'][$i], $format); + } + + if (DIRECTORY_SEPARATOR == '\\') { + $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); + $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S'); + if (strpos($format, '%e') !== false) { + $_win_from[] = '%e'; + $_win_to[] = sprintf('%\' 2d', date('j', $timestamp)); + } + if (strpos($format, '%l') !== false) { + $_win_from[] = '%l'; + $_win_to[] = sprintf('%\' 2d', date('h', $timestamp)); + } + $format = str_replace($_win_from, $_win_to, $format); + } + + return strftime($format, $timestamp); + + + } + + + function theme_smarty_modifier_date_format_daily( + $string, + $format = null, + $default_date = '' + ) { + + global $THEME_CURRENT_DAY, $lang, $fp_config; + + if (is_null($format)) + $format = $fp_config['locale']['dateformat']; + + $current_day = theme_smarty_modifier_date_format($string, $format, $default_date); + + if (!isset($THEME_CURRENT_DAY) || $THEME_CURRENT_DAY != $current_day) { + $THEME_CURRENT_DAY = $current_day; + + return $current_day; + + } + + return ''; + + } + + + /** + * Get date in RFC3339 + * For example used in XML/Atom + * + * @param integer $timestamp + * @return string date in RFC3339 + * @author Boris Korobkov + * @see http://tools.ietf.org/html/rfc3339 + * + * http://it.php.net/manual/en/function.date.php#75757 + * + */ + + function theme_smarty_modifier_date_rfc3339($timestamp='') { + + if (!$timestamp) { + $timestamp = time(); + } + + $date = date('Y-m-d\TH:i:s', $timestamp); + + $matches = array(); + if (preg_match('/^([\-+])(\d{2})(\d{2})$/', date('O', $timestamp), $matches)) { + $date .= $matches[1].$matches[2].':'.$matches[3]; + } else { + $date .= 'Z'; + } + return $date; + + } + + + + + + // {{{ permalink, commentlink, staticlink: filters + + add_filter('feed_link', 'theme_def_feed_link', 0, 2); + function theme_def_feed_link($str, $type) { + return BLOG_BASEURL . "?feed={$type}"; + } + function theme_feed_link ($feed='rss2') { + return apply_filters('feed_link', '', $feed); + } + + add_filter('post_comments_feed_link', 'theme_def_feed_comments_link', 0, 3); + function theme_def_feed_comments_link($str, $feed, $id) { + return BLOG_BASEURL . "?entry=$id&comments&feed={$feed}"; + } + function theme_comments_feed_link ($feed='rss2', $id) { + return apply_filters('post_comments_feed_link', '', $feed, $id); + } + + + add_filter('post_link', 'theme_def_permalink', 0, 2); + function theme_def_permalink($str, $id) { + return BLOG_BASEURL . "?entry=$id"; + } + function get_permalink ($id) { + return apply_filters('post_link', '', $id); + } + + add_filter('comments_link', 'theme_def_commentlink', 0, 2); + function theme_def_commentlink($str, $id) { + return BLOG_BASEURL . "?entry=$id&comments"; + } + function get_comments_link ($id) { + return apply_filters('comments_link', '', $id); + } + + + add_filter('page_link', 'theme_def_staticlink', 0, 2); + function theme_def_staticlink($str, $id) { + return BLOG_BASEURL . "?page=$id"; + } + function theme_staticlink ($id) { + return apply_filters('page_link', '', $id); + } + + add_filter('category_link', 'theme_def_catlink', 0, 2); + function theme_def_catlink($str, $catid) { + return BLOG_BASEURL . "?cat=$catid"; + } + function get_category_link($catid) { + return apply_filters('category_link', '', $catid); + } + + + function get_year_link($year) { + return wp_specialchars( + apply_filters( + 'year_link', + BLOG_BASEURL . '?y='. str_pad($year, 2, '0', STR_PAD_LEFT), + $year) + ); + } + + function get_month_link($year, $month) { + return wp_specialchars( + apply_filters( + 'month_link', + BLOG_BASEURL . '?y='. str_pad($year, 2, '0', STR_PAD_LEFT) . + '&m=' . str_pad($month, 2, '0', STR_PAD_LEFT), + $year, + $month) + ); + } + + function get_day_link($year, $month, $day) { + return wp_specialchars( + apply_filters( + 'month_link', + BLOG_BASEURL . '?y='. str_pad($year, 2, '0', STR_PAD_LEFT) + . '&m=' . str_pad($month, 2, '0', STR_PAD_LEFT) + . '&d=' . str_pad($day, 2, '0', STR_PAD_LEFT), + $year, + $month) + ); + } + + + + // }}} + + + function theme_entry_commentcount($count) { + global $lang; + switch ($count) { + case 0: return $comments = $lang['main']['nocomments']; + case 1: return $comments = $lang['main']['comment']; + default: return $comments = $count . ' ' . $lang['main']['comments']; + } + + } + add_filter('comments_number', 'theme_entry_commentcount'); + + + function theme_entry_categories($cats, $link = true, $separator=', ') { + if (!$cats) { + return; + } else { + $filed=array(); + if ($tmp1 = entry_categories_get('defs')) { + + foreach ($tmp1 as $k=>$c) { + if(array_intersect(array($k),$cats)) { + $filed[] = $link? "$c" : $c; + } + } + } + if ($filed) { + return implode($separator, $filed); + } + } + } + + /* + this is called only in legacy mode + + */ + + + // {{{ ENTRY + function &theme_entry_filters(&$contentarr, $id=null) { + + $contentarr['subject']=apply_filters('the_title', $contentarr['subject']); + + $contentarr['content'] = apply_filters('the_content', $contentarr['content']); + + if (isset($contentarr['comments'])) { + $contentarr['commentcount'] = $contentarr['comments']; + $contentarr['comments'] = apply_filters('comments_number', $contentarr['commentcount']); + } + + $contentarr['permalink']=get_permalink($id); + + $contentarr['commentlink']=get_comments_link($id); + return $contentarr; + } + + //{{{ COMMENTS + function &theme_comments_filters(&$contentarr, $key) { + + $contentarr['name']=apply_filters('comment_author_name', $contentarr['name']); + if (isset($contentarr['email'])) { + $contentarr['email']=apply_filters('comment_author_email', $contentarr['email']); + $contentarr['mailto'] = 'mailto:' . $contentarr['email']; + } + if (!isset($contentarr['url'])) $contentarr['url'] = '#'; + $contentarr['timestamp']=$contentarr['date']; + $contentarr['content']=apply_filters('comment_text', $contentarr['content']); + + return $contentarr; + + } + + +?> diff --git a/fp-includes/core/core.users.php b/fp-includes/core/core.users.php new file mode 100755 index 0000000..12665c7 --- /dev/null +++ b/fp-includes/core/core.users.php @@ -0,0 +1,184 @@ +_cachefile = CACHE_DIR . 'userlist.php'; + parent::cache_filelister(); + } + + function _checkFile($directory, $file) { + if (fnmatch('*.php', $file)) { + array_push($this->_list, basename($file,EXT)); + return 0; + } + } + + } + + + function user_list(){ + $obj =& new user_lister; + if ($users = $obj->getList()) { + return $entry_arr; + } else return false; + + + + } + + function user_pwd($userid, $pwd){ + return md5($userid.$pwd); + } + + + function user_login($userid, $pwd, $params=null){ + + global $loggedin; + + $loggedin = false; + + $user = user_get($userid); + // $retval = 0; + + /* + print_r($user); + print_r(user_pwd($userid,$pwd)); + */ + + if (user_pwd($userid,$pwd) == $user['password']){ + + $loggedin = true; + + // session_regenerate_id(); + + $expire = time() + 31536000; + + setcookie(USER_COOKIE, $userid, $expire, COOKIEPATH, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, $user['password'], $expire, COOKIEPATH, COOKIE_DOMAIN); + + /* + + $retval = 1; + + sess_close(); + + sess_setup(60*60*24*7); + + $retval = 1; + + + sess_add('userid', $userid); + // sess_add('userhash', $user['PWD']); + sess_add('loggedin', true); + sess_add('ip', $_SERVER['REMOTE_ADDR']); + sess_add('host', $_SERVER['SERVER_ADDR']); + sess_add('path', ABS_PATH); + + $user = user_get($userid); + $user['LOGINTIME']=time(); + system_save(USERS_DIR . $user['NAME'] . ".php", compact('user')); + */ + + } + + return $loggedin; + } + + function user_logout(){ + global $loggedin; + + if ( user_loggedin() ) { + + setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); + + + /* + + $user = user_get(sess_get('userid')); + unset($user['LOGINTIME']); + system_save(USERS_DIR . $user['NAME'] . ".php", compact('user')); + sess_close(); + + */ + + } + + $loggedin = false; + + } + + function user_loggedin(){ + + global $loggedin, $fp_user; + + if ($loggedin) + return $fp_user; + + if ( empty($_COOKIE[USER_COOKIE]) || empty($_COOKIE[PASS_COOKIE]) ) { + $fp_user = null; + return $loggedin = false; + } + + // print_r($_COOKIE); + + $fp_user = user_get($_COOKIE[USER_COOKIE]); + + if ($fp_user) { + $loggedin = ($_COOKIE[PASS_COOKIE] == $fp_user['password']); + } + + return $fp_user; + + /* + //return true; + if (!$loggedin && sess_get('loggedin')) { + $user = user_get(sess_get('userid')); + // removed: sess_get('ip') == $_SERVER['REMOTE_ADDR'] && + // quite stupid, as people usually will disconnect sooner or later :D + if (sess_get('host') == $_SERVER['SERVER_ADDR'] && + sess_get('path') == ABS_PATH ) { + @sess_setup(60*60*24*7); + + // may bug sometimes: + // session_regenerate_id(); + $loggedin = true; + + } + } + */ + + + return $loggedin; + } + + + + function user_get($userid=null){ + if ($userid == null && ($user = user_loggedin())) { + return $user; + } + if (file_exists($f = USERS_DIR . $userid.".php")) { + include($f); + + return $user; + } + } + + + + function user_add($user){ + + $user['password']=user_pwd($user['userid'], $user['password']); + + return system_save(USERS_DIR . $user['userid'] . ".php", compact('user')); + + } + + +?> diff --git a/fp-includes/core/core.utils.php b/fp-includes/core/core.utils.php new file mode 100644 index 0000000..012f7af --- /dev/null +++ b/fp-includes/core/core.utils.php @@ -0,0 +1,362 @@ +$string + keys were supposed to be UPPERCASE but \"$k\" was found; file may be corrupted + or in an expected format.
    + Some SimplePHPBlog files may raise this error: set DUMB_MODE_ENABLED + to true in your defaults.php to force parsing of the offending keys.", + E_USER_WARNING); + */ + continue; + } + + $arr[$k] = strtok($delim); + } + + return $arr; + } + + + /* + function utils_newkexplode($string, $delim='|') { + + $arr = array(); + + $lastoffset = $offset = 0; + $len = strlen($string); + + while ($lastoffset<$len) { + $offset = strpos($string, $delim, $lastoffset); + $key = substr($string, $lastoffset, $offset-$lastoffset); + //echo 'parsing key: ', $key, $offset, chr(10); + + $lastoffset = $offset + 1; + + if (!ctype_upper($key)) + trigger_error("Failed parsing \"$string\" + keys were supposed to be UPPERCASE", E_USER_ERROR); + + $offset = strpos($string, $delim, $lastoffset); + + if ($offset===false) + $offset = $len; + + $val = substr($string, $lastoffset, $offset-$lastoffset); + + //echo 'parsing value ', $val, $offset, chr(10); + + $lastoffset = $offset + 1; + + $arr[$key] = $val; + + } + return $arr; + + }*/ + + + // function prototype: + // array utils_kimplode(string $string, string $delim='|') + + // explodes a string into an array by the given delimiter; + // delimiter defaults to pipe ('|'). + // the string must be formatted as in: + // key1|value1|key2|value2 , etc. + // the array will look like + // $arr['key1'] = 'value1'; $arr['key2'] = 'value2'; etc. + + function utils_kimplode($arr, $delim='|') { + $string = ""; + foreach ($arr as $k => $val) { + if ($val) + $string .= $k . $delim . $val . $delim; + } + return $string; + } + + /** + * @todo send mail to admin + */ + + + function &utils_explode_recursive($array, &$string, $rdelim, $ldelim='', $outerldelim='', $outerrdelim='') { + + $string .= $outerldelim; + + while (list(,$val) = each($array)) { + + $string .= $rdelim; + if (is_array($val)) { + $string .= utils_explode_recursive($val, $string, $rdelim, $ldelim, $outerldelim, $outerrdelim); + } else { + $string .= $val; + } + + $string .= $ldelim; + + } + + $string .= $outerrdelim; + + } + + + + + + function utils_validateinput($str) { + + if (preg_match('/[^a-z0-9\-_]/i',$str)){ + trigger_error("String \"$str\" is not a valid input", E_USER_ERROR); + //return false; + } else + return true; + } + + function utils_cut_string($str,$maxc) { + $car = strlen($str); + if($car > $maxc) { + return substr($str, 0, $maxc)."..."; + } else { + return $str; + } + } + + + function utils_status_header($status) { + + switch ($status) { + case 301: + header("HTTP/1.1 301 Moved Permanently"); + break; + case 403: + header("HTTP/1.1 403 Forbidden"); + break; + case 404: + header("HTTP/1.1 404 Not Found"); + break; + + } + + } + + // code from php.net ;) + // defaults to index.php ;) + function utils_redirect($location="", $absolute_path=false, $red_type=null) { + + if (!$absolute_path) + $location = BLOG_BASEURL . $location; + + header("Location: $location"); + exit(); + + } + + + /* + * utils_geturlstring() + * + * @return string complete url string as displayed in the browser + * + */ + + function utils_geturlstring() { + $str = BLOG_BASEURL . $_SERVER['PHP_SELF']; + if ($_SERVER['QUERY_STRING']) + $str .='?'.$_SERVER['QUERY_STRING']; + return $str; + } + + // custom array_merge: + // pads the second array to match the length of the first + // this can be improved, anyway for now I'd just + // do a quick & dirty solution :) + function utils_array_merge($arr1, $arr2) { + + $len=count($arr1[0]); + + foreach($arr2 as $k=>$v) + $arr2[$k]=array_pad((Array) $v, $len, null); + + return array_merge($arr1, $arr2); + } + + + /* + * Simple function to replicate PHP 5 behaviour + */ + function utils_microtime() + { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } + + function utils_countdashes($string, &$rest) { + trim($string); + $i = 0; + while ($string{$i} == '-') { + $i++; + } + if ($i) + $rest = substr($string, $i); + else $rest = $string; + + return $i; + + + } + + function utils_mail($from, $subject, $message, $headers = '') { + global $fp_config; + if( $headers == '' ) { + $headers = "MIME-Version: 1.0\n" . + "From: " . $from . "\n" . + "Content-Type: text/plain; charset=\"" . $fp_config['general']['charset'] . "\"\n"; + } + + return mail($fp_config['general']['email'], $subject, $message, $headers); + } + + // get client IP + function utils_ipget() { + if ( !empty ( $_SERVER[ 'HTTP_CLIENT_IP' ] ) ) { + $ip = $_SERVER[ 'HTTP_CLIENT_IP' ]; + } + elseif ( !empty ( $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ) ) { + $ip = $_SERVER[ 'HTTP_X_FORWARDED_FOR' ]; + } + elseif ( !empty ( $_SERVER[ 'REMOTE_ADDR' ] ) ) { + $ip = $_SERVER[ 'REMOTE_ADDR' ]; + } + elseif ( getenv( "HTTP_CLIENT_IP" ) ) { + $ip = getenv( "HTTP_CLIENT_IP" ); + } + elseif ( getenv( "HTTP_X_FORWARDED_FOR" ) ) { + $ip = getenv( "HTTP_X_FORWARDED_FOR" ); + } + elseif ( getenv( "REMOTE_ADDR") ) { + $ip = getenv( "REMOTE_ADDR" ); + } + else { + $ip = "UNKNOWN"; + } + return( $ip ); + } + + function utils_nocache_headers() { + @ header('Expires: Wed, 11 Jan 1984 05:00:00 GMT'); + @ header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + @ header('Cache-Control: no-cache, must-revalidate, max-age=0'); + @ header('Pragma: no-cache'); + } + + + function utils_checksmarty() { + + if (!file_exists(SMARTY_DIR . 'Smarty.class.php')) { + $err = <<http://smarty.php.net; you will + probably need SmartyValidate as well; unpack them to fp-includes/core/smarty: please do not overwrite files in fp-includes/core/smarty/plugins/ +ERR; + trigger_error($err, E_USER_ERROR); + } + + } + + + function fplog($str) { + if(!defined('DEBUG_MODE')) + echo "\n[DEBUG] $str \n"; + } + +?> diff --git a/fp-includes/core/core.widgets.php b/fp-includes/core/core.widgets.php new file mode 100755 index 0000000..3f6ce65 --- /dev/null +++ b/fp-includes/core/core.widgets.php @@ -0,0 +1,174 @@ +_enabledlist = CONFIG_DIR . 'widgets.conf.php'; + $this->getEnableds(); + } + + function getEnableds() { + + if (!file_exists($this->_enabledlist)) + return; + + include($this->_enabledlist); + + $this->_list = ${$this->_varname}; + + } + + function hasMore($hor) { + + return is_array($this->_list[$hor]) && (current($this->_list[$hor]) !== false); + } + + + + function get($hor) { + + global $fp_registered_widgets; + + $content = array(); + + do { + list(,$id) = each($this->_list[$hor]); + + @list($newid, $params) = explode(":", $id); + if ($params) $params = explode(',', $params); else $params = array(); + // $var = 'plugin_' . $newid . '_widget'; + $var = $fp_registered_widgets[ $newid ]['func']; + if (function_exists($var)) { + $content = call_user_func_array($var, $params); + if (!isset($content['id'])) { + $content['id'] = "widget-$newid"; + } + } /* + else $content = array( + 'subject' => "Sidebar::Error", + 'content' => "
    • No $var function found for plugin $newid. + Plugin may not have been loaded. + Verify whether it is enabled.
    ", + ); + */ + + } while(!$content); + + return array_change_key_case($content, CASE_LOWER); + + + + + } + + } + + + function register_widgetset($widgetset) { + global $fp_registered_widgetsets; + if (!$fp_registered_widgetsets) { + $fp_registered_widgetsets = array(); + } + + if (!in_array($widgetset, $fp_registered_widgetsets)) + $fp_registered_widgetsets[] = $widgetset; + + } + + + + function get_registered_widgetsets($widgetset) { + global $fp_registered_widgetsets; + if (!$fp_registered_widgetsets) { + $fp_registered_widgetsets = array(); + } + + return $fp_registered_widgetsets; + } + + + + function register_widget( + $widgetid, // widget id + $widgetname, // name to show + $widget_func, // function/method to call + $num_params = 0, // number of eventually needed parameters + // -1 means optional, + // 0 means no parameters + // each N>0 means *at least* N parameters + + $limit_params_to=array()// indexed array of arrays, containing + // allowed parameters (not impl.) + ) { + + global $fp_registered_widgets; + if (!$fp_registered_widgets) + $fp_registered_widgets = array(); + + /* we won't mind about collisions, for now */ + + $fp_registered_widgets[$widgetid] = array( + 'name' => $widgetname, + 'func' => $widget_func, + 'nparams'=> $num_params, + //'needed'=> $params_needed, + 'params'=> $limit_params_to + ); + + } + + + + function get_registered_widgets($widget=null) { + global $fp_registered_widgets; + + if (!$fp_registered_widgets) + $fp_registered_widgets = array(); + + + ksort($fp_registered_widgets); + + if ($widget) + return isset($fp_registered_widgets[$widget])? + $fp_registered_widgets[$widget] + : + false; + + return $fp_registered_widgets; + + } + + + + function smarty_block_widgets($params, $content, &$smarty, &$repeat) { + global $fp_widgets; + + if($repeat = $fp_widgets->hasMore(($params['pos']))) { + + $entry = $fp_widgets->get(($params['pos'])); + $smarty->assign($entry); + } + + return $content; + + } + + + $smarty->register_block('widgets','smarty_block_widgets'); + + + +?> diff --git a/fp-includes/core/core.wp-default-filters.php b/fp-includes/core/core.wp-default-filters.php new file mode 100755 index 0000000..ce539de --- /dev/null +++ b/fp-includes/core/core.wp-default-filters.php @@ -0,0 +1,96 @@ + \ No newline at end of file diff --git a/fp-includes/core/core.wp-formatting.php b/fp-includes/core/core.wp-formatting.php new file mode 100644 index 0000000..abbec53 --- /dev/null +++ b/fp-includes/core/core.wp-formatting.php @@ -0,0 +1,1039 @@ +)/Us", $text, -1, PREG_SPLIT_DELIM_CAPTURE); + $stop = count($textarr); $next = true; // loop stuff + for ($i = 0; $i < $stop; $i++) { + $curl = $textarr[$i]; + + if (isset($curl{0}) && '<' != $curl{0} && $next) { // If it's not a tag + $curl = str_replace('---', '—', $curl); + $curl = str_replace(' -- ', ' — ', $curl); + $curl = str_replace('--', '–', $curl); + $curl = str_replace('xn–', 'xn--', $curl); + $curl = str_replace('...', '…', $curl); + $curl = str_replace('``', '“', $curl); + + + // This is a hack, look at this more later. It works pretty well though. + $cockney = array("'tain't","'twere","'twas","'tis","'twill","'til","'bout","'nuff","'round","'cause"); + $cockneyreplace = array("’tain’t","’twere","’twas","’tis","’twill","’til","’bout","’nuff","’round","’cause"); + $curl = str_replace($cockney, $cockneyreplace, $curl); + + $curl = preg_replace("/'s/", '’s', $curl); + $curl = preg_replace("/'(\d\d(?:’|')?s)/", "’$1", $curl); + $curl = preg_replace('/(\s|\A|")\'/', '$1‘', $curl); + //$curl = preg_replace('/(\d+)"/', '$1″', $curl); + + $curl = preg_replace('/(\s|\A)("|")(?!\s)/', '$1“$3', $curl); + + $curl = preg_replace("/(\d+)'/", '$1′', $curl); + $curl = preg_replace("/(\S)'([^'\s])/", "$1’$2", $curl); + // $curl = preg_replace('/(\s|\A)"(?!\s)/', '$1“$2', $curl); + + $curl = preg_replace('/(\s|\A)("|")(?!\s)/', '$1“$3', $curl); + + $curl = preg_replace('/("|")(\s|\S|\Z)/', '”$2', $curl); + $curl = preg_replace("/'([\s.]|\Z)/", '’$1', $curl); + $curl = preg_replace("/ \(tm\)/i", ' ™', $curl); + $curl = str_replace("''", '”', $curl); + + $curl = preg_replace('/(\d+)x(\d+)/', "$1×$2", $curl); + + } elseif (strstr($curl, '', '', $text); + $text = str_replace('

    ', "\n", $text); + $text = str_replace('

    ', '', $text); + return $text; + } + + function wpautop($pee, $br = 1) { + $pee = $pee . "\n"; // just to make things a little easier, pad the end + $pee = preg_replace('|
    \s*
    |', "\n\n", $pee); + // Space things out a little + $pee = preg_replace('!(<(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6])[^>]*>)!', "\n$1", $pee); + $pee = preg_replace('!()!', "$1\n", $pee); + $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines + $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates + $pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "\t

    $1

    \n", $pee); // make paragraphs, including one at the end + $pee = preg_replace('|

    \s*?

    |', '', $pee); // under certain strange conditions it could create a P of entirely whitespace + $pee = preg_replace('!

    \s*(]*>)\s*

    !', "$1", $pee); // don't pee all over a tag + $pee = preg_replace("|

    (|", "$1", $pee); // problem with nested lists + + + + /* + $pee = preg_replace('/

    (.*)(]*>)/msiU', '

    $1

    $2', $pee); // problem with list in paragraph... + $pee = preg_replace('|(.*)

    |msiU', "

    $1

    ", $pee); // same as above + */ + + $pee = preg_replace('|

    \s*()\s*

    \s*?(
    )*|msiU', '$1', $pee); // comments and paragraphs + + $pee = preg_replace('|

    ]*)>|i', "

    ", $pee); + $pee = str_replace('

    ', '

    ', $pee); + $pee = preg_replace('!

    \s*(]*>)!', "$1", $pee); + $pee = preg_replace('!(]*>)\s*

    !', "$1", $pee); + if ($br) $pee = preg_replace('|(?)\s*\n|', "
    \n", $pee); // optionally make line breaks + $pee = preg_replace('!(]*>)\s*
    !', "$1", $pee); + $pee = preg_replace('!
    (\s*)!', '$1', $pee); + $pee = preg_replace('!()(.*?)!ise', " stripslashes('$1') . clean_pre('$2') . '' ", $pee); + + return $pee; + } + + + function seems_utf8($Str) { # by bmorel at ssi dot fr + for ($i=0; $i', '>', $text); + if ( $quotes ) { + $text = str_replace('"', '"', $text); + $text = str_replace("'", ''', $text); + } + + return $text; + } + + function utf8_uri_encode( $utf8_string ) { + $unicode = ''; + $values = array(); + $num_octets = 1; + + for ($i = 0; $i < strlen( $utf8_string ); $i++ ) { + + $value = ord( $utf8_string[ $i ] ); + + if ( $value < 128 ) { + $unicode .= chr($value); + } else { + if ( count( $values ) == 0 ) $num_octets = ( $value < 224 ) ? 2 : 3; + + $values[] = $value; + + if ( count( $values ) == $num_octets ) { + if ($num_octets == 3) { + $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]) . '%' . dechex($values[2]); + } else { + $unicode .= '%' . dechex($values[0]) . '%' . dechex($values[1]); + } + + $values = array(); + $num_octets = 1; + } + } + } + + return $unicode; + } + + function remove_accents($string) { + if (seems_utf8($string)) { + $chars = array( + // Decompositions for Latin-1 Supplement + chr(195).chr(128) => 'A', chr(195).chr(129) => 'A', + chr(195).chr(130) => 'A', chr(195).chr(131) => 'A', + chr(195).chr(132) => 'A', chr(195).chr(133) => 'A', + chr(195).chr(135) => 'C', chr(195).chr(136) => 'E', + chr(195).chr(137) => 'E', chr(195).chr(138) => 'E', + chr(195).chr(139) => 'E', chr(195).chr(140) => 'I', + chr(195).chr(141) => 'I', chr(195).chr(142) => 'I', + chr(195).chr(143) => 'I', chr(195).chr(145) => 'N', + chr(195).chr(146) => 'O', chr(195).chr(147) => 'O', + chr(195).chr(148) => 'O', chr(195).chr(149) => 'O', + chr(195).chr(150) => 'O', chr(195).chr(153) => 'U', + chr(195).chr(154) => 'U', chr(195).chr(155) => 'U', + chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y', + chr(195).chr(159) => 's', chr(195).chr(160) => 'a', + chr(195).chr(161) => 'a', chr(195).chr(162) => 'a', + chr(195).chr(163) => 'a', chr(195).chr(164) => 'a', + chr(195).chr(165) => 'a', chr(195).chr(167) => 'c', + chr(195).chr(168) => 'e', chr(195).chr(169) => 'e', + chr(195).chr(170) => 'e', chr(195).chr(171) => 'e', + chr(195).chr(172) => 'i', chr(195).chr(173) => 'i', + chr(195).chr(174) => 'i', chr(195).chr(175) => 'i', + chr(195).chr(177) => 'n', chr(195).chr(178) => 'o', + chr(195).chr(179) => 'o', chr(195).chr(180) => 'o', + chr(195).chr(181) => 'o', chr(195).chr(182) => 'o', + chr(195).chr(182) => 'o', chr(195).chr(185) => 'u', + chr(195).chr(186) => 'u', chr(195).chr(187) => 'u', + chr(195).chr(188) => 'u', chr(195).chr(189) => 'y', + chr(195).chr(191) => 'y', + // Decompositions for Latin Extended-A + chr(196).chr(128) => 'A', chr(196).chr(129) => 'a', + chr(196).chr(130) => 'A', chr(196).chr(131) => 'a', + chr(196).chr(132) => 'A', chr(196).chr(133) => 'a', + chr(196).chr(134) => 'C', chr(196).chr(134) => 'c', + chr(196).chr(136) => 'C', chr(196).chr(137) => 'c', + chr(196).chr(138) => 'C', chr(196).chr(139) => 'c', + chr(196).chr(140) => 'C', chr(196).chr(141) => 'c', + chr(196).chr(142) => 'D', chr(196).chr(143) => 'd', + chr(196).chr(144) => 'D', chr(196).chr(145) => 'd', + chr(196).chr(146) => 'E', chr(196).chr(147) => 'e', + chr(196).chr(148) => 'E', chr(196).chr(149) => 'e', + chr(196).chr(150) => 'E', chr(196).chr(151) => 'e', + chr(196).chr(152) => 'E', chr(196).chr(153) => 'e', + chr(196).chr(154) => 'E', chr(196).chr(155) => 'e', + chr(196).chr(156) => 'G', chr(196).chr(157) => 'g', + chr(196).chr(158) => 'G', chr(196).chr(159) => 'g', + chr(196).chr(160) => 'G', chr(196).chr(161) => 'g', + chr(196).chr(162) => 'G', chr(196).chr(163) => 'g', + chr(196).chr(164) => 'H', chr(196).chr(165) => 'h', + chr(196).chr(166) => 'H', chr(196).chr(167) => 'h', + chr(196).chr(168) => 'I', chr(196).chr(169) => 'i', + chr(196).chr(170) => 'I', chr(196).chr(171) => 'i', + chr(196).chr(172) => 'I', chr(196).chr(173) => 'i', + chr(196).chr(174) => 'I', chr(196).chr(175) => 'i', + chr(196).chr(176) => 'I', chr(196).chr(177) => 'i', + chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij', + chr(196).chr(180) => 'J', chr(196).chr(181) => 'j', + chr(196).chr(182) => 'K', chr(196).chr(183) => 'k', + chr(196).chr(184) => 'k', chr(196).chr(185) => 'L', + chr(196).chr(186) => 'l', chr(196).chr(187) => 'L', + chr(196).chr(188) => 'l', chr(196).chr(189) => 'L', + chr(196).chr(190) => 'l', chr(196).chr(191) => 'L', + chr(197).chr(128) => 'l', chr(196).chr(129) => 'L', + chr(197).chr(130) => 'l', chr(196).chr(131) => 'N', + chr(197).chr(132) => 'n', chr(196).chr(133) => 'N', + chr(197).chr(134) => 'n', chr(196).chr(135) => 'N', + chr(197).chr(136) => 'n', chr(196).chr(137) => 'N', + chr(197).chr(138) => 'n', chr(196).chr(139) => 'N', + chr(197).chr(140) => 'O', chr(196).chr(141) => 'o', + chr(197).chr(142) => 'O', chr(196).chr(143) => 'o', + chr(197).chr(144) => 'O', chr(196).chr(145) => 'o', + chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe', + chr(197).chr(148) => 'R',chr(197).chr(149) => 'r', + chr(197).chr(150) => 'R',chr(197).chr(151) => 'r', + chr(197).chr(152) => 'R',chr(197).chr(153) => 'r', + chr(197).chr(154) => 'S',chr(197).chr(155) => 's', + chr(197).chr(156) => 'S',chr(197).chr(157) => 's', + chr(197).chr(158) => 'S',chr(197).chr(159) => 's', + chr(197).chr(160) => 'S', chr(197).chr(161) => 's', + chr(197).chr(162) => 'T', chr(197).chr(163) => 't', + chr(197).chr(164) => 'T', chr(197).chr(165) => 't', + chr(197).chr(166) => 'T', chr(197).chr(167) => 't', + chr(197).chr(168) => 'U', chr(197).chr(169) => 'u', + chr(197).chr(170) => 'U', chr(197).chr(171) => 'u', + chr(197).chr(172) => 'U', chr(197).chr(173) => 'u', + chr(197).chr(174) => 'U', chr(197).chr(175) => 'u', + chr(197).chr(176) => 'U', chr(197).chr(177) => 'u', + chr(197).chr(178) => 'U', chr(197).chr(179) => 'u', + chr(197).chr(180) => 'W', chr(197).chr(181) => 'w', + chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y', + chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z', + chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z', + chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z', + chr(197).chr(190) => 'z', chr(197).chr(191) => 's', + // Euro Sign + chr(226).chr(130).chr(172) => 'E'); + + $string = strtr($string, $chars); + } else { + // Assume ISO-8859-1 if not UTF-8 + $chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158) + .chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194) + .chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202) + .chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210) + .chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218) + .chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227) + .chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235) + .chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243) + .chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251) + .chr(252).chr(253).chr(255); + + $chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy"; + + $string = strtr($string, $chars['in'], $chars['out']); + $double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254)); + $double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'); + $string = str_replace($double_chars['in'], $double_chars['out'], $string); + } + + return $string; + } + + function sanitize_title($title, $fallback_title = '') { + $title = strip_tags($title); + $title = apply_filters('sanitize_title', $title); + + if (empty($title)) { + $title = $fallback_title; + } + + return $title; + } + + function sanitize_title_with_dashes($title) { + $title = strip_tags($title); + // Preserve escaped octets. + $title = preg_replace('|%([a-fA-F0-9][a-fA-F0-9])|', '---$1---', $title); + // Remove percent signs that are not part of an octet. + $title = str_replace('%', '', $title); + // Restore octets. + $title = preg_replace('|---([a-fA-F0-9][a-fA-F0-9])---|', '%$1', $title); + + $title = remove_accents($title); + if (seems_utf8($title)) { + if (function_exists('mb_strtolower')) { + $title = mb_strtolower($title, 'UTF-8'); + } + $title = utf8_uri_encode($title); + } + + $title = strtolower($title); + $title = preg_replace('/&.+?;/', '', $title); // kill entities + $title = preg_replace('/[^%a-z0-9 _-]/', '', $title); + $title = preg_replace('/\s+/', '-', $title); + $title = preg_replace('|-+|', '-', $title); + $title = trim($title, '-'); + + return $title; + } + + function convert_chars($content, $flag = 'obsolete') { + // Translation of invalid Unicode references range to valid range + $wp_htmltranswinuni = array( + '€' => '€', // the Euro sign + '' => '', + '‚' => '‚', // these are Windows CP1252 specific characters + 'ƒ' => 'ƒ', // they would look weird on non-Windows browsers + '„' => '„', + '…' => '…', + '†' => '†', + '‡' => '‡', + 'ˆ' => 'ˆ', + '‰' => '‰', + 'Š' => 'Š', + '‹' => '‹', + 'Œ' => 'Œ', + '' => '', + 'Ž' => 'ž', + '' => '', + '' => '', + '‘' => '‘', + '’' => '’', + '“' => '“', + '”' => '”', + '•' => '•', + '–' => '–', + '—' => '—', + '˜' => '˜', + '™' => '™', + 'š' => 'š', + '›' => '›', + 'œ' => 'œ', + '' => '', + 'ž' => '', + 'Ÿ' => 'Ÿ' + ); + + // Remove metadata tags + $content = preg_replace('/(.+?)<\/title>/','',$content); + $content = preg_replace('/<category>(.+?)<\/category>/','',$content); + + // Converts lone & characters into & (a.k.a. &) + $content = preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $content); + + // Fix Word pasting + $content = strtr($content, $wp_htmltranswinuni); + + // Just a little XHTML help + $content = str_replace('<br>', '<br />', $content); + $content = str_replace('<hr>', '<hr />', $content); + + return $content; + } + + function funky_javascript_fix($text) { + // Fixes for browsers' javascript bugs + global $is_macIE, $is_winIE; + + if ( $is_winIE || $is_macIE ) + $text = preg_replace("/\%u([0-9A-F]{4,4})/e", "'&#'.base_convert('\\1',16,10).';'", $text); + + return $text; + } + + /* + balanceTags + + Balances Tags of string using a modified stack. + + @param text Text to be balanced + @return Returns balanced text + @author Leonard Lin (leonard@acm.org) + @version v1.1 + @date November 4, 2001 + @license GPL v2.0 + @notes + @changelog + --- Modified by Scott Reilly (coffee2code) 02 Aug 2004 + 1.2 ***TODO*** Make better - change loop condition to $text + 1.1 Fixed handling of append/stack pop order of end text + Added Cleaning Hooks + 1.0 First Version + */ + function balanceTags($text, $is_comment = 0) { + + /* + if (get_settings('use_balanceTags') == 0) { + return $text; + } + */ + + $tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = ''; + + # WP bug fix for comments - in case you REALLY meant to type '< !--' + $text = str_replace('< !--', '< !--', $text); + # WP bug fix for LOVE <3 (and other situations with '<' before a number) + $text = preg_replace('#<([0-9]{1})#', '<$1', $text); + + while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) { + $newtext .= $tagqueue; + + $i = strpos($text,$regex[0]); + $l = strlen($regex[0]); + + // clear the shifter + $tagqueue = ''; + // Pop or Push + if ($regex[1][0] == "/") { // End Tag + $tag = strtolower(substr($regex[1],1)); + // if too many closing tags + if($stacksize <= 0) { + $tag = ''; + //or close to be safe $tag = '/' . $tag; + } + // if stacktop value = tag close value then pop + else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag + $tag = '</' . $tag . '>'; // Close Tag + // Pop + array_pop ($tagstack); + $stacksize--; + } else { // closing tag not at top, search for it + for ($j=$stacksize-1;$j>=0;$j--) { + if ($tagstack[$j] == $tag) { + // add tag to tagqueue + for ($k=$stacksize-1;$k>=$j;$k--){ + $tagqueue .= '</' . array_pop ($tagstack) . '>'; + $stacksize--; + } + break; + } + } + $tag = ''; + } + } else { // Begin Tag + $tag = strtolower($regex[1]); + + // Tag Cleaning + + // If self-closing or '', don't do anything. + if((substr($regex[2],-1) == '/') || ($tag == '')) { + } + // ElseIf it's a known single-entity tag but it doesn't close itself, do so + elseif ($tag == 'br' || $tag == 'img' || $tag == 'hr' || $tag == 'input') { + $regex[2] .= '/'; + } else { // Push the tag onto the stack + // If the top of the stack is the same as the tag we want to push, close previous tag + if (($stacksize > 0) && ($tag != 'div') && ($tagstack[$stacksize - 1] == $tag)) { + $tagqueue = '</' . array_pop ($tagstack) . '>'; + $stacksize--; + } + $stacksize = array_push ($tagstack, $tag); + } + + // Attributes + $attributes = $regex[2]; + if($attributes) { + $attributes = ' '.$attributes; + } + $tag = '<'.$tag.$attributes.'>'; + //If already queuing a close tag, then put this tag on, too + if ($tagqueue) { + $tagqueue .= $tag; + $tag = ''; + } + } + $newtext .= substr($text,0,$i) . $tag; + $text = substr($text,$i+$l); + } + + // Clear Tag Queue + $newtext .= $tagqueue; + + // Add Remaining text + $newtext .= $text; + + // Empty Stack + while($x = array_pop($tagstack)) { + $newtext .= '</' . $x . '>'; // Add remaining tags to close + } + + // WP fix for the bug with HTML comments + $newtext = str_replace("< !--","<!--",$newtext); + $newtext = str_replace("< !--","< !--",$newtext); + + return $newtext; + } + + + function format_to_edit($content) { + $content = apply_filters('format_to_edit', $content); + $content = htmlspecialchars($content); + return $content; + } + + function format_to_post($content) { + global $wpdb; + $content = apply_filters('format_to_post', $content); + return $content; + } + + function zeroise($number,$threshold) { // function to add leading zeros when necessary + return sprintf('%0'.$threshold.'s', $number); + } + + + function backslashit($string) { + $string = preg_replace('/([a-z])/i', '\\\\\1', $string); + return $string; + } + + function trailingslashit($string) { + if ( '/' != substr($string, -1)) { + $string .= '/'; + } + return $string; + } + + function addslashes_gpc($gpc) { + if (!get_magic_quotes_gpc()) { + $gpc = addslashes($gpc); + } + return $gpc; + } + + function antispambot($emailaddy, $mailto=0) { + $emailNOSPAMaddy = ''; + srand ((float) microtime() * 1000000); + for ($i = 0; $i < strlen($emailaddy); $i = $i + 1) { + $j = floor(rand(0, 1+$mailto)); + if ($j==0) { + $emailNOSPAMaddy .= '&#'.ord(substr($emailaddy,$i,1)).';'; + } elseif ($j==1) { + $emailNOSPAMaddy .= substr($emailaddy,$i,1); + } elseif ($j==2) { + $emailNOSPAMaddy .= '%'.zeroise(dechex(ord(substr($emailaddy, $i, 1))), 2); + } + } + $emailNOSPAMaddy = str_replace('@','@',$emailNOSPAMaddy); + return $emailNOSPAMaddy; + } + + function make_clickable($ret) { + $ret = ' ' . $ret . ' '; + $ret = preg_replace("#([\s>])(https?)://([^\s<>{}()]+[^\s.,<>{}()])#i", "$1<a href='$2://$3' rel='nofollow'>$2://$3</a>", $ret); + $ret = preg_replace("#(\s)www\.([a-z0-9\-]+)\.([a-z0-9\-.\~]+)((?:/[^ <>{}()\n\r]*[^., <>{}()\n\r]?)?)#i", "$1<a href='http://www.$2.$3$4' rel='nofollow'>www.$2.$3$4</a>", $ret); + $ret = preg_replace("#(\s)([a-z0-9\-_.]+)@([^,< \n\r]+)#i", "$1<a href=\"mailto:$2@$3\">$2@$3</a>", $ret); + $ret = trim($ret); + return $ret; + } + + function wp_rel_nofollow( $text ) { + $text = preg_replace('|<a (.+?)>|i', '<a $1 rel="nofollow">', $text); + return $text; + } + + + /* + function convert_smilies($text) { + global $wp_smiliessearch, $wp_smiliesreplace; + $output = ''; + if (get_settings('use_smilies')) { + // HTML loop taken from texturize function, could possible be consolidated + $textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE); // capture the tags as well as in between + $stop = count($textarr);// loop stuff + for ($i = 0; $i < $stop; $i++) { + $content = $textarr[$i]; + if ((strlen($content) > 0) && ('<' != $content{0})) { // If it's not a tag + $content = str_replace($wp_smiliessearch, $wp_smiliesreplace, $content); + } + $output .= $content; + } + } else { + // return default text. + $output = $text; + } + return $output; + } + */ + + function is_email($user_email) { + $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i"; + if(strstr($user_email, '@') && strstr($user_email, '.')) { + if (preg_match($chars, $user_email)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + + function strip_all_but_one_link($text, $mylink) { + $match_link = '#(<a.+?href.+?'.'>)(.+?)(</a>)#'; + preg_match_all($match_link, $text, $matches); + $count = count($matches[0]); + for ($i=0; $i<$count; $i++) { + if (!strstr($matches[0][$i], $mylink)) { + $text = str_replace($matches[0][$i], $matches[2][$i], $text); + } + } + return $text; + } + + + // used by wp-mail to handle charsets in email subjects + function wp_iso_descrambler($string) { + /* this may only work with iso-8859-1, I'm afraid */ + if (!preg_match('#\=\?(.+)\?Q\?(.+)\?\=#i', $string, $matches)) { + return $string; + } else { + $subject = str_replace('_', ' ', $matches[2]); + $subject = preg_replace('#\=([0-9a-f]{2})#ei', "chr(hexdec(strtolower('$1')))", $subject); + return $subject; + } + } + + + // give it a date, it will give you the same date as GMT + function get_gmt_from_date($string) { + // note: this only substracts $time_difference from the given date + preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches); + $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); + $string_gmt = gmdate('Y-m-d H:i:s', $string_time - get_settings('gmt_offset') * 3600); + return $string_gmt; + } + + // give it a GMT date, it will give you the same date with $time_difference added + function get_date_from_gmt($string) { + // note: this only adds $time_difference to the given date + preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches); + $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]); + $string_localtime = gmdate('Y-m-d H:i:s', $string_time + get_settings('gmt_offset')*3600); + return $string_localtime; + } + + // computes an offset in seconds from an iso8601 timezone + function iso8601_timezone_to_offset($timezone) { + // $timezone is either 'Z' or '[+|-]hhmm' + if ($timezone == 'Z') { + $offset = 0; + } else { + $sign = (substr($timezone, 0, 1) == '+') ? 1 : -1; + $hours = intval(substr($timezone, 1, 2)); + $minutes = intval(substr($timezone, 3, 4)) / 60; + $offset = $sign * 3600 * ($hours + $minutes); + } + return $offset; + } + + // converts an iso8601 date to MySQL DateTime format used by post_date[_gmt] + function iso8601_to_datetime($date_string, $timezone = USER) { + if ($timezone == GMT) { + preg_match('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', $date_string, $date_bits); + if (!empty($date_bits[7])) { // we have a timezone, so let's compute an offset + $offset = iso8601_timezone_to_offset($date_bits[7]); + } else { // we don't have a timezone, so we assume user local timezone (not server's!) + $offset = 3600 * get_settings('gmt_offset'); + } + $timestamp = gmmktime($date_bits[4], $date_bits[5], $date_bits[6], $date_bits[2], $date_bits[3], $date_bits[1]); + $timestamp -= $offset; + return gmdate('Y-m-d H:i:s', $timestamp); + } elseif ($timezone == USER) { + return preg_replace('#([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(Z|[\+|\-][0-9]{2,4}){0,1}#', '$1-$2-$3 $4:$5:$6', $date_string); + } + } + + function popuplinks($text) { + // Comment text in popup windows should be filtered through this. + // Right now it's a moderately dumb function, ideally it would detect whether + // a target or rel attribute was already there and adjust its actions accordingly. + $text = preg_replace('/<a (.+?)>/i', "<a $1 target='_blank' rel='external'>", $text); + return $text; + } + + function sanitize_email($email) { + return preg_replace('/[^a-z0-9+_.@-]/i', '', $email); + } + + function human_time_diff( $from, $to = '' ) { + if ( empty($to) ) + $to = time(); + $diff = (int) abs($to - $from); + if ($diff <= 3600) { + $mins = round($diff / 60); + if ($mins <= 1) + $since = __('1 min'); + else + $since = sprintf( __('%s mins'), $mins); + } else if (($diff <= 86400) && ($diff > 3600)) { + $hours = round($diff / 3600); + if ($hours <= 1) + $since = __('1 hour'); + else + $since = sprintf( __('%s hours'), $hours ); + } elseif ($diff >= 86400) { + $days = round($diff / 86400); + if ($days <= 1) + $since = __('1 day'); + else + $since = sprintf( __('%s days'), $days ); + } + return $since; + } + + function wp_trim_excerpt($text) { // Fakes an excerpt if needed + global $post; + if ( '' == $text ) { + $text = $post->post_content; + $text = apply_filters('the_content', $text); + $text = str_replace(']]>', ']]>', $text); + $text = strip_tags($text); + $excerpt_length = 55; + $words = explode(' ', $text, $excerpt_length + 1); + if (count($words) > $excerpt_length) { + array_pop($words); + array_push($words, '[...]'); + $text = implode(' ', $words); + } + } + return $text; + } + + function ent2ncr($text) { + $to_ncr = array( + '"' => '"', + '&' => '&', + '⁄' => '/', + '<' => '<', + '>' => '>', + ' ' => ' ', + '¡' => '¡', + '¢' => '¢', + '£' => '£', + '¤' => '¤', + '¥' => '¥', + '|' => '¦', + '¦' => '¦', + '&brkbar;' => '¦', + '§' => '§', + '¨' => '¨', + '¨' => '¨', + '©' => '©', + 'ª' => 'ª', + '«' => '«', + '¬' => '¬', + '­' => '­', + '®' => '®', + '¯' => '¯', + '&hibar;' => '¯', + '°' => '°', + '±' => '±', + '²' => '²', + '³' => '³', + '´' => '´', + 'µ' => 'µ', + '¶' => '¶', + '·' => '·', + '¸' => '¸', + '¹' => '¹', + 'º' => 'º', + '»' => '»', + '¼' => '¼', + '½' => '½', + '¾' => '¾', + '¿' => '¿', + 'À' => 'À', + 'Á' => 'Á', + 'Â' => 'Â', + 'Ã' => 'Ã', + 'Ä' => 'Ä', + 'Å' => 'Å', + 'Æ' => 'Æ', + 'Ç' => 'Ç', + 'È' => 'È', + 'É' => 'É', + 'Ê' => 'Ê', + 'Ë' => 'Ë', + 'Ì' => 'Ì', + 'Í' => 'Í', + 'Î' => 'Î', + 'Ï' => 'Ï', + 'Ð' => 'Ð', + 'Ñ' => 'Ñ', + 'Ò' => 'Ò', + 'Ó' => 'Ó', + 'Ô' => 'Ô', + 'Õ' => 'Õ', + 'Ö' => 'Ö', + '×' => '×', + 'Ø' => 'Ø', + 'Ù' => 'Ù', + 'Ú' => 'Ú', + 'Û' => 'Û', + 'Ü' => 'Ü', + 'Ý' => 'Ý', + 'Þ' => 'Þ', + 'ß' => 'ß', + 'à' => 'à', + 'á' => 'á', + 'â' => 'â', + 'ã' => 'ã', + 'ä' => 'ä', + 'å' => 'å', + 'æ' => 'æ', + 'ç' => 'ç', + 'è' => 'è', + 'é' => 'é', + 'ê' => 'ê', + 'ë' => 'ë', + 'ì' => 'ì', + 'í' => 'í', + 'î' => 'î', + 'ï' => 'ï', + 'ð' => 'ð', + 'ñ' => 'ñ', + 'ò' => 'ò', + 'ó' => 'ó', + 'ô' => 'ô', + 'õ' => 'õ', + 'ö' => 'ö', + '÷' => '÷', + 'ø' => 'ø', + 'ù' => 'ù', + 'ú' => 'ú', + 'û' => 'û', + 'ü' => 'ü', + 'ý' => 'ý', + 'þ' => 'þ', + 'ÿ' => 'ÿ', + 'Œ' => 'Œ', + 'œ' => 'œ', + 'Š' => 'Š', + 'š' => 'š', + 'Ÿ' => 'Ÿ', + 'ƒ' => 'ƒ', + 'ˆ' => 'ˆ', + '˜' => '˜', + 'Α' => 'Α', + 'Β' => 'Β', + 'Γ' => 'Γ', + 'Δ' => 'Δ', + 'Ε' => 'Ε', + 'Ζ' => 'Ζ', + 'Η' => 'Η', + 'Θ' => 'Θ', + 'Ι' => 'Ι', + 'Κ' => 'Κ', + 'Λ' => 'Λ', + 'Μ' => 'Μ', + 'Ν' => 'Ν', + 'Ξ' => 'Ξ', + 'Ο' => 'Ο', + 'Π' => 'Π', + 'Ρ' => 'Ρ', + 'Σ' => 'Σ', + 'Τ' => 'Τ', + 'Υ' => 'Υ', + 'Φ' => 'Φ', + 'Χ' => 'Χ', + 'Ψ' => 'Ψ', + 'Ω' => 'Ω', + 'α' => 'α', + 'β' => 'β', + 'γ' => 'γ', + 'δ' => 'δ', + 'ε' => 'ε', + 'ζ' => 'ζ', + 'η' => 'η', + 'θ' => 'θ', + 'ι' => 'ι', + 'κ' => 'κ', + 'λ' => 'λ', + 'μ' => 'μ', + 'ν' => 'ν', + 'ξ' => 'ξ', + 'ο' => 'ο', + 'π' => 'π', + 'ρ' => 'ρ', + 'ς' => 'ς', + 'σ' => 'σ', + 'τ' => 'τ', + 'υ' => 'υ', + 'φ' => 'φ', + 'χ' => 'χ', + 'ψ' => 'ψ', + 'ω' => 'ω', + 'ϑ' => 'ϑ', + 'ϒ' => 'ϒ', + 'ϖ' => 'ϖ', + ' ' => ' ', + ' ' => ' ', + ' ' => ' ', + '‌' => '‌', + '‍' => '‍', + '‎' => '‎', + '‏' => '‏', + '–' => '–', + '—' => '—', + '‘' => '‘', + '’' => '’', + '‚' => '‚', + '“' => '“', + '”' => '”', + '„' => '„', + '†' => '†', + '‡' => '‡', + '•' => '•', + '…' => '…', + '‰' => '‰', + '′' => '′', + '″' => '″', + '‹' => '‹', + '›' => '›', + '‾' => '‾', + '⁄' => '⁄', + '€' => '€', + 'ℑ' => 'ℑ', + '℘' => '℘', + 'ℜ' => 'ℜ', + '™' => '™', + 'ℵ' => 'ℵ', + '↵' => '↵', + '⇐' => '⇐', + '⇑' => '⇑', + '⇒' => '⇒', + '⇓' => '⇓', + '⇔' => '⇔', + '∀' => '∀', + '∂' => '∂', + '∃' => '∃', + '∅' => '∅', + '∇' => '∇', + '∈' => '∈', + '∉' => '∉', + '∋' => '∋', + '∏' => '∏', + '∑' => '∑', + '−' => '−', + '∗' => '∗', + '√' => '√', + '∝' => '∝', + '∞' => '∞', + '∠' => '∠', + '∧' => '∧', + '∨' => '∨', + '∩' => '∩', + '∪' => '∪', + '∫' => '∫', + '∴' => '∴', + '∼' => '∼', + '≅' => '≅', + '≈' => '≈', + '≠' => '≠', + '≡' => '≡', + '≤' => '≤', + '≥' => '≥', + '⊂' => '⊂', + '⊃' => '⊃', + '⊄' => '⊄', + '⊆' => '⊆', + '⊇' => '⊇', + '⊕' => '⊕', + '⊗' => '⊗', + '⊥' => '⊥', + '⋅' => '⋅', + '⌈' => '⌈', + '⌉' => '⌉', + '⌊' => '⌊', + '⌋' => '⌋', + '⟨' => '〈', + '⟩' => '〉', + '←' => '←', + '↑' => '↑', + '→' => '→', + '↓' => '↓', + '↔' => '↔', + '◊' => '◊', + '♠' => '♠', + '♣' => '♣', + '♥' => '♥', + '♦' => '♦' + ); + + foreach ($to_ncr as $entity => $ncr) { + $text = str_replace($entity, $ncr, $text); + } + return $text; + } + +?> diff --git a/fp-includes/core/core.wp-functions-compat.php b/fp-includes/core/core.wp-functions-compat.php new file mode 100755 index 0000000..e038a70 --- /dev/null +++ b/fp-includes/core/core.wp-functions-compat.php @@ -0,0 +1,92 @@ +<?php + +/* Functions missing from older PHP versions */ + + +/* Added in PHP 4.2.0 */ + +if (!function_exists('floatval')) { + function floatval($string) { + return ((float) $string); + } +} + +if (!function_exists('is_a')) { + function is_a($object, $class) { + // by Aidan Lister <aidan@php.net> + if (get_class($object) == strtolower($class)) { + return true; + } else { + return is_subclass_of($object, $class); + } + } +} + +if (!function_exists('ob_clean')) { + function ob_clean() { + // by Aidan Lister <aidan@php.net> + if (@ob_end_clean()) { + return ob_start(); + } + return false; + } +} + + +/* Added in PHP 4.3.0 */ + +function printr($var, $do_not_echo = false) { + // from php.net/print_r user contributed notes + ob_start(); + print_r($var); + $code = htmlentities(ob_get_contents()); + ob_clean(); + if (!$do_not_echo) { + echo "<pre>$code</pre>"; + } + return $code; +} + +if (!defined('CASE_LOWER')) { + define('CASE_LOWER', 0); +} + +if (!defined('CASE_UPPER')) { + define('CASE_UPPER', 1); +} + + +/** + * Replace array_change_key_case() + * + * @category PHP + * @package PHP_Compat + * @link http://php.net/function.array_change_key_case + * @author Stephan Schmidt <schst@php.net> + * @author Aidan Lister <aidan@php.net> + * @version $Revision: 1.1.1.2 $ + * @since PHP 4.2.0 + * @require PHP 4.0.0 (user_error) + */ +if (!function_exists('array_change_key_case')) { + function array_change_key_case($input, $case = CASE_LOWER) + { + if (!is_array($input)) { + user_error('array_change_key_case(): The argument should be an array', + E_USER_WARNING); + return false; + } + + $output = array (); + $keys = array_keys($input); + $casefunc = ($case == CASE_LOWER) ? 'strtolower' : 'strtoupper'; + + foreach ($keys as $key) { + $output[$casefunc($key)] = $input[$key]; + } + + return $output; + } +} + +?> \ No newline at end of file diff --git a/fp-includes/core/core.wp-functions.php b/fp-includes/core/core.wp-functions.php new file mode 100755 index 0000000..ae851c5 --- /dev/null +++ b/fp-includes/core/core.wp-functions.php @@ -0,0 +1,76 @@ +<?php + +function wp_nonce_url($actionurl, $action = -1) { + return wp_specialchars( $actionurl . '&_wpnonce=' . wp_create_nonce($action) ); +} + +function wp_nonce_field($action = -1) { + echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce($action) . '" />'; + wp_referer_field(); +} + +function wp_referer_field() { + $ref = wp_specialchars($_SERVER['REQUEST_URI']); + echo '<input type="hidden" name="_wp_http_referer" value="'. $ref . '" />'; + if ( wp_get_original_referer() ) { + $original_ref = wp_specialchars(stripslashes(wp_get_original_referer())); + echo '<input type="hidden" name="_wp_original_http_referer" value="'. $original_ref . '" />'; + } +} + +function wp_original_referer_field() { + echo '<input type="hidden" name="_wp_original_http_referer" value="' . wp_specialchars(stripslashes($_SERVER['REQUEST_URI'])) . '" />'; +} + +function wp_get_referer() { + foreach ( array(@$_REQUEST['_wp_http_referer'],@$_SERVER['HTTP_REFERER']) as $ref ) + if ( !empty($ref) ) + return $ref; + return false; +} + +function wp_get_original_referer() { + if ( !empty($_REQUEST['_wp_original_http_referer']) ) + return $_REQUEST['_wp_original_http_referer']; + return false; +} + + + + + +function add_magic_quotes($array) { + foreach ($array as $k => $v) { + if (is_array($v)) { + $array[$k] = add_magic_quotes($v); + } else { + $array[$k] = addslashes($v); + } + } + return $array; +} + +function wp_remote_fopen( $uri ) { + if ( ini_get('allow_url_fopen') ) { + $fp = fopen( $uri, 'r' ); + if ( !$fp ) + return false; + $linea = ''; + while( $remote_read = fread($fp, 4096) ) + $linea .= $remote_read; + fclose($fp); + return $linea; + } else if ( function_exists('curl_init') ) { + $handle = curl_init(); + curl_setopt ($handle, CURLOPT_URL, $uri); + curl_setopt ($handle, CURLOPT_CONNECTTIMEOUT, 1); + curl_setopt ($handle, CURLOPT_RETURNTRANSFER, 1); + $buffer = curl_exec($handle); + curl_close($handle); + return $buffer; + } else { + return false; + } +} + +?> \ No newline at end of file diff --git a/fp-includes/core/core.wp-options.php b/fp-includes/core/core.wp-options.php new file mode 100755 index 0000000..f006bb5 --- /dev/null +++ b/fp-includes/core/core.wp-options.php @@ -0,0 +1,56 @@ +<?php + + //======================// + /* Options functions */ + + function get_settings($setting) { + + /*$options=get_alloptions(); + return isset($options[$setting])? $options[$setting] : false;*/ + + } + + function get_option($option) { + return get_settings($option); + } + + function form_option($option) { + // echo htmlspecialchars( get_option($option), ENT_QUOTES ); + } + + function get_alloptions() { + + global $blog_config; + //global $theme; + //if (!isset($theme)) die ('Invalid call of get_alloptions(): theme not loaded'); + + $options=$blog_config; + + system_dprint($options); + + return $options; + + } + + function update_option($option_name, $newvalue) { + $options = get_alloptions(); + $options[$option_name]=$newvalue; + config_save($options); + } + + + // thx Alex Stapleton, http://alex.vort-x.net/blog/ + function add_option($name, $value = '', $description = '', $autoload = 'yes') { + //not yet fully implemented + $options=get_alloptions(); + $options[$name]=$value; + return config_save($options); + } + + function delete_option($name) { + $options = get_alloptions(); + unset($options[$name]); + return config_save($options); + } + +?> diff --git a/fp-includes/core/core.wp-pluggable-funcs.php b/fp-includes/core/core.wp-pluggable-funcs.php new file mode 100755 index 0000000..7be251f --- /dev/null +++ b/fp-includes/core/core.wp-pluggable-funcs.php @@ -0,0 +1,469 @@ +<?php + + /* These functions can be replaced via plugins. They are loaded after + plugins are loaded. */ + + + function _get_nextprev_link($nextprev) { + + global $fpdb; + $q =& $fpdb->getQuery(); + + list($caption, $id) = call_user_func(array(&$q, 'get'.$nextprev)); + + if (!$id) + return null; + + if ($q->single) { + $link = "?entry={$id}"; + } else { + if ($_SERVER['QUERY_STRING']){ + + if ( strpos($_SERVER['QUERY_STRING'], 'paged')!==false ){ + $link = '?'.preg_replace( + '{paged=[0-9]+}', + "paged={$id}", + $_SERVER['QUERY_STRING'] + ); + } else { + $link = '?' . $_SERVER['QUERY_STRING'] . "&paged={$id}"; + } + $link = str_replace('&', '&', $link); + + } else { + $link = "?paged={$id}"; + } + } + + return array($caption, BLOG_BASEURL . $link); + + } + + if (!function_exists('get_nextpage_link')) : + function get_nextpage_link() { + + global $fpdb; + $q =& $fpdb->getQuery(); + + $a = _get_nextprev_link('NextPage'); + + + if ($q->single) { + $a[0] .= ' » '; + } + + return $a; + + } + endif; + + if (!function_exists('get_prevpage_link')) : + function get_prevpage_link() { + + global $fpdb; + $q =& $fpdb->getQuery(); + + $a = _get_nextprev_link('PrevPage'); + + if ($q->single) { + $a[0] = ' « ' . $a[0]; + } + + return $a; + } + endif; + + + + + function wp_filter_kses($str) { + return $str; + } + + //---------------------------------------------------------------------------- + // WordPress pluggable functions + //---------------------------------------------------------------------------- + + + /* + get_currentuserinfo() + Grabs the information of the current logged in user, if there is one. Essentially a + wrapper for get_userdata(), but it also stores information in global variables. + get_userdata($userid) + Pulls user information for the specified user from the database. + get_userdatabylogin($user_login) + Pulls user information for the specified user from the database. + wp_mail($to, $subject, $message, $headers = '') + A convenient wrapper for PHP's mail function. + wp_login($username, $password, $already_md5 = false) + Returns true if the specified username and password correspond to a registered + user. + auth_redirect() + If a user is not logged in, he or she will be redirected to WordPress' login page before + being allowed to access content on the page from which this function was called. + Upon sucessfully logging in, the user is sent back to the page in question. + wp_redirect($location) + Redirects a browser to the absolute URI specified by the $location parameter. + wp_setcookie($username, $password, $already_md5 = false, $home = + '', $siteurl = '') + Sets the WordPress cookies for a logged in user. See WordPress Cookies. + wp_clearcookie() + Clears the cookies for a logged in user. See WordPress Cookies. + wp_notify_postauthor($comment_id, $comment_type='') + Emails the author of the comment's post the content of the comment specified. + wp_notify_moderator($comment_id) + Informs the administrative email account that the comment specified needs to be + moderated. See General Options SubPanel. + */ + + + +if ( !function_exists('get_currentuserinfo') ) : +function get_currentuserinfo() { +/* global $user_login, $userdata, $user_level, $user_ID, $user_nickname, $user_email, $user_url, $user_pass_md5, $user_identity; + // *** retrieving user's data from cookies and db - no spoofing + + if (isset($_COOKIE['wordpressuser_' . COOKIEHASH])) + $user_login = $_COOKIE['wordpressuser_' . COOKIEHASH]; + $userdata = get_userdatabylogin($user_login); + $user_level = $userdata->user_level; + $user_ID = $userdata->ID; + $user_nickname = $userdata->user_nickname; + $user_email = $userdata->user_email; + $user_url = $userdata->user_url; + $user_pass_md5 = md5($userdata->user_pass); + + $idmode = $userdata->user_idmode; + if ($idmode == 'nickname') $user_identity = $userdata->user_nickname; + if ($idmode == 'login') $user_identity = $userdata->user_login; + if ($idmode == 'firstname') $user_identity = $userdata->user_firstname; + if ($idmode == 'lastname') $user_identity = $userdata->user_lastname; + if ($idmode == 'namefl') $user_identity = $userdata->user_firstname.' '.$userdata->user_lastname; + if ($idmode == 'namelf') $user_identity = $userdata->user_lastname.' '.$userdata->user_firstname; + if (!$idmode) $user_identity = $userdata->user_nickname; +*/ +} +endif; + + + +if ( !function_exists('get_userdata') ) : +function get_userdata($userid) { +/* global $wpdb, $cache_userdata; + $userid = (int) $userid; + if ( empty($cache_userdata[$userid]) && $userid != 0) { + $cache_userdata[$userid] = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE ID = $userid"); + $cache_userdata[$cache_userdata[$userid]->user_login] =& $cache_userdata[$userid]; + } + + return $cache_userdata[$userid]; +*/ +} +endif; + + + +if ( !function_exists('get_userdatabylogin') ) : +function get_userdatabylogin($user_login) { +/* global $cache_userdata, $wpdb; + if ( !empty($user_login) && empty($cache_userdata[$user_login]) ) { + $user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE user_login = '$user_login'"); // todo: get rid of this intermediate var + $cache_userdata[$user->ID] = $user; + $cache_userdata[$user_login] =& $cache_userdata[$user->ID]; + } else { + $user = $cache_userdata[$user_login]; + } + return $user; +*/ +} +endif; + + + +if ( !function_exists('wp_mail') ) : +function wp_mail($to, $subject, $message, $headers = '') { + if( $headers == '' ) { + $headers = "MIME-Version: 1.0\n" . + "From: " . get_settings('admin_email') . "\n" . + "Content-Type: text/plain; charset=\"" . get_settings('blog_charset') . "\"\n"; + } + + return @mail($to, $subject, $message, $headers); +} +endif; + + + +if ( !function_exists('wp_login') ) : +function wp_login($username, $password, $already_md5 = false) { +/* global $wpdb, $error; + + if ( !$username ) + return false; + + if ( !$password ) { + $error = __('<strong>Error</strong>: The password field is empty.'); + return false; + } + + $login = $wpdb->get_row("SELECT ID, user_login, user_pass FROM $wpdb->users WHERE user_login = '$username'"); + + if (!$login) { + $error = __('<strong>Error</strong>: Wrong username.'); + return false; + } else { + // If the password is already_md5, it has been double hashed. + // Otherwise, it is plain text. + if ( ($already_md5 && $login->user_login == $username && md5($login->user_pass) == $password) || ($login->user_login == $username && $login->user_pass == md5($password)) ) { + return true; + } else { + $error = __('<strong>Error</strong>: Incorrect password.'); + $pwd = ''; + return false; + } + } +*/ +} +endif; + +if ( !function_exists('auth_redirect') ) : +function auth_redirect() { + // Checks if a user is logged in, if not redirects them to the login page +/* if ( (!empty($_COOKIE['wordpressuser_' . COOKIEHASH]) && + !wp_login($_COOKIE['wordpressuser_' . COOKIEHASH], $_COOKIE['wordpresspass_' . COOKIEHASH], true)) || + (empty($_COOKIE['wordpressuser_' . COOKIEHASH])) ) { + header('Expires: Wed, 11 Jan 1984 05:00:00 GMT'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + header('Cache-Control: no-cache, must-revalidate, max-age=0'); + header('Pragma: no-cache'); + + header('Location: ' . get_settings('siteurl') . '/wp-login.php?redirect_to=' . urlencode($_SERVER['REQUEST_URI'])); + exit(); + } +*/ +} +endif; + +// Cookie safe redirect. Works around IIS Set-Cookie bug. +// http://support.microsoft.com/kb/q176113/ +if ( !function_exists('wp_redirect') ) : +function wp_redirect($location) { + global $is_IIS; + + if ($is_IIS) + header("Refresh: 0;url=$location"); + else + header("Location: $location"); +} +endif; + +if ( !function_exists('wp_setcookie') ) : +function wp_setcookie($username, $password, $already_md5 = false, $home = '', $siteurl = '') { + if ( !$already_md5 ) + $password = md5( md5($password) ); // Double hash the password in the cookie. + + if ( empty($home) ) + $cookiepath = COOKIEPATH; + else + $cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' ); + + if ( empty($siteurl) ) { + $sitecookiepath = SITECOOKIEPATH; + $cookiehash = COOKIEHASH; + } else { + $sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' ); + $cookiehash = md5($siteurl); + } + + setcookie('wordpressuser_'. $cookiehash, $username, time() + 31536000, $cookiepath); + setcookie('wordpresspass_'. $cookiehash, $password, time() + 31536000, $cookiepath); + + if ( $cookiepath != $sitecookiepath ) { + setcookie('wordpressuser_'. $cookiehash, $username, time() + 31536000, $sitecookiepath); + setcookie('wordpresspass_'. $cookiehash, $password, time() + 31536000, $sitecookiepath); + } +} +endif; + +if ( !function_exists('wp_clearcookie') ) : +function wp_clearcookie() { + setcookie('wordpressuser_' . COOKIEHASH, ' ', time() - 31536000, COOKIEPATH); + setcookie('wordpresspass_' . COOKIEHASH, ' ', time() - 31536000, COOKIEPATH); + setcookie('wordpressuser_' . COOKIEHASH, ' ', time() - 31536000, SITECOOKIEPATH); + setcookie('wordpresspass_' . COOKIEHASH, ' ', time() - 31536000, SITECOOKIEPATH); +} +endif; + + + +if ( !function_exists('check_admin_referer') ) : +function check_admin_referer($action = -1) { + $adminurl = BLOG_BASEURL . 'admin.php'; + $referer = strtolower(wp_get_referer()); + if ( !wp_verify_nonce(@$_REQUEST['_wpnonce'], $action) && + !(-1 == $action && strstr($referer, $adminurl)) ) { + wp_nonce_ays($action); + die(); + } + do_action('check_admin_referer', $action); +} +endif; + + +if ( !function_exists('wp_verify_nonce') ) : +function wp_verify_nonce($nonce, $action = -1) { + + $user = user_get(); + $uid = $user['userid']; + + $i = ceil(time() / 43200); + + //Allow for expanding range, but only do one check if we can + if( substr(wp_hash($i . $action . $uid), -12, 10) == $nonce || substr(wp_hash(($i - 1) . $action . $uid), -12, 10) == $nonce ) + return true; + return false; +} +endif; + +if ( !function_exists('wp_create_nonce') ) : +function wp_create_nonce($action = -1) { + $user = user_get(); + $uid = $user['userid']; + + $i = ceil(time() / 43200); + + return substr(wp_hash($i . $action . $uid), -12, 10); +} +endif; + +if ( !function_exists('wp_salt') ) : +function wp_salt() { + global $fp_config; + static $salt = null; + if (!$salt) + $salt = $fp_config['general']['blogid'] . $fp_config['general']['author'] . ABS_PATH . BLOG_BASEURL ; + return $salt; +} +endif; + +if ( !function_exists('wp_hash') ) : +function wp_hash($data) { + $salt = wp_salt(); + + if ( function_exists('hash_hmac') ) { + return hash_hmac('md5', $data, $salt); + } else { + return md5($data . $salt); + } +} +endif; + + +if ( ! function_exists('wp_notify_postauthor') ) : +function wp_notify_postauthor($comment_id, $comment_type='') { +/* global $wpdb; + + $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1"); + $post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID='$comment->comment_post_ID' LIMIT 1"); + $user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE ID='$post->post_author' LIMIT 1"); + + if ('' == $user->user_email) return false; // If there's no email to send the comment to + + $comment_author_domain = gethostbyaddr($comment->comment_author_IP); + + $blogname = get_settings('blogname'); + + if ( empty( $comment_type ) ) $comment_type = 'comment'; + + if ('comment' == $comment_type) { + $notify_message = sprintf( __('New comment on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n"; + $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; + $notify_message .= sprintf( __('URI : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= sprintf( __('Whois : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n"; + $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= __('You can see all comments on this post here: ') . "\r\n"; + $subject = sprintf( __('[%1$s] Comment: "%2$s"'), $blogname, $post->post_title ); + } elseif ('trackback' == $comment_type) { + $notify_message = sprintf( __('New trackback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n"; + $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('URI : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= __('Excerpt: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= __('You can see all trackbacks on this post here: ') . "\r\n"; + $subject = sprintf( __('[%1$s] Trackback: "%2$s"'), $blogname, $post->post_title ); + } elseif ('pingback' == $comment_type) { + $notify_message = sprintf( __('New pingback on your post #%1$s "%2$s"'), $comment->comment_post_ID, $post->post_title ) . "\r\n"; + $notify_message .= sprintf( __('Website: %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('URI : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= __('Excerpt: ') . "\r\n" . sprintf( __('[...] %s [...]'), $comment->comment_content ) . "\r\n\r\n"; + $notify_message .= __('You can see all pingbacks on this post here: ') . "\r\n"; + $subject = sprintf( __('[%1$s] Pingback: "%2$s"'), $blogname, $post->post_title ); + } + $notify_message .= get_permalink($comment->comment_post_ID) . "#comments\r\n\r\n"; + $notify_message .= sprintf( __('To delete this comment, visit: %s'), get_settings('siteurl').'/wp-admin/post.php?action=confirmdeletecomment&p='.$comment->comment_post_ID."&comment=$comment_id" ) . "\r\n"; + + if ('' == $comment->comment_author_email || '' == $comment->comment_author) { + $from = "From: \"$blogname\" <wordpress@" . $_SERVER['SERVER_NAME'] . '>'; + } else { + $from = 'From: "' . $comment->comment_author . "\" <$comment->comment_author_email>"; + } + + $notify_message = apply_filters('comment_notification_text', $notify_message); + $subject = apply_filters('comment_notification_subject', $subject); + $message_headers = apply_filters('comment_notification_headers', $message_headers); + + $message_headers = "MIME-Version: 1.0\n" + . "$from\n" + . "Content-Type: text/plain; charset=\"" . get_settings('blog_charset') . "\"\n"; + + @wp_mail($user->user_email, $subject, $notify_message, $message_headers); + + return true; +*/ +} +endif; + +/* wp_notify_moderator + notifies the moderator of the blog (usually the admin) + about a new comment that waits for approval + always returns true + */ +if ( !function_exists('wp_notify_moderator') ) : +function wp_notify_moderator($comment_id) { +/* global $wpdb; + + if( get_settings( "moderation_notify" ) == 0 ) + return true; + + $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID='$comment_id' LIMIT 1"); + $post = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE ID='$comment->comment_post_ID' LIMIT 1"); + + $comment_author_domain = gethostbyaddr($comment->comment_author_IP); + $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $wpdb->comments WHERE comment_approved = '0'"); + + $notify_message = sprintf( __('A new comment on the post #%1$s "%2$s" is waiting for your approval'), $post->ID, $post->post_title ) . "\r\n"; + $notify_message .= get_permalink($comment->comment_post_ID) . "\r\n\r\n"; + $notify_message .= sprintf( __('Author : %1$s (IP: %2$s , %3$s)'), $comment->comment_author, $comment->comment_author_IP, $comment_author_domain ) . "\r\n"; + $notify_message .= sprintf( __('E-mail : %s'), $comment->comment_author_email ) . "\r\n"; + $notify_message .= sprintf( __('URI : %s'), $comment->comment_author_url ) . "\r\n"; + $notify_message .= sprintf( __('Whois : http://ws.arin.net/cgi-bin/whois.pl?queryinput=%s'), $comment->comment_author_IP ) . "\r\n"; + $notify_message .= __('Comment: ') . "\r\n" . $comment->comment_content . "\r\n\r\n"; + $notify_message .= sprintf( __('To approve this comment, visit: %s'), get_settings('siteurl').'/wp-admin/post.php?action=mailapprovecomment&p='.$comment->comment_post_ID."&comment=$comment_id" ) . "\r\n"; + $notify_message .= sprintf( __('To delete this comment, visit: %s'), get_settings('siteurl').'/wp-admin/post.php?action=confirmdeletecomment&p='.$comment->comment_post_ID."&comment=$comment_id" ) . "\r\n"; + $notify_message .= sprintf( __('Currently %s comments are waiting for approval. Please visit the moderation panel:'), $comments_waiting ) . "\r\n"; + $notify_message .= get_settings('siteurl') . "/wp-admin/moderation.php\r\n"; + + $subject = sprintf( __('[%1$s] Please moderate: "%2$s"'), get_settings('blogname'), $post->post_title ); + $admin_email = get_settings("admin_email"); + + $notify_message = apply_filters('comment_moderation_text', $notify_message); + $subject = apply_filters('comment_moderation_subject', $subject); + + @wp_mail($admin_email, $subject, $notify_message); + + return true; +*/ +} +endif; + +?> \ No newline at end of file diff --git a/fp-includes/core/core.wp-pluggable-funcs_old.php b/fp-includes/core/core.wp-pluggable-funcs_old.php new file mode 100755 index 0000000..a9cf0ee --- /dev/null +++ b/fp-includes/core/core.wp-pluggable-funcs_old.php @@ -0,0 +1,64 @@ +<?php + + /* These functions can be replaced via plugins. They are loaded after + plugins are loaded. */ + + + function get_settings() { + + } + + function wp_filter_kses($str) { + return $str; + } + + //---------------------------------------------------------------------------- + // WordPress pluggable functions + //---------------------------------------------------------------------------- + + + /* + get_currentuserinfo() + Grabs the information of the current logged in user, if there is one. Essentially a + wrapper for get_userdata(), but it also stores information in global variables. + get_userdata($userid) + Pulls user information for the specified user from the database. + get_userdatabylogin($user_login) + Pulls user information for the specified user from the database. + wp_mail($to, $subject, $message, $headers = '') + A convenient wrapper for PHP's mail function. + wp_login($username, $password, $already_md5 = false) + Returns true if the specified username and password correspond to a registered + user. + auth_redirect() + If a user is not logged in, he or she will be redirected to WordPress' login page before + being allowed to access content on the page from which this function was called. + Upon sucessfully logging in, the user is sent back to the page in question. + wp_redirect($location) + Redirects a browser to the absolute URI specified by the $location parameter. + wp_setcookie($username, $password, $already_md5 = false, $home = + '', $siteurl = '') + Sets the WordPress cookies for a logged in user. See WordPress Cookies. + wp_clearcookie() + Clears the cookies for a logged in user. See WordPress Cookies. + wp_notify_postauthor($comment_id, $comment_type='') + Emails the author of the comment's post the content of the comment specified. + wp_notify_moderator($comment_id) + Informs the administrative email account that the comment specified needs to be + moderated. See General Options SubPanel. + */ + +if ( !function_exists('wp_mail') ) : +function wp_mail($to, $subject, $message, $headers = '') { + if( $headers == '' ) { + $headers = "MIME-Version: 1.0\n" . + "From: " . get_settings('admin_email') . "\n" . + "Content-Type: text/plain; charset=\"" . get_settings('blog_charset') . "\"\n"; + } + + return @mail($to, $subject, $message, $headers); +} +endif; + + +?> \ No newline at end of file diff --git a/fp-includes/core/core.wp-plugin-interface.php b/fp-includes/core/core.wp-plugin-interface.php new file mode 100755 index 0000000..cccd2fe --- /dev/null +++ b/fp-includes/core/core.wp-plugin-interface.php @@ -0,0 +1,228 @@ +<?php + + // plugins.php + // plugin interface + + // This is EXACTLY a copy & paste from wordpress + + // Filters: these are the core of WP's plugin architecture + + function merge_filters($tag) { + global $wp_filter; + if (isset($wp_filter['all'])) { + foreach ($wp_filter['all'] as $priority => $functions) { + if (isset($wp_filter[$tag][$priority])) + $wp_filter[$tag][$priority] = array_merge($wp_filter['all'][$priority], $wp_filter[$tag][$priority]); + else + $wp_filter[$tag][$priority] = array_merge($wp_filter['all'][$priority], array()); + $wp_filter[$tag][$priority] = array_unique($wp_filter[$tag][$priority]); + } + } + + if ( isset($wp_filter[$tag]) ) + ksort( $wp_filter[$tag] ); + } + + function apply_filters($tag, $string) { + global $wp_filter; + + $args = array_slice(func_get_args(), 2); + + merge_filters($tag); + + if (!isset($wp_filter[$tag])) { + return $string; + } + foreach ($wp_filter[$tag] as $priority => $functions) { + if (!is_null($functions)) { + foreach($functions as $function) { + + $all_args = array_merge(array($string), $args); + $function_name = $function['function']; + $accepted_args = $function['accepted_args']; + + if($accepted_args == 1) { + $the_args = array($string); + } elseif ($accepted_args > 1) { + $the_args = array_slice($all_args, 0, $accepted_args); + } elseif($accepted_args == 0) { + $the_args = NULL; + } else { + $the_args = $all_args; + } + + $string = call_user_func_array($function_name, $the_args); + } + } + } + return $string; + } + + function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + global $wp_filter; + + // check that we don't already have the same filter at the same priority + if (isset($wp_filter[$tag]["$priority"])) { + foreach($wp_filter[$tag]["$priority"] as $filter) { + // uncomment if we want to match function AND accepted_args + //if ($filter == array($function, $accepted_args)) { + if ($filter['function'] == $function_to_add) { + return true; + } + } + } + + // So the format is wp_filter['tag']['array of priorities']['array of ['array (functions, accepted_args)]'] + $wp_filter[$tag]["$priority"][] = array('function'=>$function_to_add, 'accepted_args'=>$accepted_args); + //added by NoWhereMan + ksort($wp_filter[$tag]["$priority"]); + return true; + } + + function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { + global $wp_filter; + + $new_function_list = array(); + + // rebuild the list of filters + if (isset($wp_filter[$tag]["$priority"])) { + foreach($wp_filter[$tag]["$priority"] as $filter) { + if ($filter['function'] != $function_to_remove) { + $new_function_list[] = $filter; + } + } + $wp_filter[$tag]["$priority"] = $new_function_list; + } + return true; + } + + // The *_action functions are just aliases for the *_filter functions, they take special strings instead of generic content + + function do_action($tag, $arg = '') { + global $wp_filter; + $extra_args = array_slice(func_get_args(), 2); + if ( is_array($arg) ) + $args = array_merge($arg, $extra_args); + else + $args = array_merge(array($arg), $extra_args); + + merge_filters($tag); + + if (!isset($wp_filter[$tag])) { + return; + } + foreach ($wp_filter[$tag] as $priority => $functions) { + if (!is_null($functions)) { + foreach($functions as $function) { + + $function_name = $function['function']; + $accepted_args = $function['accepted_args']; + + if($accepted_args == 1) { + if ( is_array($arg) ) + $the_args = $arg; + else + $the_args = array($arg); + } elseif ($accepted_args > 1) { + $the_args = array_slice($args, 0, $accepted_args); + } elseif($accepted_args == 0) { + $the_args = NULL; + } else { + $the_args = $args; + } + + $string = call_user_func_array($function_name, $the_args); + } + } + } + } + + function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + add_filter($tag, $function_to_add, $priority, $accepted_args); + } + + function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { + remove_filter($tag, $function_to_remove, $priority, $accepted_args); + } + + + //---------------------------------------------------------------------------- + // WordPress hooks + //---------------------------------------------------------------------------- + /* + Current Hooks For Actions + This is a comprehensive list of plugin hooks in the core distribution of WordPress as of version 1.5 beta 1. + + NOTE: the following list is not a comprehensive listing of hooks available in 1.5 final. See Skippy's list (http://codex.wordpress.org/User:Skippy) for a more comprehensive, if less descriptive, listing of actions and filters. + + admin_footer + No parameter. Executes at the end of the admin panel inside the body tag. Useful for insertion of additional content. + admin_head + No parameter. Executes in the <head> section of the admin panel. Useful for insertion of additional content. + admin_menu + No parameter. Executes after the basic admin panel menu structure is in place. Useful for adding additional menus to the admin panel. + comment_closed + Receives the comment's post ID as a parameter. Executes when attempting to display the comment form for a post that has closed comments. + comment_form + Receives the comment's post ID as a parameter. Template tag. Executes after displaying the comment form for a post that allows comments. + comment_id_not_found + Receives the comment's post ID as a parameter. Executes when attempting to display the comment form for a post that does not exist. + comment_post + Receives the comment ID as a parameter. Executes when a comment is added through wp-comments.php. + delete_comment + Receives the comment ID as a parameter. Executes when a comment is deleted. + delete_post + Receives the post ID as a parameter. Executes whenever a post is deleted. + edit_comment + Receives the comment ID as a parameter. Executes whenever a comment is edited. + edit_form_advanced + No parameter. Executes during the display of the admin panel's advanced editing page, just before the <div> is closed that contains the post content textarea. Useful for inserting additional input fields into the advanced editing form. + edit_page_form + No parameter. Executes inside the <form> tag on the page editing form. Useful for inserting additional input fields in the page editing form. + edit_post + Receives the post ID as a parameter. Executes every time a post is edited. + generate_rewrite_rules + No parameter. Executes whenever the rewrite rules are recomputed. To modify the computed rules, use the filter rewrite_rules_array instead. + init + Executes after WordPress has finished loading but before any headers are sent. Useful for intercepting $_GET or $_POST triggers. + pingback_post + Receives the comment ID as a parameter. Executes when a comment is added via XMLRPC. + private_to_published + Receives the post ID as a parameter. Executes when a post is moved from private to published status. + publish_phone + Receives the post ID as a parameter. Executes when a post is added via wp-mail.php. + publish_post + Receives the post ID as a parameter. Executes when a post is saved and its status is set to "publish", regardless of its prior setting. NOTE: to add a hook to this action in 1.2, be sure to specify a priority between 0 and 9. The generic_ping hook is buggy and prevents any lesser priority hooks from working. + save_post + Receives the post ID as a parameter. Executes when a post is saved to the database. + shutdown + No parameter. Executes when the page output is complete. + simple_edit_form + No parameter. Executes during the display of the admin panel's simple editing page, just before the <div> is closed that contains the post content textarea. Useful for inserting additional input fields into the simple editing form. + switch_theme + Receives the name of the current theme as a parameter. Executes when the blog theme is changed. + template_redirect + No parameter. Executes before the determination of the template file to be used to display the requested page. Useful for providing additional templates based on request criteria. Example (pedagogical, not useful): Redirect all requests to the all.php template file in the current themes' directory. + function all_on_one () { + include(TEMPLATEPATH . '/all.php'); + exit; + } + + add_action('template_redirect', 'all_on_one'); + trackback_post + Receives the comment ID as a parameter. Executes when a comment is added via trackback.php. + wp_footer + No parameter. Template tag. Executes at the end of the <body> tag. Useful for insertion of additional content. + wp_head + No parameter. Executes in the <head> section. Useful for insertion of additional content. + wp_meta + No parameter. Executes in the <li>Meta</li> section of the included Theme's sidebar.php's. Useful for insertion of additional content. + wp_set_comment_status + Receives the comment ID as a parameter. Executes when the comment status changes. + */ + + + + + +?> \ No newline at end of file diff --git a/fp-includes/core/includes.php b/fp-includes/core/includes.php new file mode 100755 index 0000000..2579362 --- /dev/null +++ b/fp-includes/core/includes.php @@ -0,0 +1,48 @@ +<?php + + // includes.php + // this is just a list of all the standard includes + + require_once INCLUDES_DIR.'core.utils.php'; + utils_checksmarty(); + require(SMARTY_DIR . 'Smarty.class.php'); + $smarty =& new Smarty; + $_FP_SMARTY =& $smarty; + + + // WordPress plugin system + require_once INCLUDES_DIR.'core.wp-plugin-interface.php'; + require_once INCLUDES_DIR.'core.wp-functions.php'; + //require_once INCLUDES_DIR.'core.wp-options.php'; + require_once INCLUDES_DIR.'core.wp-formatting.php'; + require_once INCLUDES_DIR.'core.wp-default-filters.php'; + + + require_once INCLUDES_DIR.'core.filesystem.php'; + require_once INCLUDES_DIR.'core.fileio.php'; + require_once INCLUDES_DIR.'core.cache.php'; + require_once INCLUDES_DIR.'core.blogdb.php'; + + + require_once INCLUDES_DIR.'core.administration.php'; + require_once INCLUDES_DIR.'core.widgets.php'; + require_once INCLUDES_DIR.'core.comment.php'; + require_once INCLUDES_DIR.'core.config.php'; + require_once INCLUDES_DIR.'core.date.php'; + require_once INCLUDES_DIR.'core.entry.php'; + require_once INCLUDES_DIR.'core.static.php'; + require_once INCLUDES_DIR.'core.draft.php'; + + + require_once INCLUDES_DIR.'core.fpdb.class.php'; + + require_once INCLUDES_DIR.'core.language.php'; + require_once INCLUDES_DIR.'core.plugins.php'; + require_once INCLUDES_DIR.'core.session.php'; + require_once INCLUDES_DIR.'core.cookie.php'; + require_once INCLUDES_DIR.'core.system.php'; + require_once INCLUDES_DIR.'core.theme.php'; + require_once INCLUDES_DIR.'core.layout.php'; + require_once INCLUDES_DIR.'core.users.php'; + +?> diff --git a/fp-includes/smarty/Config_File.class.php b/fp-includes/smarty/Config_File.class.php new file mode 100644 index 0000000..3d7c1b4 --- /dev/null +++ b/fp-includes/smarty/Config_File.class.php @@ -0,0 +1,389 @@ +<?php + +/** + * Config_File class. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @link http://smarty.php.net/ + * @version 2.6.18 + * @copyright Copyright: 2001-2005 New Digital Group, Inc. + * @author Andrei Zmievski <andrei@php.net> + * @access public + * @package Smarty + */ + +/* $Id: Config_File.class.php,v 1.88 2007/03/06 10:40:06 messju Exp $ */ + +/** + * Config file reading class + * @package Smarty + */ +class Config_File { + /**#@+ + * Options + * @var boolean + */ + /** + * Controls whether variables with the same name overwrite each other. + */ + var $overwrite = true; + + /** + * Controls whether config values of on/true/yes and off/false/no get + * converted to boolean values automatically. + */ + var $booleanize = true; + + /** + * Controls whether hidden config sections/vars are read from the file. + */ + var $read_hidden = true; + + /** + * Controls whether or not to fix mac or dos formatted newlines. + * If set to true, \r or \r\n will be changed to \n. + */ + var $fix_newlines = true; + /**#@-*/ + + /** @access private */ + var $_config_path = ""; + var $_config_data = array(); + /**#@-*/ + + /** + * Constructs a new config file class. + * + * @param string $config_path (optional) path to the config files + */ + function Config_File($config_path = NULL) + { + if (isset($config_path)) + $this->set_path($config_path); + } + + + /** + * Set the path where configuration files can be found. + * + * @param string $config_path path to the config files + */ + function set_path($config_path) + { + if (!empty($config_path)) { + if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) { + $this->_trigger_error_msg("Bad config file path '$config_path'"); + return; + } + if(substr($config_path, -1) != DIRECTORY_SEPARATOR) { + $config_path .= DIRECTORY_SEPARATOR; + } + + $this->_config_path = $config_path; + } + } + + + /** + * Retrieves config info based on the file, section, and variable name. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @param string $var_name (optional) variable to get info for + * @return string|array a value or array of values + */ + function get($file_name, $section_name = NULL, $var_name = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) + $this->load_file($file_name, false); + } + + if (!empty($var_name)) { + if (empty($section_name)) { + return $this->_config_data[$file_name]["vars"][$var_name]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name])) + return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]; + else + return array(); + } + } else { + if (empty($section_name)) { + return (array)$this->_config_data[$file_name]["vars"]; + } else { + if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"])) + return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"]; + else + return array(); + } + } + } + + + /** + * Retrieves config info based on the key. + * + * @param $file_name string config key (filename/section/var) + * @return string|array same as get() + * @uses get() retrieves information from config file and returns it + */ + function &get_key($config_key) + { + list($file_name, $section_name, $var_name) = explode('/', $config_key, 3); + $result = &$this->get($file_name, $section_name, $var_name); + return $result; + } + + /** + * Get all loaded config file names. + * + * @return array an array of loaded config file names + */ + function get_file_names() + { + return array_keys($this->_config_data); + } + + + /** + * Get all section names from a loaded file. + * + * @param string $file_name config file to get section names from + * @return array an array of section names from the specified file + */ + function get_section_names($file_name) + { + $file_name = $this->_config_path . $file_name; + if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + return array_keys($this->_config_data[$file_name]["sections"]); + } + + + /** + * Get all global or section variable names. + * + * @param string $file_name config file to get info for + * @param string $section_name (optional) section to get info for + * @return array an array of variables names from the specified file/section + */ + function get_var_names($file_name, $section = NULL) + { + if (empty($file_name)) { + $this->_trigger_error_msg('Empty config file name'); + return; + } else if (!isset($this->_config_data[$file_name])) { + $this->_trigger_error_msg("Unknown config file '$file_name'"); + return; + } + + if (empty($section)) + return array_keys($this->_config_data[$file_name]["vars"]); + else + return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]); + } + + + /** + * Clear loaded config data for a certain file or all files. + * + * @param string $file_name file to clear config data for + */ + function clear($file_name = NULL) + { + if ($file_name === NULL) + $this->_config_data = array(); + else if (isset($this->_config_data[$file_name])) + $this->_config_data[$file_name] = array(); + } + + + /** + * Load a configuration file manually. + * + * @param string $file_name file name to load + * @param boolean $prepend_path whether current config path should be + * prepended to the filename + */ + function load_file($file_name, $prepend_path = true) + { + if ($prepend_path && $this->_config_path != "") + $config_file = $this->_config_path . $file_name; + else + $config_file = $file_name; + + ini_set('track_errors', true); + $fp = @fopen($config_file, "r"); + if (!is_resource($fp)) { + $this->_trigger_error_msg("Could not open config file '$config_file'"); + return false; + } + + $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; + fclose($fp); + + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * Store the contents of a file manually. + * + * @param string $config_file file name of the related contents + * @param string $contents the file-contents to parse + */ + function set_file_contents($config_file, $contents) + { + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } + + /** + * parse the source of a configuration file manually. + * + * @param string $contents the file-contents to parse + */ + function parse_contents($contents) + { + if($this->fix_newlines) { + // fix mac/dos formatted newlines + $contents = preg_replace('!\r\n?!', "\n", $contents); + } + + $config_data = array(); + $config_data['sections'] = array(); + $config_data['vars'] = array(); + + /* reference to fill with data */ + $vars =& $config_data['vars']; + + /* parse file line by line */ + preg_match_all('!^.*\r?\n?!m', $contents, $match); + $lines = $match[0]; + for ($i=0, $count=count($lines); $i<$count; $i++) { + $line = $lines[$i]; + if (empty($line)) continue; + + if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { + /* section found */ + if (substr($match[1], 0, 1) == '.') { + /* hidden section */ + if ($this->read_hidden) { + $section_name = substr($match[1], 1); + } else { + /* break reference to $vars to ignore hidden section */ + unset($vars); + $vars = array(); + continue; + } + } else { + $section_name = $match[1]; + } + if (!isset($config_data['sections'][$section_name])) + $config_data['sections'][$section_name] = array('vars' => array()); + $vars =& $config_data['sections'][$section_name]['vars']; + continue; + } + + if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { + /* variable found */ + $var_name = rtrim($match[1]); + if (strpos($match[2], '"""') === 0) { + /* handle multiline-value */ + $lines[$i] = substr($match[2], 3); + $var_value = ''; + while ($i<$count) { + if (($pos = strpos($lines[$i], '"""')) === false) { + $var_value .= $lines[$i++]; + } else { + /* end of multiline-value */ + $var_value .= substr($lines[$i], 0, $pos); + break; + } + } + $booleanize = false; + + } else { + /* handle simple value */ + $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); + $booleanize = $this->booleanize; + + } + $this->_set_config_var($vars, $var_name, $var_value, $booleanize); + } + /* else unparsable line / means it is a comment / means ignore it */ + } + return $config_data; + } + + /**#@+ @access private */ + /** + * @param array &$container + * @param string $var_name + * @param mixed $var_value + * @param boolean $booleanize determines whether $var_value is converted to + * to true/false + */ + function _set_config_var(&$container, $var_name, $var_value, $booleanize) + { + if (substr($var_name, 0, 1) == '.') { + if (!$this->read_hidden) + return; + else + $var_name = substr($var_name, 1); + } + + if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) { + $this->_trigger_error_msg("Bad variable name '$var_name'"); + return; + } + + if ($booleanize) { + if (preg_match("/^(on|true|yes)$/i", $var_value)) + $var_value = true; + else if (preg_match("/^(off|false|no)$/i", $var_value)) + $var_value = false; + } + + if (!isset($container[$var_name]) || $this->overwrite) + $container[$var_name] = $var_value; + else { + settype($container[$var_name], 'array'); + $container[$var_name][] = $var_value; + } + } + + /** + * @uses trigger_error() creates a PHP warning/error + * @param string $error_msg + * @param integer $error_type one of + */ + function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Config_File error: $error_msg", $error_type); + } + /**#@-*/ +} + +?> diff --git a/fp-includes/smarty/Smarty.class.php b/fp-includes/smarty/Smarty.class.php new file mode 100644 index 0000000..f05e0da --- /dev/null +++ b/fp-includes/smarty/Smarty.class.php @@ -0,0 +1,1944 @@ +<?php + +/** + * Project: Smarty: the PHP compiling template engine + * File: Smarty.class.php + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For questions, help, comments, discussion, etc., please join the + * Smarty mailing list. Send a blank e-mail to + * smarty-general-subscribe@lists.php.net + * + * @link http://smarty.php.net/ + * @copyright 2001-2005 New Digital Group, Inc. + * @author Monte Ohrt <monte at ohrt dot com> + * @author Andrei Zmievski <andrei@php.net> + * @package Smarty + * @version 2.6.18 + */ + +/* $Id: Smarty.class.php,v 1.528 2007/03/06 10:40:06 messju Exp $ */ + +/** + * DIR_SEP isn't used anymore, but third party apps might + */ +if(!defined('DIR_SEP')) { + define('DIR_SEP', DIRECTORY_SEPARATOR); +} + +/** + * set SMARTY_DIR to absolute path to Smarty library files. + * if not defined, include_path will be used. Sets SMARTY_DIR only if user + * application has not already defined it. + */ + +if (!defined('SMARTY_DIR')) { + define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); +} + +if (!defined('SMARTY_CORE_DIR')) { + define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); +} + +define('SMARTY_PHP_PASSTHRU', 0); +define('SMARTY_PHP_QUOTE', 1); +define('SMARTY_PHP_REMOVE', 2); +define('SMARTY_PHP_ALLOW', 3); + +/** + * @package Smarty + */ +class Smarty +{ + /**#@+ + * Smarty Configuration Section + */ + + /** + * The name of the directory where templates are located. + * + * @var string + */ + var $template_dir = 'templates'; + + /** + * The directory where compiled templates are located. + * + * @var string + */ + var $compile_dir = 'templates_c'; + + /** + * The directory where config files are located. + * + * @var string + */ + var $config_dir = 'configs'; + + /** + * An array of directories searched for plugins. + * + * @var array + */ + var $plugins_dir = array('plugins'); + + /** + * If debugging is enabled, a debug console window will display + * when the page loads (make sure your browser allows unrequested + * popup windows) + * + * @var boolean + */ + var $debugging = false; + + /** + * When set, smarty does uses this value as error_reporting-level. + * + * @var boolean + */ + var $error_reporting = null; + + /** + * This is the path to the debug console template. If not set, + * the default one will be used. + * + * @var string + */ + var $debug_tpl = ''; + + /** + * This determines if debugging is enable-able from the browser. + * <ul> + * <li>NONE => no debugging control allowed</li> + * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li> + * </ul> + * @link http://www.foo.dom/index.php?SMARTY_DEBUG + * @var string + */ + var $debugging_ctrl = 'NONE'; + + /** + * This tells Smarty whether to check for recompiling or not. Recompiling + * does not need to happen unless a template or config file is changed. + * Typically you enable this during development, and disable for + * production. + * + * @var boolean + */ + var $compile_check = true; + + /** + * This forces templates to compile every time. Useful for development + * or debugging. + * + * @var boolean + */ + var $force_compile = false; + + /** + * This enables template caching. + * <ul> + * <li>0 = no caching</li> + * <li>1 = use class cache_lifetime value</li> + * <li>2 = use cache_lifetime in cache file</li> + * </ul> + * @var integer + */ + var $caching = 0; + + /** + * The name of the directory for cache files. + * + * @var string + */ + var $cache_dir = 'cache'; + + /** + * This is the number of seconds cached content will persist. + * <ul> + * <li>0 = always regenerate cache</li> + * <li>-1 = never expires</li> + * </ul> + * + * @var integer + */ + var $cache_lifetime = 3600; + + /** + * Only used when $caching is enabled. If true, then If-Modified-Since headers + * are respected with cached content, and appropriate HTTP headers are sent. + * This way repeated hits to a cached page do not send the entire page to the + * client every time. + * + * @var boolean + */ + var $cache_modified_check = false; + + /** + * This determines how Smarty handles "<?php ... ?>" tags in templates. + * possible values: + * <ul> + * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li> + * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li> + * <li>SMARTY_PHP_REMOVE -> remove php tags</li> + * <li>SMARTY_PHP_ALLOW -> execute php tags</li> + * </ul> + * + * @var integer + */ + var $php_handling = SMARTY_PHP_PASSTHRU; + + /** + * This enables template security. When enabled, many things are restricted + * in the templates that normally would go unchecked. This is useful when + * untrusted parties are editing templates and you want a reasonable level + * of security. (no direct execution of PHP in templates for example) + * + * @var boolean + */ + var $security = false; + + /** + * This is the list of template directories that are considered secure. This + * is used only if {@link $security} is enabled. One directory per array + * element. {@link $template_dir} is in this list implicitly. + * + * @var array + */ + var $secure_dir = array(); + + /** + * These are the security settings for Smarty. They are used only when + * {@link $security} is enabled. + * + * @var array + */ + var $security_settings = array( + 'PHP_HANDLING' => false, + 'IF_FUNCS' => array('array', 'list', + 'isset', 'empty', + 'count', 'sizeof', + 'in_array', 'is_array', + 'true', 'false', 'null'), + 'INCLUDE_ANY' => false, + 'PHP_TAGS' => false, + 'MODIFIER_FUNCS' => array('count'), + 'ALLOW_CONSTANTS' => false + ); + + /** + * This is an array of directories where trusted php scripts reside. + * {@link $security} is disabled during their inclusion/execution. + * + * @var array + */ + var $trusted_dir = array(); + + /** + * The left delimiter used for the template tags. + * + * @var string + */ + var $left_delimiter = '{'; + + /** + * The right delimiter used for the template tags. + * + * @var string + */ + var $right_delimiter = '}'; + + /** + * The order in which request variables are registered, similar to + * variables_order in php.ini E = Environment, G = GET, P = POST, + * C = Cookies, S = Server + * + * @var string + */ + var $request_vars_order = 'EGPCS'; + + /** + * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) + * are uses as request-vars or $_*[]-vars. note: if + * request_use_auto_globals is true, then $request_vars_order has + * no effect, but the php-ini-value "gpc_order" + * + * @var boolean + */ + var $request_use_auto_globals = true; + + /** + * Set this if you want different sets of compiled files for the same + * templates. This is useful for things like different languages. + * Instead of creating separate sets of templates per language, you + * set different compile_ids like 'en' and 'de'. + * + * @var string + */ + var $compile_id = null; + + /** + * This tells Smarty whether or not to use sub dirs in the cache/ and + * templates_c/ directories. sub directories better organized, but + * may not work well with PHP safe mode enabled. + * + * @var boolean + * + */ + var $use_sub_dirs = false; + + /** + * This is a list of the modifiers to apply to all template variables. + * Put each modifier in a separate array element in the order you want + * them applied. example: <code>array('escape:"htmlall"');</code> + * + * @var array + */ + var $default_modifiers = array(); + + /** + * This is the resource type to be used when not specified + * at the beginning of the resource path. examples: + * $smarty->display('file:index.tpl'); + * $smarty->display('db:index.tpl'); + * $smarty->display('index.tpl'); // will use default resource type + * {include file="file:index.tpl"} + * {include file="db:index.tpl"} + * {include file="index.tpl"} {* will use default resource type *} + * + * @var array + */ + var $default_resource_type = 'file'; + + /** + * The function used for cache file handling. If not set, built-in caching is used. + * + * @var null|string function name + */ + var $cache_handler_func = null; + + /** + * This indicates which filters are automatically loaded into Smarty. + * + * @var array array of filter names + */ + var $autoload_filters = array(); + + /**#@+ + * @var boolean + */ + /** + * This tells if config file vars of the same name overwrite each other or not. + * if disabled, same name variables are accumulated in an array. + */ + var $config_overwrite = true; + + /** + * This tells whether or not to automatically booleanize config file variables. + * If enabled, then the strings "on", "true", and "yes" are treated as boolean + * true, and "off", "false" and "no" are treated as boolean false. + */ + var $config_booleanize = true; + + /** + * This tells whether hidden sections [.foobar] are readable from the + * tempalates or not. Normally you would never allow this since that is + * the point behind hidden sections: the application can access them, but + * the templates cannot. + */ + var $config_read_hidden = false; + + /** + * This tells whether or not automatically fix newlines in config files. + * It basically converts \r (mac) or \r\n (dos) to \n + */ + var $config_fix_newlines = true; + /**#@-*/ + + /** + * If a template cannot be found, this PHP function will be executed. + * Useful for creating templates on-the-fly or other special action. + * + * @var string function name + */ + var $default_template_handler_func = ''; + + /** + * The file that contains the compiler class. This can a full + * pathname, or relative to the php_include path. + * + * @var string + */ + var $compiler_file = 'Smarty_Compiler.class.php'; + + /** + * The class used for compiling templates. + * + * @var string + */ + var $compiler_class = 'Smarty_Compiler'; + + /** + * The class used to load config vars. + * + * @var string + */ + var $config_class = 'Config_File'; + +/**#@+ + * END Smarty Configuration Section + * There should be no need to touch anything below this line. + * @access private + */ + /** + * where assigned template vars are kept + * + * @var array + */ + var $_tpl_vars = array(); + + /** + * stores run-time $smarty.* vars + * + * @var null|array + */ + var $_smarty_vars = null; + + /** + * keeps track of sections + * + * @var array + */ + var $_sections = array(); + + /** + * keeps track of foreach blocks + * + * @var array + */ + var $_foreach = array(); + + /** + * keeps track of tag hierarchy + * + * @var array + */ + var $_tag_stack = array(); + + /** + * configuration object + * + * @var Config_file + */ + var $_conf_obj = null; + + /** + * loaded configuration settings + * + * @var array + */ + var $_config = array(array('vars' => array(), 'files' => array())); + + /** + * md5 checksum of the string 'Smarty' + * + * @var string + */ + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; + + /** + * Smarty version number + * + * @var string + */ + var $_version = '2.6.18'; + + /** + * current template inclusion depth + * + * @var integer + */ + var $_inclusion_depth = 0; + + /** + * for different compiled templates + * + * @var string + */ + var $_compile_id = null; + + /** + * text in URL to enable debug mode + * + * @var string + */ + var $_smarty_debug_id = 'SMARTY_DEBUG'; + + /** + * debugging information for debug console + * + * @var array + */ + var $_smarty_debug_info = array(); + + /** + * info that makes up a cache file + * + * @var array + */ + var $_cache_info = array(); + + /** + * default file permissions + * + * @var integer + */ + var $_file_perms = 0644; + + /** + * default dir permissions + * + * @var integer + */ + var $_dir_perms = 0771; + + /** + * registered objects + * + * @var array + */ + var $_reg_objects = array(); + + /** + * table keeping track of plugins + * + * @var array + */ + var $_plugins = array( + 'modifier' => array(), + 'function' => array(), + 'block' => array(), + 'compiler' => array(), + 'prefilter' => array(), + 'postfilter' => array(), + 'outputfilter' => array(), + 'resource' => array(), + 'insert' => array()); + + + /** + * cache serials + * + * @var array + */ + var $_cache_serials = array(); + + /** + * name of optional cache include file + * + * @var string + */ + var $_cache_include = null; + + /** + * indicate if the current code is used in a compiled + * include + * + * @var string + */ + var $_cache_including = false; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty() + { + $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] + : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); + } + + /** + * assigns values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to assign + */ + function assign($tpl_var, $value = null) + { + if (is_array($tpl_var)){ + foreach ($tpl_var as $key => $val) { + if ($key != '') { + $this->_tpl_vars[$key] = $val; + } + } + } else { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = $value; + } + } + + /** + * assigns values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to assign + */ + function assign_by_ref($tpl_var, &$value) + { + if ($tpl_var != '') + $this->_tpl_vars[$tpl_var] = &$value; + } + + /** + * appends values to template variables + * + * @param array|string $tpl_var the template variable name(s) + * @param mixed $value the value to append + */ + function append($tpl_var, $value=null, $merge=false) + { + if (is_array($tpl_var)) { + // $tpl_var is an array, ignore $value + foreach ($tpl_var as $_key => $_val) { + if ($_key != '') { + if(!@is_array($this->_tpl_vars[$_key])) { + settype($this->_tpl_vars[$_key],'array'); + } + if($merge && is_array($_val)) { + foreach($_val as $_mkey => $_mval) { + $this->_tpl_vars[$_key][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$_key][] = $_val; + } + } + } + } else { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if($merge && is_array($value)) { + foreach($value as $_mkey => $_mval) { + $this->_tpl_vars[$tpl_var][$_mkey] = $_mval; + } + } else { + $this->_tpl_vars[$tpl_var][] = $value; + } + } + } + } + + /** + * appends values to template variables by reference + * + * @param string $tpl_var the template variable name + * @param mixed $value the referenced value to append + */ + function append_by_ref($tpl_var, &$value, $merge=false) + { + if ($tpl_var != '' && isset($value)) { + if(!@is_array($this->_tpl_vars[$tpl_var])) { + settype($this->_tpl_vars[$tpl_var],'array'); + } + if ($merge && is_array($value)) { + foreach($value as $_key => $_val) { + $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key]; + } + } else { + $this->_tpl_vars[$tpl_var][] = &$value; + } + } + } + + + /** + * clear the given assigned template variable. + * + * @param string $tpl_var the template variable to clear + */ + function clear_assign($tpl_var) + { + if (is_array($tpl_var)) + foreach ($tpl_var as $curr_var) + unset($this->_tpl_vars[$curr_var]); + else + unset($this->_tpl_vars[$tpl_var]); + } + + + /** + * Registers custom function to be used in templates + * + * @param string $function the name of the template function + * @param string $function_impl the name of the PHP function to register + */ + function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['function'][$function] = + array($function_impl, null, null, false, $cacheable, $cache_attrs); + + } + + /** + * Unregisters custom function + * + * @param string $function name of template function + */ + function unregister_function($function) + { + unset($this->_plugins['function'][$function]); + } + + /** + * Registers object to be used in templates + * + * @param string $object name of template object + * @param object &$object_impl the referenced PHP object to register + * @param null|array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param null|array $block_functs list of methods that are block format + */ + function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) + { + settype($allowed, 'array'); + settype($smarty_args, 'boolean'); + $this->_reg_objects[$object] = + array(&$object_impl, $allowed, $smarty_args, $block_methods); + } + + /** + * Unregisters object + * + * @param string $object name of template object + */ + function unregister_object($object) + { + unset($this->_reg_objects[$object]); + } + + + /** + * Registers block function to be used in templates + * + * @param string $block name of template block + * @param string $block_impl PHP function to register + */ + function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + { + $this->_plugins['block'][$block] = + array($block_impl, null, null, false, $cacheable, $cache_attrs); + } + + /** + * Unregisters block function + * + * @param string $block name of template function + */ + function unregister_block($block) + { + unset($this->_plugins['block'][$block]); + } + + /** + * Registers compiler function + * + * @param string $function name of template function + * @param string $function_impl name of PHP function to register + */ + function register_compiler_function($function, $function_impl, $cacheable=true) + { + $this->_plugins['compiler'][$function] = + array($function_impl, null, null, false, $cacheable); + } + + /** + * Unregisters compiler function + * + * @param string $function name of template function + */ + function unregister_compiler_function($function) + { + unset($this->_plugins['compiler'][$function]); + } + + /** + * Registers modifier to be used in templates + * + * @param string $modifier name of template modifier + * @param string $modifier_impl name of PHP function to register + */ + function register_modifier($modifier, $modifier_impl) + { + $this->_plugins['modifier'][$modifier] = + array($modifier_impl, null, null, false); + } + + /** + * Unregisters modifier + * + * @param string $modifier name of template modifier + */ + function unregister_modifier($modifier) + { + unset($this->_plugins['modifier'][$modifier]); + } + + /** + * Registers a resource to fetch a template + * + * @param string $type name of resource + * @param array $functions array of functions to handle resource + */ + function register_resource($type, $functions) + { + if (count($functions)==4) { + $this->_plugins['resource'][$type] = + array($functions, false); + + } elseif (count($functions)==5) { + $this->_plugins['resource'][$type] = + array(array(array(&$functions[0], $functions[1]) + ,array(&$functions[0], $functions[2]) + ,array(&$functions[0], $functions[3]) + ,array(&$functions[0], $functions[4])) + ,false); + + } else { + $this->trigger_error("malformed function-list for '$type' in register_resource"); + + } + } + + /** + * Unregisters a resource + * + * @param string $type name of resource + */ + function unregister_resource($type) + { + unset($this->_plugins['resource'][$type]); + } + + /** + * Registers a prefilter function to apply + * to a template before compiling + * + * @param string $function name of PHP function to register + */ + function register_prefilter($function) + { + $_name = (is_array($function)) ? $function[1] : $function; + $this->_plugins['prefilter'][$_name] + = array($function, null, null, false); + } + + /** + * Unregisters a prefilter function + * + * @param string $function name of PHP function + */ + function unregister_prefilter($function) + { + unset($this->_plugins['prefilter'][$function]); + } + + /** + * Registers a postfilter function to apply + * to a compiled template after compilation + * + * @param string $function name of PHP function to register + */ + function register_postfilter($function) + { + $_name = (is_array($function)) ? $function[1] : $function; + $this->_plugins['postfilter'][$_name] + = array($function, null, null, false); + } + + /** + * Unregisters a postfilter function + * + * @param string $function name of PHP function + */ + function unregister_postfilter($function) + { + unset($this->_plugins['postfilter'][$function]); + } + + /** + * Registers an output filter function to apply + * to a template output + * + * @param string $function name of PHP function + */ + function register_outputfilter($function) + { + $_name = (is_array($function)) ? $function[1] : $function; + $this->_plugins['outputfilter'][$_name] + = array($function, null, null, false); + } + + /** + * Unregisters an outputfilter function + * + * @param string $function name of PHP function + */ + function unregister_outputfilter($function) + { + unset($this->_plugins['outputfilter'][$function]); + } + + /** + * load a filter of specified type and name + * + * @param string $type filter type + * @param string $name filter name + */ + function load_filter($type, $name) + { + switch ($type) { + case 'output': + $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + break; + + case 'pre': + case 'post': + if (!isset($this->_plugins[$type . 'filter'][$name])) + $this->_plugins[$type . 'filter'][$name] = false; + break; + } + } + + /** + * clear cached content for the given template and cache id + * + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * @return boolean + */ + function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) + { + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + if (!isset($tpl_file)) + $compile_id = null; + + $_auto_id = $this->_get_auto_id($cache_id, $compile_id); + + if (!empty($this->cache_handler_func)) { + return call_user_func_array($this->cache_handler_func, + array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time)); + } else { + $_params = array('auto_base' => $this->cache_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $_auto_id, + 'exp_time' => $exp_time); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + } + + + /** + * clear the entire contents of cache (all templates) + * + * @param string $exp_time expire time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_all_cache($exp_time = null) + { + return $this->clear_cache(null, null, null, $exp_time); + } + + + /** + * test to see if valid cache exists for this template + * + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * @return string|false results of {@link _read_cache_file()} + */ + function is_cached($tpl_file, $cache_id = null, $compile_id = null) + { + if (!$this->caching) + return false; + + if (!isset($compile_id)) + $compile_id = $this->compile_id; + + $_params = array( + 'tpl_file' => $tpl_file, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + return smarty_core_read_cache_file($_params, $this); + } + + + /** + * clear all the assigned template variables. + * + */ + function clear_all_assign() + { + $this->_tpl_vars = array(); + } + + /** + * clears compiled version of specified template resource, + * or all compiled template files if one is not specified. + * This function is for advanced use only, not normally needed. + * + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * @return boolean results of {@link smarty_core_rm_auto()} + */ + function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) + { + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + $_params = array('auto_base' => $this->compile_dir, + 'auto_source' => $tpl_file, + 'auto_id' => $compile_id, + 'exp_time' => $exp_time, + 'extensions' => array('.inc', '.php')); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); + return smarty_core_rm_auto($_params, $this); + } + + /** + * Checks whether requested template exists. + * + * @param string $tpl_file + * @return boolean + */ + function template_exists($tpl_file) + { + $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false); + return $this->_fetch_resource_info($_params); + } + + /** + * Returns an array containing template variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_template_vars($name=null) + { + if(!isset($name)) { + return $this->_tpl_vars; + } elseif(isset($this->_tpl_vars[$name])) { + return $this->_tpl_vars[$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * Returns an array containing config variables + * + * @param string $name + * @param string $type + * @return array + */ + function &get_config_vars($name=null) + { + if(!isset($name) && is_array($this->_config[0])) { + return $this->_config[0]['vars']; + } else if(isset($this->_config[0]['vars'][$name])) { + return $this->_config[0]['vars'][$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; + } + } + + /** + * trigger Smarty error + * + * @param string $error_msg + * @param integer $error_type + */ + function trigger_error($error_msg, $error_type = E_USER_WARNING) + { + trigger_error("Smarty error: $error_msg", $error_type); + } + + + /** + * executes & displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + */ + function display($resource_name, $cache_id = null, $compile_id = null) + { + $this->fetch($resource_name, $cache_id, $compile_id, true); + } + + /** + * executes & returns or displays the template results + * + * @param string $resource_name + * @param string $cache_id + * @param string $compile_id + * @param boolean $display + */ + function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) + { + static $_cache_info = array(); + + $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) + ? $this->error_reporting : error_reporting() & ~E_NOTICE); + + if (!$this->debugging && $this->debugging_ctrl == 'URL') { + $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; + if (@strstr($_query_string, $this->_smarty_debug_id)) { + if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { + // enable debugging for this browser session + @setcookie('SMARTY_DEBUG', true); + $this->debugging = true; + } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { + // disable debugging for this browser session + @setcookie('SMARTY_DEBUG', false); + $this->debugging = false; + } else { + // enable debugging for this page + $this->debugging = true; + } + } else { + $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); + } + } + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $_debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $resource_name, + 'depth' => 0); + $_included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + if (!isset($compile_id)) { + $compile_id = $this->compile_id; + } + + $this->_compile_id = $compile_id; + $this->_inclusion_depth = 0; + + if ($this->caching) { + // save old cache_info, initialize cache_info + array_push($_cache_info, $this->_cache_info); + $this->_cache_info = array(); + $_params = array( + 'tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => null + ); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); + if (smarty_core_read_cache_file($_params, $this)) { + $_smarty_results = $_params['results']; + if (!empty($this->_cache_info['insert_tags'])) { + $_params = array('plugins' => $this->_cache_info['insert_tags']); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + } + if (!empty($this->_cache_info['cache_serials'])) { + $_params = array('results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); + $_smarty_results = smarty_core_process_compiled_include($_params, $this); + } + + + if ($display) { + if ($this->debugging) + { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + $_smarty_results .= smarty_core_display_debug_console($_params, $this); + } + if ($this->cache_modified_check) { + $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); + $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; + if (@count($this->_cache_info['insert_tags']) == 0 + && !$this->_cache_serials + && $_gmt_mtime == $_last_modified_date) { + if (php_sapi_name()=='cgi') + header('Status: 304 Not Modified'); + else + header('HTTP/1.1 304 Not Modified'); + + } else { + header('Last-Modified: '.$_gmt_mtime); + echo $_smarty_results; + } + } else { + echo $_smarty_results; + } + error_reporting($_smarty_old_error_level); + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return true; + } else { + error_reporting($_smarty_old_error_level); + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + return $_smarty_results; + } + } else { + $this->_cache_info['template'][$resource_name] = true; + if ($this->cache_modified_check && $display) { + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); + } + } + } + + // load filters that are marked as autoload + if (count($this->autoload_filters)) { + foreach ($this->autoload_filters as $_filter_type => $_filters) { + foreach ($_filters as $_filter) { + $this->load_filter($_filter_type, $_filter); + } + } + } + + $_smarty_compile_path = $this->_get_compile_path($resource_name); + + // if we just need to display the results, don't perform output + // buffering - for speed + $_cache_including = $this->_cache_including; + $this->_cache_including = false; + if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) { + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + } else { + ob_start(); + if ($this->_is_compiled($resource_name, $_smarty_compile_path) + || $this->_compile_resource($resource_name, $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + $_smarty_results = ob_get_contents(); + ob_end_clean(); + + foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) { + $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this)); + } + } + + if ($this->caching) { + $_params = array('tpl_file' => $resource_name, + 'cache_id' => $cache_id, + 'compile_id' => $compile_id, + 'results' => $_smarty_results); + require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); + smarty_core_write_cache_file($_params, $this); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); + $_smarty_results = smarty_core_process_cached_inserts($_params, $this); + + if ($this->_cache_serials) { + // strip nocache-tags from output + $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s' + ,'' + ,$_smarty_results); + } + // restore initial cache_info + $this->_cache_info = array_pop($_cache_info); + } + $this->_cache_including = $_cache_including; + + if ($display) { + if (isset($_smarty_results)) { echo $_smarty_results; } + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); + echo smarty_core_display_debug_console($_params, $this); + } + error_reporting($_smarty_old_error_level); + return; + } else { + error_reporting($_smarty_old_error_level); + if (isset($_smarty_results)) { return $_smarty_results; } + } + } + + /** + * load configuration values + * + * @param string $file + * @param string $section + * @param string $scope + */ + function config_load($file, $section = null, $scope = 'global') + { + require_once($this->_get_plugin_filepath('function', 'config_load')); + smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this); + } + + /** + * return a reference to a registered object + * + * @param string $name + * @return object + */ + function &get_registered_object($name) { + if (!isset($this->_reg_objects[$name])) + $this->_trigger_fatal_error("'$name' is not a registered object"); + + if (!is_object($this->_reg_objects[$name][0])) + $this->_trigger_fatal_error("registered '$name' is not an object"); + + return $this->_reg_objects[$name][0]; + } + + /** + * clear configuration values + * + * @param string $var + */ + function clear_config($var = null) + { + if(!isset($var)) { + // clear all values + $this->_config = array(array('vars' => array(), + 'files' => array())); + } else { + unset($this->_config[0]['vars'][$var]); + } + } + + /** + * get filepath of requested plugin + * + * @param string $type + * @param string $name + * @return string|false + */ + function _get_plugin_filepath($type, $name) + { + $_params = array('type' => $type, 'name' => $name); + require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); + return smarty_core_assemble_plugin_filepath($_params, $this); + } + + /** + * test if resource needs compiling + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _is_compiled($resource_name, $compile_path) + { + if (!$this->force_compile && file_exists($compile_path)) { + if (!$this->compile_check) { + // no need to check compiled file + return true; + } else { + // get file source and timestamp + $_params = array('resource_name' => $resource_name, 'get_source'=>false); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + if ($_params['resource_timestamp'] <= filemtime($compile_path)) { + // template not expired, no recompile + return true; + } else { + // compile template + return false; + } + } + } else { + // compiled template does not exist, or forced compile + return false; + } + } + + /** + * compile the template + * + * @param string $resource_name + * @param string $compile_path + * @return boolean + */ + function _compile_resource($resource_name, $compile_path) + { + + $_params = array('resource_name' => $resource_name); + if (!$this->_fetch_resource_info($_params)) { + return false; + } + + $_source_content = $_params['source_content']; + $_cache_include = substr($compile_path, 0, -4).'.inc'; + + if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { + // if a _cache_serial was set, we also have to write an include-file: + if ($this->_cache_include_info) { + require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); + smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); + } + + $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); + smarty_core_write_compiled_resource($_params, $this); + + return true; + } else { + return false; + } + + } + + /** + * compile the given source + * + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return boolean + */ + function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null) + { + if (file_exists(SMARTY_DIR . $this->compiler_file)) { + require_once(SMARTY_DIR . $this->compiler_file); + } else { + // use include_path + require_once($this->compiler_file); + } + + + $smarty_compiler = new $this->compiler_class; + + $smarty_compiler->template_dir = $this->template_dir; + $smarty_compiler->compile_dir = $this->compile_dir; + $smarty_compiler->plugins_dir = $this->plugins_dir; + $smarty_compiler->config_dir = $this->config_dir; + $smarty_compiler->force_compile = $this->force_compile; + $smarty_compiler->caching = $this->caching; + $smarty_compiler->php_handling = $this->php_handling; + $smarty_compiler->left_delimiter = $this->left_delimiter; + $smarty_compiler->right_delimiter = $this->right_delimiter; + $smarty_compiler->_version = $this->_version; + $smarty_compiler->security = $this->security; + $smarty_compiler->secure_dir = $this->secure_dir; + $smarty_compiler->security_settings = $this->security_settings; + $smarty_compiler->trusted_dir = $this->trusted_dir; + $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; + $smarty_compiler->_reg_objects = &$this->_reg_objects; + $smarty_compiler->_plugins = &$this->_plugins; + $smarty_compiler->_tpl_vars = &$this->_tpl_vars; + $smarty_compiler->default_modifiers = $this->default_modifiers; + $smarty_compiler->compile_id = $this->_compile_id; + $smarty_compiler->_config = $this->_config; + $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; + + if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { + $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; + } + $smarty_compiler->_cache_include = $cache_include_path; + + + $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content); + + if ($smarty_compiler->_cache_serial) { + $this->_cache_include_info = array( + 'cache_serial'=>$smarty_compiler->_cache_serial + ,'plugins_code'=>$smarty_compiler->_plugins_code + ,'include_file_path' => $cache_include_path); + + } else { + $this->_cache_include_info = null; + + } + + return $_results; + } + + /** + * Get the compile path for this resource + * + * @param string $resource_name + * @return string results of {@link _get_auto_filename()} + */ + function _get_compile_path($resource_name) + { + return $this->_get_auto_filename($this->compile_dir, $resource_name, + $this->_compile_id) . '.php'; + } + + /** + * fetch the template info. Gets timestamp, and source + * if get_source is true + * + * sets $source_content to the source of the template, and + * $resource_timestamp to its time stamp + * @param string $resource_name + * @param string $source_content + * @param integer $resource_timestamp + * @param boolean $get_source + * @param boolean $quiet + * @return boolean + */ + + function _fetch_resource_info(&$params) + { + if(!isset($params['get_source'])) { $params['get_source'] = true; } + if(!isset($params['quiet'])) { $params['quiet'] = false; } + + $_return = false; + $_params = array('resource_name' => $params['resource_name']) ; + if (isset($params['resource_base_path'])) + $_params['resource_base_path'] = $params['resource_base_path']; + else + $_params['resource_base_path'] = $this->template_dir; + + if ($this->_parse_resource_name($_params)) { + $_resource_type = $_params['resource_type']; + $_resource_name = $_params['resource_name']; + switch ($_resource_type) { + case 'file': + if ($params['get_source']) { + $params['source_content'] = $this->_read_file($_resource_name); + } + $params['resource_timestamp'] = filemtime($_resource_name); + $_return = is_file($_resource_name); + break; + + default: + // call resource functions to fetch the template source and timestamp + if ($params['get_source']) { + $_source_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][0], + array($_resource_name, &$params['source_content'], &$this)); + } else { + $_source_return = true; + } + + $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) && + call_user_func_array($this->_plugins['resource'][$_resource_type][0][1], + array($_resource_name, &$params['resource_timestamp'], &$this)); + + $_return = $_source_return && $_timestamp_return; + break; + } + } + + if (!$_return) { + // see if we can get a template with the default template handler + if (!empty($this->default_template_handler_func)) { + if (!is_callable($this->default_template_handler_func)) { + $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist."); + } else { + $_return = call_user_func_array( + $this->default_template_handler_func, + array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this)); + } + } + } + + if (!$_return) { + if (!$params['quiet']) { + $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); + } + } else if ($_return && $this->security) { + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if (!smarty_core_is_secure($_params, $this)) { + if (!$params['quiet']) + $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); + $params['source_content'] = null; + $params['resource_timestamp'] = null; + return false; + } + } + return $_return; + } + + + /** + * parse out the type and name from the resource + * + * @param string $resource_base_path + * @param string $resource_name + * @param string $resource_type + * @param string $resource_name + * @return boolean + */ + + function _parse_resource_name(&$params) + { + + // split tpl_path by the first colon + $_resource_name_parts = explode(':', $params['resource_name'], 2); + + if (count($_resource_name_parts) == 1) { + // no resource type given + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $_resource_name_parts[0]; + } else { + if(strlen($_resource_name_parts[0]) == 1) { + // 1 char is not resource type, but part of filepath + $params['resource_type'] = $this->default_resource_type; + $params['resource_name'] = $params['resource_name']; + } else { + $params['resource_type'] = $_resource_name_parts[0]; + $params['resource_name'] = $_resource_name_parts[1]; + } + } + + if ($params['resource_type'] == 'file') { + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { + // relative pathname to $params['resource_base_path'] + // use the first directory where the file is found + foreach ((array)$params['resource_base_path'] as $_curr_path) { + $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; + if (file_exists($_fullpath) && is_file($_fullpath)) { + $params['resource_name'] = $_fullpath; + return true; + } + // didn't find the file, try include_path + $_params = array('file_path' => $_fullpath); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); + if(smarty_core_get_include_path($_params, $this)) { + $params['resource_name'] = $_params['new_file_path']; + return true; + } + } + return false; + } else { + /* absolute path */ + return file_exists($params['resource_name']); + } + } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { + $_params = array('type' => $params['resource_type']); + require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); + smarty_core_load_resource_plugin($_params, $this); + } + + return true; + } + + + /** + * Handle modifiers + * + * @param string|null $modifier_name + * @param array|null $map_array + * @return string result of modifiers + */ + function _run_mod_handler() + { + $_args = func_get_args(); + list($_modifier_name, $_map_array) = array_splice($_args, 0, 2); + list($_func_name, $_tpl_file, $_tpl_line) = + $this->_plugins['modifier'][$_modifier_name]; + + $_var = $_args[0]; + foreach ($_var as $_key => $_val) { + $_args[0] = $_val; + $_var[$_key] = call_user_func_array($_func_name, $_args); + } + return $_var; + } + + /** + * Remove starting and ending quotes from the string + * + * @param string $string + * @return string + */ + function _dequote($string) + { + if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && + substr($string, -1) == substr($string, 0, 1)) + return substr($string, 1, -1); + else + return $string; + } + + + /** + * read in a file + * + * @param string $filename + * @return string + */ + function _read_file($filename) + { + if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) { + $contents = ''; + while (!feof($fd)) { + $contents .= fread($fd, 8192); + } + fclose($fd); + return $contents; + } else { + return false; + } + } + + /** + * get a concrete filename for automagically created content + * + * @param string $auto_base + * @param string $auto_source + * @param string $auto_id + * @return string + * @staticvar string|null + * @staticvar string|null + */ + function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) + { + $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; + $_return = $auto_base . DIRECTORY_SEPARATOR; + + if(isset($auto_id)) { + // make auto_id safe for directory names + $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id))); + // split into separate directories + $_return .= $auto_id . $_compile_dir_sep; + } + + if(isset($auto_source)) { + // make source name safe for filename + $_filename = urlencode(basename($auto_source)); + $_crc32 = sprintf('%08X', crc32($auto_source)); + // prepend %% to avoid name conflicts with + // with $params['auto_id'] names + $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . + substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; + $_return .= '%%' . $_crc32 . '%%' . $_filename; + } + + return $_return; + } + + /** + * unlink a file, possibly using expiration time + * + * @param string $resource + * @param integer $exp_time + */ + function _unlink($resource, $exp_time = null) + { + if(isset($exp_time)) { + if(time() - @filemtime($resource) >= $exp_time) { + return @unlink($resource); + } + } else { + return @unlink($resource); + } + } + + /** + * returns an auto_id for auto-file-functions + * + * @param string $cache_id + * @param string $compile_id + * @return string|null + */ + function _get_auto_id($cache_id=null, $compile_id=null) { + if (isset($cache_id)) + return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id; + elseif(isset($compile_id)) + return $compile_id; + else + return null; + } + + /** + * trigger Smarty plugin error + * + * @param string $error_msg + * @param string $tpl_file + * @param integer $tpl_line + * @param string $file + * @param integer $line + * @param integer $error_type + */ + function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null, + $file = null, $line = null, $error_type = E_USER_ERROR) + { + if(isset($file) && isset($line)) { + $info = ' ('.basename($file).", line $line)"; + } else { + $info = ''; + } + if (isset($tpl_line) && isset($tpl_file)) { + $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); + } else { + $this->trigger_error($error_msg . $info, $error_type); + } + } + + + /** + * callback function for preg_replace, to call a non-cacheable block + * @return string + */ + function _process_compiled_include_callback($match) { + $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3]; + ob_start(); + $_func($this); + $_ret = ob_get_contents(); + ob_end_clean(); + return $_ret; + } + + + /** + * called for included templates + * + * @param string $_smarty_include_tpl_file + * @param string $_smarty_include_vars + */ + + // $_smarty_include_tpl_file, $_smarty_include_vars + + function _smarty_include($params) + { + if ($this->debugging) { + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $debug_start_time = smarty_core_get_microtime($_params, $this); + $this->_smarty_debug_info[] = array('type' => 'template', + 'filename' => $params['smarty_include_tpl_file'], + 'depth' => ++$this->_inclusion_depth); + $included_tpls_idx = count($this->_smarty_debug_info) - 1; + } + + $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']); + + // config vars are treated as local, so push a copy of the + // current ones onto the front of the stack + array_unshift($this->_config, $this->_config[0]); + + $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']); + + + if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path) + || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path)) + { + include($_smarty_compile_path); + } + + // pop the local vars off the front of the stack + array_shift($this->_config); + + $this->_inclusion_depth--; + + if ($this->debugging) { + // capture time for debugging info + $_params = array(); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); + $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; + } + + if ($this->caching) { + $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true; + } + } + + + /** + * get or set an array of cached attributes for function that is + * not cacheable + * @return array + */ + function &_smarty_cache_attrs($cache_serial, $count) { + $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count]; + + if ($this->_cache_including) { + /* return next set of cache_attrs */ + $_return = current($_cache_attrs); + next($_cache_attrs); + return $_return; + + } else { + /* add a reference to a new set of cache_attrs */ + $_cache_attrs[] = array(); + return $_cache_attrs[count($_cache_attrs)-1]; + + } + + } + + + /** + * wrapper for include() retaining $this + * @return mixed + */ + function _include($filename, $once=false, $params=null) + { + if ($once) { + return include_once($filename); + } else { + return include($filename); + } + } + + + /** + * wrapper for eval() retaining $this + * @return mixed + */ + function _eval($code, $params=null) + { + return eval($code); + } + /**#@-*/ + +} + +/* vim: set expandtab: */ + +?> diff --git a/fp-includes/smarty/SmartyValidate.class.php b/fp-includes/smarty/SmartyValidate.class.php new file mode 100644 index 0000000..f7b4575 --- /dev/null +++ b/fp-includes/smarty/SmartyValidate.class.php @@ -0,0 +1,662 @@ +<?php + +/** + * Project: SmartyValidate: Form Validator for the Smarty Template Engine + * File: SmartyValidate.class.php + * Author: Monte Ohrt <monte at newdigitalgroup dot com> + * Website: http://www.phpinsider.com/php/code/SmartyValidate/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @link http://www.phpinsider.com/php/code/SmartyValidate/ + * @copyright 2001-2005 New Digital Group, Inc. + * @author Monte Ohrt <monte at newdigitalgroup dot com> + * @package SmartyValidate + * @version 2.8 + */ + +if(!defined('SMARTY_VALIDATE_DEFAULT_FORM')) + define('SMARTY_VALIDATE_DEFAULT_FORM', 'default'); + +class SmartyValidate { + + /** + * Class Constructor + */ + function SmartyValidate() { } + + + /** + * initialize the validator + * + * @param obj $smarty the smarty object + * @param string $reset reset the default form? + */ + function connect(&$smarty, $reset = false) { + if(SmartyValidate::is_valid_smarty_object($smarty)) { + SmartyValidate::_object_instance('Smarty', $smarty); + SmartyValidate::register_form(SMARTY_VALIDATE_DEFAULT_FORM, $reset); + } else { + trigger_error("SmartyValidate: [connect] I need a valid Smarty object."); + return false; + } + } + + /** + * test if object is a valid smarty object + * + * @param obj $smarty_obj the smarty object + */ + function is_valid_smarty_object(&$smarty_obj) { + return (is_object($smarty_obj) && (strtolower(get_class($smarty_obj)) == 'smarty' || is_subclass_of($smarty_obj, 'smarty'))); + + } + + /** + * clear the entire SmartyValidate session + * + */ + function disconnect() { + unset($_SESSION['SmartyValidate']); + SmartyValidate::_object_instance('-', $_dummy); + } + + /** + * initialize the session data + * + * @param string $form the name of the form being validated + * @param string $reset reset an already registered form? + */ + function register_form($form, $reset = false) { + if(SmartyValidate::is_registered_form($form) && !$reset) { + return false; + } else { + $_SESSION['SmartyValidate'][$form] = array(); + $_SESSION['SmartyValidate'][$form]['registered_funcs']['criteria'] = array(); + $_SESSION['SmartyValidate'][$form]['registered_funcs']['transform'] = array(); + $_SESSION['SmartyValidate'][$form]['validators'] = array(); + $_SESSION['SmartyValidate'][$form]['is_error'] = false; + $_SESSION['SmartyValidate'][$form]['is_init'] = true; + SmartyValidate::_smarty_assign(); + return true; + } + } + + /** + * unregister a form from the session + * + * @param string $form the name of the form being validated + */ + function unregister_form($form) { + unset($_SESSION['SmartyValidate'][$form]); + } + + /** + * test if the session data is initialized + * + * @param string $form the name of the form being validated + */ + function is_registered_form($form = SMARTY_VALIDATE_DEFAULT_FORM) { + return isset($_SESSION['SmartyValidate'][$form]); + } + + function _failed_fields(&$formvars, $form = SMARTY_VALIDATE_DEFAULT_FORM, $revalidate = false) + { + // keep track of failed fields + static $_failed_fields = array(); + + if(isset($_failed_fields[$form]) && !$revalidate) { + // already validated the form + return $_failed_fields[$form]; + } + + // failed fields for current pass + $_ret = array(); + + $_sess =& $_SESSION['SmartyValidate'][$form]['validators']; + + foreach($_sess as $_key => $_val) { + + if(isset($_SESSION['SmartyValidate'][$form]['page']) + && $_sess[$_key]['page'] != $_SESSION['SmartyValidate'][$form]['page']) { + // not on page, do not validate + continue; + } + + $_full_field = $_field = $_sess[$_key]['field']; + $_field_key = null; + $_empty = isset($_sess[$_key]['empty']) ? $_sess[$_key]['empty'] : false; + $_message = isset($_sess[$_key]['message']) ? $_sess[$_key]['message'] : null; + + if(is_array($_ret) && in_array($_full_field, $_ret)) { + // already failed, skip this test + continue; + } + + // field is name-keyed array, pull it apart + if(($_lpos = strpos($_field, '[')) !== false && ($_rpos = strpos($_field, ']')) !== false) { + if (($_keylen = ($_rpos - $_lpos - 1)) > 0) { + $_field_key = substr($_field, $_lpos+1, $_keylen); + } + $_field = substr($_field, 0, $_lpos); + } + + if(isset($_sess[$_key]['transform'])) { + $_trans_names = preg_split('![\s,]+!', $_sess[$_key]['transform'], -1, PREG_SPLIT_NO_EMPTY); + if($_sess[$_key]['trim']) { + // put trim on front of transform array + array_unshift($_trans_names, 'trim'); + } + foreach($_trans_names as $_trans_name) { + if(substr($_trans_name,0,1) == '@') { + // transformation will apply to entire array + $_trans_on_array = true; + $_trans_name = substr($_trans_name,1); + } else { + // transformation will apply to each array element + $_trans_on_array = false; + } + + if(strpos($_trans_name,':') !== false) { + // transform has parameters, put them in $formvars + $_trans_parts = explode(':', $_trans_name); + $_trans_name = array_shift($_trans_parts); + $_trans_index = 2; + foreach($_trans_parts as $_trans_param) { + $_trans_field = $_trans_name . $_trans_index; + $_sess[$_key][$_trans_field] = $_trans_param; + $_trans_index++; + } + } + + if(is_array($formvars[$_field]) && !$_trans_on_array) { + if(isset($_field_key)) { + // only apply to given key + if(($_new_val = SmartyValidate::_execute_transform($_trans_name, $formvars[$_field][$_field_key], $_sess[$_key], $formvars, $form)) !== false) + $formvars[$_field][$_field_key] = $_new_val; + + } else { + // apply to all keys + for($_x = 0, $_y = count($formvars[$_field]); $_x < $_y; $_x++) { + if(($_new_val = SmartyValidate::_execute_transform($_trans_name, $formvars[$_field][$_x], $_sess[$_key], $formvars, $form)) !== false) + $formvars[$_field][$_x] = $_new_val; + } + } + } else { + if(($_new_val = SmartyValidate::_execute_transform($_trans_name, $formvars[$_field], $_sess[$_key], $formvars, $form)) !== false) + $formvars[$_field] = $_new_val; + } + } + } + + if((!isset($formvars[$_field]) && (!isset($_FILES[$_field]))) + || ( + ((is_array($formvars[$_field]) && count($_field) == 0) || (is_string($formvars[$_field]) && strlen($formvars[$_field]) == 0)) && $_empty + ) + ) { + // field must exist, or else fails automatically + $_sess[$_key]['valid'] = $_empty; + } else { + if(substr($_val['criteria'],0,1) == '@') { + // criteria will apply to entire array or given key + $_criteria_on_array = true; + $_val['criteria'] = substr($_val['criteria'],1); + } else { + // criteria will apply to each array element + $_criteria_on_array = false; + } + + if(is_array($formvars[$_field]) && !$_criteria_on_array) { + if(isset($_field_key)) { + // only apply to given key + $_sess[$_key]['valid'] = SmartyValidate::_is_valid_criteria($_val['criteria'], $formvars[$_field][$_field_key], $_empty, $_sess[$_key], $formvars, $form); + } else { + // apply to all keys + for($_x = 0, $_y = count($formvars[$_field]); $_x < $_y; $_x++) { + if(! $_sess[$_key]['valid'] = SmartyValidate::_is_valid_criteria($_val['criteria'], $formvars[$_field][$_x], $_empty, $_sess[$_key], $formvars, $form)) { + // found invalid array element, exit for loop + break; + } + } + } + } else { + $_sess[$_key]['valid'] = SmartyValidate::_is_valid_criteria($_val['criteria'], $formvars[$_field], $_empty, $_sess[$_key], $formvars, $form); + } + } + + if(!$_sess[$_key]['valid']) { + $_ret[] = $_full_field; + if(isset($_sess[$_key]['halt']) && $_sess[$_key]['halt']) + break; + } + } + + $_failed_fields[$form] = $_ret; + + return $_ret; + } + + /** + * validate the form + * + * @param string $formvars the array of submitted for variables + * @param string $form the name of the form being validated + */ + function is_valid(&$formvars, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + + static $_is_valid = array(); + + if(isset($_is_valid[$form])) { + // already validated the form + return $_is_valid[$form]; + } + + $_smarty_obj =& SmartyValidate::_object_instance('Smarty', $_dummy); + if(!SmartyValidate::is_valid_smarty_object($_smarty_obj)) { + trigger_error("SmartyValidate: [is_valid] No valid smarty object, call connect() first."); + return false; + } + + if(!SmartyValidate::is_registered_form($form)) { + trigger_error("SmartyValidate: [is_valid] form '$form' is not registered."); + return false; + } elseif ($_SESSION['SmartyValidate'][$form]['is_init']) { + // first run, skip validation + return false; + } elseif (count($_SESSION['SmartyValidate'][$form]['validators']) == 0) { + // nothing to validate + return true; + } + + // check for failed fields + $_failed_fields = SmartyValidate::_failed_fields($formvars, $form); + $_ret = is_array($_failed_fields) && count($_failed_fields) == 0; + + // set validation state of form + $_SESSION['SmartyValidate'][$form]['is_error'] = !$_ret; + + $_is_valid[$form] = $_ret; + + return $_ret; + } + + /** + * register a callable function for form verification + * + * @param string $func_name the function being registered + */ + function register_object($object_name, &$object) { + if(!is_object($object)) { + trigger_error("SmartyValidate: [register_object] not a valid object."); + return false; + } + SmartyValidate::_object_instance($object_name, $object); + } + + /** + * register a callable function for form verification + * + * @param string $func_name the function being registered + */ + function is_registered_object($object_name) { + $_object =& SmartyValidate::_object_instance($object_name, $_dummy); + return is_object($_object); + } + + /** + * register a callable function for form verification + * + * @param string $func_name the function being registered + */ + function register_criteria($name, $func_name, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + return SmartyValidate::_register_function('criteria', $name, $func_name, $form); + } + + /** + * register a callable function for form verification + * + * @param string $func_name the function being registered + */ + function register_transform($name, $func_name, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + return SmartyValidate::_register_function('transform', $name, $func_name, $form); + } + + /** + * test if a criteria function is registered + * + * @param string $var the value being booleanized + */ + function is_registered_criteria($name, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + if(!SmartyValidate::is_registered_form($form)) { + trigger_error("SmartyValidate: [is_registered_criteria] form '$form' is not registered."); + return false; + } + return isset($_SESSION['SmartyValidate'][$form]['registered_funcs']['criteria'][$name]); + } + + /** + * test if a tranform function is registered + * + * @param string $var the value being booleanized + */ + function is_registered_transform($name, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + if(!SmartyValidate::is_registered_form($form)) { + trigger_error("SmartyValidate: [is_registered_transform] form '$form' is not registered."); + return false; + } + return isset($_SESSION['SmartyValidate'][$form]['registered_funcs']['transform'][$name]); + } + + /** + * register a validator + * + * @param string $id the id of the validator + * @param string $field the field to be validated + * @param string $criteria the name of the criteria function + * @param string $empty allow field to be empty (optional) + * @param string $halt stop validation if this one fails (optional) + * @param string $transform transform function(s) to apply (optional) + * @param string $form name of the form (optional) + */ + function register_validator($id, $field, $criteria, $empty = false, $halt = false, $transform = null, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + if(!SmartyValidate::is_registered_form($form)) { + trigger_error("SmartyValidate: [register_validator] form '$form' is not registered."); + return false; + } + SmartyValidate::unregister_validator($id,$form); + + $_field = explode(':', $field); + $_validator = array(); + + foreach($_field as $_key => $_val) { + if($_key == 0) + $_validator['field'] = $_val; + else { + $_field_name = 'field'; + $_field_name .= $_key + 1; + $_validator[$_field_name] = $_val; + } + } + + $_validator['id'] = $id; + $_validator['criteria'] = $criteria; + $_validator['message'] = ''; + $_validator['trim'] = false; + $_validator['empty'] = $empty; + $_validator['halt'] = $halt; + $_validator['transform'] = $transform; + + $_SESSION['SmartyValidate'][$form]['validators'][] = $_validator; + } + + /** + * register a validator + * + * @param string $id the id of the validator + * @param string $transform the name of the transform function(s) + * @param string $form name of the form (optional) + */ + function set_transform($id, $transform, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + + if(($_validator_key = SmartyValidate::is_registered_validator($id,$form)) === false) { + trigger_error("SmartyValidate: [set_transform] validator '$id' is not registered."); + return false; + } + + $_SESSION['SmartyValidate'][$form]['validators'][$_validator_key]['transform'] = $transform; + } + + + /** + * test if a validator is registered + * + * @param string $id the validator to test + */ + function is_registered_validator($id, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + if(!SmartyValidate::is_registered_form($form)) { + trigger_error("SmartyValidate: [is_registered_validator] form '$form' is not registered."); + return false; + } + + foreach($_SESSION['SmartyValidate'][$form]['validators'] as $_key => $_val) { + if($_SESSION['SmartyValidate'][$form]['validators'][$_key]['id'] == $id) { + // return array index of validator + return $_key; + } + } + return false; + } + + /** + * unregister a validator + * + * @param string $id the validator to unregister + */ + function unregister_validator($id, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + if(!SmartyValidate::is_registered_form($form)) { + return false; + } + + foreach($_SESSION['SmartyValidate'][$form]['validators'] as $_key => $_val) { + if(isset($_SESSION['SmartyValidate'][$form]['validators'][$_key]['id']) + && $_SESSION['SmartyValidate'][$form]['validators'][$_key]['id'] == $id) { + unset($_SESSION['SmartyValidate'][$form]['validators'][$_key]); + break; + } + } + + } + + /** + * set the current page of the form + * + * @param string $page the name of the page being validated + * @param string $form the name of the form being validated + */ + function set_page($page, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + $_SESSION['SmartyValidate'][$form]['page'] = $page; + $_SESSION['SmartyValidate'][$form]['is_error'] = false; + $_SESSION['SmartyValidate'][$form]['is_init'] = true; + } + + /** + * return actual function name of registered func + * + * @param string $type the type of func + * @param string $name the registered name + * @param string $form the form name + */ + function _execute_transform($name, $value, $params, &$formvars, $form) { + + if(SmartyValidate::is_registered_transform($name, $form)) { + $_func_name = SmartyValidate::_get_registered_func_name('transform', $name, $form); + } else { + $_func_name = 'smarty_validate_transform_' . $name; + if(!function_exists($_func_name)) { + $_smarty_obj =& SmartyValidate::_object_instance('Smarty', $_dummy); + if($_plugin_file = $_smarty_obj->_get_plugin_filepath('validate_transform', $name)) { + include_once($_plugin_file); + } else { + trigger_error("SmartyValidate: [is_valid] transform function '$name' was not found."); + return false; + } + } + } + if(strpos($_func_name,'->') !== false) { + // object method + preg_match('!(\w+)->(\w+)!', $_func_name, $_match); + $_object_name = $_match[1]; + $_method_name = $_match[2]; + $_object =& SmartyValidate::_object_instance($_object_name, $_dummy); + if(!method_exists($_object, $_method_name)) { + trigger_error("SmartyValidate: [is_valid] method '$_method_name' is not valid for object '$_object_name'."); + return false; + } + return $_object->$_method_name($value, $params, $formvars); + } else { + return $_func_name($value, $params, $formvars); + } + } + + /** + * register a callable function for form verification + * + * @param string $func_name the function being registered + */ + function _register_function($type, $name, $func_name, $form = SMARTY_VALIDATE_DEFAULT_FORM) { + if(!SmartyValidate::is_registered_form($form)) { + trigger_error("SmartyValidate: [register_$type] form '$form' is not registered."); + return false; + } + if(strpos($func_name,'->') !== false) { + // object method + preg_match('!(\w+)->(\w+)!', $func_name, $_match); + $_object_name = $_match[1]; + $_method_name = $_match[2]; + $_object =& SmartyValidate::_object_instance($_object_name, $_dummy); + if(!method_exists($_object, $_method_name)) { + trigger_error("SmartyValidate: [register_$type] method '$_method_name' is not valid for object '$_object_name'."); + return false; + } + } elseif (strpos($func_name,'::') !== false) { + // static method + preg_match('!(\w+)::(\w+)!', $func_name, $_match); + if(!is_callable(array($_match[1], $_match[2]))) { + trigger_error("SmartyValidate: [register_$type] static method '$func_name' does not exist."); + return false; + } + } elseif(!function_exists($func_name)) { + trigger_error("SmartyValidate: [register_$type] function '$func_name' does not exist."); + return false; + } + $_SESSION['SmartyValidate'][$form]['registered_funcs'][$type][$name] = $func_name; + return true; + } + + /** + * return actual function name of registered func + * + * @param string $type the type of func + * @param string $name the registered name + * @param string $form the form name + */ + function _get_registered_func_name($type,$name,$form) { + return isset($_SESSION['SmartyValidate'][$form]['registered_funcs'][$type][$name]) + ? $_SESSION['SmartyValidate'][$form]['registered_funcs'][$type][$name] + : false; + } + + + /** + * booleanize a value + * + * @param string $var the value being booleanized + */ + function _booleanize($var) { + if(in_array(strtolower($var), array(true, 1, 'true','on','yes','y'),true)) { + return true; + } + return false; + } + + /** + * validate criteria for given value + * + * @param string $criteria the criteria to test against + * @param string $value the value being tested + * @param string $empty skip empty values or not + */ + function _is_valid_criteria($criteria, $value, $empty, &$params, &$formvars, $form) { + if(SmartyValidate::is_registered_criteria($criteria,$form)) { + $_func_name = SmartyValidate::_get_registered_func_name('criteria',$criteria, $form); + } else { + $_func_name = 'smarty_validate_criteria_' . $criteria; + if(!function_exists($_func_name)) { + $_smarty_obj =& SmartyValidate::_object_instance('Smarty', $_dummy); + if($_plugin_file = $_smarty_obj->_get_plugin_filepath('validate_criteria', $criteria)) { + include_once($_plugin_file); + } else { + trigger_error("SmartyValidate: [is_valid] criteria function '$criteria' was not found."); + return false; + } + } + } + if(strpos($_func_name,'->') !== false) { + // object method + preg_match('!(\w+)->(\w+)!', $_func_name, $_match); + $_object_name = $_match[1]; + $_method_name = $_match[2]; + $_object =& SmartyValidate::_object_instance($_object_name, $_dummy); + if(!method_exists($_object, $_method_name)) { + trigger_error("SmartyValidate: [is_valid] method '$_method_name' is not valid for object '$_object_name'."); + return false; + } + return $_object->$_method_name($value, $empty, $params, $formvars); + } else { + return $_func_name($value, $empty, $params, $formvars); + } + } + + /** + * get or set an object instance + * + * @param string $name the object name + * @param object $object the object being set + */ + function &_object_instance($name, &$object) { + $return = false; + static $_objects = array(); + if ($name=='-') { + unset ($_objects); + static $_objects = array(); + } + if(!is_object($object)) { + if (isset($_objects[$name])) + return $_objects[$name]; + else + return $return; + } else { + $_objects[$name] =& $object; + return $object; + } + } + + /** + * get or set the smarty object instance + * + * @param string $value the value being tested + */ + function _smarty_assign($vars = array()) { + + $_smarty_obj =& SmartyValidate::_object_instance('Smarty', $_dummy); + + if(!is_object($_smarty_obj)) { + trigger_error("SmartyValidate: [assign] no valid smarty object found, call connect() first."); + return false; + } + + if(!empty($vars)) { + $_smarty_obj->assign($vars); + } + foreach($_SESSION['SmartyValidate'] as $_key => $_val) { + $_info[$_key]['is_error'] = isset($_SESSION['SmartyValidate'][$_key]['is_error']) ? $_SESSION['SmartyValidate'][$_key]['is_error'] : null; + } + $_smarty_obj->assign('validate', $_info); + + } + +} + +?> diff --git a/fp-includes/smarty/Smarty_Compiler.class.php b/fp-includes/smarty/Smarty_Compiler.class.php new file mode 100644 index 0000000..f54cc21 --- /dev/null +++ b/fp-includes/smarty/Smarty_Compiler.class.php @@ -0,0 +1,2327 @@ +<?php + +/** + * Project: Smarty: the PHP compiling template engine + * File: Smarty_Compiler.class.php + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @link http://smarty.php.net/ + * @author Monte Ohrt <monte at ohrt dot com> + * @author Andrei Zmievski <andrei@php.net> + * @version 2.6.18 + * @copyright 2001-2005 New Digital Group, Inc. + * @package Smarty + */ + +/* $Id: Smarty_Compiler.class.php,v 1.395 2007/03/06 10:40:06 messju Exp $ */ + +/** + * Template compiling class + * @package Smarty + */ +class Smarty_Compiler extends Smarty { + + // internal vars + /**#@+ + * @access private + */ + var $_folded_blocks = array(); // keeps folded template blocks + var $_current_file = null; // the current template being compiled + var $_current_line_no = 1; // line number for error messages + var $_capture_stack = array(); // keeps track of nested capture buffers + var $_plugin_info = array(); // keeps track of plugins to load + var $_init_smarty_vars = false; + var $_permitted_tokens = array('true','false','yes','no','on','off','null'); + var $_db_qstr_regexp = null; // regexps are setup in the constructor + var $_si_qstr_regexp = null; + var $_qstr_regexp = null; + var $_func_regexp = null; + var $_reg_obj_regexp = null; + var $_var_bracket_regexp = null; + var $_num_const_regexp = null; + var $_dvar_guts_regexp = null; + var $_dvar_regexp = null; + var $_cvar_regexp = null; + var $_svar_regexp = null; + var $_avar_regexp = null; + var $_mod_regexp = null; + var $_var_regexp = null; + var $_parenth_param_regexp = null; + var $_func_call_regexp = null; + var $_obj_ext_regexp = null; + var $_obj_start_regexp = null; + var $_obj_params_regexp = null; + var $_obj_call_regexp = null; + var $_cacheable_state = 0; + var $_cache_attrs_count = 0; + var $_nocache_count = 0; + var $_cache_serial = null; + var $_cache_include = null; + + var $_strip_depth = 0; + var $_additional_newline = "\n"; + + /**#@-*/ + /** + * The class constructor. + */ + function Smarty_Compiler() + { + // matches double quoted strings: + // "foobar" + // "foo\"bar" + $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"'; + + // matches single quoted strings: + // 'foobar' + // 'foo\'bar' + $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + // matches single or double quoted strings + $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')'; + + // matches bracket portion of vars + // [0] + // [foo] + // [$bar] + $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; + + // matches numerical constants + // 30 + // -12 + // 13.22 + $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; + + // matches $ vars (not objects): + // $foo + // $foo.bar + // $foo.bar.foobar + // $foo[0] + // $foo[$bar] + // $foo[5][blah] + // $foo[5].bar[$foobar][4] + $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; + $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; + $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp + . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; + $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; + + // matches config vars: + // #foo# + // #foobar123_foo# + $this->_cvar_regexp = '\#\w+\#'; + + // matches section vars: + // %foo.bar% + $this->_svar_regexp = '\%\w+\.\w+\%'; + + // matches all valid variables (no quotes, no modifiers) + $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|' + . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')'; + + // matches valid variable syntax: + // $foo + // $foo + // #foo# + // #foo# + // "text" + // "text" + $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; + + // matches valid object call (one level of object nesting allowed in parameters): + // $foo->bar + // $foo->bar() + // $foo->bar("text") + // $foo->bar($foo, $bar, "text") + // $foo->bar($foo, "foo") + // $foo->bar->foo() + // $foo->bar->foo->bar() + // $foo->bar($foo->bar) + // $foo->bar($foo->bar()) + // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) + $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; + $this->_obj_restricted_param_regexp = '(?:' + . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' + . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; + $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; + $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp + . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; + $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; + $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; + + // matches valid modifier syntax: + // |foo + // |@foo + // |foo:"bar" + // |foo:$bar + // |foo:"bar":$foobar + // |foo|bar + // |foo:$foo->bar + $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' + . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; + + // matches valid function name: + // foo123 + // _foo_bar + $this->_func_regexp = '[a-zA-Z_]\w*'; + + // matches valid registered object: + // foo->bar + $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*'; + + // matches valid parameter values: + // true + // $foo + // $foo|bar + // #foo# + // #foo#|bar + // "text" + // "text"|bar + // $foo->bar + $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' + . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; + + // matches valid parenthesised function parameters: + // + // "text" + // $foo, $bar, "text" + // $foo|bar, "foo"|bar, $foo->bar($foo)|bar + $this->_parenth_param_regexp = '(?:\((?:\w+|' + . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_param_regexp . ')))*)?\))'; + + // matches valid function call: + // foo() + // foo_bar($foo) + // _foo_bar($foo,"bar") + // foo123($foo,$foo->bar(),"foo") + $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:' + . $this->_parenth_param_regexp . '))'; + } + + /** + * compile a resource + * + * sets $compiled_content to the compiled source + * @param string $resource_name + * @param string $source_content + * @param string $compiled_content + * @return true + */ + function _compile_file($resource_name, $source_content, &$compiled_content) + { + + if ($this->security) { + // do not allow php syntax to be executed unless specified + if ($this->php_handling == SMARTY_PHP_ALLOW && + !$this->security_settings['PHP_HANDLING']) { + $this->php_handling = SMARTY_PHP_PASSTHRU; + } + } + + $this->_load_filters(); + + $this->_current_file = $resource_name; + $this->_current_line_no = 1; + $ldq = preg_quote($this->left_delimiter, '~'); + $rdq = preg_quote($this->right_delimiter, '~'); + + // run template source through prefilter functions + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) continue; + if ($prefilter[3] || is_callable($prefilter[0])) { + $source_content = call_user_func_array($prefilter[0], + array($source_content, &$this)); + $this->_plugins['prefilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented"); + } + } + } + + /* fetch all special blocks */ + $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; + + preg_match_all($search, $source_content, $match, PREG_SET_ORDER); + $this->_folded_blocks = $match; + reset($this->_folded_blocks); + + /* replace special blocks by "{php}" */ + $source_content = preg_replace($search.'e', "'" + . $this->_quote_replace($this->left_delimiter) . 'php' + . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" + . $this->_quote_replace($this->right_delimiter) + . "'" + , $source_content); + + /* Gather all template tags. */ + preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); + $template_tags = $_match[1]; + /* Split content by template tags to obtain non-template content. */ + $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); + + /* loop through text blocks */ + for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { + /* match anything resembling php tags */ + if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { + /* replace tags with placeholders to prevent recursive replacements */ + $sp_match[1] = array_unique($sp_match[1]); + usort($sp_match[1], '_smarty_sort_length'); + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]); + } + /* process each one */ + for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { + if ($this->php_handling == SMARTY_PHP_PASSTHRU) { + /* echo php contents */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_QUOTE) { + /* quote php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]); + } else if ($this->php_handling == SMARTY_PHP_REMOVE) { + /* remove php tags */ + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); + } else { + /* SMARTY_PHP_ALLOW, but echo non php starting tags */ + $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]); + $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); + } + } + } + } + + /* Compile the template tags into PHP code. */ + $compiled_tags = array(); + for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) { + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); + $this->_current_line_no += substr_count($template_tags[$i], "\n"); + } + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = end($this->_tag_stack); + $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); + return; + } + + /* Reformat $text_blocks between 'strip' and '/strip' tags, + removing spaces, tabs and newlines. */ + $strip = false; + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '{strip}') { + $compiled_tags[$i] = ''; + $strip = true; + /* remove leading whitespaces */ + $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); + } + if ($strip) { + /* strip all $text_blocks before the next '/strip' */ + for ($j = $i + 1; $j < $for_max; $j++) { + /* remove leading and trailing whitespaces of each line */ + $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); + if ($compiled_tags[$j] == '{/strip}') { + /* remove trailing whitespaces from the last text_block */ + $text_blocks[$j] = rtrim($text_blocks[$j]); + } + $text_blocks[$j] = "<?php echo '" . strtr($text_blocks[$j], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>"; + if ($compiled_tags[$j] == '{/strip}') { + $compiled_tags[$j] = "\n"; /* slurped by php, but necessary + if a newline is following the closing strip-tag */ + $strip = false; + $i = $j; + break; + } + } + } + } + $compiled_content = ''; + + $tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%'; + + /* Interleave the compiled contents and text blocks to get the final result. */ + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '') { + // tag result empty, remove first newline from following text block + $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); + } + // replace legit PHP tags with placeholder + $text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]); + $compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]); + + $compiled_content .= $text_blocks[$i] . $compiled_tags[$i]; + } + $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]); + + // escape php tags created by interleaving + $compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content); + $compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content); + + // recover legit tags + $compiled_content = str_replace($tag_guard, '<?', $compiled_content); + + // remove \n from the end of the file, if any + if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) { + $compiled_content = substr($compiled_content, 0, -1); + } + + if (!empty($this->_cache_serial)) { + $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; + } + + // run compiled template through postfilter functions + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) continue; + if ($postfilter[3] || is_callable($postfilter[0])) { + $compiled_content = call_user_func_array($postfilter[0], + array($compiled_content, &$this)); + $this->_plugins['postfilter'][$filter_name][3] = true; + } else { + $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented"); + } + } + } + + // put header at the top of the compiled template + $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n"; + + /* Emit code to load needed plugins. */ + $this->_plugins_code = ''; + if (count($this->_plugin_info)) { + $_plugins_params = "array('plugins' => array("; + foreach ($this->_plugin_info as $plugin_type => $plugins) { + foreach ($plugins as $plugin_name => $plugin_info) { + $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; + $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; + } + } + $_plugins_params .= '))'; + $plugins_code = "<?php require_once(SMARTY_CORE_DIR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n"; + $template_header .= $plugins_code; + $this->_plugin_info = array(); + $this->_plugins_code = $plugins_code; + } + + if ($this->_init_smarty_vars) { + $template_header .= "<?php require_once(SMARTY_CORE_DIR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n"; + $this->_init_smarty_vars = false; + } + + $compiled_content = $template_header . $compiled_content; + return true; + } + + /** + * Compile a template tag + * + * @param string $template_tag + * @return string + */ + function _compile_tag($template_tag) + { + /* Matched comment. */ + if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') + return ''; + + /* Split tag into two three parts: command, command modifiers and the arguments. */ + if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp + . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) + (?:\s+(.*))?$ + ~xs', $template_tag, $match)) { + $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $tag_command = $match[1]; + $tag_modifier = isset($match[2]) ? $match[2] : null; + $tag_args = isset($match[3]) ? $match[3] : null; + + if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { + /* tag name is a variable or object */ + $_return = $this->_parse_var_props($tag_command . $tag_modifier); + return "<?php echo $_return; ?>" . $this->_additional_newline; + } + + /* If the tag name is a registered object, we process it. */ + if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { + return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); + } + + switch ($tag_command) { + case 'include': + return $this->_compile_include_tag($tag_args); + + case 'include_php': + return $this->_compile_include_php_tag($tag_args); + + case 'if': + $this->_push_tag('if'); + return $this->_compile_if_tag($tag_args); + + case 'else': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); + else + $this->_push_tag('else'); + return '<?php else: ?>'; + + case 'elseif': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); + if ($_open_tag == 'if') + $this->_push_tag('elseif'); + return $this->_compile_if_tag($tag_args, true); + + case '/if': + $this->_pop_tag('if'); + return '<?php endif; ?>'; + + case 'capture': + return $this->_compile_capture_tag(true, $tag_args); + + case '/capture': + return $this->_compile_capture_tag(false); + + case 'ldelim': + return $this->left_delimiter; + + case 'rdelim': + return $this->right_delimiter; + + case 'section': + $this->_push_tag('section'); + return $this->_compile_section_start($tag_args); + + case 'sectionelse': + $this->_push_tag('sectionelse'); + return "<?php endfor; else: ?>"; + break; + + case '/section': + $_open_tag = $this->_pop_tag('section'); + if ($_open_tag == 'sectionelse') + return "<?php endif; ?>"; + else + return "<?php endfor; endif; ?>"; + + case 'foreach': + $this->_push_tag('foreach'); + return $this->_compile_foreach_start($tag_args); + break; + + case 'foreachelse': + $this->_push_tag('foreachelse'); + return "<?php endforeach; else: ?>"; + + case '/foreach': + $_open_tag = $this->_pop_tag('foreach'); + if ($_open_tag == 'foreachelse') + return "<?php endif; unset(\$_from); ?>"; + else + return "<?php endforeach; endif; unset(\$_from); ?>"; + break; + + case 'strip': + case '/strip': + if (substr($tag_command, 0, 1)=='/') { + $this->_pop_tag('strip'); + if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ + $this->_additional_newline = "\n"; + return '{' . $tag_command . '}'; + } + } else { + $this->_push_tag('strip'); + if ($this->_strip_depth++==0) { /* outermost opening {strip} */ + $this->_additional_newline = ""; + return '{' . $tag_command . '}'; + } + } + return ''; + + case 'php': + /* handle folded tags replaced by {php} */ + list(, $block) = each($this->_folded_blocks); + $this->_current_line_no += substr_count($block[0], "\n"); + /* the number of matched elements in the regexp in _compile_file() + determins the type of folded tag that was found */ + switch (count($block)) { + case 2: /* comment */ + return ''; + + case 3: /* literal */ + return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; + + case 4: /* php */ + if ($this->security && !$this->security_settings['PHP_TAGS']) { + $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); + return; + } + return '<?php ' . $block[3] .' ?>'; + } + break; + + case 'insert': + return $this->_compile_insert_tag($tag_args); + + default: + if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) { + return $output; + } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; + } else { + $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); + } + + } + } + + + /** + * compile the custom compiler tag + * + * sets $output to the compiled custom compiler tag + * @param string $tag_command + * @param string $tag_args + * @param string $output + * @return boolean + */ + function _compile_compiler_tag($tag_command, $tag_args, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the compiler function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['compiler'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['compiler'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "compiler function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_compiler_' . $tag_command; + if (!is_callable($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true); + } + } + + /* + * True return value means that we either found a plugin or a + * dynamically registered function. False means that we didn't and the + * compiler should now emit code to load custom function plugin for this + * tag. + */ + if ($found) { + if ($have_function) { + $output = call_user_func_array($plugin_func, array($tag_args, &$this)); + if($output != '') { + $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command) + . $output + . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>'; + } + } else { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + } + return true; + } else { + return false; + } + } + + + /** + * compile block function tag + * + * sets $output to compiled block function tag + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @param string $output + * @return boolean + */ + function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else + $start_tag = true; + + $found = false; + $have_function = true; + + /* + * First we check if the block function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['block'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['block'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "block function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_block_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* + * Even though we've located the plugin function, compilation + * happens only once, so the plugin will still need to be loaded + * at runtime for future requests. + */ + $this->_add_plugin('block', $tag_command); + + if ($start_tag) + $this->_push_tag($tag_command); + else + $this->_pop_tag($tag_command); + + if ($start_tag) { + $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs=''; + $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); + $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; + $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; + $output .= 'while ($_block_repeat) { ob_start(); ?>'; + } else { + $output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); '; + $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; + if ($tag_modifier != '') { + $this->_parse_modifiers($_out_tag_text, $tag_modifier); + } + $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; + $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; + } + + return true; + } + + + /** + * compile custom function tag + * + * @param string $tag_command + * @param string $tag_args + * @param string $tag_modifier + * @return string + */ + function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) + { + $found = false; + $have_function = true; + + /* + * First we check if the custom function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['function'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['function'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "custom function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_function_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* declare plugin to be loaded on display of the template that + we compile right now */ + $this->_add_plugin('function', $tag_command); + + $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); + $attrs = $this->_parse_attrs($tag_args); + $_cache_attrs = ''; + $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); + + $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; + if($tag_modifier != '') { + $this->_parse_modifiers($output, $tag_modifier); + } + + if($output != '') { + $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';' + . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; + } + + return true; + } + + /** + * compile a registered object tag + * + * @param string $tag_command + * @param array $attrs + * @param string $tag_modifier + * @return string + */ + function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) + { + if (substr($tag_command, 0, 1) == '/') { + $start_tag = false; + $tag_command = substr($tag_command, 1); + } else { + $start_tag = true; + } + + list($object, $obj_comp) = explode('->', $tag_command); + + $arg_list = array(); + if(count($attrs)) { + $_assign_var = false; + foreach ($attrs as $arg_name => $arg_value) { + if($arg_name == 'assign') { + $_assign_var = $arg_value; + unset($attrs['assign']); + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + if($this->_reg_objects[$object][2]) { + // smarty object argument format + $args = "array(".implode(',', (array)$arg_list)."), \$this"; + } else { + // traditional argument format + $args = implode(',', array_values($attrs)); + if (empty($args)) { + $args = 'null'; + } + } + + $prefix = ''; + $postfix = ''; + $newline = ''; + if(!is_object($this->_reg_objects[$object][0])) { + $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { + $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { + // method + if(in_array($obj_comp, $this->_reg_objects[$object][3])) { + // block method + if ($start_tag) { + $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; + $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; + $prefix .= "while (\$_block_repeat) { ob_start();"; + $return = null; + $postfix = ''; + } else { + $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; + $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; + $postfix = "} array_pop(\$this->_tag_stack);"; + } + } else { + // non-block method + $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)"; + } + } else { + // property + $return = "\$this->_reg_objects['$object'][0]->$obj_comp"; + } + + if($return != null) { + if($tag_modifier != '') { + $this->_parse_modifiers($return, $tag_modifier); + } + + if(!empty($_assign_var)) { + $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);"; + } else { + $output = 'echo ' . $return . ';'; + $newline = $this->_additional_newline; + } + } else { + $output = ''; + } + + return '<?php ' . $prefix . $output . $postfix . "?>" . $newline; + } + + /** + * Compile {insert ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_insert_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $name = $this->_dequote($attrs['name']); + + if (empty($name)) { + return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!preg_match('~^\w+$~', $name)) { + return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__); + } + + if (!empty($attrs['script'])) { + $delayed_loading = true; + } else { + $delayed_loading = false; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $this->_add_plugin('insert', $name, $delayed_loading); + + $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; + + return "<?php require_once(SMARTY_CORE_DIR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline; + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__); + } + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'file') { + $include_file = $arg_value; + continue; + } else if ($arg_name == 'assign') { + $assign_var = $arg_value; + continue; + } + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + $output = '<?php '; + + if (isset($assign_var)) { + $output .= "ob_start();\n"; + } + + $output .= + "\$_smarty_tpl_vars = \$this->_tpl_vars;\n"; + + + $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; + $output .= "\$this->_smarty_include($_params);\n" . + "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" . + "unset(\$_smarty_tpl_vars);\n"; + + if (isset($assign_var)) { + $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n"; + } + + $output .= ' ?>'; + + return $output; + + } + + /** + * Compile {include ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_include_php_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__); + } + + $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); + $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; + + $arg_list = array(); + foreach($attrs as $arg_name => $arg_value) { + if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { + if(is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + + $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; + + return "<?php require_once(SMARTY_CORE_DIR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline; + } + + + /** + * Compile {section ...} tag + * + * @param string $tag_args + * @return string + */ + function _compile_section_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + $output = '<?php '; + $section_name = $attrs['name']; + if (empty($section_name)) { + $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); + } + + $output .= "unset(\$this->_sections[$section_name]);\n"; + $section_props = "\$this->_sections[$section_name]"; + + foreach ($attrs as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $show_attr_value = $attr_value ? 'true' : 'false'; + else + $show_attr_value = "(bool)$attr_value"; + $output .= "{$section_props}['show'] = $show_attr_value;\n"; + break; + + case 'name': + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + case 'max': + case 'start': + $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n"; + break; + + case 'step': + $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n"; + break; + + default: + $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + } + + if (!isset($attrs['show'])) + $output .= "{$section_props}['show'] = true;\n"; + + if (!isset($attrs['loop'])) + $output .= "{$section_props}['loop'] = 1;\n"; + + if (!isset($attrs['max'])) + $output .= "{$section_props}['max'] = {$section_props}['loop'];\n"; + else + $output .= "if ({$section_props}['max'] < 0)\n" . + " {$section_props}['max'] = {$section_props}['loop'];\n"; + + if (!isset($attrs['step'])) + $output .= "{$section_props}['step'] = 1;\n"; + + if (!isset($attrs['start'])) + $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n"; + else { + $output .= "if ({$section_props}['start'] < 0)\n" . + " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" . + "else\n" . + " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n"; + } + + $output .= "if ({$section_props}['show']) {\n"; + if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) { + $output .= " {$section_props}['total'] = {$section_props}['loop'];\n"; + } else { + $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n"; + } + $output .= " if ({$section_props}['total'] == 0)\n" . + " {$section_props}['show'] = false;\n" . + "} else\n" . + " {$section_props}['total'] = 0;\n"; + + $output .= "if ({$section_props}['show']):\n"; + $output .= " + for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1; + {$section_props}['iteration'] <= {$section_props}['total']; + {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n"; + $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n"; + $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n"; + $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n"; + $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n"; + + $output .= "?>"; + + return $output; + } + + + /** + * Compile {foreach ...} tag. + * + * @param string $tag_args + * @return string + */ + function _compile_foreach_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $arg_list = array(); + + if (empty($attrs['from'])) { + return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $from = $attrs['from']; + + if (empty($attrs['item'])) { + return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); + } + $item = $this->_dequote($attrs['item']); + if (!preg_match('~^\w+$~', $item)) { + return $this->_syntax_error("'foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + + if (isset($attrs['key'])) { + $key = $this->_dequote($attrs['key']); + if (!preg_match('~^\w+$~', $key)) { + return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); + } + $key_part = "\$this->_tpl_vars['$key'] => "; + } else { + $key = null; + $key_part = ''; + } + + if (isset($attrs['name'])) { + $name = $attrs['name']; + } else { + $name = null; + } + + $output = '<?php '; + $output .= "\$_from = $from; if (!is_array(\$_from) && !is_object(\$_from)) { settype(\$_from, 'array'); }"; + if (isset($name)) { + $foreach_props = "\$this->_foreach[$name]"; + $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; + $output .= "if ({$foreach_props}['total'] > 0):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + $output .= " {$foreach_props}['iteration']++;\n"; + } else { + $output .= "if (count(\$_from)):\n"; + $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; + } + $output .= '?>'; + + return $output; + } + + + /** + * Compile {capture} .. {/capture} tags + * + * @param boolean $start true if this is the {capture} tag + * @param string $tag_args + * @return string + */ + + function _compile_capture_tag($start, $tag_args = '') + { + $attrs = $this->_parse_attrs($tag_args); + + if ($start) { + if (isset($attrs['name'])) + $buffer = $attrs['name']; + else + $buffer = "'default'"; + + if (isset($attrs['assign'])) + $assign = $attrs['assign']; + else + $assign = null; + $output = "<?php ob_start(); ?>"; + $this->_capture_stack[] = array($buffer, $assign); + } else { + list($buffer, $assign) = array_pop($this->_capture_stack); + $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); "; + if (isset($assign)) { + $output .= " \$this->assign($assign, ob_get_contents());"; + } + $output .= "ob_end_clean(); ?>"; + } + + return $output; + } + + /** + * Compile {if ...} tag + * + * @param string $tag_args + * @param boolean $elseif if true, uses elseif instead of if + * @return string + */ + function _compile_if_tag($tag_args, $elseif = false) + { + + /* Tokenize args for 'if' tag. */ + preg_match_all('~(?> + ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call + ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string + \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token + \b\w+\b | # valid word token + \S+ # anything else + )~x', $tag_args, $match); + + $tokens = $match[0]; + + if(empty($tokens)) { + $_error_msg = $elseif ? "'elseif'" : "'if'"; + $_error_msg .= ' statement requires arguments'; + $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); + } + + + // make sure we have balanced parenthesis + $token_count = array_count_values($tokens); + if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { + $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + + $is_arg_stack = array(); + + for ($i = 0; $i < count($tokens); $i++) { + + $token = &$tokens[$i]; + + switch (strtolower($token)) { + case '!': + case '%': + case '!==': + case '==': + case '===': + case '>': + case '<': + case '!=': + case '<>': + case '<<': + case '>>': + case '<=': + case '>=': + case '&&': + case '||': + case '|': + case '^': + case '&': + case '~': + case ')': + case ',': + case '+': + case '-': + case '*': + case '/': + case '@': + break; + + case 'eq': + $token = '=='; + break; + + case 'ne': + case 'neq': + $token = '!='; + break; + + case 'lt': + $token = '<'; + break; + + case 'le': + case 'lte': + $token = '<='; + break; + + case 'gt': + $token = '>'; + break; + + case 'ge': + case 'gte': + $token = '>='; + break; + + case 'and': + $token = '&&'; + break; + + case 'or': + $token = '||'; + break; + + case 'not': + $token = '!'; + break; + + case 'mod': + $token = '%'; + break; + + case '(': + array_push($is_arg_stack, $i); + break; + + case 'is': + /* If last token was a ')', we operate on the parenthesized + expression. The start of the expression is on the stack. + Otherwise, we operate on the last encountered token. */ + if ($tokens[$i-1] == ')') + $is_arg_start = array_pop($is_arg_stack); + else + $is_arg_start = $i-1; + /* Construct the argument for 'is' expression, so it knows + what to operate on. */ + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); + + /* Pass all tokens from next one until the end to the + 'is' expression parsing function. The function will + return modified tokens, where the first one is the result + of the 'is' expression and the rest are the tokens it + didn't touch. */ + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); + + /* Replace the old tokens with the new ones. */ + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); + + /* Adjust argument start so that it won't change from the + current position for the next iteration. */ + $i = $is_arg_start; + break; + + default: + if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { + // function call + if($this->security && + !in_array($token, $this->security_settings['IF_FUNCS'])) { + $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } + } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { + // variable function call + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { + // object or variable + $token = $this->_parse_var_props($token); + } elseif(is_numeric($token)) { + // number, skip it + } else { + $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + } + } + + if ($elseif) + return '<?php elseif ('.implode(' ', $tokens).'): ?>'; + else + return '<?php if ('.implode(' ', $tokens).'): ?>'; + } + + + function _compile_arg_list($type, $name, $attrs, &$cache_code) { + $arg_list = array(); + + if (isset($type) && isset($name) + && isset($this->_plugins[$type]) + && isset($this->_plugins[$type][$name]) + && empty($this->_plugins[$type][$name][4]) + && is_array($this->_plugins[$type][$name][5]) + ) { + /* we have a list of parameters that should be cached */ + $_cache_attrs = $this->_plugins[$type][$name][5]; + $_count = $this->_cache_attrs_count++; + $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');"; + + } else { + /* no parameters are cached */ + $_cache_attrs = null; + } + + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + if (is_null($arg_value)) + $arg_value = 'null'; + if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) { + $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)"; + } else { + $arg_list[] = "'$arg_name' => $arg_value"; + } + } + return $arg_list; + } + + /** + * Parse is expression + * + * @param string $is_arg + * @param array $tokens + * @return array + */ + function _parse_is_expr($is_arg, $tokens) + { + $expr_end = 0; + $negate_expr = false; + + if (($first_token = array_shift($tokens)) == 'not') { + $negate_expr = true; + $expr_type = array_shift($tokens); + } else + $expr_type = $first_token; + + switch ($expr_type) { + case 'even': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "!(1 & $is_arg)"; + break; + + case 'odd': + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; + } else + $expr = "(1 & $is_arg)"; + break; + + case 'div': + if (@$tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")"; + } else { + $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__); + } + break; + + default: + $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if ($negate_expr) { + $expr = "!($expr)"; + } + + array_splice($tokens, 0, $expr_end, $expr); + + return $tokens; + } + + + /** + * Parse attribute string + * + * @param string $tag_args + * @return array + */ + function _parse_attrs($tag_args) + { + + /* Tokenize tag attributes. */ + preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) + )+ | + [=] + ~x', $tag_args, $match); + $tokens = $match[0]; + + $attrs = array(); + /* Parse state: + 0 - expecting attribute name + 1 - expecting '=' + 2 - expecting attribute value (not '=') */ + $state = 0; + + foreach ($tokens as $token) { + switch ($state) { + case 0: + /* If the token is a valid identifier, we set attribute name + and go to state 1. */ + if (preg_match('~^\w+$~', $token)) { + $attr_name = $token; + $state = 1; + } else + $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 1: + /* If the token is '=', then we go to state 2. */ + if ($token == '=') { + $state = 2; + } else + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + break; + + case 2: + /* If token is not '=', we set the attribute value and go to + state 0. */ + if ($token != '=') { + /* We booleanize the token if it's a non-quoted possible + boolean value. */ + if (preg_match('~^(on|yes|true)$~', $token)) { + $token = 'true'; + } else if (preg_match('~^(off|no|false)$~', $token)) { + $token = 'false'; + } else if ($token == 'null') { + $token = 'null'; + } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { + /* treat integer literally */ + } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { + /* treat as a string, double-quote it escaping quotes */ + $token = '"'.addslashes($token).'"'; + } + + $attrs[$attr_name] = $token; + $state = 0; + } else + $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__); + break; + } + $last_token = $token; + } + + if($state != 0) { + if($state == 1) { + $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__); + } else { + $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__); + } + } + + $this->_parse_vars_props($attrs); + + return $attrs; + } + + /** + * compile multiple variables and section properties tokens into + * PHP code + * + * @param array $tokens + */ + function _parse_vars_props(&$tokens) + { + foreach($tokens as $key => $val) { + $tokens[$key] = $this->_parse_var_props($val); + } + } + + /** + * compile single variable and section properties token into + * PHP code + * + * @param string $val + * @param string $tag_attrs + * @return string + */ + function _parse_var_props($val) + { + $val = trim($val); + + if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { + // $ variable or object + $return = $this->_parse_var($match[1]); + $modifiers = $match[2]; + if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { + $_default_mod_string = implode('|',(array)$this->default_modifiers); + $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; + } + $this->_parse_modifiers($return, $modifiers); + return $return; + } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // double quoted text + preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + $return = $this->_expand_quoted_text($match[1]); + if($match[2] != '') { + $this->_parse_modifiers($return, $match[2]); + } + return $return; + } + elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // numerical constant + preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // single quoted text + preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // config var + return $this->_parse_conf_var($val); + } + elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // section var + return $this->_parse_section_prop($val); + } + elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { + // literal string + return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); + } + return $val; + } + + /** + * expand quoted text with embedded variables + * + * @param string $var_expr + * @return string + */ + function _expand_quoted_text($var_expr) + { + // if contains unescaped $, expand it + if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) { + $_match = $_match[0]; + $_replace = array(); + foreach($_match as $_var) { + $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."'; + } + $var_expr = strtr($var_expr, $_replace); + $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr); + } else { + $_return = $var_expr; + } + // replace double quoted literal string with single quotes + $_return = preg_replace('~^"([\s\w]+)"$~',"'\\1'",$_return); + return $_return; + } + + /** + * parse variable expression into PHP code + * + * @param string $var_expr + * @param string $output + * @return string + */ + function _parse_var($var_expr) + { + $_has_math = false; + $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); + + if(count($_math_vars) > 1) { + $_first_var = ""; + $_complete_var = ""; + $_output = ""; + // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) + foreach($_math_vars as $_k => $_math_var) { + $_math_var = $_math_vars[$_k]; + + if(!empty($_math_var) || is_numeric($_math_var)) { + // hit a math operator, so process the stuff which came before it + if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { + $_has_math = true; + if(!empty($_complete_var) || is_numeric($_complete_var)) { + $_output .= $this->_parse_var($_complete_var); + } + + // just output the math operator to php + $_output .= $_math_var; + + if(empty($_first_var)) + $_first_var = $_complete_var; + + $_complete_var = ""; + } else { + $_complete_var .= $_math_var; + } + } + } + if($_has_math) { + if(!empty($_complete_var) || is_numeric($_complete_var)) + $_output .= $this->_parse_var($_complete_var); + + // get the modifiers working (only the last var from math + modifier is left) + $var_expr = $_complete_var; + } + } + + // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) + if(is_numeric(substr($var_expr, 0, 1))) + $_var_ref = $var_expr; + else + $_var_ref = substr($var_expr, 1); + + if(!$_has_math) { + + // get [foo] and .foo and ->foo and (...) pieces + preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); + + $_indexes = $match[0]; + $_var_name = array_shift($_indexes); + + /* Handle $smarty.* variable references as a special case. */ + if ($_var_name == 'smarty') { + /* + * If the reference could be compiled, use the compiled output; + * otherwise, fall back on the $smarty variable generated at + * run-time. + */ + if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) { + $_output = $smarty_ref; + } else { + $_var_name = substr(array_shift($_indexes), 1); + $_output = "\$this->_smarty_vars['$_var_name']"; + } + } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { + // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers + if(count($_indexes) > 0) + { + $_var_name .= implode("", $_indexes); + $_indexes = array(); + } + $_output = $_var_name; + } else { + $_output = "\$this->_tpl_vars['$_var_name']"; + } + + foreach ($_indexes as $_index) { + if (substr($_index, 0, 1) == '[') { + $_index = substr($_index, 1, -1); + if (is_numeric($_index)) { + $_output .= "[$_index]"; + } elseif (substr($_index, 0, 1) == '$') { + if (strpos($_index, '.') !== false) { + $_output .= '[' . $this->_parse_var($_index) . ']'; + } else { + $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]"; + } + } else { + $_var_parts = explode('.', $_index); + $_var_section = $_var_parts[0]; + $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; + $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; + } + } else if (substr($_index, 0, 1) == '.') { + if (substr($_index, 1, 1) == '$') + $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; + else + $_output .= "['" . substr($_index, 1) . "']"; + } else if (substr($_index,0,2) == '->') { + if(substr($_index,2,2) == '__') { + $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif($this->security && substr($_index, 2, 1) == '_') { + $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } elseif (substr($_index, 2, 1) == '$') { + if ($this->security) { + $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); + } else { + $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}'; + } + } else { + $_output .= $_index; + } + } elseif (substr($_index, 0, 1) == '(') { + $_index = $this->_parse_parenth_args($_index); + $_output .= $_index; + } else { + $_output .= $_index; + } + } + } + + return $_output; + } + + /** + * parse arguments in function call parenthesis + * + * @param string $parenth_args + * @return string + */ + function _parse_parenth_args($parenth_args) + { + preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); + $orig_vals = $match = $match[0]; + $this->_parse_vars_props($match); + $replace = array(); + for ($i = 0, $count = count($match); $i < $count; $i++) { + $replace[$orig_vals[$i]] = $match[$i]; + } + return strtr($parenth_args, $replace); + } + + /** + * parse configuration variable expression into PHP code + * + * @param string $conf_var_expr + */ + function _parse_conf_var($conf_var_expr) + { + $parts = explode('|', $conf_var_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + $var_name = substr($var_ref, 1, -1); + + $output = "\$this->_config[0]['vars']['$var_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + /** + * parse section property expression into PHP code + * + * @param string $section_prop_expr + * @return string + */ + function _parse_section_prop($section_prop_expr) + { + $parts = explode('|', $section_prop_expr, 2); + $var_ref = $parts[0]; + $modifiers = isset($parts[1]) ? $parts[1] : ''; + + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); + $section_name = $match[1]; + $prop_name = $match[2]; + + $output = "\$this->_sections['$section_name']['$prop_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + + /** + * parse modifier chain into PHP code + * + * sets $output to parsed modified chain + * @param string $output + * @param string $modifier_string + */ + function _parse_modifiers(&$output, $modifier_string) + { + preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); + list(, $_modifiers, $modifier_arg_strings) = $_match; + + for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { + $_modifier_name = $_modifiers[$_i]; + + if($_modifier_name == 'smarty') { + // skip smarty modifier + continue; + } + + preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); + $_modifier_args = $_match[1]; + + if (substr($_modifier_name, 0, 1) == '@') { + $_map_array = false; + $_modifier_name = substr($_modifier_name, 1); + } else { + $_map_array = true; + } + + if (empty($this->_plugins['modifier'][$_modifier_name]) + && !$this->_get_plugin_filepath('modifier', $_modifier_name) + && function_exists($_modifier_name)) { + if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { + $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); + } else { + $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); + } + } + $this->_add_plugin('modifier', $_modifier_name); + + $this->_parse_vars_props($_modifier_args); + + if($_modifier_name == 'default') { + // supress notifications of default modifier vars and args + if(substr($output, 0, 1) == '$') { + $output = '@' . $output; + } + if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { + $_modifier_args[0] = '@' . $_modifier_args[0]; + } + } + if (count($_modifier_args) > 0) + $_modifier_args = ', '.implode(', ', $_modifier_args); + else + $_modifier_args = ''; + + if ($_map_array) { + $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))"; + + } else { + + $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)"; + + } + } + } + + + /** + * add plugin + * + * @param string $type + * @param string $name + * @param boolean? $delayed_loading + */ + function _add_plugin($type, $name, $delayed_loading = null) + { + if (!isset($this->_plugin_info[$type])) { + $this->_plugin_info[$type] = array(); + } + if (!isset($this->_plugin_info[$type][$name])) { + $this->_plugin_info[$type][$name] = array($this->_current_file, + $this->_current_line_no, + $delayed_loading); + } + } + + + /** + * Compiles references of type $smarty.foo + * + * @param string $indexes + * @return string + */ + function _compile_smarty_ref(&$indexes) + { + /* Extract the reference name. */ + $_ref = substr($indexes[0], 1); + foreach($indexes as $_index_no=>$_index) { + if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { + $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + } + + switch ($_ref) { + case 'now': + $compiled_ref = 'time()'; + $_max_index = 1; + break; + + case 'foreach': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $_propname = substr($indexes[1], 1); + $_max_index = 1; + switch ($_propname) { + case 'index': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; + break; + + case 'first': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; + break; + + case 'last': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; + break; + + case 'show': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; + break; + + default: + unset($_max_index); + $compiled_ref = "\$this->_foreach[$_var]"; + } + break; + + case 'section': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = "\$this->_sections[$_var]"; + break; + + case 'get': + $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']"; + break; + + case 'post': + $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']"; + break; + + case 'cookies': + $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']"; + break; + + case 'env': + $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']"; + break; + + case 'server': + $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']"; + break; + + case 'session': + $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']"; + break; + + /* + * These cases are handled either at run-time or elsewhere in the + * compiler. + */ + case 'request': + if ($this->request_use_auto_globals) { + $compiled_ref = '$_REQUEST'; + break; + } else { + $this->_init_smarty_vars = true; + } + return null; + + case 'capture': + return null; + + case 'template': + $compiled_ref = "'$this->_current_file'"; + $_max_index = 1; + break; + + case 'version': + $compiled_ref = "'$this->_version'"; + $_max_index = 1; + break; + + case 'const': + if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { + $this->_syntax_error("(secure mode) constants not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } + array_shift($indexes); + if (preg_match('!^\.\w+$!', $indexes[0])) { + $compiled_ref = '@' . substr($indexes[0], 1); + } else { + $_val = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = '@constant(' . $_val . ')'; + } + $_max_index = 1; + break; + + case 'config': + $compiled_ref = "\$this->_config[0]['vars']"; + $_max_index = 3; + break; + + case 'ldelim': + $compiled_ref = "'$this->left_delimiter'"; + break; + + case 'rdelim': + $compiled_ref = "'$this->right_delimiter'"; + break; + + default: + $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); + break; + } + + if (isset($_max_index) && count($indexes) > $_max_index) { + $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); + } + + array_shift($indexes); + return $compiled_ref; + } + + /** + * compiles call to plugin of type $type with name $name + * returns a string containing the function-name or method call + * without the paramter-list that would have follow to make the + * call valid php-syntax + * + * @param string $type + * @param string $name + * @return string + */ + function _compile_plugin_call($type, $name) { + if (isset($this->_plugins[$type][$name])) { + /* plugin loaded */ + if (is_array($this->_plugins[$type][$name][0])) { + return ((is_object($this->_plugins[$type][$name][0][0])) ? + "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */ + : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */ + ). $this->_plugins[$type][$name][0][1]; + + } else { + /* function callback */ + return $this->_plugins[$type][$name][0]; + + } + } else { + /* plugin not loaded -> auto-loadable-plugin */ + return 'smarty_'.$type.'_'.$name; + + } + } + + /** + * load pre- and post-filters + */ + function _load_filters() + { + if (count($this->_plugins['prefilter']) > 0) { + foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) { + if ($prefilter === false) { + unset($this->_plugins['prefilter'][$filter_name]); + $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + if (count($this->_plugins['postfilter']) > 0) { + foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { + if ($postfilter === false) { + unset($this->_plugins['postfilter'][$filter_name]); + $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); + smarty_core_load_plugins($_params, $this); + } + } + } + } + + + /** + * Quote subpattern references + * + * @param string $string + * @return string + */ + function _quote_replace($string) + { + return strtr($string, array('\\' => '\\\\', '$' => '\\$')); + } + + /** + * display Smarty syntax error + * + * @param string $error_msg + * @param integer $error_type + * @param string $file + * @param integer $line + */ + function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) + { + $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); + } + + + /** + * check if the compilation changes from cacheable to + * non-cacheable state with the beginning of the current + * plugin. return php-code to reflect the transition. + * @return string + */ + function _push_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || 0<$this->_cacheable_state++) return ''; + if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); + $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:' + . $this->_cache_serial . '#' . $this->_nocache_count + . '}\'; endif;'; + return $_ret; + } + + + /** + * check if the compilation changes from non-cacheable to + * cacheable state with the end of the current plugin return + * php-code to reflect the transition. + * @return string + */ + function _pop_cacheable_state($type, $name) { + $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; + if ($_cacheable + || --$this->_cacheable_state>0) return ''; + return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:' + . $this->_cache_serial . '#' . ($this->_nocache_count++) + . '}\'; endif;'; + } + + + /** + * push opening tag-name, file-name and line-number on the tag-stack + * @param string the opening tag's name + */ + function _push_tag($open_tag) + { + array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); + } + + /** + * pop closing tag-name + * raise an error if this stack-top doesn't match with the closing tag + * @param string the closing tag's name + * @return string the opening tag's name + */ + function _pop_tag($close_tag) + { + $message = ''; + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = array_pop($this->_tag_stack); + if ($close_tag == $_open_tag) { + return $_open_tag; + } + if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { + return $this->_pop_tag($close_tag); + } + if ($close_tag == 'section' && $_open_tag == 'sectionelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($_open_tag == 'else' || $_open_tag == 'elseif') { + $_open_tag = 'if'; + } elseif ($_open_tag == 'sectionelse') { + $_open_tag = 'section'; + } elseif ($_open_tag == 'foreachelse') { + $_open_tag = 'foreach'; + } + $message = " expected {/$_open_tag} (opened line $_line_no)."; + } + $this->_syntax_error("mismatched tag {/$close_tag}.$message", + E_USER_ERROR, __FILE__, __LINE__); + } + +} + +/** + * compare to values by their string length + * + * @access private + * @param string $a + * @param string $b + * @return 0|-1|1 + */ +function _smarty_sort_length($a, $b) +{ + if($a == $b) + return 0; + + if(strlen($a) == strlen($b)) + return ($a > $b) ? -1 : 1; + + return (strlen($a) > strlen($b)) ? -1 : 1; +} + + +/* vim: set et: */ + +?> diff --git a/fp-includes/smarty/debug.tpl b/fp-includes/smarty/debug.tpl new file mode 100644 index 0000000..c05ef5d --- /dev/null +++ b/fp-includes/smarty/debug.tpl @@ -0,0 +1,157 @@ +{* Smarty *} +{* debug.tpl, last updated version 2.1.0 *} +{assign_debug_info} +{capture assign=debug_output} +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> +<head> + <title>Smarty Debug Console +{literal} + +{/literal} + + + +

    Smarty Debug Console

    + +

    included templates & config files (load time in seconds)

    + +
    +{section name=templates loop=$_debug_tpls} + {section name=indent loop=$_debug_tpls[templates].depth}   {/section} + + {$_debug_tpls[templates].filename|escape:html} + {if isset($_debug_tpls[templates].exec_time)} + + ({$_debug_tpls[templates].exec_time|string_format:"%.5f"}) + {if %templates.index% eq 0}(total){/if} + + {/if} +
    +{sectionelse} +

    no templates included

    +{/section} +
    + +

    assigned template variables

    + + + {section name=vars loop=$_debug_keys} + + + + {sectionelse} + + {/section} +
    {ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}{$_debug_vals[vars]|@debug_print_var}

    no template variables assigned

    + +

    assigned config file variables (outer template scope)

    + + + {section name=config_vars loop=$_debug_config_keys} + + + + {sectionelse} + + {/section} +
    {ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}{$_debug_config_vals[config_vars]|@debug_print_var}

    no config vars assigned

    + + +{/capture} +{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} + {$debug_output} +{else} + +{/if} \ No newline at end of file diff --git a/fp-includes/smarty/internals/core.assemble_plugin_filepath.php b/fp-includes/smarty/internals/core.assemble_plugin_filepath.php new file mode 100644 index 0000000..690d3dd --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.assign_smarty_interface.php b/fp-includes/smarty/internals/core.assign_smarty_interface.php new file mode 100644 index 0000000..7e65a73 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.create_dir_structure.php b/fp-includes/smarty/internals/core.create_dir_structure.php new file mode 100644 index 0000000..3eecc49 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.display_debug_console.php b/fp-includes/smarty/internals/core.display_debug_console.php new file mode 100644 index 0000000..1a80f39 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.get_include_path.php b/fp-includes/smarty/internals/core.get_include_path.php new file mode 100644 index 0000000..4343241 --- /dev/null +++ b/fp-includes/smarty/internals/core.get_include_path.php @@ -0,0 +1,44 @@ + diff --git a/fp-includes/smarty/internals/core.get_microtime.php b/fp-includes/smarty/internals/core.get_microtime.php new file mode 100644 index 0000000..f1a28e0 --- /dev/null +++ b/fp-includes/smarty/internals/core.get_microtime.php @@ -0,0 +1,23 @@ + diff --git a/fp-includes/smarty/internals/core.get_php_resource.php b/fp-includes/smarty/internals/core.get_php_resource.php new file mode 100644 index 0000000..786d4e7 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.is_secure.php b/fp-includes/smarty/internals/core.is_secure.php new file mode 100644 index 0000000..d54abd4 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.is_trusted.php b/fp-includes/smarty/internals/core.is_trusted.php new file mode 100644 index 0000000..4299731 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.load_plugins.php b/fp-includes/smarty/internals/core.load_plugins.php new file mode 100644 index 0000000..6db1dc5 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.load_resource_plugin.php b/fp-includes/smarty/internals/core.load_resource_plugin.php new file mode 100644 index 0000000..a7d37d1 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.process_cached_inserts.php b/fp-includes/smarty/internals/core.process_cached_inserts.php new file mode 100644 index 0000000..1d78edd --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.process_compiled_include.php b/fp-includes/smarty/internals/core.process_compiled_include.php new file mode 100644 index 0000000..d539423 --- /dev/null +++ b/fp-includes/smarty/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_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/fp-includes/smarty/internals/core.read_cache_file.php b/fp-includes/smarty/internals/core.read_cache_file.php new file mode 100644 index 0000000..c60e113 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.rm_auto.php b/fp-includes/smarty/internals/core.rm_auto.php new file mode 100644 index 0000000..b251f64 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.rmdir.php b/fp-includes/smarty/internals/core.rmdir.php new file mode 100644 index 0000000..2166c44 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.run_insert_handler.php b/fp-includes/smarty/internals/core.run_insert_handler.php new file mode 100644 index 0000000..71c3845 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.smarty_include_php.php b/fp-includes/smarty/internals/core.smarty_include_php.php new file mode 100644 index 0000000..30c6e76 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.write_cache_file.php b/fp-includes/smarty/internals/core.write_cache_file.php new file mode 100644 index 0000000..72f785b --- /dev/null +++ b/fp-includes/smarty/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'], null)); + } 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/fp-includes/smarty/internals/core.write_compiled_include.php b/fp-includes/smarty/internals/core.write_compiled_include.php new file mode 100644 index 0000000..c14adb5 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.write_compiled_resource.php b/fp-includes/smarty/internals/core.write_compiled_resource.php new file mode 100644 index 0000000..b902eff --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/internals/core.write_file.php b/fp-includes/smarty/internals/core.write_file.php new file mode 100644 index 0000000..8a3a3b3 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/block.admincontrols.php b/fp-includes/smarty/plugins/block.admincontrols.php new file mode 100755 index 0000000..45bc39d --- /dev/null +++ b/fp-includes/smarty/plugins/block.admincontrols.php @@ -0,0 +1,17 @@ + + * Name: admincontrols
    + * Purpose: automatically show/hides admin controls
    + * @author NoWhereMan + * @return string string $content if loggedin + */ +function smarty_block_admincontrols($params, $content, &$smarty) +{ + if (user_loggedin()) + return $content; +} + +?> diff --git a/fp-includes/smarty/plugins/block.html_form.php b/fp-includes/smarty/plugins/block.html_form.php new file mode 100644 index 0000000..975572c --- /dev/null +++ b/fp-includes/smarty/plugins/block.html_form.php @@ -0,0 +1,71 @@ + + * Type: function
    + * Name: html_submit
    + * Date: 25.Jul.2006
    + * Purpose: Create a simple submit button but also saves its id/name into the $_SESSION + * (used by flatpress)
    + * Input:
    + * - name (optional) - string default "submit" + * - id (optional) - string default blank + * - value (optional) - string (default "Submit") + * - extra (optional) - string (default blank): allows to add extra + * parameters as in "class=\"myclass\" onclick=\"dosomething()\"" + * + * @author NoWhereMan + * @version 1.0 + * @param array + * @param Smarty + * @return string + */ + + +function smarty_block_html_form($params, $content, &$smarty) +{ + + if (!isset($params['name']) && defined('ADMIN_PANEL')) { + $params['name'] = 'admin_' . ADMIN_PANEL . '_' . ADMIN_PANEL_ACTION; + + } + + $str = '
    $val) { + $str .= "{$key}=\"" . ($val) . "\" " ; + } + + $str .= ">\n"; + + ob_start(); + wp_nonce_field($params['name']); + $nonce = ob_get_contents(); + ob_end_clean(); + + return + $str . + $nonce . + $content . + '
    '; + +} + +?> diff --git a/fp-includes/smarty/plugins/block.textformat.php b/fp-includes/smarty/plugins/block.textformat.php new file mode 100644 index 0000000..8cd010a --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/compiler.assign.php b/fp-includes/smarty/plugins/compiler.assign.php new file mode 100644 index 0000000..be17298 --- /dev/null +++ b/fp-includes/smarty/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) + * @auther 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/fp-includes/smarty/plugins/function.assign_debug_info.php b/fp-includes/smarty/plugins/function.assign_debug_info.php new file mode 100644 index 0000000..6540498 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.comment_form.php b/fp-includes/smarty/plugins/function.comment_form.php new file mode 100755 index 0000000..a1f6033 --- /dev/null +++ b/fp-includes/smarty/plugins/function.comment_form.php @@ -0,0 +1,15 @@ + diff --git a/fp-includes/smarty/plugins/function.config_load.php b/fp-includes/smarty/plugins/function.config_load.php new file mode 100644 index 0000000..db89f63 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.counter.php b/fp-includes/smarty/plugins/function.counter.php new file mode 100644 index 0000000..1f26db5 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.cycle.php b/fp-includes/smarty/plugins/function.cycle.php new file mode 100644 index 0000000..fe78bb8 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.date.php b/fp-includes/smarty/plugins/function.date.php new file mode 100755 index 0000000..96df37c --- /dev/null +++ b/fp-includes/smarty/plugins/function.date.php @@ -0,0 +1,32 @@ +_get_plugin_filepath('modifier','date_format'); + + + $format = isset($params['format'])? $params['format'] : "%B %e, %Y"; + $date = $smarty->get_template_vars('date'); + $day = smarty_modifier_date_format($date, $format); + + if ($smarty->get_template_vars('prev_entry_day') != $day) { + $smarty->assign('prev_entry_day', $day); + + $ret = isset($params['html'])? sprintf($params['html'], $day) : $day; + + return $ret; + } + + return ''; + +} + + +/* vim: set expandtab: */ + +?> \ No newline at end of file diff --git a/fp-includes/smarty/plugins/function.debug.php b/fp-includes/smarty/plugins/function.debug.php new file mode 100644 index 0000000..4345230 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.eval.php b/fp-includes/smarty/plugins/function.eval.php new file mode 100644 index 0000000..ff0472d --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.fetch.php b/fp-includes/smarty/plugins/function.fetch.php new file mode 100644 index 0000000..81b1bfc --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.html_checkboxes.php b/fp-includes/smarty/plugins/function.html_checkboxes.php new file mode 100644 index 0000000..ed8ad7f --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.html_image.php b/fp-includes/smarty/plugins/function.html_image.php new file mode 100644 index 0000000..9abae72 --- /dev/null +++ b/fp-includes/smarty/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/fp-includes/smarty/plugins/function.html_options.php b/fp-includes/smarty/plugins/function.html_options.php new file mode 100644 index 0000000..cebadde --- /dev/null +++ b/fp-includes/smarty/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