webcalendar

Check-in [8f1b474690]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Snapshot, latest Webcalendar into git
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | descendants | master | trunk
Files: files | file ages | folders
SHA3-256:8f1b474690a2841bf8847f71fa0a484eac9a1b1f14ac6c9bda24007bf125db6b
User & Date: ajv-899-334-8894@vsta.org 2017-05-29 22:43:11
Context
2017-05-29
22:44
Get ical export working. Add option to pull all user-selected layers. (Damn it's slow, but it works.) check-in: 490daaaec6 user: ajv-899-334-8894@vsta.org tags: master, trunk
22:43
Snapshot, latest Webcalendar into git check-in: 8f1b474690 user: ajv-899-334-8894@vsta.org tags: master, trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace

Added AUTHORS.

            1  +Most of the code was written by:
            2  +  Craig Knudsen <cknudsenATcknudsen.com>
            3  +
            4  +
            5  +New features and bug fixes provided by:
            6  +  Jukka Aittola <Jukka.AittolaAThut.fi>
            7  +  Mike Baptiste <baptisteATcc-concepts.com>
            8  +  Ralph Bo&szlig;ler <rbosslerATgmx.de>
            9  +  Toby Cabot <tobyATtoby.cabotATpobox.com>
           10  +  Antonio Costa <accmdqATesoterica.pt>
           11  +  Lachlan Cox <lachieATzip.com.au>
           12  +  Matthew Crosby <mcrosbyATmarthon.org>
           13  +  Dominik Fischer <dfischerATmegla.de>
           14  +  Tollef Fog Heen <tollefATadd.no>
           15  +  T.R. Fullhart <kayosATkayos.org>
           16  +  Ken Harris <kharrisATlhinfo.com>
           17  +  Florian Helmberger <fhATenemy.org>
           18  +  Michiel Holtkamp <michielATreseau.nl>
           19  +  Jeff Hoover* <jhoovATthebusstop.net>
           20  +  Lucie Houel <lyly134ATcaramail.com>
           21  +  Peter Huetmannsberger <huetmannATsite38.ping.at>
           22  +  Thomas James <tbjamesATbellsouth.net>
           23  +  Ian R. Justman <ianjATcalweb.com>
           24  +  Thorsten Klein <kleinATlfm.rwth-aachen.de>
           25  +  Ulrich Leodolter <ulrichATlab1.psy.univie.ac.at>
           26  +  Benoit Maisonny <benoitATsynclude.com>
           27  +  Jonathan Mark <jhmarkATxenops.com>
           28  +  Ed Palmer <palmeredATusers.sourceforge.net>
           29  +  Otto Paukner <Otto.PauknerATm-v-l.de>
           30  +  Paul Reisdorf <preisdorfATbinus.net>
           31  +  Adam Roben* <adam.robenATgmail.com>
           32  +  David Rodrigues <drodrigATnetextensions.com>
           33  +  Adam Shantz* <adamATadamshantzDOTcom>
           34  +  Andy Skunza <askunzaATdynamix-ltd.com>
           35  +  Oliver Teuber <teuberATdevicen.de>
           36  +  Romuald Texier <romualdATidp9001.com>
           37  +  Frederic Tyndiuk <email address suppressed>
           38  +  Jan Willamowius <janATmobile.de>
           39  +  Vadim Zaliva <lordATcrocodile.org>
           40  +  Ray Jones* <rjonesATumces.edu>
           41  +  Bruce Bannon* <bbannonATusersDOTsourceforgeDOTnet>
           42  +
           43  +
           44  +* ( Development Team )
           45  +
           46  +
           47  +Translations:
           48  + Bulgarian:
           49  +  Malen Malenov <malen_malenovATyahoo.com>
           50  + Catalan:
           51  +  Tradu&iuml;t <infoATtraduit.com>
           52  + Chinese-Big5:
           53  +  Liang-Kuan Liu <lianguanATpchome.com.tw>
           54  + Croatian_utf8:
           55  +  Krunoslav Zubrinic <krunoslav.zubrinicATvip.hr>
           56  + Czech:
           57  +  Hanu&scaron; Adler <hadATpenguin.cz>
           58  + Danish:
           59  +  Allan Thraen <allanAT12go.dk>
           60  +  J&oslash;rgen Thomsen <jthATjth.net>
           61  +  Jens Th <photoATjens-th.com>
           62  +  Nicolaj Rasmussen <drlandauATmsn.com>
           63  +  Morten Nielsen <mniATit.dk>
           64  +  Leo Todaro <leotodaroAThotmail.com>
           65  + Dutch:
           66  +  Marcel van der Boom <marcelAThsdev.com>
           67  +  Patrick Gutlich <pgutlichATcasema.net>
           68  +  Klaus Spithost <k.spithostATit-works.nl>
           69  +  Marieke Timmer <marieke.timmerATtijdhof.nl>
           70  +  Arnout Engelen <arnoutenATbzzt.net>
           71  +  Oliver Heesakkers <devATheesakkers.info>
           72  + Estonian:
           73  +  Madis Listak <madisATnetbell.ee>
           74  + Finnish:
           75  +  Juha-Matti &Aring;berg <juffeATliveware.fi>
           76  +  Jussi Siponen <jussi.siponenATposiona.com>
           77  + French:
           78  +  Luc Capronnier <email address suppressed>
           79  +  Olivier Piquerez <PiquerezATtopd.ch>
           80  +  Yves Moenner <yves.moennerATmailcity.com>
           81  +  Romuald Texier <romualdtATfree.fr>
           82  +  Wilfrid Hubert
           83  +  G&eacute;rard Delafond
           84  +  Mario Dragone <mario.dragoneATreims.iufm.fr>
           85  +  erational <http://www.erational.org>
           86  +  Ivan Machetto
           87  +  Emmanuel Rihn <acontrecourantATonline_fr>
           88  + Galician:
           89  +  Ra&uacute;l Araya Tauler <nubeiroATnubeiro.com>
           90  + German:
           91  +  Markus Egartner <markus.egartnerATkh.hallein.at>
           92  +  Ralph Bo&szlig;ler <rbosslerATgmx.de>
           93  +  Peter Huetmannsberger <huetmannATsite38.ping.at>
           94  + Greek:
           95  +  Paul Gessos <cham_gssAThotmail.com>
           96  + Hebrew:
           97  +  Dov Zamir <dovATzamirfamily.com>
           98  + Holo-Big5:
           99  +  Henry H. Tan-Tenn <share2002novATlomaji.com>
          100  + Hungarian:
          101  +  Gyorgy Baffia <gyorgyATbaffia.hu>
          102  +  Laszlo Csecsy <boobaaATajrg.hu_>
          103  +  Istvan Bubreg <bubregATfreemail.hu>
          104  + Icelandic:
          105  +  Kristofer Arnar Einarsson <kristoferATkristofer.com>
          106  + Italian:
          107  +  Simone Cortesi <simoneATcortesi.com>
          108  +  Alessandro <a.orlandiATiol.it>
          109  + Japanese:
          110  +  Makoto Hamanaka <VYA04230ATnifty.com>
          111  +  Tadashi Jokagi <elf2000ATusers.sourceforge.net>
          112  + Korean:
          113  +  Joonyup Jeon <goodwillATwowbook.com>
          114  + Norwegian:
          115  +  P&aring;l L&oslash;berg/Magni Ons&oslash;ien <initioATinitio.no>
          116  +  Hans Fredrik Nordhaug <hansfnATusers.sourceforge.net>
          117  + Polish:
          118  +  Lipowczan Pawel <lpao2ATo2.pl>
          119  +  Jano <j4n0ATusers.sourceforge.net>
          120  + Portuguese:
          121  +  Antonio Costa <accmdqATmail.esoterica.pt>
          122  +  Nuno Lopes <nuno.lopesATmaxitel.com>
          123  + Portuguese/Brazil:
          124  +  S&eacute;rgio Oliveira <slolivATterra.com.br>
          125  +  Mauricio Piza <mpizaATformare.com.br>
          126  +  Paulino Michelazzo <paulinoATmichelazzo.com.br>
          127  +  Jos&eacute; Roberto Kerne <joserobertoATdicaslinux.com.br>
          128  +  Nuno Lopes <nmlATmaxitel.pt>
          129  +  Andre Oliveira <zack22ATig.com.br>
          130  + Romanian:
          131  +  Dan Protopopescu <protopopATphysics.gla.ac.uk>
          132  + Russian:
          133  +  Andre E. Bar&rsquo;yudin <baryudinATpob.huji.ac.il>
          134  +  Ilya G. Teterev <remirranATgmail.com>
          135  + Spanish:
          136  +  Pedro Del Medico <pdmpATinterhoster.com>
          137  +  P&eacute;rez Rilo
          138  +  Eduardo Dominguez <lalo_notthispleaseATteligens.com>
          139  +  Mario Benito <mbenitoATmaberi.com>
          140  + Swedish:
          141  +  Jesper Th&ouml;rn <jesperATthorn.as>
          142  +  Bernt Sj&ouml;str&ouml;m <berntATsjostrom.pchemma.nu>
          143  + Turkish:
          144  +  Atilla Kazanci <supportATdig-it-berlin.de>
          145  + Welsh:
          146  +  Wyn James <wynjamesATonetel.net.uk>
          147  +
          148  +
          149  +There are probably many others that I have inadvertantly missed.
          150  +
          151  +
          152  +Thank you all for contributing to WebCalendar!

Added GPL.html.

            1  +<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
            2  +<html>
            3  +<head>
            4  +<title>GNU General Public License - GNU Project - Free Software Foundation (FSF)</title>
            5  +<link rev="made" href="mailto:webmasters@www.gnu.org">
            6  +<base href="http://www.gnu.org/licenses/gpl.html">
            7  +</head>
            8  +<body bgcolor="#FFFFFF" text="#000000" link="#1F00FF" alink="#FF0000" vlink="#9900DD">
            9  +<h1>GNU General Public License</h1>
           10  +<a href="/graphics/philosophicalgnu.html"><img src="/graphics/philosophical-gnu-sm.jpg"
           11  +   alt=" [image of a Philosophical GNU] "
           12  +   width="160" height="200"></a>
           13  +
           14  +<!-- Please keep this list alphabetical -->
           15  +<!-- tower, gpl.ja.html is Japanese translation of THIS PAGE, -->
           16  +<!-- NOT translation of GPL itself (gpl.ja.html contains the original -->
           17  +<!-- English version). So please do not remove the following. -->
           18  +<!-- Thanks -mhatta -->
           19  +<!-- The same for the Czech page. The entire text of GPL is not -->
           20  +<!-- translated on this page. Thanks Sisao -->
           21  +
           22  +[
           23  +  <a href="/licenses/gpl.cs.html">Czech</a>
           24  +| <a href="/licenses/gpl.html">English</a>
           25  +| <a href="/licenses/gpl.ja.html">Japanese</a>
           26  +]
           27  +
           28  +<!-- It is best to not enumerate the translations here in a menu bar, -->
           29  +<!-- It is best to have the users follow this link, so they have the FSF' -->
           30  +<!-- explanation about translations being unofficial, etc. -->
           31  +
           32  +<p>
           33  +<ul>
           34  +  <li><a href="/licenses/gpl-violation.html"><em>What to do if you see a
           35  +       possible GPL violation</em></a>
           36  +  <li><a href="/licenses/translations.html"><em>Translations
           37  +       of the GPL</em></a>
           38  +  <li><a href="/licenses/gpl-faq.html"><em>GPL Frequently Asked Questions</em></a>
           39  +  <li>The GNU General Public License (GPL)
           40  +       <a href="/licenses/gpl.txt">in plain text format</a>
           41  +  <li>The GNU General Public License (GPL)
           42  +       <a href="/licenses/gpl.texi">in Texinfo format</a>
           43  +</ul>
           44  +<p>
           45  +<hr>
           46  +
           47  +<p>
           48  +
           49  +<h2>Table of Contents</h2>
           50  +<ul>
           51  +
           52  +  <li><a name="TOC1" href="gpl.html#SEC1">GNU GENERAL PUBLIC LICENSE</a>
           53  +<ul>
           54  +<li><a name="TOC2" href="gpl.html#SEC2">Preamble</a>
           55  +<li><a name="TOC3" href="gpl.html#SEC3">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a>
           56  +<li><a name="TOC4" href="gpl.html#SEC4">How to Apply These Terms to Your New Programs</a>
           57  +
           58  +</ul>
           59  +</ul>
           60  +
           61  +<p>
           62  +
           63  +<hr>
           64  +
           65  +<p>
           66  +
           67  +<h2><a name="SEC1" href="gpl.html#TOC1">GNU GENERAL PUBLIC LICENSE</a></h2>
           68  +<p>
           69  +Version 2, June 1991
           70  +
           71  +</p>
           72  +
           73  +<pre>
           74  +Copyright (C) 1989, 1991 Free Software Foundation, Inc.
           75  +59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
           76  +
           77  +Everyone is permitted to copy and distribute verbatim copies
           78  +of this license document, but changing it is not allowed.
           79  +</pre>
           80  +
           81  +<h2><a name="SEC2" href="gpl.html#TOC2">Preamble</a></h2>
           82  +
           83  +<p>
           84  +  The licenses for most software are designed to take away your
           85  +freedom to share and change it.  By contrast, the GNU General Public
           86  +License is intended to guarantee your freedom to share and change free
           87  +software--to make sure the software is free for all its users.  This
           88  +General Public License applies to most of the Free Software
           89  +Foundation's software and to any other program whose authors commit to
           90  +using it.  (Some other Free Software Foundation software is covered by
           91  +the GNU Library General Public License instead.)  You can apply it to
           92  +your programs, too.
           93  +
           94  +</p>
           95  +<p>
           96  +  When we speak of free software, we are referring to freedom, not
           97  +price.  Our General Public Licenses are designed to make sure that you
           98  +have the freedom to distribute copies of free software (and charge for
           99  +this service if you wish), that you receive source code or can get it
          100  +if you want it, that you can change the software or use pieces of it
          101  +in new free programs; and that you know you can do these things.
          102  +
          103  +</p>
          104  +<p>
          105  +  To protect your rights, we need to make restrictions that forbid
          106  +anyone to deny you these rights or to ask you to surrender the rights.
          107  +These restrictions translate to certain responsibilities for you if you
          108  +distribute copies of the software, or if you modify it.
          109  +
          110  +</p>
          111  +<p>
          112  +  For example, if you distribute copies of such a program, whether
          113  +gratis or for a fee, you must give the recipients all the rights that
          114  +you have.  You must make sure that they, too, receive or can get the
          115  +source code.  And you must show them these terms so they know their
          116  +rights.
          117  +
          118  +</p>
          119  +<p>
          120  +  We protect your rights with two steps: (1) copyright the software, and
          121  +(2) offer you this license which gives you legal permission to copy,
          122  +distribute and/or modify the software.
          123  +
          124  +</p>
          125  +<p>
          126  +  Also, for each author's protection and ours, we want to make certain
          127  +that everyone understands that there is no warranty for this free
          128  +software.  If the software is modified by someone else and passed on, we
          129  +want its recipients to know that what they have is not the original, so
          130  +that any problems introduced by others will not reflect on the original
          131  +authors' reputations.
          132  +
          133  +</p>
          134  +<p>
          135  +  Finally, any free program is threatened constantly by software
          136  +patents.  We wish to avoid the danger that redistributors of a free
          137  +program will individually obtain patent licenses, in effect making the
          138  +program proprietary.  To prevent this, we have made it clear that any
          139  +patent must be licensed for everyone's free use or not licensed at all.
          140  +
          141  +</p>
          142  +<p>
          143  +  The precise terms and conditions for copying, distribution and
          144  +modification follow.
          145  +
          146  +</p>
          147  +
          148  +<h2><a name="SEC3" href="gpl.html#TOC3">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></h2>
          149  +
          150  +<p>
          151  +
          152  +<strong>0.</strong>
          153  + This License applies to any program or other work which contains
          154  +a notice placed by the copyright holder saying it may be distributed
          155  +under the terms of this General Public License.  The "Program", below,
          156  +refers to any such program or work, and a "work based on the Program"
          157  +means either the Program or any derivative work under copyright law:
          158  +that is to say, a work containing the Program or a portion of it,
          159  +either verbatim or with modifications and/or translated into another
          160  +language.  (Hereinafter, translation is included without limitation in
          161  +the term "modification".)  Each licensee is addressed as "you".
          162  +<p>
          163  +
          164  +Activities other than copying, distribution and modification are not
          165  +covered by this License; they are outside its scope.  The act of
          166  +running the Program is not restricted, and the output from the Program
          167  +is covered only if its contents constitute a work based on the
          168  +Program (independent of having been made by running the Program).
          169  +Whether that is true depends on what the Program does.
          170  +
          171  +<p>
          172  +
          173  +<strong>1.</strong>
          174  + You may copy and distribute verbatim copies of the Program's
          175  +source code as you receive it, in any medium, provided that you
          176  +conspicuously and appropriately publish on each copy an appropriate
          177  +copyright notice and disclaimer of warranty; keep intact all the
          178  +notices that refer to this License and to the absence of any warranty;
          179  +and give any other recipients of the Program a copy of this License
          180  +along with the Program.
          181  +<p>
          182  +
          183  +You may charge a fee for the physical act of transferring a copy, and
          184  +you may at your option offer warranty protection in exchange for a fee.
          185  +<p>
          186  +
          187  +<strong>2.</strong>
          188  + You may modify your copy or copies of the Program or any portion
          189  +of it, thus forming a work based on the Program, and copy and
          190  +distribute such modifications or work under the terms of Section 1
          191  +above, provided that you also meet all of these conditions:
          192  +<p>
          193  +
          194  +<ul>
          195  +
          196  +<li><strong>a)</strong>
          197  +     You must cause the modified files to carry prominent notices
          198  +     stating that you changed the files and the date of any change.
          199  +
          200  +<p>
          201  +<li><strong>b)</strong>
          202  +     You must cause any work that you distribute or publish, that in
          203  +     whole or in part contains or is derived from the Program or any
          204  +     part thereof, to be licensed as a whole at no charge to all third
          205  +     parties under the terms of this License.
          206  +
          207  +<p>
          208  +<li><strong>c)</strong>
          209  +     If the modified program normally reads commands interactively
          210  +     when run, you must cause it, when started running for such
          211  +     interactive use in the most ordinary way, to print or display an
          212  +     announcement including an appropriate copyright notice and a
          213  +     notice that there is no warranty (or else, saying that you provide
          214  +     a warranty) and that users may redistribute the program under
          215  +     these conditions, and telling the user how to view a copy of this
          216  +     License.  (Exception: if the Program itself is interactive but
          217  +     does not normally print such an announcement, your work based on
          218  +     the Program is not required to print an announcement.)
          219  +</ul>
          220  +
          221  +These requirements apply to the modified work as a whole.  If
          222  +identifiable sections of that work are not derived from the Program,
          223  +and can be reasonably considered independent and separate works in
          224  +themselves, then this License, and its terms, do not apply to those
          225  +sections when you distribute them as separate works.  But when you
          226  +distribute the same sections as part of a whole which is a work based
          227  +on the Program, the distribution of the whole must be on the terms of
          228  +this License, whose permissions for other licensees extend to the
          229  +entire whole, and thus to each and every part regardless of who wrote it.
          230  +<p>
          231  +
          232  +Thus, it is not the intent of this section to claim rights or contest
          233  +your rights to work written entirely by you; rather, the intent is to
          234  +exercise the right to control the distribution of derivative or
          235  +collective works based on the Program.
          236  +<p>
          237  +
          238  +In addition, mere aggregation of another work not based on the Program
          239  +with the Program (or with a work based on the Program) on a volume of
          240  +a storage or distribution medium does not bring the other work under
          241  +the scope of this License.
          242  +
          243  +<p>
          244  +
          245  +<strong>3.</strong>
          246  + You may copy and distribute the Program (or a work based on it,
          247  +under Section 2) in object code or executable form under the terms of
          248  +Sections 1 and 2 above provided that you also do one of the following:
          249  +
          250  +<!-- we use this doubled UL to get the sub-sections indented, -->
          251  +<!-- while making the bullets as unobvious as possible. -->
          252  +<ul>
          253  +
          254  +<li><strong>a)</strong>
          255  +     Accompany it with the complete corresponding machine-readable
          256  +     source code, which must be distributed under the terms of Sections
          257  +     1 and 2 above on a medium customarily used for software interchange; or,
          258  +
          259  +<p>
          260  +<li><strong>b)</strong>
          261  +     Accompany it with a written offer, valid for at least three
          262  +     years, to give any third party, for a charge no more than your
          263  +     cost of physically performing source distribution, a complete
          264  +     machine-readable copy of the corresponding source code, to be
          265  +     distributed under the terms of Sections 1 and 2 above on a medium
          266  +     customarily used for software interchange; or,
          267  +
          268  +<p>
          269  +<li><strong>c)</strong>
          270  +     Accompany it with the information you received as to the offer
          271  +     to distribute corresponding source code.  (This alternative is
          272  +     allowed only for noncommercial distribution and only if you
          273  +     received the program in object code or executable form with such
          274  +     an offer, in accord with Subsection b above.)
          275  +</ul>
          276  +
          277  +The source code for a work means the preferred form of the work for
          278  +making modifications to it.  For an executable work, complete source
          279  +code means all the source code for all modules it contains, plus any
          280  +associated interface definition files, plus the scripts used to
          281  +control compilation and installation of the executable.  However, as a
          282  +special exception, the source code distributed need not include
          283  +anything that is normally distributed (in either source or binary
          284  +form) with the major components (compiler, kernel, and so on) of the
          285  +operating system on which the executable runs, unless that component
          286  +itself accompanies the executable.
          287  +<p>
          288  +
          289  +If distribution of executable or object code is made by offering
          290  +access to copy from a designated place, then offering equivalent
          291  +access to copy the source code from the same place counts as
          292  +distribution of the source code, even though third parties are not
          293  +compelled to copy the source along with the object code.
          294  +<p>
          295  +
          296  +<strong>4.</strong>
          297  + You may not copy, modify, sublicense, or distribute the Program
          298  +except as expressly provided under this License.  Any attempt
          299  +otherwise to copy, modify, sublicense or distribute the Program is
          300  +void, and will automatically terminate your rights under this License.
          301  +However, parties who have received copies, or rights, from you under
          302  +this License will not have their licenses terminated so long as such
          303  +parties remain in full compliance.
          304  +
          305  +<p>
          306  +
          307  +<strong>5.</strong>
          308  + You are not required to accept this License, since you have not
          309  +signed it.  However, nothing else grants you permission to modify or
          310  +distribute the Program or its derivative works.  These actions are
          311  +prohibited by law if you do not accept this License.  Therefore, by
          312  +modifying or distributing the Program (or any work based on the
          313  +Program), you indicate your acceptance of this License to do so, and
          314  +all its terms and conditions for copying, distributing or modifying
          315  +the Program or works based on it.
          316  +
          317  +<p>
          318  +
          319  +<strong>6.</strong>
          320  + Each time you redistribute the Program (or any work based on the
          321  +Program), the recipient automatically receives a license from the
          322  +original licensor to copy, distribute or modify the Program subject to
          323  +these terms and conditions.  You may not impose any further
          324  +restrictions on the recipients' exercise of the rights granted herein.
          325  +You are not responsible for enforcing compliance by third parties to
          326  +this License.
          327  +
          328  +<p>
          329  +
          330  +<strong>7.</strong>
          331  + If, as a consequence of a court judgment or allegation of patent
          332  +infringement or for any other reason (not limited to patent issues),
          333  +conditions are imposed on you (whether by court order, agreement or
          334  +otherwise) that contradict the conditions of this License, they do not
          335  +excuse you from the conditions of this License.  If you cannot
          336  +distribute so as to satisfy simultaneously your obligations under this
          337  +License and any other pertinent obligations, then as a consequence you
          338  +may not distribute the Program at all.  For example, if a patent
          339  +license would not permit royalty-free redistribution of the Program by
          340  +all those who receive copies directly or indirectly through you, then
          341  +the only way you could satisfy both it and this License would be to
          342  +refrain entirely from distribution of the Program.
          343  +<p>
          344  +
          345  +If any portion of this section is held invalid or unenforceable under
          346  +any particular circumstance, the balance of the section is intended to
          347  +apply and the section as a whole is intended to apply in other
          348  +circumstances.
          349  +<p>
          350  +
          351  +It is not the purpose of this section to induce you to infringe any
          352  +patents or other property right claims or to contest validity of any
          353  +such claims; this section has the sole purpose of protecting the
          354  +integrity of the free software distribution system, which is
          355  +implemented by public license practices.  Many people have made
          356  +generous contributions to the wide range of software distributed
          357  +through that system in reliance on consistent application of that
          358  +system; it is up to the author/donor to decide if he or she is willing
          359  +to distribute software through any other system and a licensee cannot
          360  +impose that choice.
          361  +<p>
          362  +
          363  +This section is intended to make thoroughly clear what is believed to
          364  +be a consequence of the rest of this License.
          365  +
          366  +<p>
          367  +
          368  +<strong>8.</strong>
          369  + If the distribution and/or use of the Program is restricted in
          370  +certain countries either by patents or by copyrighted interfaces, the
          371  +original copyright holder who places the Program under this License
          372  +may add an explicit geographical distribution limitation excluding
          373  +those countries, so that distribution is permitted only in or among
          374  +countries not thus excluded.  In such case, this License incorporates
          375  +the limitation as if written in the body of this License.
          376  +
          377  +<p>
          378  +
          379  +<strong>9.</strong>
          380  + The Free Software Foundation may publish revised and/or new versions
          381  +of the General Public License from time to time.  Such new versions will
          382  +be similar in spirit to the present version, but may differ in detail to
          383  +address new problems or concerns.
          384  +<p>
          385  +
          386  +Each version is given a distinguishing version number.  If the Program
          387  +specifies a version number of this License which applies to it and "any
          388  +later version", you have the option of following the terms and conditions
          389  +either of that version or of any later version published by the Free
          390  +Software Foundation.  If the Program does not specify a version number of
          391  +this License, you may choose any version ever published by the Free Software
          392  +Foundation.
          393  +
          394  +<p>
          395  +
          396  +<strong>10.</strong>
          397  + If you wish to incorporate parts of the Program into other free
          398  +programs whose distribution conditions are different, write to the author
          399  +to ask for permission.  For software which is copyrighted by the Free
          400  +Software Foundation, write to the Free Software Foundation; we sometimes
          401  +make exceptions for this.  Our decision will be guided by the two goals
          402  +of preserving the free status of all derivatives of our free software and
          403  +of promoting the sharing and reuse of software generally.
          404  +
          405  +<p><strong>NO WARRANTY</strong></p>
          406  +
          407  +<p>
          408  +
          409  +<strong>11.</strong>
          410  + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
          411  +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
          412  +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
          413  +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
          414  +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
          415  +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
          416  +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
          417  +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
          418  +REPAIR OR CORRECTION.
          419  +
          420  +<p>
          421  +
          422  +<strong>12.</strong>
          423  + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
          424  +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
          425  +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
          426  +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
          427  +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
          428  +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
          429  +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
          430  +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
          431  +POSSIBILITY OF SUCH DAMAGES.
          432  +
          433  +<p>
          434  +
          435  +<h2>END OF TERMS AND CONDITIONS</h2>
          436  +
          437  +<h2><a name="SEC4" href="gpl.html#TOC4">How to Apply These Terms to Your New Programs</a></h2>
          438  +
          439  +<p>
          440  +  If you develop a new program, and you want it to be of the greatest
          441  +possible use to the public, the best way to achieve this is to make it
          442  +free software which everyone can redistribute and change under these terms.
          443  +
          444  +</p>
          445  +<p>
          446  +  To do so, attach the following notices to the program.  It is safest
          447  +to attach them to the start of each source file to most effectively
          448  +convey the exclusion of warranty; and each file should have at least
          449  +the "copyright" line and a pointer to where the full notice is found.
          450  +
          451  +</p>
          452  +
          453  +<pre>
          454  +<var>one line to give the program's name and an idea of what it does.</var>
          455  +Copyright (C) <var>yyyy</var>  <var>name of author</var>
          456  +
          457  +This program is free software; you can redistribute it and/or
          458  +modify it under the terms of the GNU General Public License
          459  +as published by the Free Software Foundation; either version 2
          460  +of the License, or (at your option) any later version.
          461  +
          462  +This program is distributed in the hope that it will be useful,
          463  +but WITHOUT ANY WARRANTY; without even the implied warranty of
          464  +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          465  +GNU General Public License for more details.
          466  +
          467  +You should have received a copy of the GNU General Public License
          468  +along with this program; if not, write to the Free Software
          469  +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
          470  +</pre>
          471  +
          472  +<p>
          473  +Also add information on how to contact you by electronic and paper mail.
          474  +
          475  +</p>
          476  +<p>
          477  +If the program is interactive, make it output a short notice like this
          478  +when it starts in an interactive mode:
          479  +
          480  +</p>
          481  +
          482  +<pre>
          483  +Gnomovision version 69, Copyright (C) <var>year</var> <var>name of author</var>
          484  +Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
          485  +type `show w'.  This is free software, and you are welcome
          486  +to redistribute it under certain conditions; type `show c'
          487  +for details.
          488  +</pre>
          489  +
          490  +<p>
          491  +The hypothetical commands <samp>`show w'</samp> and <samp>`show c'</samp> should show
          492  +the appropriate parts of the General Public License.  Of course, the
          493  +commands you use may be called something other than <samp>`show w'</samp> and
          494  +<samp>`show c'</samp>; they could even be mouse-clicks or menu items--whatever
          495  +suits your program.
          496  +
          497  +</p>
          498  +<p>
          499  +You should also get your employer (if you work as a programmer) or your
          500  +school, if any, to sign a "copyright disclaimer" for the program, if
          501  +necessary.  Here is a sample; alter the names:
          502  +
          503  +</p>
          504  +
          505  +<pre>
          506  +Yoyodyne, Inc., hereby disclaims all copyright
          507  +interest in the program `Gnomovision'
          508  +(which makes passes at compilers) written
          509  +by James Hacker.
          510  +
          511  +<var>signature of Ty Coon</var>, 1 April 1989
          512  +Ty Coon, President of Vice
          513  +</pre>
          514  +
          515  +<p>
          516  +This General Public License does not permit incorporating your program into
          517  +proprietary programs.  If your program is a subroutine library, you may
          518  +consider it more useful to permit linking proprietary applications with the
          519  +library.  If this is what you want to do, use the GNU Library General
          520  +Public License instead of this License.
          521  +
          522  +<hr>
          523  +
          524  +Return to <a href="/home.html">GNU's home page</a>.
          525  +<p>
          526  +FSF &amp; GNU inquiries &amp; questions to
          527  +<a href="mailto:gnu@gnu.org"><em>gnu@gnu.org</em></a>.
          528  +Other <a href="/home.html#ContactInfo">ways to contact</a> the FSF.
          529  +<p>
          530  +Comments on these web pages to
          531  +<a href="mailto:webmasters@www.gnu.org"><em>webmasters@www.gnu.org</em></a>,
          532  +send other questions to
          533  +<a href="mailto:gnu@gnu.org"><em>gnu@gnu.org</em></a>.
          534  +<p>
          535  +Copyright notice above.<br />
          536  +Free Software Foundation, Inc.,
          537  +59 Temple Place - Suite 330, Boston, MA  02111,  USA
          538  +<p>
          539  +Updated:
          540  +<!-- hhmts start -->
          541  +Last modified: Sun Jul 15 13:13:30 CEST 2001
          542  +<!-- hhmts end -->
          543  +<hr>
          544  +</body>
          545  +</html>

Added NEWS.

            1  +WebCalendar NEWS File
            2  +Version: $Id: NEWS,v 1.468.2.28 2013/02/22 15:56:46 cknudsen Exp $
            3  +
            4  +This file lists significant changes to WebCalendar.  For a more detailed
            5  +list (that includes specific bugs fixed, please look at ChangeLog):
            6  +
            7  +http://webcalendar.cvs.sourceforge.net/*checkout*/webcalendar/webcalendar/ChangeLog?&pathrev=REL_1_2
            8  +
            9  +---------------------------------------------------------------------------
           10  +
           11  +Version 1.2.7 (22 Jan 2013)
           12  + - Security fix: Do not show the reason for a failed login (i.e. "no such user")
           13  + - Security fix: Escape HTML characters in category name.
           14  + - Security fix: Check all passed in fields (either via HTML form or via
           15  +   URL parameter) for certain malicious tags (script, embed, etc.) and
           16  +   generate fatal error if found.
           17  +
           18  +Version 1.2.6 (07 Jan 2013)
           19  + - Fix for "undefined function require_valide" bug
           20  + - Other minor bug fixes.
           21  + - Updated Greek translation
           22  +
           23  +Version 1.2.5 (29 Feb 2012)
           24  + - Fixes for various security vulnerabilities include LFI (local file
           25  +   inclusion), XSS (cross site scripting) and others.
           26  + - Updated translations: German, German-utf8, Dutch, Dutch-utf8
           27  + - Misc. minor bug fixes
           28  +
           29  +Version 1.2.4 (08 Aug 2011)
           30  + - Fixed XSS vulnerability: malicious javascript in event descriptions submitted
           31  +   by public can do bad things (create admin account, delete events, etc.)
           32  +   when the pending event is viewed by the admin.
           33  + - Fixed bug: PHP warnings on search
           34  + - Removed PHP warnings
           35  + - Bug fix: undefined function date_default_timezone_set in older versions
           36  +   of PHP.
           37  +
           38  +Version 1.2.3 (14 Aug 2010)
           39  + - Fixed bug: could not save events with more than one category
           40  + - Include backtrace in fatal errors when in development mode
           41  +
           42  +Version 1.2.2 (14 Aug 2010)
           43  + - Fixes for PHP warnings about default timezone not being set.
           44  +
           45  +Version 1.2.1 (09 Apr 2010)
           46  + - Addressed some published security vulnerabilities related to
           47  +   cross site scripting (XSS).
           48  + - Fixed "500 Server Error" seen with PHP 5.2.8 and later.  Some users saw
           49  +   either blank web page or seg fault errors with this.
           50  + - Fixed mb_language error message some non-English users were seeing in 1.2.0.
           51  + - A handful of minor bugfixes and patches.
           52  + - Updated translations: Italian
           53  +
           54  +Version 1.2.0 (27 Sep 2008)
           55  + - Added new 'Security Audit' page.
           56  + - Moved hard-coded upcoming.php config setting to System Settings.
           57  + - Added new RSS feed for Activity Log.  This will allow you to be
           58  +   notified via RSS of event approvals/rejections, email notification,
           59  +   new event submissions, event updates, etc.
           60  + - Removed old hack for register_globals work-around that is no longer
           61  +   needed.  This will improve security.
           62  + - Category icons can now be displayed next to events in upcoming.php
           63  + - Updated Portuguese_BR translations
           64  +
           65  +Version 1.2.b1 (25 Feb 2008)
           66  + - Changed default installation user/password to root/none
           67  + - Added read/write test to db_cache /tmp folder
           68  + - The following translations were updated:
           69  +   French, German-UTF
           70  +
           71  +Version 1.1.6 (19 Sep 2007)
           72  +
           73  + - This release fixes bugs found in 1.1.5.
           74  +   (For a complete list of changes, see the ChangeLog in CVS.)
           75  + - Security:
           76  +   Fixes cross-site scripting (XSS) vulnerability in export_handler.php.
           77  +
           78  +Version 1.1.5 (12 Sep 2007)
           79  +
           80  +  - Security fix: vulnerability in $includeDir in functions.php
           81  +  - The following translations were updated:
           82  +    Indonesian
           83  +
           84  +Version 1.1.4 (28 Aug 2007)
           85  +
           86  +  - This release fixes bugs found in 1.1.3.
           87  +
           88  +Version 1.1.3 (04 Aug 2007)
           89  +
           90  +  - New Features / Enhancements:
           91  +    = Import / Export / iCalendar / hCalendar / RSS
           92  +      + VTIMEZONE information is now captured from imported ics files and can be reused
           93  +        for future exports. This greatly simplifies the process and speeds up exports.
           94  +    = User Interface
           95  +      + Added option to display end times in calendars
           96  +      + Added CAPTCHA validation option  to Public Access event creation
           97  +  - The following translations were updated:
           98  +    German
           99  +    Basque
          100  +
          101  +Version 1.1.2 (18 Dec 2006)
          102  +
          103  +  - New Features / Enhancements:
          104  +    = Site Extras
          105  +      + Radio control are now available 
          106  +      + Checkbox controls are now available. 
          107  +      + Multi-Select Select controls are now available. 
          108  +      + Site-Extra fields are now included in emails. 
          109  +      + You can now set where each Site Extra fields show up. 
          110  +        - All 
          111  +        - Email 
          112  +        - View (view_entry) 
          113  +        - Reports 
          114  +        - Reminders 
          115  +        Any combination of the above is possible using bitwise operators.
          116  +    = User Interface
          117  +      + Date Range Searches have been added
          118  +      + Site Extra Seaches have been added
          119  +      + Category Filter has beed added to Advanced Search
          120  +      + Added Category Color option
          121  +      + Admin can now specify a background image for inclusion into CSS
          122  +      + Added new feature 'Display Long Day Names'
          123  +      + Added new Color Picker with many options
          124  +      + Added new About WebCalendar page
          125  +      + Reports can now contain 'fullname'
          126  +      + When creating Reports, you can now simply click desired value
          127  +        and it will auto-insert at the cursor.
          128  +      + The top menu is now fully configurable and custom menus can be
          129  +        added easily. See includes/menu/menu_config.php for details.
          130  +      + Added 'System Log' in menu.  Added logging for adding/editing/deleting
          131  +        users and invalid logins.
          132  +      + Reorganized and grouped System Settings and user preferences
          133  +
          134  +  - The following translations were updated:
          135  +    French-UTF8(new), German, Russian
          136  +
          137  +---------------------------------------------------------------------------
          138  +
          139  +Version 1.1.1 (15 Sep 2006)
          140  +
          141  +  - Fixes:
          142  +    + Fixed vulnerablity: SQL injection possible in edit_template.php,
          143  +      activity_log.php, admin_handler.php, pref_handler.php, export_handler.php
          144  +    + Fixed security: exploit allows execution of code downloaded from
          145  +      remote server
          146  +    + HUGE list of fixes (see ChangeLog for details)
          147  +
          148  +  - New Features / Enhancements / Changes:
          149  +    = Permissions
          150  +      + User Access Control: fine grain setting of all user's permissions
          151  +    = Import / Export / iCalendar / hCalendar / RSS
          152  +      + Read/write remote ical subscriptions with new icalclient.php file.
          153  +        Can be enabled in user preferences in the Subscripe/Publish area.
          154  +      + Added Remote Calendars which allow a WebCalendar user to view
          155  +        external iCalendar/ics (icalshare.com, etc.) or hCalendar files
          156  +        from within WebCalendar.
          157  +      + Improved iCal parsing
          158  +      + Export only a specified category
          159  +      + Implemented VTODO support with floating display of due date per RFC2445 
          160  +      + Allow users to import from Outlook 2003/XP CSV file
          161  +      + Palm Desktop datebook import works for versions 4.1.1 and newer
          162  +      + Added iCal FreeBusy support
          163  +      + Added RSS feed if admin and user preference are enabled for it.
          164  +    = Performance
          165  +      + Style sheets no longer included in each page (faster downloads)
          166  +      + Added caching of db requests and parsed translations.
          167  +    = Event Details
          168  +      + Full timezone support rather than timezone offset
          169  +      + Improved reminder UI and added repeating functionality per RFC2445
          170  +      + Can attach comments and documents to events using database BLOBs
          171  +      + Added support for events overlapping into next day
          172  +      + Added new Repeat type 'Manual' that allows adding Inclusions/Exclusions 
          173  +        without other repeat attributes.
          174  +      + Implemented a new repeating event system that incorporates most
          175  +        requirements of RFC2445.
          176  +        Multiple Categories, multiple Alarms and RDATE are now supported,
          177  +        along with the abiity to export VTIMEZONE elements if desired.
          178  +    = Event Approval
          179  +      + Approve/confirm/reject all unapproved events
          180  +      + Can add a comment for reject/accept event
          181  +    = User Interface
          182  +      + Added install wizard functionality that will create or update
          183  +        database tables.
          184  +      + New JS/DHTML top menu bar added
          185  +      + Use drop-down selection lists for selecting time
          186  +      + Divided content of preferences pages into tabs
          187  +      + Uploadable category icons
          188  +      + Modified upcoming.php to display tasks (see upcoming.php for details)
          189  +      + Layers can be global
          190  +      + Allow date styles to be specified in translation file
          191  +      + Use FCKEditor for editing HTML event descriptions
          192  +      + Added new time range options for reports: next 14/30/60/90/180/365 days
          193  +        This allows reports to show events starting with current date
          194  +      + Added ability to use custom header/stylesheet/trailer on a per-user
          195  +        basis via user preferences.
          196  +      + Optional lunar phases to month view
          197  +      + Allow site extras in reports
          198  +      + Added minical.php for using in iframe in external site
          199  +      + Added support for multiple public calendars by enabling
          200  +        nonuser calendars to act as public calendar.
          201  +      + Added ability to change text Public Access in system settings.
          202  +      + Added new view that will display similar to day.php and week.php do now
          203  +        except for multiple users (each in their own column)
          204  +    = User Authentication
          205  +      + User authentication by IMAP
          206  +      + User authentication from Joomla file (user-app-joomla.php)
          207  +      + Added user self-registration.
          208  +        blacklist and email notification are optional
          209  +    = Email
          210  +      + Added support for SMTP mail using PHPMailer
          211  +      + Email ics attachment to external event participants
          212  +      + Added sending of HTML mail (for reminders only now)
          213  +    = Database
          214  +      + Added support for IBM DB2
          215  +    = PHP
          216  +      + Do not require magic_quote PHP setting
          217  +
          218  +  - The following translations were updated:
          219  +    + Czech, Danish, French, German, Greek (new), Hungarian, Norwegian, Polish,
          220  +      Portuguese_BR, Japanese (switched to UTF-8), Japanese-sjis (new),
          221  +      Japanese-eucjp, Portuguese
          222  +
          223  +---------------------------------------------------------------------------
          224  +
          225  +Version 1.0.0 (17 May 2005) aka Buster
          226  +  - Fixed the following bug reports on SourceForge:
          227  +      1202127: [ 1187734 ] Timezone offset problems still exist
          228  +      1201821: Bypass user_sees_only_his_groups
          229  +      1193835: Creator cannot edit a nonuser-event after Admin changes it.
          230  +      1193579: Untimed shows up wrong in edit page
          231  +      1189515: Possible to create blank usernames
          232  +      1190687: users.php called as public
          233  +      1190699: export.php available to public
          234  +      1190704: public can access assistant_edit.php
          235  +      1103215: Invalid work hours
          236  +      1187734: Timezone offset problem
          237  +      1120897: Conflict with exceptions
          238  +      1181682: Report with no name entered -> phantom report!
          239  +      1179423: private events displayed on reports
          240  +      1183714: Translation error
          241  +      1154432: vCal import from Mozilla fails to translate quoted-printable
          242  +      1176164: iCalendar import fatally corrupts database
          243  +      1181682: Reports with just spaces for a name cannot be edited
          244  +      1179403: Availability selection fails when Time Format =24
          245  +      1065461: timezone offset & all-day events
          246  +      1107253: time zone offset
          247  +      1140453: Time zone offset in email notifications
          248  +      1148602: External Recipients with same name fails
          249  +      1160167: 12AM Events cause display problems in edit_entry.php
          250  +      1158769: Category lost when modifing event by Admin
          251  +      1168686: Month display collides with minicals on Safari
          252  +      1168682: RC3 Language Detection Broken for Safari.
          253  +      1169403: Public Access not DEFAULT selected if Particiapants not shown. 
          254  +      1169078: Bad function call in import_handler.php
          255  +      1168092: Overlapping events display problem
          256  +      1167281: View_l loses colour for today
          257  +      1167790: class=selectedday assignments in other than day.php
          258  +      1162486: Path exposure issue with view_entry.php
          259  +
          260  +  - Other bugs fixed:
          261  +    + Fixed problem with ical import weekly BYDAY parsing in import_ical.php
          262  +    + Fixed problem with missing $cat_id in week and day URLs in month.php
          263  +    + Fixed problem with second edit of a single event in a repeating series 
          264  +      losing linkage with the original event.
          265  +    + Fixed problem with views_edit.php, select groups not returning menbers
          266  +    + Fixed problem with 12AM event not adding hour=0 to URL in week.php
          267  +    + Fixed day.php rendering problem in Safar
          268  +    + Applied bug fix 1151442: Overlapping events display error in week.php
          269  +
          270  +  - New Features / Enhancements / Changes:
          271  +    + Split import/export back to two separate links & pages
          272  +    + Moved contents of scheduling tab to details tab
          273  +    + Updated install/index.php to improve security and display advanced php info
          274  +    + Added new DEFAULT webcal_config values to all sql table definition files
          275  +    + Removed most instances of htmlentities as unneeded
          276  +    + Admin no longer needs to approve Public events that they create
          277  +    + Added option to set LDAP_OPT_PROTOCOL_VERSION in user-ldap.php
          278  +    + Updated install web page to work better on Windows systems.
          279  +      Added display of current PHP settings.
          280  +    + When viewing a report, if allow_html_description is enabled but no HTML
          281  +      is found in an event description, use nl2br to preserve plain text
          282  +      formatting.
          283  +
          284  +  - The following translations were updated:
          285  +    + Danish, Finnish, German, French, Japanese, Norwegian, Polish
          286  +
          287  +---------------------------------------------------------------------------
          288  +
          289  +Version 1.0RC3 (11 Mar 2005)
          290  +  - Fixed the following bug reports on SourceForge:
          291  +      1156729: Global-view with no valid user creates a non-translatable message
          292  +      1152863: Japanese strings munged by reports.php and upcoming.php
          293  +      1124461: Apostrophe in Text Aborts Translation
          294  +      1154854: Nonuser cals not showing up in views
          295  +      1154007: Highlight today in Year view
          296  +      1088772: Nonuser calendar w/ Public as DEFAULT participant
          297  +      1145390: Merge arrays with array_merge vs + in view_t.php
          298  +      1151442: Overlapping events display error in day.php
          299  +      1146037: Availibility legend size not dynamic and not centered in IE.
          300  +      1148603: Assistants can't view Bosses Unapproved Events.
          301  +      1145342: Category selection not tranferred to edit_entry page.
          302  +      1118121: get_admins in user-ldap has bad search
          303  +      1123508: RC3 browser language detection always returns none.
          304  +      1112787: missing charset in upcoming.php
          305  +  - Other bugs fixed:
          306  +    + Fixed problem with upcoming.php header. xml:lang and lang were set to full 
          307  +      LANGUAGE value, not abbreviation.
          308  +    + Fixed problem with upcoming.php with You are not Authorized error message
          309  +      being sent without a header. 
          310  +    + Fixed problem with popups.php with long text strings going off screen.
          311  +      Maximum width is now configurable.
          312  +    + Fixed issue with Application Name containing ? characters in logon.php.
          313  +      If Application Name = Title then translate, else use Admin defined 
          314  +      name and run through htmlspecialchars
          315  +    + Fixed issues with display_small_month URLs. Extra & if no $user specified.
          316  +    - Add meta tag for charset since MSIE requires it.
          317  +    + Fixed broken advanced search that would not allowing searching other
          318  +      users' calendars.  Also added searching non-user calendars.
          319  +    + Added javascript that enables visibility of the start/end time or
          320  +      duration on the edit_entry page from availability.php
          321  +    + Fixed printer friendly view problem. With refresh on, the refresh URL
          322  +      reverted to the regular page
          323  +    + Fixed date_selection_html function to include values for day control
          324  +    + Purge events was not deleting from webcal_entry_ext_user table
          325  +    + Fixed issues with ODBC returning 'invalid db_type'
          326  +    + Fixed issue where month.php and mini-calendar today highlight
          327  +      based on server time
          328  +  - New Features / Enhancements / Changes:
          329  +    + Merged task files into entry files
          330  +    + Added 'Public Access' to Manage Calendar of: list, if Admin. 
          331  +    + Allow user-created views to be the DEFAULT view set in user preferences.
          332  +      After saving or deleting an event, the user will return to this page.
          333  +    + Replaced popups.php code with new knoppix based code. This should eliminate
          334  +      the problems with popups going off screen. Popups also follow the cursor now,
          335  +      but can be disabled in the file.
          336  +    + Replaced all instances of forms[0] in javascript with the real form
          337  +      names. This will allow WebCalendar to co-exist with other forms on
          338  +      the same page.
          339  +    + Added patch to allow TLS with LDAP
          340  +    + Added patch 900968: Add outlook-style availability popup
          341  +    + Added global views (available to all users)
          342  +    + Added option to select all users for a view (rather than having
          343  +      to select all users in the list).  If users are added later, they
          344  +      will be automatically included in the view.
          345  +    + Converted comments for use with phpDocumentor
          346  +  - The following translations were updated:
          347  +    + Dutch, Japanese (utf8, euc-jp, shift-jis), Spanish, German
          348  +
          349  +---------------------------------------------------------------------------
          350  +
          351  +Version 1.0RC2 (09 Feb 2005)
          352  +  - Fixed the following bugs reports on SourceForge:
          353  +      1116008: Got invalid user error when clicking on '+' icon
          354  +               to add new event
          355  +  - Other bugs fixed:
          356  +    + Fixed a problem with the Repeat Tab on edit_entry page, if disabled, 
          357  +      the SAVE button was hidden as well.
          358  +  - New Features / Enhancements / Changes:
          359  +    + Modified the way settings.php file is read to handle unix/dos/mac
          360  +      format and also check main directory and include directory.
          361  +    + In day and week view, time slots with events will now use a different
          362  +      background color than time slots that are empty.  (This restores
          363  +      how this worked a couple of versions ago.)
          364  +    + Many code changes were made to prevent the undefined variable
          365  +      warning that users may get if they have the PHP error_reporting
          366  +      setting enabled.
          367  +    + Documentation updated to System Administrator Guide including
          368  +      new instructions for setting up reminders on Windows.
          369  +  - The following translations were updated:
          370  +    + Czech
          371  +
          372  +---------------------------------------------------------------------------
          373  +
          374  +Version 1.0RC1 (04 Feb 2005)
          375  +  - Fixed the following bugs reports on SourceForge:
          376  +       824268: Emails notifications used wront timezone
          377  +       931096: Restrict views and view edits to owner of that view
          378  +       986774: Editing category as assistant was not working
          379  +      1061746: layout issues with views (daily)
          380  +      1066440: End Time increased by timezone offset
          381  +      1085337: Categories combo-box in month.php in assistant mode
          382  +      1088857: SQL bug affecting ODBC users when viewing event
          383  +      1101823: Problem importing palm desktop datebook.dat file
          384  +      1102167: custom header when non-admin user
          385  +      1109141: Email notifications where using sender language
          386  +               rather than recipient language
          387  +      1109323: Error in LDAP function for getting list of admins
          388  +      1087604: Vanishing Layers / cookies
          389  +      1086357: repeating details display
          390  +      1085846: SQL error in when listing users on some databases
          391  +      1085971: repeat tab does not display details
          392  +      1074403: Day View is not accounting for server offset
          393  +  - Other bugs fixed:
          394  +    + Security fix: Fixed protential problem if a user attempts to login
          395  +      with a username that has charaters that will affect the database.
          396  +    + When using web-based authentication, two database connections
          397  +      were being opened and only one was being closed.
          398  +    + vCal import was completely broken
          399  +    + Fixed problem using htmlarea where event description would not be saved
          400  +    + View Event page would not display links to edit/delete under
          401  +      some circumstances
          402  +    + Fixes for WN web server
          403  +    + Removed duplicate trailer from edit user page (when using a custom
          404  +      trailer)
          405  +  - New Features / Enhancements:
          406  +    + MS SQL Server is now suppported
          407  +    + If php.ini setting for file_uploads is not enabled, then indicate
          408  +      this on the import page
          409  +    + Streamlined layers.php & made layers only be displayed when layers
          410  +      are enabled
          411  +    + Updated Admin docs for content & xhtml/css validity
          412  +    + Added new documentation in docs directory:
          413  +      WebCalendar-Functions.html
          414  +      WebCalendar-DeveloperGuide.html
          415  +      WebCalendar-Styling.html
          416  +    + Fixed various xhtml/css issues
          417  +    + Updated reading of settings file to better handle when file
          418  +      is not in exact format we are expecting.
          419  +    + Added database sanity check
          420  +    + Updated DEFAULT color scheme (Will only apply to new installs)
          421  +    + When html is allowed in event description, still replace newline with
          422  +      html break in view page and event popup if the user did not use any html.
          423  +    + Fixing users.php so it only shows a single user's info when the user
          424  +      isn't an admin
          425  +    + Added ability to authenticate users with postnuke user info.
          426  +    + Added support for automatic gradient background images for table cells
          427  +  - The following translations were updated:
          428  +    + Japanese (with support for 3 character sets)
          429  +    + Romanian (new)
          430  +    + French
          431  +    + German
          432  +    + Italian
          433  +    + Norwegian

Added README.html.

            1  +<?xml version="1.0" encoding="utf-8"?>
            2  +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            3  +  "DTD/xhtml1-transitional.dtd">
            4  +<!-- $Id: README.html,v 1.29.2.2 2007/08/06 02:28:29 cknudsen Exp $ -->
            5  +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
            6  +  <head>
            7  +  <title>WebCalendar README</title>
            8  +  <style type="text/css">
            9  +<!--
           10  +  body {
           11  +    background-color: #FFFFFF;
           12  +    font-family: arial, verdana;
           13  +  }
           14  +  a {
           15  +    text-decoration: none;
           16  +  }
           17  +  table {
           18  +    border-width: 0;
           19  +  }
           20  +  dt {
           21  +    font-weight: bold;
           22  +  }
           23  +  tr {
           24  +    background-color: #606080;
           25  +  }
           26  +  td {
           27  +    background-color: #E0E0E0;
           28  +    vertical-align: top;
           29  +  }
           30  +  h3 {
           31  +    background-color: #191970;
           32  +    color: #FFFFFF;
           33  +    padding: 5px;
           34  +  }
           35  +-->
           36  +  </style>
           37  +  </head>
           38  +  <body>
           39  +    <h2>WebCalendar README</h2>
           40  +    <table cellpadding="10">
           41  +      <tr>
           42  +        <td style="font-weight:bold;">URL:</td>
           43  +        <td><a href="http://www.k5n.us/webcalendar.php">www.k5n.us/webcalendar.php</a></td>
           44  +      </tr>
           45  +      <tr>
           46  +        <td style="vertical-align:top; font-weight:bold;">Developers:</td>
           47  +        <td valign="top">
           48  +          Craig Knudsen,
           49  +          <a href="mailto:&#99;&#114;&#97;&#105;&#103;&#64;&#107;&#53;&#110;&#46;&#117;&#115;">&#99;&#114;&#97;&#105;&#103;&#64;&#107;&#53;&#110;&#46;&#117;&#115;</a>
           50  +          <a href="http://www.k5n.us/">http://www.k5n.us</a><br />
           51  +          Jeff Hoover<br />
           52  +          Adam Shantz,
           53  +          <a href="mailto:adamATadamshantzDOTcom">adamATadamshantzDOTcom</a>,
           54  +          <a href="http://adamshantz.com">adamshantz.com</a><br />
           55  +          Ray Jones, <a href="mailto:rjonesATumcesDOTedu">rjonesATumcesDOTedu</a><br />
           56  +          Adam Roben,
           57  +          Bruce Bannon
           58  +        </td>
           59  +      </tr>
           60  +      <tr>
           61  +        <td style="font-weight:bold;">Documentation:</td>
           62  +        <td>
           63  +          <a href="docs/WebCalendar-SysAdmin.html">System Administrator's Guide</a>
           64  +          (Installation instructions, FAQ)<br />
           65  +          <a href="docs/WebCalendar-UserManual.html">User Manual</a><br />
           66  +          <a href="UPGRADING.html">Upgrading Instructions</a>
           67  +          (<strong>Required</strong> when upgrading from an older version)<br />
           68  +          <a href="GPL.html">License</a><br />
           69  +          <a href="ChangeLog">History of Changes</a><br />
           70  +          <a href="http://webcalendar.sourceforge.net/demo/">Online Demo</a>
           71  +        </td>
           72  +      </tr>
           73  +      <tr>
           74  +        <td style="font-weight:bold;">Developer Resources:</td>
           75  +        <td>
           76  +          <a href="http://sourceforge.net/projects/webcalendar/">Sourceforge.net Home</a><br />
           77  +          <a href="docs/WebCalendar-Functions.html">WebCalendar-Functions.html</a><br />
           78  +          <a href="docs/WebCalendar-Database.html">WebCalendar-Database.html</a><br />
           79  +          <a href="docs/WebCalendar-DeveloperGuide.html">WebCalendar-DeveloperGuide.html</a><br />
           80  +          <a href="http://sourceforge.net/forum/forum.php?forum_id=11588">Help/Troubleshooting Forum</a><br />
           81  +          <a href="http://sourceforge.net/forum/forum.php?forum_id=11587">Open Discussion Forum</a><br />
           82  +          <a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=103870">Bug Reports</a><br />
           83  +          <a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=303870">Patches</a><br />
           84  +          <a href="https://sourceforge.net/project/showfiles.php?group_id=3870">Latest Version</a>
           85  +        </td>
           86  +      </tr>
           87  +    </table>
           88  +    <h3>Note</h3>
           89  +    <p>For a complete feature list, system requirements, and installation instructions, please see the <a href="docs/WebCalendar-SysAdmin.html">WebCalendar System Administrator's Guide</a>.</p>
           90  +    <h3>Outstanding issues</h3>
           91  +    <ul>
           92  +      <li>Updated translations (some are slightly out of date)</li>
           93  +    </ul>
           94  +    <h3>Possible features for future releases</h3>
           95  +    <ul>
           96  +      <li>See <a href="http://www.k5n.us/webcalendar.php?topic=Plans">Plans</a> on the WebCalendar home page.</li>
           97  +    </ul>
           98  +  </body>
           99  +</html>

Added UPGRADING.html.

            1  +<?xml version="1.0" encoding="iso-8859-1"?>
            2  +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            3  +  "DTD/xhtml1-transitional.dtd">
            4  +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
            5  +  <head>
            6  +    <title>WebCalendar Upgrading Notes</title>
            7  +    <style type="text/css">
            8  +      body {
            9  +        background: #FFF;
           10  +        font-family: Arial, Helvetica, sans-serif;
           11  +      }
           12  +      a {
           13  +        text-decoration: none;
           14  +      }
           15  +      p {
           16  +        margin: 10px;
           17  +      }
           18  +      dl,
           19  +      ul {
           20  +        margin-left: 10px;
           21  +      }
           22  +      h2,
           23  +      h3 {
           24  +        padding: 5px;
           25  +      }
           26  +      h2 {
           27  +        background: #191970;
           28  +        color: #FFF;
           29  +      }
           30  +      dt {
           31  +        margin-top: 10px;
           32  +        font-weight: bold;
           33  +      }
           34  +      pre {
           35  +        margin-right: 25px;
           36  +        margin-left: 25px;
           37  +        border: 1px solid #00F;
           38  +        padding: 4px;
           39  +        background: #EEF;
           40  +        font-size: 14px;
           41  +        font-family: courier, monospace;
           42  +      }
           43  +      .tip {
           44  +        padding: 2px;
           45  +        background: #FF0;
           46  +        font-weight: bold;
           47  +      }
           48  +      .note {
           49  +        padding: 2px;
           50  +        background: #87CEFA;
           51  +        font-weight: bold;
           52  +      }
           53  +      hr {
           54  +        margin-bottom: 7px;
           55  +      }
           56  +      .valid {
           57  +        border: 0;
           58  +      }
           59  +      .top {
           60  +        text-align: right;
           61  +      }
           62  +    </style>
           63  +  </head>
           64  +  <body>
           65  +    <h1>WebCalendar Upgrading Notes</h1>
           66  +
           67  +    <table border="0" style="margin-left: 50px;">
           68  +    <tr><th style="text-align: right;">WebCalendar Version:</th><td> 1.2.7 </td></tr>
           69  +    <tr><th valign="top" style="text-align: right;">Document Version:</th><td> $Revision: 1.43.2.15 $ <br/> $Date: 2013/02/22 15:56:47 $</td>
           70  +    </table>
           71  +
           72  +    <p style="margin-bottom: 0"><span class="note">Important News:</span> A major
           73  +    improvement beginning with Version 1.1 is the addition of an automated
           74  +    installation script. This script will guide you through the installation
           75  +    process and help identify any problem areas that might prevent successful
           76  +    installation or operation of WebCalendar.</p>
           77  +
           78  +    <ul style="margin-top: 0">
           79  +      <li style="margin-left: 30px">If upgrading, the script will attempt to
           80  +      determine your current installation version and bring your database up to
           81  +      date.</li>
           82  +
           83  +      <li style="margin-left: 30px">If this is a new installation, the
           84  +      installation script will create your database and setup the required
           85  +      tables for you. It can then create a default Administrator account and
           86  +      add the basic configuration data to get you up and running.</li>
           87  +    </ul>
           88  +
           89  +    <p>This installation script was tested primarily using MySQL and Apache on a
           90  +    dedicated server. If using an ISP or a CPANEL installer, your mileage may
           91  +    vary. If problems arise, you can always follow the instruction below as in
           92  +    previous versions and setup your database manually. As with any upgrade,
           93  +    it's always a good idea to <span style="color: #F00">backup your data prior
           94  +    to installation</span>.</p>
           95  +
           96  +    <p>Another major upgrade to WebCalendar for v1.1 is the implementation of
           97  +    full timezone support. In previous versions, all date/time data was stored
           98  +    based on server time and users set their 'time offset' relative to server
           99  +    time. Now, all date/time data will be stored in the database as
          100  +    Greenwich Mean Time (GMT) and users will be able to select a timezone based
          101  +    on their geographical location.</p>
          102  +
          103  +    <p>Having true timezone information available within WebCalendar enables the
          104  +    system to correct for Daylight Savings Time (DST) even if users are in
          105  +    different timezones. The database houses timezone information from 1970 to
          106  +    2038 and can calculate the appropriate GMT offset required to allow users to
          107  +    see events in their true 'local time'.</p>
          108  +
          109  +    <p>The installation script will perform the initial import of the timezone
          110  +    data and guide you through the one-time conversion required to get your
          111  +    existing data converted to GMT.</p>
          112  +
          113  +    <p><a href="install/index.php">Launch the Automatic Installation Script</a></p>
          114  +
          115  +    <h2>Upgrading Steps</h2>
          116  +
          117  +    <p>With the new 1.1 install wizard, you will no longer have to be troubled
          118  +    with uploading SQL files to phpMyAdmin or executing SQL commands yourself.
          119  +    Your database will be upgraded automatically from your current older
          120  +    WebCalendar installation.  Follow the steps below to upgrade to WebCalendar
          121  +    1.1 from an older version of WebCalendar.
          122  +    </p>
          123  +
          124  +    <ol>
          125  +       <li>Make a backup of your current WebCalendar database.  This can be done
          126  +       a couple of different ways.
          127  +         <ul>
          128  +           <li>If you have access to phpMyAdmin, you can use the export function:
          129  +             <ul>
          130  +               <li>Startup phpMyAdmin </li>
          131  +               <li>Select the database from the pulldown on the left under the
          132  +                   label "Databases".  (This will be the same database name
          133  +                   used in your <tt>includes/settings.php</tt> file in your
          134  +                   old WebCalendar install.)</li>
          135  +               <li>Click on the "Export" tab.</li>
          136  +               <li>It's best to use "SQL" for the format so it can be easily imported again.</li>
          137  +               <li>Select "zipped" for compression.  If you don't do this, you will just
          138  +                   see the SQL in your browser window, and you will have to cut and
          139  +                   paste this into a text editor to save it.
          140  +               <li>Click on the "Go" button at the bottom of the page. </li>
          141  +
          142  +             </ul> </li>
          143  +          <li>If you have access to a MySQL command line (typically via shell access on a
          144  +              Linux server), you can use the mysqldump command:<br/>
          145  +             &nbsp;&nbsp;<tt>mysqldump -u<b>USERNAME</b> -p<b>PASSWORD</b> <b>DATABASE</b> > dumpfile.sql</tt>
          146  +             <br/>Of course, replace USERNAME, PASSWORD and DATABASE from the values in
          147  +            your <tt>includes/settings.php</tt> file from your old WebCalendar install.
          148  +         </li>
          149  +         </ul></li>
          150  +       </li>
          151  +
          152  +    <li>Make a backup of your current WebCalendar files on the server.  You would typically
          153  +        do this with an FTP client
          154  +        (like <a href="http://filezilla.sourceforge.net/">FileZilla</a>).
          155  +    </li>
          156  +
          157  +    <li>Install the new WebCalendar files in a <b>new</b> directory on your server.
          158  +        How you do this will depend on what type of access you have to your server.
          159  +        It is best to not overwrite your old WebCalendar install.  The unpacked/unzipped
          160  +        files will create a directory with the current WebCalendar version name in it.
          161  +    </li>
          162  +    <li><b>Optional:</b>
          163  +        If you prefer to use a simple name (like "webcalendar" rather than "WebCalendar-1.1.6"),
          164  +        then you can rename the directory after you've installed the files.
          165  +        A good way to do this might be to rename your old webcalendar install to
          166  +        something like "webcalendar-oldinstall" and rename the new install to be
          167  +        the same name as your old one.
          168  +        <br/><b>Note:</b> If you are planning on renaming the directory, it is best to do
          169  +        this <i>before</i> you proceed to the automated install.
          170  +    </li>
          171  +
          172  +    <li>Change the permissions the permissions of the <tt>includes</tt> directory.
          173  +        If you are doing this from FTP, change directories to the new webcalendar directory
          174  +        and use the following command:<br/>
          175  +        &nbsp;&nbsp;<tt>chmod 777 includes</tt>
          176  +    <li>Change the permissions the permissions of the <tt>icons</tt> directory.
          177  +        If you are doing this from FTP, change directories to the new webcalendar directory
          178  +        and use the following command:<br/>
          179  +        &nbsp;&nbsp;<tt>chmod 777 icons</tt>
          180  +
          181  +    <li>Download a copy of your old <tt>includes/settings.php</tt> file from the old
          182  +        WebCalendar install and have it handy so you can enter the same values in your
          183  +        upgrade process. </li>
          184  +    <li>Download all files in your old <tt>icons</tt> directory from your old
          185  +        WebCalendar and copy the files into the <tt>icons</tt> directory in
          186  +        the new install directory. </li>
          187  +
          188  +   <li>You're now ready to start the install/upgrade wizard.  Point your browser to the
          189  +       web server where you have installed the files.   You only need to specify
          190  +       the webcalendar directory to get to the wizard.  Because there is no
          191  +       <tt>includes/settings.php</tt> file in the new install, you will be redirected
          192  +       to the install/upgrade wizard.</li>
          193  +    
          194  +   <li>Once the wizard is complete, it's a good idea to change your <tt>includes</tt>
          195  +       permissions back to what they were originally for better security. </li>
          196  +    </ol>
          197  +
          198  +    <hr />
          199  +    <h2>Manual Upgrade Instructions</h2>
          200  +
          201  +    <p>Below are the steps needed to manually upgrade from a previous version.
          202  +    <b>You can ignore everything below if you use the Automated Installation
          203  +    Script.</b>  Select the version of your existing install from the list below.
          204  +    If you are more than one version behind (i.e. the new version is v1.1.6,
          205  +    and you're using 0.9.39), click the "next..." link at the end of each
          206  +    section to move to the next version.
          207  +    Always follow the versions in sequence.</p>
          208  +
          209  +    <p><span class="note">Note:</span> Due to large number of database types
          210  +    that WebCalendar can support, it would be impractical to list all the SQL
          211  +    variations here. All SQL listed is taken from the
          212  +    <a href="install/sql/upgrade-mysql.sql" target="_blank">upgrade-mysq.sql</a>
          213  +    file used during the automatic installation process. If you are using a
          214  +    database other then MySQL, you may want refer to the appropriate
          215  +    upgrade-xxxxx.sql file in the install/sql folder.</p>
          216  +
          217  +    <h2>My previous install was...</h2>
          218  +
          219  +    <ul>
          220  +      <li><a href="UPGRADING.html#from_1.1.0a-CVS">1.1.0-CVS or 1.1.0a-CVS</a></li>
          221  +      <li><a href="UPGRADING.html#from_1.0.0">1.0RC3 or 1.0.0</a></li>
          222  +      <li><a href="UPGRADING.html#from_1_0RC2">0.9.45, 1.0RC1 or 1.0RC2</a></li>
          223  +      <li><a href="UPGRADING.html#dot944">0.9.44</a></li>
          224  +      <li><a href="UPGRADING.html#dot943">0.9.43</a></li>
          225  +      <li><a href="UPGRADING.html#dot942">0.9.42</a></li>
          226  +      <li><a href="UPGRADING.html#dot941">0.9.41</a></li>
          227  +      <li><a href="UPGRADING.html#dot940">0.9.40</a></li>
          228  +      <li><a href="UPGRADING.html#dot939">0.9.39</a></li>
          229  +      <li><a href="UPGRADING.html#dot938">0.9.38</a></li>
          230  +      <li><a href="UPGRADING.html#dot937">0.9.37</a></li>
          231  +      <li><a href="UPGRADING.html#dot936">0.9.35 - 0.9.36</a></li>
          232  +      <li><a href="UPGRADING.html#dot934">0.9.27 - 0.9.34</a></li>
          233  +      <li><a href="UPGRADING.html#dot926">0.9.22 - 0.9.26</a></li>
          234  +      <li><a href="UPGRADING.html#dot921">0.9.14 - 0.9.21</a></li>
          235  +      <li><a href="UPGRADING.html#dot913">0.9.12 - 0.9.13</a></li>
          236  +      <li><a href="UPGRADING.html#dot911">0.9.07 - 0.9.11</a></li>
          237  +      <li><a href="UPGRADING.html#dot906">0.9.01 - 0.9.06</a></li>
          238  +      <li><a href="UPGRADING.html#dot9">0.9</a></li>
          239  +    </ul>
          240  +
          241  +    <hr />
          242  +    <h2><a id="dot9">To upgrade from v0.9</a></h2>
          243  +
          244  +    <p>You need to create the table cal_user_pref in tables.sql. You need to
          245  +    create the table cal_entry_user in tables.sql that was mistakenly created as
          246  +    "cal_event_user" in the 0.9 release.</p>
          247  +
          248  +    <a href="UPGRADING.html#dot906">next...</a>
          249  +    <hr />
          250  +
          251  +    <h2><a id="dot906">To upgrade from v0.9.01</a></h2>
          252  +
          253  +    <p>Entirely new tables are used. Use the following commands to convert your
          254  +    existing MySQL tables to the new tables:</p>
          255  +
          256  +    <pre>
          257  +cd tools
          258  +./upgrade_to_0.9.7.pl
          259  +mysql intranet &lt; commands.sql
          260  +    </pre>
          261  +
          262  +    <p>where "intranet" is the name of the MySQL database that contains your
          263  +    WebCalendar tables.</p>
          264  +
          265  +    <a href="UPGRADING.html#dot911">next...</a>
          266  +    <hr />
          267  +
          268  +    <h2><a id="dot911">To upgrade from v0.9.07 - v0.9.11</a></h2>
          269  +
          270  +    <p>To fix a bug in the handing of events at midnight, all the entries with
          271  +    NULL for cal_time are changed to -1. Use the following SQL command:</p>
          272  +
          273  +    <pre>UPDATE webcal_entry SET cal_time = -1 WHERE cal_time is null;</pre>
          274  +
          275  +    <a href="UPGRADING.html#dot913">next...</a>
          276  +    <hr />
          277  +
          278  +    <h2><a id="dot913">To upgrade from v0.9.12 or v0.9.13</a></h2>
          279  +
          280  +    <p>A new table was added to support repeating events. Use the following SQL
          281  +    command:</p>
          282  +
          283  +    <pre>
          284  +CREATE TABLE webcal_entry_repeats (
          285  +  cal_id INT DEFAULT '0' NOT NULL,
          286  +  cal_days CHAR(7),
          287  +  cal_end INT,
          288  +  cal_frequency INT DEFAULT '1',
          289  +  cal_type VARCHAR(20),
          290  +  PRIMARY KEY (cal_id)
          291  +);
          292  +    </pre>
          293  +
          294  +    <a href="UPGRADING.html#dot921">next...</a>
          295  +    <hr />
          296  +
          297  +    <h2><a id="dot921">To upgrade from v0.9.14 - v0.9.21</a></h2>
          298  +
          299  +    <p>A new table was added to support layering. For MySQL, the SQL is:</p>
          300  +
          301  +    <pre>
          302  +CREATE TABLE webcal_user_layers (
          303  +  cal_login varchar(25) NOT NULL,
          304  +  cal_layeruser varchar(25) NOT NULL,
          305  +  cal_color varchar(25) NULL,
          306  +  cal_dups CHAR(1) DEFAULT 'N',
          307  +  cal_layerid INT DEFAULT '0' NOT NULL,
          308  +  PRIMARY KEY ( cal_login, cal_layeruser )
          309  +);
          310  +    </pre>
          311  +
          312  +    <a href="UPGRADING.html#dot926">next...</a>
          313  +    <hr />
          314  +
          315  +    <h2><a id="dot926">To upgrade from v0.9.22 - v0.9.26</a></h2>
          316  +
          317  +    <p>Two new tables were added for custom event fields and reminders.
          318  +    For MySQL the SQL is:</p>
          319  +
          320  +    <pre>
          321  +CREATE TABLE webcal_site_extras (
          322  +  cal_id INT DEFAULT '0' NOT NULL,
          323  +  cal_name VARCHAR(25) NOT NULL,
          324  +  cal_type INT NOT NULL,
          325  +  cal_date INT DEFAULT '0',
          326  +  cal_remind INT DEFAULT '0',
          327  +  cal_data TEXT,
          328  +  PRIMARY KEY ( cal_id, cal_name, cal_type )
          329  +);
          330  +CREATE TABLE webcal_reminder_log (
          331  +  cal_id INT DEFAULT '0' NOT NULL,
          332  +  cal_name VARCHAR(25) NOT NULL,
          333  +  cal_event_date INT NOT NULL DEFAULT 0,
          334  +  cal_last_sent INT NOT NULL DEFAULT 0,
          335  +  PRIMARY KEY ( cal_id, cal_name, cal_event_date )
          336  +);
          337  +    </pre>
          338  +
          339  +    <p>You will also need to setup the tools/send_reminders.php script to be run
          340  +    periodically. I would recommend once an hour. For Linux/UNIX, this is
          341  +    simple. Just use cron and add a line to your crontab file that looks like:</p>
          342  +
          343  +    <pre>1 * * * * cd /some/directory/webcalendar/tools; ./send_reminders.php</pre>
          344  +
          345  +    <p>This will tell cron to run the script at one minute after the hour.
          346  +    Windows users will have to find another way to run the script. There are
          347  +    ports/look-a-likes of cron for Windows, so look around.</p>
          348  +
          349  +    <a href="UPGRADING.html#dot934">next...</a>
          350  +    <hr />
          351  +
          352  +    <h2><a id="dot934">To upgrade from v0.9.27 - v0.9.34</a></h2>
          353  +
          354  +    <p>Six new tables were added for group support, views, system settings and
          355  +    activity logs. For MySQL the SQL is:</p>
          356  +
          357  +    <pre>
          358  +CREATE TABLE webcal_group (
          359  +  cal_group_id INT NOT NULL,
          360  +  cal_last_update INT NOT NULL,
          361  +  cal_name VARCHAR(50) NOT NULL,
          362  +  cal_owner VARCHAR(25) NULL,
          363  +  PRIMARY KEY ( cal_group_id )
          364  +);
          365  +CREATE TABLE webcal_group_user (
          366  +  cal_group_id INT NOT NULL,
          367  +  cal_login VARCHAR(25) NOT NULL,
          368  +  PRIMARY KEY ( cal_group_id, cal_login )
          369  +);
          370  +CREATE TABLE webcal_view (
          371  +  cal_view_id INT NOT NULL,
          372  +  cal_name VARCHAR(50) NOT NULL,
          373  +  cal_owner VARCHAR(25) NOT NULL,
          374  +  cal_view_type CHAR(1),
          375  +  PRIMARY KEY ( cal_view_id )
          376  +);
          377  +CREATE TABLE webcal_view_user (
          378  +  cal_view_id INT NOT NULL,
          379  +  cal_login VARCHAR(25) NOT NULL,
          380  +  PRIMARY KEY ( cal_view_id, cal_login )
          381  +);
          382  +CREATE TABLE webcal_config (
          383  +  cal_setting VARCHAR(50) NOT NULL,
          384  +  cal_value VARCHAR(50) NULL,
          385  +  PRIMARY KEY ( cal_setting )
          386  +);
          387  +CREATE TABLE webcal_entry_log (
          388  +  cal_log_id INT NOT NULL,
          389  +  cal_date INT NOT NULL,
          390  +  cal_entry_id INT NOT NULL,
          391  +  cal_login VARCHAR(25) NOT NULL,
          392  +  cal_time INT NULL,
          393  +  cal_type CHAR(1) NOT NULL,
          394  +  cal_text TEXT,
          395  +  PRIMARY KEY ( cal_log_id )
          396  +);
          397  +    </pre>
          398  +
          399  +    <a href="UPGRADING.html#dot936">next...</a>
          400  +    <hr />
          401  +
          402  +    <h2><a id="dot936">To upgrade from v0.9.35 or v0.9.36</a></h2>
          403  +
          404  +    <p>The webcal_entry_log table was modified, and a new table
          405  +webcal_entry_repeats_not was created. Use the following SQL for MySQL:</p>
          406  +
          407  +    <pre>
          408  +ALTER TABLE webcal_entry_log ADD cal_user_cal VARCHAR(25);
          409  +CREATE TABLE webcal_entry_repeats_not (
          410  +  cal_id INT NOT NULL,
          411  +  cal_date INT NOT NULL,
          412  +  PRIMARY KEY ( cal_id, cal_date )
          413  +);
          414  +    </pre>
          415  +
          416  +    <a href="UPGRADING.html#dot937">next...</a>
          417  +    <hr />
          418  +
          419  +    <h2><a id="dot937">To upgrade from v0.9.37</a></h2>
          420  +
          421  +    <p>The webcal_entry_user table was modified, and a new table
          422  +    webcal_categories was created. Use the following SQL for MySQL:</p>
          423  +
          424  +    <pre>
          425  +ALTER TABLE webcal_entry_user ADD cal_category INT DEFAULT NULL;
          426  +CREATE TABLE webcal_categories (
          427  +  cat_id INT NOT NULL,
          428  +  cat_name VARCHAR(80) NOT NULL,
          429  +  cat_owner VARCHAR(25),
          430  +  PRIMARY KEY ( cat_id )
          431  +);
          432  +    </pre>
          433  +
          434  +    <a href="UPGRADING.html#dot938">next...</a>
          435  +    <hr />
          436  +
          437  +    <h2><a id="dot938">To upgrade from v0.9.38</a></h2>
          438  +
          439  +    <p>The names of the date settings in the database were modified. All old
          440  +    data settings need to be removed from the database.</p>
          441  +
          442  +    <pre>
          443  +DELETE FROM webcal_config WHERE cal_setting LIKE 'DATE_FORMAT%';
          444  +DELETE FROM webcal_user_pref WHERE cal_setting LIKE 'DATE_FORMAT%';
          445  +    </pre>
          446  +
          447  +    <a href="UPGRADING.html#dot939">next...</a>
          448  +    <hr />
          449  +
          450  +    <h2><a id="dot939">To upgrade from v0.9.39</a></h2>
          451  +
          452  +    <p>Two new tables were created: webcal_asst and webcal_entry_ext_user.
          453  +    And the column cal_ext_for_id was added to the webcal_entry table. Use the
          454  +    following SQL for MySQL:</p>
          455  +
          456  +    <pre>
          457  +CREATE TABLE webcal_asst (
          458  +  cal_boss VARCHAR(25) NOT NULL,
          459  +  cal_assistant VARCHAR(25) NOT NULL,
          460  +  PRIMARY KEY ( cal_boss, cal_assistant )
          461  +);
          462  +CREATE TABLE webcal_entry_ext_user (
          463  +  cal_id INT DEFAULT 0 NOT NULL,
          464  +  cal_fullname VARCHAR(50) NOT NULL,
          465  +  cal_email VARCHAR(75) NULL,
          466  +  PRIMARY KEY ( cal_id, cal_fullname )
          467  +);
          468  +ALTER TABLE webcal_entry ADD cal_ext_for_id INT NULL;
          469  +    </pre>
          470  +
          471  +    <a href="UPGRADING.html#dot940">next...</a>
          472  +    <hr />
          473  +
          474  +    <h2><a id="dot940">To upgrade from v0.9.40</a></h2>
          475  +
          476  +    <p>One new table was added: webcal_nonuser_cals. Use the following SQL for
          477  +    MySQL:</p>
          478  +
          479  +    <pre>
          480  +CREATE TABLE webcal_nonuser_cals (
          481  +  cal_login VARCHAR(25) NOT NULL,
          482  +  cal_admin VARCHAR(25) NOT NULL,
          483  +  cal_firstname VARCHAR(25),
          484  +  cal_lastname VARCHAR(25),
          485  +  PRIMARY KEY ( cal_login )
          486  +);
          487  +    </pre>
          488  +
          489  +    <a href="UPGRADING.html#dot941">next...</a>
          490  +    <hr />
          491  +
          492  +    <h2><a id="dot941">To upgrade from v0.9.41</a></h2>
          493  +
          494  +    <p>Three new tables were added: webcal_report, webcal_report_template, and
          495  +    webcal_import_data. Use the following SQL for MySQL:</p>
          496  +
          497  +    <pre>
          498  +CREATE TABLE webcal_report (
          499  +  cal_report_id INT NOT NULL,
          500  +  cal_allow_nav CHAR(1) DEFAULT 'Y',
          501  +  cal_cat_id INT NULL,
          502  +  cal_include_empty CHAR(1) DEFAULT 'N',
          503  +  cal_include_header CHAR(1) DEFAULT 'Y' NOT NULL,
          504  +  cal_is_global CHAR(1) DEFAULT 'N' NOT NULL,
          505  +  cal_login VARCHAR(25) NOT NULL,
          506  +  cal_report_name VARCHAR(50) NOT NULL,
          507  +  cal_report_type VARCHAR(20) NOT NULL,
          508  +  cal_show_in_trailer CHAR(1) DEFAULT 'N',
          509  +  cal_time_range INT NOT NULL,
          510  +  cal_update_date INT NOT NULL,
          511  +  cal_user VARCHAR(25) NULL,
          512  +  PRIMARY KEY ( cal_report_id )
          513  +);
          514  +CREATE TABLE webcal_report_template (
          515  +  cal_report_id INT NOT NULL,
          516  +  cal_template_type CHAR(1) NOT NULL,
          517  +  cal_template_text TEXT,
          518  +  PRIMARY KEY ( cal_report_id, cal_template_type )
          519  +);
          520  +CREATE TABLE webcal_import_data (
          521  +  cal_id int NOT NULL,
          522  +  cal_login VARCHAR(25) NOT NULL,
          523  +  cal_external_id VARCHAR(200) NULL,
          524  +  cal_import_type VARCHAR(15) NOT NULL,
          525  +  PRIMARY KEY  ( cal_id, cal_login )
          526  +);
          527  +    </pre>
          528  +
          529  +    <a href="UPGRADING.html#dot942">next...</a>
          530  +    <hr />
          531  +
          532  +    <h2><a id="dot942">To upgrade from v0.9.42</a></h2>
          533  +
          534  +    <p>User passwords are now stored using md5 and require the webcal_user table
          535  +    to be altered to accommodate larger password data. Use the following SQL
          536  +    for MySQL:</p>
          537  +
          538  +    <pre>
          539  +ALTER TABLE webcal_user MODIFY cal_passwd VARCHAR(32) NULL;
          540  +DROP TABLE webcal_import_data;
          541  +CREATE TABLE webcal_import (
          542  +  cal_import_id INT NOT NULL,
          543  +  cal_date INT NOT NULL,
          544  +  cal_login VARCHAR(25) NULL,
          545  +  cal_name VARCHAR(50) NULL,
          546  +  cal_type VARCHAR(10) NOT NULL,
          547  +  PRIMARY KEY ( cal_import_id )
          548  +);
          549  +CREATE TABLE webcal_import_data (
          550  +  cal_id INT NOT NULL,
          551  +  cal_login VARCHAR(25) NOT NULL,
          552  +  cal_external_id VARCHAR(200) NULL,
          553  +  cal_import_id INT NOT NULL,
          554  +  cal_import_type VARCHAR(15) NOT NULL,
          555  +  PRIMARY KEY  ( cal_id, cal_login )
          556  +);
          557  +    </pre>
          558  +
          559  +    <p>Next, you will need to run the script found in the <tt>tools</tt>
          560  +    subdirectory. This will convert all your passwords from plain text to md5.
          561  +    You can run this from the command line (if you have a standalone version of
          562  +    PHP compiled):</p>
          563  +
          564  +    <pre>
          565  +cd tools
          566  +php convert_passwords.php
          567  +    </pre>
          568  +
          569  +    <p>Or, if you do not have a standalone version of PHP, you can just type in
          570  +    the URL to access the script in your browser:</p>
          571  +
          572  +    <pre>http://yourcalendarurl/tools/convert_passwords.php</pre>
          573  +
          574  +    <p>You may safely delete the file <tt>/tools/convert_passwords.php</tt>
          575  +    after successfully performing this step.</p>
          576  +
          577  +    <p>Delete all webcalendar_login browser cookies. Details should be available
          578  +    on your local browser help section.</p>
          579  +
          580  +    <a href="UPGRADING.html#from_1_0RC2">next...</a>
          581  +    <hr />
          582  +
          583  +    <h2><a id="from_1_0RC2">To upgrade from v0.9.43 - v1.0RC2</a></h2>
          584  +
          585  +    <p>The <tt>webcal_view</tt> table was modified. Execute the following SQL
          586  +    to update your database:</p>
          587  +
          588  +    <pre>
          589  +UPDATE webcal_config SET cal_value = 'week.php' WHERE cal_setting = 'STARTVIEW';
          590  +UPDATE webcal_user_pref SET cal_value = 'day.php'
          591  +  WHERE cal_value = 'day' AND cal_setting = 'STARTVIEW';
          592  +UPDATE webcal_user_pref SET cal_value = 'month.php'
          593  +  WHERE cal_value = 'month' AND cal_setting = 'STARTVIEW';
          594  +UPDATE webcal_user_pref SET cal_value = 'week.php'
          595  +  WHERE cal_value = 'week' AND cal_setting = 'STARTVIEW';
          596  +UPDATE webcal_user_pref SET cal_value = 'year.php'
          597  +  WHERE cal_value = 'year' AND cal_setting = 'STARTVIEW';
          598  +ALTER TABLE webcal_view ADD cal_is_global CHAR(1) NOT NULL DEFAULT 'N';
          599  +UPDATE webcal_view SET cal_is_global = 'N';
          600  +    </pre>
          601  +
          602  +    <a href="UPGRADING.html#from_1.0.0">next...</a>
          603  +    <hr />
          604  +
          605  +    <h2><a id="from_1.0.0">To upgrade from v1.0RC3 - v1.0.0</a></h2>
          606  +
          607  +    <p>Two new tables need to be created to support advanced user access control.
          608  +    One new table is needed to store custom user header/footer template
          609  +    information. Execute the following SQL to update your database:</p>
          610  +
          611  +    <pre>
          612  +CREATE TABLE webcal_access_user (
          613  +  cal_login VARCHAR(25) NOT NULL,
          614  +  cal_other_user VARCHAR(25) NOT NULL,
          615  +  cal_can_approve CHAR(1) NOT NULL DEFAULT 'N',
          616  +  cal_can_delete CHAR(1) NOT NULL DEFAULT 'N',
          617  +  cal_can_edit CHAR(1) NOT NULL DEFAULT 'N',
          618  +  cal_can_view CHAR(1) NOT NULL DEFAULT 'N',
          619  +  PRIMARY KEY ( cal_login, cal_other_user )
          620  +);
          621  +CREATE TABLE webcal_access_function (
          622  +  cal_login VARCHAR(25) NOT NULL,
          623  +  cal_permissions VARCHAR(64) NOT NULL,
          624  +  PRIMARY KEY ( cal_login )
          625  +);
          626  +ALTER TABLE webcal_nonuser_cals ADD cal_is_public CHAR(1) NOT NULL DEFAULT 'N';
          627  +CREATE TABLE webcal_user_template (
          628  +  cal_login VARCHAR(25) NOT NULL,
          629  +  cal_type CHAR(1) NOT NULL,
          630  +  cal_template_text TEXT,
          631  +  PRIMARY KEY ( cal_login, cal_type )
          632  +);
          633  +    </pre>
          634  +
          635  +    <hr />
          636  +
          637  +    <h2><a id="from_1.1.0a-CVS">To upgrade from v1.1.0-CVS or v1.1.0a-CVS</a></h2>
          638  +
          639  +    <p>A new table is needed to support multiple categories. In addition,
          640  +    several new columns have been added to webcal_entry and one column added to
          641  +    webcal_entry_user to support VTODO tasks, and to webcal_repeats to support
          642  +    the much improved ical support. A new column was added to
          643  +    webcal_entry_repeats_not to differentiate between exclusion and inclusions.
          644  +    Use the following SQL to update your MySQL database:</p>
          645  +
          646  +    <pre>
          647  +ALTER TABLE webcal_entry ADD cal_due_date int(11) default NULL;
          648  +ALTER TABLE webcal_entry ADD cal_due_time int(11) default NULL;
          649  +ALTER TABLE webcal_entry ADD cal_location varchar(50) default NULL;
          650  +ALTER TABLE webcal_entry ADD cal_url varchar(100) default NULL;
          651  +ALTER TABLE webcal_entry ADD cal_completed int(11) default NULL;
          652  +ALTER TABLE webcal_entry_repeats ADD cal_endtime int(11) default NULL;
          653  +ALTER TABLE webcal_entry_repeats ADD cal_byday varchar(100) default NULL;
          654  +ALTER TABLE webcal_entry_repeats ADD cal_bymonth varchar(50) default NULL;
          655  +ALTER TABLE webcal_entry_repeats ADD cal_bymonthday varchar(100) default NULL;
          656  +ALTER TABLE webcal_entry_repeats ADD cal_bysetpos varchar(50) default NULL;
          657  +ALTER TABLE webcal_entry_repeats ADD cal_byweekno varchar(50) default NULL;
          658  +ALTER TABLE webcal_entry_repeats ADD cal_byyearday varchar(50) default NULL;
          659  +ALTER TABLE webcal_entry_repeats ADD cal_count int(11) default NULL;
          660  +ALTER TABLE webcal_entry_repeats ADD cal_wkst char(2) default 'MO';
          661  +ALTER TABLE webcal_entry_repeats_not ADD cal_exdate int(1) NOT NULL DEFAULT '1';
          662  +ALTER TABLE webcal_entry_user ADD cal_percent int(11) NOT NULL DEFAULT '0';
          663  +CREATE TABLE webcal_entry_categories (
          664  +  cal_id int(11) NOT NULL default '0',
          665  +  cat_id int(11) NOT NULL default '0',
          666  +  cat_order int(11) NOT NULL default '0',
          667  +  cat_owner varchar(25) default NULL
          668  +);
          669  +    </pre>
          670  +
          671  +    <hr />
          672  +
          673  +    <p>After you complete manually updating your database, you will still need
          674  +    to run the <a href="install/index.php">installation script</a> to perform
          675  +    any necessary data changes needed to convert existing data.</p>
          676  +
          677  +    <p><a href="http://validator.w3.org/check?uri=referer">
          678  +      <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!"
          679  +      class="valid" /></a></p>
          680  +  </body>
          681  +</html>

Added about.php.

            1  +<?php
            2  +/* $Id: about.php,v 1.16.2.3 2007/08/06 02:28:29 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +$credits = getPostValue ( 'Credits' );
            6  +$data = '';
            7  +
            8  +if ( ! empty ( $credits ) ) {
            9  +  // Get Names from AUTHORS file.
           10  +  if ( $fd = @fopen ( 'AUTHORS', 'r' ) ) {
           11  +    // Read in contents of entire file first.
           12  +    while ( ! feof ( $fd ) && empty ( $error ) ) {
           13  +      $data .= fgets ( $fd, 4096 );
           14  +    }
           15  +    fclose ( $fd );
           16  +  }
           17  +  // $data = unhtmlentities ( $data );
           18  +  $data = preg_replace ( '/<.+>+/', '', $data );
           19  +  $data = preg_replace ( "/\n\s/", '<br />&nbsp;', $data );
           20  +  $data = preg_replace ( '/\s\s+/', '&nbsp;&nbsp;', $data );
           21  +  $data = preg_replace ( '/\n/', '<br />', $data );
           22  +}
           23  +
           24  +print_header ( '', '', '', true, false, true );
           25  +echo '
           26  +    <div align="left" style="margin-left:4px; position:absolute; bottom:0">';
           27  +if ( empty ( $credits ) )
           28  +  echo '
           29  +      <a title="' . $PROGRAM_NAME . '" href="' . $PROGRAM_URL . '" target="_blank">
           30  +      <h2 style="margin:0">' . translate ( 'Title' ) . '</h2>
           31  +      <p>' . str_replace ( 'XXX', $PROGRAM_VERSION,
           32  +        // translate ( 'version' )
           33  +        translate ( 'version XXX' ) ) . '</p>
           34  +      <p>' . $PROGRAM_DATE . '</p></a>
           35  +      <p>&nbsp;</p>
           36  +      <p>' . translate ( 'WebCalendar is a PHP application used...' ) . '</p>';
           37  +else {
           38  +
           39  +  ?>
           40  +      <script language="javascript1.2" type="text/javascript">
           41  +        var
           42  +          scrollW="235px",
           43  +          scrollH="250px",
           44  +          copyS=scrollS=1,
           45  +          pauseS=0,
           46  +          scrollcontent='<?php echo $data ?>',
           47  +          actualH='',
           48  +          cross_scroll;
           49  +
           50  +        function populate (){
           51  +          cross_scroll=document.getElementById("scroller");
           52  +          cross_scroll.innerHTML=scrollcontent;
           53  +          actualH=cross_scroll.offsetHeight;
           54  +          lefttime=setInterval("scrollMe ()",30);
           55  +        }
           56  +
           57  +        window.onload=populate;
           58  +
           59  +        function scrollMe (){
           60  +          if (parseInt (cross_scroll.style.top)>(actualH* (-1)+8))
           61  +            cross_scroll.style.top=parseInt(cross_scroll.style.top)-copyS+"px";
           62  +          else
           63  +            cross_scroll.style.top=parseInt(scrollH)+8+"px";
           64  +        }
           65  +
           66  +        with (document){
           67  +          write('<div style="position:relative; width:'+scrollW+'; height: '
           68  +            + scrollH +'; overflow:hidden;" onMouseover="copyS=pauseS" '
           69  +            + 'onMouseout="copyS=scrollS"><div id="scroller"></div></div>');
           70  +        }
           71  +      </script>
           72  +<?php
           73  +}
           74  +
           75  +echo '
           76  +      <hr />
           77  +      <div align="center" style="margin:10px;">
           78  +        <form action="about.php" name="aboutform" method="post">
           79  +          <input type="submit" name=' . ( empty ( $credits )
           80  +  ? '"Credits" value="' . translate ( 'Credits' )
           81  +  : '"About" value="<< ' . translate ( 'About' ) )
           82  + . '" />' . '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
           83  +          <input type="button" name="ok" value="' . translate ( 'OK' )
           84  + . '" onclick="window.close()" />
           85  +        </form>
           86  +      </div>
           87  +    </div>
           88  +    ' . print_trailer ( false, true, true );
           89  +
           90  +?>

Added access.php.

            1  +<?php
            2  +/* $Id: access.php,v 1.53.2.7 2012/02/28 02:07:45 cknudsen Exp $
            3  + *
            4  + * This page is used to manage user access rights.
            5  + *
            6  + * It has three different modes:
            7  + * - list users to manage (no parameters)
            8  + * - manage a single user's rights (just "user" parameter)
            9  + *   this will include which functions the user can access and
           10  + *   (if $ALLOW_VIEW_OTHER is 'Y') which calendars thay can view/edit/approve
           11  + * - update the database (form handler)
           12  + *
           13  + * Input Parameters:
           14  + *  user - specifies which user to manage, a form will be presented
           15  + *         that allows editing rights of this user
           16  + *
           17  + *  access_N - where N is 0 to ACCESS_NUMBER_FUNCTIONS as defined in
           18  + *             includes/access.php. Each should be either 'Y' or 'N'.
           19  + */
           20  +include_once 'includes/init.php';
           21  +require_valide_referring_url ();
           22  +
           23  +$allow_view_other =
           24  +( ! empty ( $ALLOW_VIEW_OTHER ) && $ALLOW_VIEW_OTHER == 'Y' );
           25  +
           26  +if ( ! access_is_enabled () ) {
           27  +  echo print_not_auth (1);
           28  +  exit;
           29  +}
           30  +// translate ( 'Database error' )
           31  +$dbErrStr = translate ( 'Database error XXX.' );
           32  +$defConfigStr = translate ( 'DEFAULT CONFIGURATION' );
           33  +$goStr = '
           34  +      </select>
           35  +      <input type="submit" value="' . translate ( 'Go' ) . '" />
           36  +    </form>';
           37  +$saveStr = translate ( 'Save' );
           38  +$undoStr = translate ( 'Undo' );
           39  +
           40  +$saved = '';
           41  +
           42  +// Are we handling the access form?
           43  +// If so, do that, then redirect.
           44  +// Handle function access first.
           45  +if ( getPostValue ( 'auser' ) != '' &&
           46  +    getPostValue ( 'submit' ) == $saveStr ) {
           47  +  $auser = getPostValue ( 'auser' );
           48  +  $perm = '';
           49  +  for ( $i = 0; $i < ACCESS_NUMBER_FUNCTIONS; $i++ ) {
           50  +    $perm .= ( getPostValue ( 'access_' . $i ) == 'Y' ? 'Y' : 'N' );
           51  +  }
           52  +
           53  +  dbi_execute ( 'DELETE FROM webcal_access_function WHERE cal_login = ?',
           54  +    array ( $auser ) );
           55  +
           56  +  if ( ! dbi_execute ( 'INSERT INTO webcal_access_function ( cal_login,
           57  +      cal_permissions ) VALUES ( ?, ? )', array ( $auser, $perm ) ) )
           58  +    die_miserable_death ( str_replace ( 'XXX', dbi_error (), $dbErrStr ) );
           59  +  $saved = true;
           60  +}
           61  +
           62  +// Are we handling the other user form?  If so, do that, then redirect.
           63  +if ( getPostValue ( 'otheruser' ) != '' &&
           64  +    getPostValue ( 'submit' ) == $saveStr ) {
           65  +  $puser = getPostValue ( 'guser' );
           66  +  $pouser = getPostValue ( 'otheruser' );
           67  +
           68  +  if ( $allow_view_other ) {
           69  +    // Handle access to other users' calendars.
           70  +    // If user is not admin,
           71  +    // reverse values so they are granting access to their own calendar.
           72  +    if ( ! $is_admin )
           73  +      list ( $puser, $pouser ) = array ( $pouser, $puser );
           74  +
           75  +    dbi_execute ( 'DELETE FROM webcal_access_user WHERE cal_login = ?
           76  +      AND cal_other_user = ?', array ( $puser, $pouser ) );
           77  +
           78  +    if ( empty ( $pouser ) )
           79  +      break;
           80  +    $approve_total = $edit_total = $view_total = 0;
           81  +    for ( $i = 1; $i <= 256; ) {
           82  +      $approve_total += getPostValue ( 'a_' . $i );
           83  +      $edit_total += getPostValue ( 'e_' . $i );
           84  +      $view_total += getPostValue ( 'v_' . $i );
           85  +      $i += $i;
           86  +    }
           87  +
           88  +    $email = getPostValue ( 'email' );
           89  +    $invite = getPostValue ( 'invite' );
           90  +    $time = getPostValue ( 'time' );
           91  +
           92  +    if ( ! dbi_execute ( 'INSERT INTO webcal_access_user ( cal_login,
           93  +      cal_other_user, cal_can_view, cal_can_edit, cal_can_approve,
           94  +      cal_can_invite, cal_can_email, cal_see_time_only )
           95  +      VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )',
           96  +        array (
           97  +          $puser,
           98  +          $pouser,
           99  +          ( $view_total > 0 ? $view_total : 0 ),
          100  +          ( $edit_total > 0 && $puser != '__public__' ? $edit_total : 0 ),
          101  +          ( $approve_total > 0 && $puser != '__public__' ? $approve_total : 0 ),
          102  +          ( strlen ( $invite ) ? $invite : 'N' ),
          103  +          ( strlen ( $email ) ? $email : 'N' ),
          104  +          ( strlen ( $time ) ? $time : 'N' ) ) ) ) {
          105  +      die_miserable_death ( str_replace ( 'XXX', dbi_error (), $dbErrStr ) );
          106  +    }
          107  +    $saved = true;
          108  +  }
          109  +}
          110  +$checked = ' checked="checked"';
          111  +$guser = getPostValue ( 'guser' );
          112  +$selected = ' selected="selected"';
          113  +
          114  +//if ( $guser == '__default__' ) {
          115  +//  $otheruser = $guser;
          116  +//  $user_fullname = $defConfigStr;
          117  +//} else
          118  +  $otheruser = getPostValue ( 'otheruser' );
          119  +
          120  +if ( $otheruser == '__default__' ) {
          121  +  $otheruser_fullname = $defConfigStr;
          122  +  $otheruser_login = '__default__';
          123  +} elseif ( $otheruser == '__public__' ) {
          124  +  $otheruser_fullname = translate ( 'Public Access' );
          125  +  $otheruser_login = '__public__';
          126  +}
          127  +if ( ! empty ( $otheruser ) ) {
          128  +  if ( $allow_view_other ) {
          129  +    user_load_variables ( $otheruser, 'otheruser_' );
          130  +    // Turn off admin override so we see the users own settings.
          131  +    $ADMIN_OVERRIDE_UAC = 'N';
          132  +    // Now load all the data from webcal_access_user.
          133  +    $allPermissions = access_load_user_permissions ( false );
          134  +    // Load default-default values if exist.
          135  +    if ( ! empty ( $allPermissions['__default__.__default__'] ) )
          136  +      $op = $allPermissions['__default__.__default__'];
          137  +
          138  +    if ( $is_admin ) {
          139  +      // Load user-default values if exist.
          140  +      if ( ! empty ( $allPermissions[ $guser . '.__default__' ] ) )
          141  +        $op = $allPermissions[ $guser . '.__default__' ];
          142  +      // Load user-otheruser values if exist.
          143  +      if ( ! empty ( $allPermissions[ $guser . '.' . $otheruser ] ) )
          144  +        $op = $allPermissions[ $guser . '.' . $otheruser ];
          145  +    } else {
          146  +      // Load defualt-user values if exist.
          147  +      if ( ! empty ( $allPermissions['__default__.' . $guser] ) )
          148  +        $op = $allPermissions['__default__.' . $guser ];
          149  +      // Load otheruser-user values if exist.
          150  +      if ( ! empty ( $allPermissions[$otheruser . '.' . $guser] ) )
          151  +        $op = $allPermissions[$otheruser . '.' . $guser];
          152  +    }
          153  +  }
          154  +}
          155  +print_header ( '', '',
          156  +  ( ! empty ( $op['time'] ) && $op['time'] == 'Y'
          157  +    ? 'onload="enableAll( true );"' : '' ) );
          158  +
          159  +echo print_success ( $saved );
          160  +
          161  +if ( ! empty ( $guser ) && $is_admin )
          162  +  user_load_variables ( $guser, 'user_' );
          163  +
          164  +ob_start ();
          165  +
          166  +if ( $is_admin ) {
          167  +  $adminStr = translate ( 'Admin' );
          168  +  $userlist = get_my_users ();
          169  +  $nonuserlist = get_nonuser_cals ();
          170  +
          171  +  // If we are here... we must need to print out a list of users.
          172  +  echo '
          173  +    <h2>' . translate ( 'User Access Control' )
          174  +   . ( ! empty ( $user_fullname ) ? ': ' . $user_fullname : '' ) . '</h2>
          175  +    ' . display_admin_link ( false ) . '
          176  +    <form action="access.php" method="post" name="SelectUser">
          177  +      <select name="guser" onchange="document.SelectUser.submit()">'
          178  +  // Add a DEFAULT CONFIGURATION to be used as a mask.
          179  +  . '
          180  +        <option value="__default__"'
          181  +   . ( $guser == '__default__' ? $selected : '' )
          182  +   . '>' . $defConfigStr . '</option>';
          183  +  for ( $i = 0, $cnt = count ( $userlist ); $i < $cnt; $i++ ) {
          184  +    echo '
          185  +        <option value="' . $userlist[$i]['cal_login'] . '"'
          186  +     . ( $guser == $userlist[$i]['cal_login'] ? $selected : '' )
          187  +     . '>' . $userlist[$i]['cal_fullname'] . '</option>';
          188  +  }
          189  +  for ( $i = 0, $cnt = count ( $nonuserlist ); $i < $cnt; $i++ ) {
          190  +    echo '
          191  +        <option value="' . $nonuserlist[$i]['cal_login'] . '"'
          192  +     . ( $guser == $nonuserlist[$i]['cal_login'] ? $selected : '' )
          193  +     . '>' . $nonuserlist[$i]['cal_fullname'] . ' '
          194  +     . ( $nonuserlist[$i]['cal_is_public'] == 'Y' ? '*' : '' ) . '</option>';
          195  +  }
          196  +
          197  +  echo $goStr;
          198  +} //end admin $guser != default test
          199  +
          200  +if ( ! empty ( $guser ) || ! $is_admin ) {
          201  +  if ( $is_admin ) {
          202  +    // Present a page to allow editing a user's rights.
          203  +    $access = access_load_user_functions ( $guser );
          204  +    $div = ceil ( ACCESS_NUMBER_FUNCTIONS / 4 );
          205  +
          206  +    // We can reorder the display of user rights here.
          207  +    $order = array (
          208  +      1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 27,
          209  +      15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 );
          210  +    // Make sure that we have defined all the types of
          211  +    // access defined in access.php
          212  +    assert ( count($order) == ACCESS_NUMBER_FUNCTIONS +1 );
          213  +
          214  +    echo '
          215  +    <div class="boxall" style="margin-top: 5px; padding: 5px;">
          216  +      <form action="access.php" method="post" name="accessform">
          217  +        <input type="hidden" name="auser" value="' . $guser . '" />
          218  +        <input type="hidden" name="guser" value="' . $guser . '" />
          219  +        <table border="0" cellspacing="10">
          220  +          <tbody>
          221  +            <tr>
          222  +              <td valign="top">';
          223  +
          224  +    for ( $i = 0; $i < ACCESS_NUMBER_FUNCTIONS; $i++ ) {
          225  +      // Public access and NUCs can never use some of these functions.
          226  +      $show = true;
          227  +      if ( $guser == '__public__' ||
          228  +        substr ( $guser, 0, 5 ) == $NONUSER_PREFIX ) {
          229  +        switch ( $order[$i] ) {
          230  +          case ACCESS_ACCESS_MANAGEMENT:
          231  +          case ACCESS_ACCOUNT_INFO:
          232  +          case ACCESS_ACTIVITY_LOG:
          233  +          case ACCESS_ADMIN_HOME:
          234  +          case ACCESS_ASSISTANTS:
          235  +          case ACCESS_CATEGORY_MANAGEMENT:
          236  +          case ACCESS_IMPORT:
          237  +          case ACCESS_PREFERENCES:
          238  +          case ACCESS_SYSTEM_SETTINGS:
          239  +          case ACCESS_USER_MANAGEMENT:
          240  +          case ACCESS_VIEW_MANAGEMENT:
          241  +          case ACCESS_SECURITY_AUDIT:
          242  +            // Skip these...
          243  +            $show = false;
          244  +            break;
          245  +        }
          246  +      }
          247  +      if ( $show )
          248  +        echo print_checkbox ( array ( 'access_' . $order[$i], 'Y',
          249  +            access_get_function_description ( $order[$i] ),
          250  +            substr ( $access, $order[$i], 1 ) ), 'dito' ) . '<br />';
          251  +
          252  +      if ( ( $i + 1 ) % $div == 0 )
          253  +        echo '
          254  +              </td>
          255  +              <td valign="top">';
          256  +    }
          257  +
          258  +    echo '
          259  +              </td>
          260  +            </tr>
          261  +          </tbody>
          262  +        </table>
          263  +        <input type="submit" value="' . $undoStr . '" />
          264  +        <input type="submit" name="submit" value="' . $saveStr . '" />
          265  +      </form>
          266  +    </div>';
          267  +
          268  +    $pagetitle = translate ( 'Allow Access to Other Users Calendar' );
          269  +  } else {
          270  +    // Get list of users that this user can see (may depend on group settings)
          271  +    // along with all nonuser calendars.
          272  +    // if ( $guser != '__default__' ) {
          273  +    $guser = $login;
          274  +    $pagetitle = translate ( 'Grant This User Access to My Calendar' );
          275  +  }
          276  +
          277  +//  if ( $guser == '__default__' ) {
          278  +//    $userlist = array ( '__default__' );
          279  +//    $otheruser = $otheruser_login = '__default__';
          280  + //   $otheruser_fullname = $defConfigStr;
          281  +//  } else
          282  +  if ( $allow_view_other ) {
          283  +    $userlist = get_list_of_users ( $guser );
          284  +    echo '
          285  +    <h2 style="margin-bottom: 2px;">' . $pagetitle . '</h2>
          286  +    <form action="access.php" method="post" name="SelectOther">
          287  +      <input type="hidden" name="guser" value="' . $guser . '" />
          288  +      <select name="otheruser" onchange="document.SelectOther.submit()">'
          289  +    // Add a DEFAULT CONFIGURATION to be used as a mask.
          290  +    . '
          291  +        <option value="__default__"'
          292  +     . ( $otheruser == '__default__' ? $selected : '' )
          293  +     . '>' . $defConfigStr . '</option>';
          294  +
          295  +    for ( $i = 0, $cnt = count ( $userlist ); $i < $cnt; $i++ ) {
          296  +      if ( $userlist[$i]['cal_login'] != $guser )
          297  +        echo '
          298  +        <option value="' . $userlist[$i]['cal_login'] . '"'
          299  +         . ( ! empty ( $otheruser ) && $otheruser == $userlist[$i]['cal_login']
          300  +          ? $selected : '' )
          301  +         . '>' . $userlist[$i]['cal_fullname'] . '</option>';
          302  +    }
          303  +    echo $goStr;
          304  +  }
          305  +}
          306  +
          307  +if ( ! empty ( $otheruser ) ) {
          308  +  if ( $allow_view_other ) {
          309  +    $typeStr = translate ( 'Type' );
          310  +    echo '
          311  +    <form action="access.php" method="post" name="EditOther">
          312  +      <input type="hidden" name="guser" value="' . $guser . '" />
          313  +      <input type="hidden" name="otheruser" value="' . $otheruser . '" /><br />
          314  +      <table cellpadding="5" cellspacing="0">
          315  +        <tbody>
          316  +          <tr>
          317  +            <th class="boxleft boxtop boxbottom" width='
          318  +     . ( $guser == '__public__'
          319  +      ? '"60%" align="center">' . translate ( 'Calendar' ) . '</th>
          320  +            <th class="boxtop boxbottom" width="20%">' . $typeStr . '</th>
          321  +            <th class="boxtop boxbottom boxright" colspan="3" width="20%">'
          322  +       . translate ( 'View Event' )
          323  +      : '"25%">' . $otheruser_fullname . '</th>
          324  +            <th class="boxtop boxbottom" width="15%">' . $typeStr . '</th>
          325  +            <th width="15%" colspan="3" class="boxtop boxbottom">'
          326  +       . translate ( 'View' ) . '</th>
          327  +            <th width="15%" colspan="3" class="boxtop boxbottom">'
          328  +       . translate ( 'Edit' ) . '</th>
          329  +            <th width="15%" colspan="3" class="boxtop boxright boxbottom">'
          330  +       . translate ( 'Approve/Reject' ) ) . '</th>
          331  +          </tr>';
          332  +
          333  +    $access_type = array (
          334  +      '',
          335  +      translate ( 'Events' ),
          336  +      translate ( 'Tasks' ),
          337  +      '',
          338  +      translate ( 'Journals' )
          339  +      );
          340  +
          341  +    for ( $j = 1; $j < 5; $j++ ) {
          342  +      $bottomedge = '';
          343  +      if ( $j == 3 )
          344  +        continue;
          345  +      echo '
          346  +          <tr>
          347  +            <td class="boxleft leftpadded' . ( $j > 3 ? ' boxbottom' : '' )
          348  +       . '"><input type="checkbox" value="Y" name=';
          349  +      if ( $j == 1 )
          350  +        echo '"invite"'
          351  +         . ( ! empty ( $op['invite'] ) && $op['invite'] == 'N' ? '' : $checked )
          352  +         . ' />' . translate ( 'Can Invite' );
          353  +      elseif ( $j == 2 )
          354  +        echo '"email"'
          355  +         . ( ! empty ( $op['email'] ) && $op['email'] == 'N' ? '' : $checked )
          356  +         . ' />' . translate ( 'Can Email' );
          357  +      else {
          358  +        echo '"time"'
          359  +         . ( ! empty ( $op['time'] ) && $op['time'] == 'Y' ? $checked : '' )
          360  +         . ' onclick="enableAll( this.checked );" />'
          361  +         . translate ( 'Can See Time Only' );
          362  +        $bottomedge = 'boxbottom';
          363  +      }
          364  +      echo '</td>
          365  +            <td align="center" class="boxleft ' . $bottomedge . '">'
          366  +       . $access_type[$j] . '</td>
          367  +            <td align="center" class="boxleft pub ' . $bottomedge . '">'
          368  +       . '<input type="checkbox" value="' . $j . '" name="v_' . $j . '"'
          369  +       . ( ! empty ( $op['view'] ) && ( $op['view'] & $j ) ? $checked : '' )
          370  +       . ' /></td>
          371  +            <td class="conf ' . $bottomedge . '"><input type="checkbox" value="'
          372  +       . $j * 8 . '" name="v_' . $j * 8 . '"'
          373  +       . ( ! empty ( $op['view'] ) && ( $op['view'] & ( $j * 8 ) )
          374  +        ? $checked : '' ) . ' /></td>
          375  +            <td class="priv ' . $bottomedge . '"><input type="checkbox" value="'
          376  +       . $j * 64 . '" name="v_' . $j * 64 . '"'
          377  +       . ( ! empty ( $op['view'] ) && ( $op['view'] & ( $j * 64 ) )
          378  +        ? $checked : '' ) . ' /></td>'
          379  +       . ( $guser != '__public__' ? '
          380  +            <td align="center" class="boxleft pub ' . $bottomedge . '"><input '
          381  +         . 'type="checkbox" value="' . $j . '" name="e_' . $j . '"'
          382  +         . ( ! empty ( $op['edit'] ) && ( $op['edit'] & $j ) ? $checked : '' )
          383  +         . ' /></td>
          384  +            <td class="conf ' . $bottomedge . '"><input type="checkbox" value="'
          385  +         . $j * 8 . '" name="e_' . $j * 8 . '"'
          386  +         . ( ! empty ( $op['edit'] ) && ( $op['edit'] & ( $j * 8 ) )
          387  +          ? $checked : '' ) . ' /></td>
          388  +            <td class="priv ' . $bottomedge . '"><input type="checkbox" value="'
          389  +         . $j * 64 . '" name="e_' . $j * 64 . '"'
          390  +         . ( ! empty ( $op['edit'] ) && ( $op['edit'] & ( $j * 64 ) )
          391  +          ? $checked : '' ) . ' /></td>
          392  +            <td align="center" class="boxleft pub ' . $bottomedge . '"><input '
          393  +         . 'type="checkbox" value="' . $j . '" name="a_' . $j . '"'
          394  +         . ( ! empty ( $op['approve'] ) && ( $op['approve'] & $j )
          395  +          ? $checked : '' ) . ' /></td>
          396  +            <td class="conf ' . $bottomedge . '"><input type="checkbox" value="'
          397  +         . $j * 8 . '" name="a_' . $j * 8 . '"'
          398  +         . ( ! empty ( $op['approve'] ) && ( $op['approve'] & ( $j * 8 ) )
          399  +          ? $checked : '' ) . ' /></td>
          400  +            <td class="boxright priv ' . $bottomedge
          401  +         . '"><input type="checkbox" value="' . $j * 64 . '" name="a_' . $j * 64
          402  +         . '"' . ( ! empty ( $op['approve'] ) && ( $op['approve'] & ( $j * 64 ) )
          403  +          ? $checked : '' ) . ' /></td>'
          404  +        : '' ) . '
          405  +          </tr>';
          406  +    }
          407  +    echo '
          408  +          <tr>
          409  +            <td colspan="2" class="boxleft alignright">'
          410  +     . ( $otheruser != '__default__' && $otheruser != '__public__' ? '
          411  +              <input type="button" value="' . translate ( 'Assistant' )
          412  +       . '" onclick="selectAll(63);" />&nbsp;&nbsp;' : '' ) . '
          413  +              <input type="button" value="' . translate ( 'Select All' )
          414  +     . '" onclick="selectAll(256);" />&nbsp;&nbsp;
          415  +              <input type="button" value="' . translate ( 'Clear All' )
          416  +     . '" onclick="selectAll(0);" />
          417  +            </td>
          418  +            <td colspan="9" class="boxright">
          419  +              <table border="0" align="center" cellpadding="5" cellspacing="2">
          420  +                <tr>
          421  +                  <td class="pub">' . translate ( 'Public' ) . '</td>
          422  +                  <td class="conf">' . translate ( 'Confidential' ) . '</td>
          423  +                  <td class="priv">' . translate ( 'Private' ) . '</td>
          424  +                </tr>
          425  +              </table>
          426  +            </td>
          427  +          </tr>';
          428  +  }
          429  +
          430  +  echo '
          431  +          <tr>
          432  +            <td colspan="11" class="boxleft boxbottom boxright">
          433  +              <input type="submit" value="' . $undoStr . '" />
          434  +              <input type="submit" name="submit" value="' . $saveStr . '" />
          435  +            </td>
          436  +          </tr>
          437  +        </tbody>
          438  +      </table>
          439  +    </form>';
          440  +
          441  +  ob_end_flush ();
          442  +
          443  +  ?>
          444  +    <script language="javascript" type="text/javascript">
          445  +<!-- <![CDATA[
          446  +      function selectAll ( limit ) {
          447  +        if ( limit == 0 )
          448  +          document.EditOther.time.checked = false;
          449  +
          450  +        document.EditOther.email.checked =
          451  +        document.EditOther.invite.checked = ( limit != 0 )
          452  +
          453  +        for ( i = 1; i <= 256; ) {
          454  +          var
          455  +            aname = 'a_' + i,
          456  +            ename = 'e_' + i,
          457  +            vname = 'v_' + i;
          458  +
          459  +          document.forms['EditOther'].elements[vname].checked = (i <= limit);
          460  +
          461  +          if (document.forms['EditOther'].elements[ename])
          462  +            document.forms['EditOther'].elements[ename].checked = (i <= limit);
          463  +
          464  +          if (document.forms['EditOther'].elements[aname])
          465  +            document.forms['EditOther'].elements[aname].checked = (i <= limit);
          466  +
          467  +          i = parseInt(i+i);
          468  +        }
          469  +      }
          470  +      function enableAll ( on ) {
          471  +        for ( i = 1; i <= 256; ) {
          472  +          var
          473  +            aname = 'a_' + i,
          474  +            ename = 'e_' + i,
          475  +            vname = 'v_' + i;
          476  +
          477  +          document.forms['EditOther'].elements[vname].disabled = on;
          478  +
          479  +          if (document.forms['EditOther'].elements[ename])
          480  +            document.forms['EditOther'].elements[ename].disabled = on;
          481  +
          482  +          if (document.forms['EditOther'].elements[aname])
          483  +            document.forms['EditOther'].elements[aname].disabled = on;
          484  +
          485  +          i = parseInt(i+i);
          486  +        }
          487  +      }
          488  +//]]> -->
          489  +    </script>
          490  +<?php
          491  +}
          492  +
          493  +echo print_trailer ();
          494  +// Get the list of users that the specified user can see.
          495  +function get_list_of_users ( $user ) {
          496  +  global $is_admin, $is_nonuser_admin;
          497  +  //Let Admins userlist be returnd
          498  +  if ( $user == '__default__' )
          499  +    $user = '';
          500  +  $u = get_my_users ( $user, 'view' );
          501  +  if ( $is_admin || $is_nonuser_admin ) {
          502  +    // Get public NUCs also.
          503  +    $nonusers = get_my_nonusers ( $user, true );
          504  +    $u = array_merge ( $nonusers, $u );
          505  +  }
          506  +  return $u;
          507  +}
          508  +
          509  +?>

Added activity_log.php.

            1  +<?php
            2  +/* $Id: activity_log.php,v 1.53.2.3 2007/11/12 15:40:29 umcesrjones Exp $
            3  + *
            4  + * Description:
            5  + *  Display either the "Activity Log" (for events/tasks) or the
            6  + *  "System Log" (entries not associated with an event).
            7  + *
            8  + * Input Parameters:
            9  + *  startid  - specified the id of the first log entry to display
           10  + *  system   - if specified, then view the system log (entries with no
           11  + *             event id associated with them) rather than the event log.
           12  + *
           13  + * Security:
           14  + *  User must be an admin user
           15  + *  AND, if user access control is enabled, they must have access to
           16  + *  activity logs. (This is because users may see event details
           17  + *  for other groups that they are not supposed to have access to.)
           18  + */
           19  +include_once 'includes/init.php';
           20  +
           21  +if ( ! $is_admin || ( access_is_enabled () && !
           22  +      access_can_access_function ( ACCESS_ACTIVITY_LOG ) ) )
           23  +  die_miserable_death ( print_not_auth (2) );
           24  +
           25  +$eventsStr = translate ( 'Events' );
           26  +$nextStr = translate ( 'Next' );
           27  +$prevStr = translate ( 'Previous' );
           28  +
           29  +$PAGE_SIZE = 25; // Number of entries to show at once.
           30  +$startid = getValue ( 'startid', '-?[0-9]+', true );
           31  +$sys = ( $is_admin && getGetValue ( 'system' ) != '' );
           32  +
           33  +print_header ();
           34  +
           35  +ob_start ();
           36  +
           37  +echo generate_activity_log ( '', $sys, $startid );
           38  +
           39  +echo '
           40  +    <div class="navigation">'
           41  +// Go BACK in time.
           42  + . ( ! empty ( $nextpage ) ? '
           43  +      <a title="' . $prevStr . '&nbsp;' . $PAGE_SIZE . '&nbsp;' . $eventsStr
           44  +   . '" class="prev" href="activity_log.php?startid=' . $nextpage
           45  +   . ( $sys ? '&amp;system=1' : '' ) . '">' . $prevStr . '&nbsp;' . $PAGE_SIZE
           46  +   . '&nbsp;' . $eventsStr . '</a>' : '' );
           47  +
           48  +if ( ! empty ( $startid ) ) {
           49  +  $previd = $startid + $PAGE_SIZE;
           50  +  $res = dbi_execute ( 'SELECT MAX( cal_log_id ) FROM webcal_entry_log' );
           51  +  if ( $res ) {
           52  +    if ( $row = dbi_fetch_row ( $res ) )
           53  +      // Go FORWARD in time.
           54  +      echo '
           55  +      <a title="' . $nextStr . '&nbsp;' . $PAGE_SIZE . '&nbsp;' . $eventsStr
           56  +       . '" class="next" href="activity_log.php' . ( $row[0] <= $previd
           57  +        ? ( $sys ? '?system=1' : '' )
           58  +        : '?startid=' . $previd . ( $sys ? '&amp;system=1' : '' ) ) . '">'
           59  +       . $nextStr . '&nbsp;' . $PAGE_SIZE . '&nbsp;' . $eventsStr . '</a><br />';
           60  +
           61  +    dbi_free_result ( $res );
           62  +  }
           63  +}
           64  +
           65  +ob_end_flush ();
           66  +
           67  +echo '
           68  +    </div>
           69  +    ' . print_trailer ();
           70  +
           71  +?>

Added add_entry.php.

            1  +<?php
            2  +/* $Id: add_entry.php,v 1.29.2.2 2007/08/06 02:28:29 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +$error = '';
            6  +// Only proceed if id was passed.
            7  +if ( $id > 0 ) {
            8  +  // Double check to make sure user doesn't already have the event.
            9  +  $is_my_event = $is_private = false;
           10  +  $res = dbi_execute ( 'SELECT cal_id FROM webcal_entry_user
           11  +    WHERE cal_login = ? AND cal_id = ?', array ( $login, $id ) );
           12  +  if ( $res ) {
           13  +    $row = dbi_fetch_row ( $res );
           14  +    if ( $row[0] == $id ) {
           15  +      $is_my_event = true;
           16  +      echo str_replace ( 'XXX', $id,
           17  +        translate ( 'Event XXX is already on your calendar.' ) );
           18  +      exit;
           19  +    }
           20  +    dbi_free_result ( $res );
           21  +  }
           22  +  // Now lets make sure the user is allowed to add the event (not private).
           23  +  $res = dbi_execute ( 'SELECT cal_access FROM webcal_entry WHERE cal_id = ?',
           24  +    array ( $id ) );
           25  +  if ( ! $res ) {
           26  +    echo str_replace ( 'XXX', $id, translate ( 'Invalid entry id XXX.' ) );
           27  +    exit;
           28  +  }
           29  +  $mayNotAddStr =
           30  +  translate ( 'a XXX event may not be added to your calendar' );
           31  +  $row = dbi_fetch_row ( $res );
           32  +
           33  +  if ( ! $is_my_event ) {
           34  +    if ( $row[0] == 'C' && ! $is_assistant && ! $is_nonuser_admin ) {
           35  +      // Assistants are allowed to see confidential stuff.
           36  +      $is_private = true;
           37  +      echo str_replace ( 'XXX', translate ( 'confidential' ), $mayNotAddStr );
           38  +      exit;
           39  +    } else
           40  +    if ( $row[0] == 'R' ) {
           41  +      $is_private = true;
           42  +      echo str_replace ( 'XXX', translate ( 'private' ), $mayNotAddStr );
           43  +      exit;
           44  +    }
           45  +  }
           46  +  // Add the event.
           47  +  if ( $readonly == 'N' && ! $is_my_event && ! $is_private ) {
           48  +    if ( ! dbi_execute ( 'INSERT INTO webcal_entry_user ( cal_id, cal_login,
           49  +      cal_status ) VALUES ( ?, ?, ? )', array ( $id, $login, 'A' ) ) )
           50  +      // translate ( 'Error adding event' )
           51  +      $error = str_replace ( 'XXX', dbi_error (),
           52  +        translate ( 'Error adding event XXX.' ) );
           53  +  }
           54  +}
           55  +
           56  +send_to_preferred_view ();
           57  +exit;
           58  +
           59  +?>

Added admin.php.

            1  +<?php
            2  +/* $Id: admin.php,v 1.183.2.9 2012/02/28 02:07:45 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +require_valide_referring_url ();
            5  +include_once 'includes/date_formats.php';
            6  +if ( file_exists ( 'install/default_config.php' ) )
            7  +  include_once 'install/default_config.php';
            8  +// .
            9  +// Force the CSS cache to clear by incrementing webcalendar_csscache cookie.
           10  +// admin.php will not use this cached CSS, but we want to make sure it's flushed.
           11  +$webcalendar_csscache = 1;
           12  +if ( isset ( $_COOKIE['webcalendar_csscache'] ) )
           13  +  $webcalendar_csscache += $_COOKIE['webcalendar_csscache'];
           14  +
           15  +SetCookie ( 'webcalendar_csscache', $webcalendar_csscache );
           16  +
           17  +function save_pref ( $prefs, $src ) {
           18  +  global $error, $my_theme;
           19  +
           20  +  while ( list ( $key, $value ) = each ( $prefs ) ) {
           21  +    if ( $src == 'post' ) {
           22  +      $prefix = substr ( $key, 0, 6 );
           23  +      $setting = substr ( $key, 6 );
           24  +      if ( $key == 'currenttab' )
           25  +        continue;
           26  +      // .
           27  +      // Validate key name.  Should start with "admin_" and not include
           28  +      // any unusual characters that might be an SQL injection attack.
           29  +      if ( ! preg_match ( '/admin_[A-Za-z0-9_]+$/', $key ) )
           30  +        die_miserable_death ( str_replace ( 'XXX', $key,
           31  +            translate ( 'Invalid setting name XXX.' ) ) );
           32  +    } else {
           33  +      $prefix = 'admin_';
           34  +      $setting = $key;
           35  +    }
           36  +    if ( strlen ( $setting ) > 0 && $prefix == 'admin_' ) {
           37  +      if ( $setting == 'THEME' && $value != 'none' )
           38  +        $my_theme = strtolower ( $value );
           39  +
           40  +      $setting = strtoupper ( $setting );
           41  +      $sql = 'DELETE FROM webcal_config WHERE cal_setting = ?';
           42  +      if ( ! dbi_execute ( $sql, array ( $setting ) ) ) {
           43  +        $error = db_error ( false, $sql );
           44  +        break;
           45  +      }
           46  +      if ( strlen ( $value ) > 0 ) {
           47  +        $sql = 'INSERT INTO webcal_config ( cal_setting, cal_value ) VALUES ( ?, ? )';
           48  +        if ( ! dbi_execute ( $sql, array ( $setting, $value ) ) ) {
           49  +          $error = db_error ( false, $sql );
           50  +          break;
           51  +        }
           52  +      }
           53  +    }
           54  +  }
           55  +  // Reload preferences so any CSS changes will take effect.
           56  +  load_global_settings ();
           57  +  load_user_preferences ();
           58  +}
           59  +
           60  +/* Generates HTML for color chooser options in admin pages.
           61  + *
           62  + * NOTE: This will be merged back into function print_color_input_html
           63  + *       in includes/function.php when I remove the tables from pref.php.
           64  + *
           65  + * @param string $varname  the name of the variable to display
           66  + * @param string $title    color description
           67  + * @param string $varval   the default value to display
           68  + *
           69  + * @return string  HTML for the color selector.
           70  + */
           71  +function admin_print_color_input_html ( $varname, $title, $varval = '' ) {
           72  +  global $prefarray, $s, $SCRIPT;
           73  +  static $select;
           74  +
           75  +  $name = '';
           76  +  $setting = $varval;
           77  +
           78  +  if ( empty ( $select ) )
           79  +    $select = translate ( 'Select' ) . '...';
           80  +
           81  +  if ( $SCRIPT == 'admin.php' ) {
           82  +    $name = 'admin_';
           83  +    $setting = $s[$varname];
           84  +  } elseif ( $SCRIPT == 'pref.php' ) {
           85  +    $name = 'pref_';
           86  +    $setting = $prefarray[$varname];
           87  +  }
           88  +
           89  +  $name .= $varname;
           90  +
           91  +  return '
           92  +            <p><label for="' . $name . '">' . $title
           93  +   . ':</label><input type="text" name="' . $name . '" id="' . $name
           94  +   . '" size="7" maxlength="7" value="' . $setting
           95  +   . '" onchange="updateColor( this, \'' . $varname
           96  +   . '_sample\' );" /><span id="' . $varname . '_sample" style="background:'
           97  +   . $setting . ';">&nbsp;</span><input type="button" onclick="selectColor( \''
           98  +   . $name . '\', event )" value="' . $select . '" /></p>';
           99  +}
          100  +
          101  +$currenttab = '';
          102  +$error = ( $is_admin ? '' : print_not_auth (3) );
          103  +
          104  +if ( ! empty ( $_POST ) && empty ( $error ) ) {
          105  +  $currenttab = getPostValue ( 'currenttab' );
          106  +  $my_theme = '';
          107  +
          108  +  save_pref ( $_POST, 'post' );
          109  +
          110  +  if ( ! empty ( $my_theme ) ) {
          111  +    include_once 'themes/' . strtolower ( $my_theme ) . '.php';
          112  +    save_pref ( $webcal_theme, 'theme' );
          113  +  }
          114  +}
          115  +// .
          116  +// Load any new config settings.  Existing ones will not be affected.
          117  +// This function is in the install/default_config.php file.
          118  +if ( function_exists ( 'db_load_config' ) && empty ( $_POST ) )
          119  +  db_load_config ();
          120  +
          121  +$menuthemes = $s = $themes = array ();
          122  +
          123  +$res = dbi_execute ( 'SELECT cal_setting, cal_value FROM webcal_config' );
          124  +
          125  +if ( $res ) {
          126  +  while ( $row = dbi_fetch_row ( $res ) ) {
          127  +    $setting = $row[0];
          128  +    $s[$setting] = $value = $row[1];
          129  +  }
          130  +  dbi_free_result ( $res );
          131  +}
          132  +// .
          133  +// Get list of theme files from /themes directory.
          134  +$dir = 'themes';
          135  +if ( is_dir ( $dir ) ) {
          136  +  if ( $dh = opendir ( $dir ) ) {
          137  +    while ( ( $file = readdir ( $dh ) ) !== false ) {
          138  +      if ( strpos ( $file, '_admin.php' ) ) {
          139  +        $themes[0][] = strtoupper ( str_replace ( '_admin.php', '', $file ) );
          140  +        $themes[1][] = strtoupper ( str_replace ( '.php', '', $file ) );
          141  +      } else
          142  +      if ( strpos ( $file, '_pref.php' ) ) {
          143  +        $themes[0][] = strtolower ( str_replace ( '_pref.php', '', $file ) );
          144  +        $themes[1][] = strtolower ( str_replace ( '.php', '', $file ) );
          145  +      }
          146  +    }
          147  +    sort ( $themes );
          148  +    closedir ( $dh );
          149  +  }
          150  +}
          151  +// .
          152  +// Get list of menu themes.
          153  +$dir = 'includes/menu/themes/';
          154  +if ( is_dir ( $dir ) ) {
          155  +  if ( $dh = opendir ( $dir ) ) {
          156  +    while ( ( $file = readdir ( $dh ) ) !== false ) {
          157  +      if ( $file == '.' || $file == '..' || $file == 'CVS' )
          158  +        continue;
          159  +
          160  +      if ( is_dir ( $dir . $file ) )
          161  +        $menuthemes[] = $file;
          162  +    }
          163  +    closedir ( $dh );
          164  +  }
          165  +}
          166  +
          167  +$currenttab = getPostValue ( 'currenttab', 'settings' );
          168  +$currenttab = ( ! empty ( $currenttab) ? $currenttab : 'settings' );
          169  +
          170  +$BodyX = 'onload="init_admin();showTab( \'' . $currenttab . '\' );"';
          171  +print_header (
          172  +  array ( 'js/admin.php', 'js/visible.php' ), '', $BodyX );
          173  +
          174  +if ( ! $error ) {
          175  +  // Make sure globals values passed to styles.php are for this user.
          176  +  // Makes the demo calendar and Page title accurate.
          177  +  $GLOBALS['APPLICATION_NAME'] = $s['APPLICATION_NAME'];
          178  +  $GLOBALS['BGCOLOR'] = $s['BGCOLOR'];
          179  +  $GLOBALS['CELLBG'] = $s['CELLBG'];
          180  +  $GLOBALS['FONTS'] = $s['FONTS'];
          181  +  $GLOBALS['H2COLOR'] = $s['H2COLOR'];
          182  +  $GLOBALS['HASEVENTSBG'] = $s['HASEVENTSBG'];
          183  +  $GLOBALS['MENU_THEME'] = $s['MENU_THEME'];
          184  +  $GLOBALS['MYEVENTS'] = $s['MYEVENTS'];
          185  +  $GLOBALS['OTHERMONTHBG'] = $s['OTHERMONTHBG'];
          186  +  $GLOBALS['TABLEBG'] = $s['TABLEBG'];
          187  +  $GLOBALS['TEXTCOLOR'] = $s['TEXTCOLOR'];
          188  +  $GLOBALS['THBG'] = $s['THBG'];
          189  +  $GLOBALS['THFG'] = $s['THFG'];
          190  +  $GLOBALS['TODAYCELLBG'] = $s['TODAYCELLBG'];
          191  +  $GLOBALS['WEEKENDBG'] = $s['WEEKENDBG'];
          192  +  $GLOBALS['WEEKNUMBER'] = $s['WEEKNUMBER'];
          193  +
          194  +  define_languages (); // Load the language list.
          195  +  reset ( $languages );
          196  +
          197  +  $checked = ' checked="checked"';
          198  +  $selected = ' selected="selected"';
          199  +  $select = translate ( 'Select' ) . '...';
          200  +  // .
          201  +  // Allow css_cache of webcal_config values.
          202  +  @session_start ();
          203  +  $_SESSION['webcal_tmp_login'] = 'blahblahblah';
          204  +
          205  +  $editStr = '<input type="button" value="' . translate ( 'Edit' )
          206  +   . "...\" onclick=\"window.open( 'edit_template.php?type=%s','cal_template','"
          207  +   . 'dependent,menubar,scrollbars,height=500,width=500,outerHeight=520,'
          208  +   . 'outerWidth=520\' );" name="" />';
          209  +  $choices = array ( 'day.php', 'week.php', 'month.php', 'year.php' );
          210  +  $choices_text = array ( translate ( 'Day' ), translate ( 'Week' ),
          211  +    translate ( 'Month' ), translate ( 'Year' ) );
          212  +
          213  +  $bottomStr = translate ( 'Bottom' );
          214  +  $topStr = translate ( 'Top' );
          215  +
          216  +  $anyoneStr = translate ( 'Anyone' );
          217  +  $partyStr = translate ( 'Participant' );
          218  +
          219  +  $saveStr = translate ( 'Save' );
          220  +
          221  +  $option = '
          222  +                <option value="';
          223  +  $color_sets = $datestyle_md = $datestyle_my = $datestyle_tk = '';
          224  +  $datestyle_ymd = $lang_list = $menu_theme_list = $prefer_vu = '';
          225  +  $start_wk_on = $start_wkend_on = $tabs = $theme_list = $user_vu = '';
          226  +  $work_hr_end = $work_hr_start = '';
          227  +  // .
          228  +  // This should be easier to add more tabs if needed.
          229  +  $tabs_ar = array ( // .
          230  +    'settings', translate ( 'Settings' ),
          231  +    'public', translate ( 'Public Access' ),
          232  +    'uac', translate ( 'User Access Control' ),
          233  +    'groups', translate ( 'Groups' ),
          234  +    'nonuser', translate ( 'NonUser Calendars' ),
          235  +    'other', translate ( 'Other' ),
          236  +    'email', translate ( 'Email' ),
          237  +    'colors', translate ( 'Colors' )
          238  +    );
          239  +  for ( $i = 0, $cnt = count ( $tabs_ar ); $i < $cnt; $i++ ) {
          240  +    $tabs .= '
          241  +        <span class="tab' . ( $i > 0 ? 'bak' : 'for' ) . '" id="tab_'
          242  +     . $tabs_ar[$i] . '"><a href="" onclick="return setTab( \'' . $tabs_ar[$i]
          243  +     . '\' )">' . $tabs_ar[++$i] . '</a></span>';
          244  +  }
          245  +  // Move the loops here and combine a few.
          246  +  while ( list ( $key, $val ) = each ( $languages ) ) {
          247  +    $lang_list .= $option . $val . '"'
          248  +     . ( $val == $s['LANGUAGE'] ? $selected : '' )
          249  +     . '>' . $key . '</option>';
          250  +  }
          251  +  for ( $i = 0, $cnt = count ( $themes[0] ); $i < $cnt; $i++ ) {
          252  +    $theme_list .= $option . $themes[1][$i] . '">' . $themes[0][$i] . '</option>';
          253  +  }
          254  +  for ( $i = 0, $cnt = count ( $datestyles ); $i < $cnt; $i += 2 ) {
          255  +    $datestyle_ymd .= $option . $datestyles[$i] . '"'
          256  +     . ( $s['DATE_FORMAT'] == $datestyles[$i] ? $selected : '' )
          257  +     . '>' . $datestyles[$i + 1] . '</option>';
          258  +  }
          259  +  for ( $i = 0, $cnt = count ( $datestyles_my ); $i < $cnt; $i += 2 ) {
          260  +    $datestyle_my .= $option . $datestyles_my[$i] . '"'
          261  +     . ( $s['DATE_FORMAT_MY'] == $datestyles_my[$i] ? $selected : '' )
          262  +     . '>' . $datestyles_my[$i + 1] . '</option>';
          263  +  }
          264  +  for ( $i = 0, $cnt = count ( $datestyles_md ); $i < $cnt; $i += 2 ) {
          265  +    $datestyle_md .= $option . $datestyles_md[$i] . '"'
          266  +     . ( $s['DATE_FORMAT_MD'] == $datestyles_md[$i] ? $selected : '' )
          267  +     . '>' . $datestyles_md[$i + 1] . '</option>';
          268  +  }
          269  +  for ( $i = 0, $cnt = count ( $datestyles_task ); $i < $cnt; $i += 2 ) {
          270  +    $datestyle_tk .= $option . $datestyles_task[$i] . '"'
          271  +     . ( $s['DATE_FORMAT_TASK'] == $datestyles_task[$i] ? $selected : '' )
          272  +     . '>' . $datestyles_task[$i + 1] . '</option>';
          273  +  }
          274  +  for ( $i = 0; $i < 7; $i++ ) {
          275  +    $start_wk_on .= $option . "$i\""
          276  +     . ( $i == $s['WEEK_START'] ? $selected : '' )
          277  +     . '>' . weekday_name ( $i ) . '</option>';
          278  +    $j = ( $i == 0 ? 6 : $i - 1 ); // Make sure to start with Saturday.
          279  +    $start_wkend_on .= $option . "$j\""
          280  +     . ( $j == $s['WEEKEND_START'] ? $selected : '' )
          281  +     . '>' . weekday_name ( $j ) . '</option>';
          282  +  }
          283  +  for ( $i = 0; $i < 24; $i++ ) {
          284  +    $tmp = display_time ( $i * 10000, 1 );
          285  +    $work_hr_start .= $option . "$i\""
          286  +     . ( $i == $s['WORK_DAY_START_HOUR'] ? $selected : '' )
          287  +     . '>' . $tmp . '</option>';
          288  +    $work_hr_end .= $option . "$i\""
          289  +     . ( $i == $s['WORK_DAY_END_HOUR'] ? $selected : '' )
          290  +     . '>' . $tmp . '</option>';
          291  +  }
          292  +  for ( $i = 0, $cnt = count ( $choices ); $i < $cnt; $i++ ) {
          293  +    $prefer_vu .= $option . $choices[$i] . '"'
          294  +     . ( $s['STARTVIEW'] == $choices[$i] ? $selected : '' )
          295  +     . '>' . $choices_text[$i] . '</option>';
          296  +  }
          297  +  // Allow user to select a view also.
          298  +  for ( $i = 0, $cnt = count ( $views ); $i < $cnt; $i++ ) {
          299  +    if ( $views[$i]['cal_is_global'] != 'Y' )
          300  +      continue;
          301  +
          302  +    $xurl = $views[$i]['url'];
          303  +    $xurl_strip = str_replace ( '&amp;', '&', $xurl );
          304  +    $user_vu .= $option . $xurl . '"'
          305  +     . ( $s['STARTVIEW'] == $xurl_strip ? $selected : '' )
          306  +     . '>' . $views[$i]['cal_name'] . '</option>';
          307  +  }
          308  +  foreach ( $menuthemes as $menutheme ) {
          309  +    $menu_theme_list .= $option . $menutheme . '"'
          310  +     . ( $s['MENU_THEME'] == $menutheme ? $selected : '' )
          311  +     . '>' . $menutheme . '</option>';
          312  +  }
          313  +  foreach ( array ( // Document color choices.
          314  +      'BGCOLOR' => translate ( 'Document background' ),
          315  +      'H2COLOR' => translate ( 'Document title' ),
          316  +      'TEXTCOLOR' => translate ( 'Document text' ),
          317  +      'MYEVENTS' => translate ( 'My event text' ),
          318  +      'TABLEBG' => translate ( 'Table grid color' ),
          319  +      'THBG' => translate ( 'Table header background' ),
          320  +      'THFG' => translate ( 'Table header text' ),
          321  +      'CELLBG' => translate ( 'Table cell background' ),
          322  +      'TODAYCELLBG' => translate ( 'Table cell background for current day' ),
          323  +      'HASEVENTSBG' => translate ( 'Table cell background for days with events' ),
          324  +      'WEEKENDBG' => translate ( 'Table cell background for weekends' ),
          325  +      'OTHERMONTHBG' => translate ( 'Table cell background for other month' ),
          326  +      'WEEKNUMBER' => translate ( 'Week number color' ),
          327  +      'POPUP_BG' => translate ( 'Event popup background' ),
          328  +      'POPUP_FG' => translate ( 'Event popup text' )
          329  +      ) as $k => $v ) {
          330  +    $color_sets .= admin_print_color_input_html ( $k, $v );
          331  +  }
          332  +
          333  +  set_today ( date ( 'Ymd' ) );
          334  +  ob_start ();
          335  +
          336  +  echo '
          337  +    <h2>' . translate ( 'System Settings' )
          338  +   . '<img src="images/help.gif" alt="' . translate ( 'Help' )
          339  +   . '" class="help" onclick="window.open( \'help_admin.php\', \'cal_help\', '
          340  +   . '\'dependent,menubar,scrollbars,height=400,width=400,innerHeight=420,'
          341  +   . 'outerWidth=420\' );" /></h2>
          342  +    <form action="admin.php" method="post" onsubmit="return valid_form( this );"'
          343  +   . ' name="prefform">'
          344  +   . display_admin_link () . '
          345  +      <input type="hidden" name="currenttab" id="currenttab" value="'
          346  +   . $currenttab . '" />
          347  +      <input type="submit" value="' . $saveStr
          348  +   . '" name="" /><br /><br />
          349  +
          350  +<!-- TABS -->
          351  +      <div id="tabs">' . $tabs . '
          352  +      </div>
          353  +
          354  +<!-- TABS BODY -->
          355  +      <div id="tabscontent">
          356  +<!-- DETAILS -->
          357  +        <div id="tabscontent_settings">
          358  +          <fieldset>
          359  +            <legend>' . translate ( 'System options' ) . '</legend>
          360  +            <p><label for="admin_APPLICATION_NAME" title="'
          361  +   . tooltip ( 'app-name-help' ) . '">' . translate ( 'Application Name' )
          362  +   . ':</label>
          363  +              <input type="text" size="40" name="admin_APPLICATION_NAME" '
          364  +   . 'id="admin_APPLICATION_NAME" value="'
          365  +   . htmlspecialchars ( $s['APPLICATION_NAME'] ) . '" />'
          366  +   . ( $s['APPLICATION_NAME'] == 'Title'
          367  +    /* translate ( 'Translated Name' ) */
          368  +    ? str_replace ( 'XXX', translate ( 'Title' ),
          369  +      translate ( 'Translated Name (XXX)' ) ) : '' ) . '</p>
          370  +            <p><label for="admin_SERVER_URL" title="'
          371  +   . tooltip ( 'server-url-help' ) . '">' . translate ( 'Server URL' )
          372  +   . ':</label>
          373  +              <input type="text" size="70" name="admin_SERVER_URL" '
          374  +   . 'id="admin_SERVER_URL" value="' . htmlspecialchars ( $s['SERVER_URL'] )
          375  +   . '" /></p>
          376  +            <p><label for="admin_HOME_LINK" title="'
          377  +   . tooltip ( 'home-url-help' ) . '">' . translate ( 'Home URL' ) . ':</label>
          378  +              <input type="text" size="40" name="admin_HOME_LINK" '
          379  +   . 'id="admin_HOME_LINK" value="'
          380  +   . ( empty ( $s['HOME_LINK'] ) ? '' : htmlspecialchars ( $s['HOME_LINK'] ) )
          381  +   . '" /></p>
          382  +            <p><label for="admin_LANGUAGE" title="' . tooltip ( 'language-help' )
          383  +   . '">' . translate ( 'Language' ) . ':</label>
          384  +              <select name="admin_LANGUAGE" id="admin_LANGUAGE">' . $lang_list . '
          385  +              </select>'/* translate ( 'Your browser default language is' ) */
          386  +   . str_replace ( 'XXX', translate ( get_browser_language ( true ) ),
          387  +    translate ( 'Your browser default language is XXX.' ) ) . '</p>
          388  +            <p><label>' . translate ( 'Allow user to use themes' ) . ':</label>'
          389  +   . print_radio ( 'ALLOW_USER_THEMES' ) . '</p>
          390  +            <p><label for="admin_THEME" title="' . tooltip ( 'themes-help' )
          391  +   . '">' . translate ( 'Themes' ) . ':</label>
          392  +              <select name="admin_THEME" id="admin_THEME">
          393  +                <option disabled="disabled">' . translate ( 'AVAILABLE THEMES' )
          394  +   . '</option>'
          395  +  /* Always use 'none' as default so we don't overwrite manual settings. */
          396  +   . $option . 'none"' . $selected . '>' . translate ( 'None' ) . '</option>'
          397  +   . $theme_list . '
          398  +              </select><input type="button" name="preview" value="'
          399  +   . translate ( 'Preview' ) . '" onclick="return showPreview()" />
          400  +            </p>
          401  +          </fieldset>
          402  +          <fieldset>
          403  +            <legend>' . translate ( 'Site customization' ) . '</legend>
          404  +            <p><label title="' . tooltip ( 'custom-script-help' ) . '">'
          405  +   . translate ( 'Custom script/stylesheet' ) . ':</label>'
          406  +   . print_radio ( 'CUSTOM_SCRIPT' );
          407  +  printf ( $editStr, 'S' );
          408  +  echo '</p>
          409  +            <p><label title="' . tooltip ( 'custom-header-help' ) . '">'
          410  +   . translate ( 'Custom header' ) . ':</label>'
          411  +   . print_radio ( 'CUSTOM_HEADER' );
          412  +  printf ( $editStr, 'H' );
          413  +  echo '</p>
          414  +            <p><label title="' . tooltip ( 'custom-trailer-help' ) . '">'
          415  +   . translate ( 'Custom trailer' ) . ':</label>'
          416  +   . print_radio ( 'CUSTOM_TRAILER' );
          417  +  printf ( $editStr, 'T' );
          418  +  echo '</p>
          419  +            <p><label title="' . tooltip ( 'enable-external-header-help' ) . '">'
          420  +   . translate ( 'Allow external file for header/script/trailer' ) . ':</label>'
          421  +   . print_radio ( 'ALLOW_EXTERNAL_HEADER' ) . '</p>
          422  +            <p><label>' . translate ( 'Allow user to override header/trailer' )
          423  +   . ':</label>' . print_radio ( 'ALLOW_USER_HEADER' ) . '</p>
          424  +          </fieldset>
          425  +          <fieldset>
          426  +            <legend>' . translate ( 'Date and Time' ) . '</legend>'
          427  +  /* Determine if we can set timezones.  If not don't display any options. */
          428  +   . ( set_env ( 'TZ', $s['SERVER_TIMEZONE'] ) ? '
          429  +            <p><label for="admin_SERVER_TIMEZONE" title="'
          430  +     . tooltip ( 'tz-help' ) . '">' . translate ( 'Server Timezone Selection' )
          431  +     . ':</label>' . print_timezone_select_html ( 'admin_', $s['SERVER_TIMEZONE'] )
          432  +     . '</p>' : '' ) . '
          433  +            <p><label title="' . tooltip ( 'display-general-use-gmt-help' )
          434  +   . '">' . translate ( 'Display Common Use Date/Times as GMT' ) . ':</label>'
          435  +   . print_radio ( 'GENERAL_USE_GMT' ) . '</p>
          436  +            <p><label title="' . tooltip ( 'date-format-help' ) . '">'
          437  +   . translate ( 'Date format' ) . ':</label>
          438  +              <select name="admin_DATE_FORMAT">' . $datestyle_ymd . '
          439  +              </select>' . $choices_text[2] . ' ' . $choices_text[0] . ' '
          440  +   . $choices_text[3] . '</p>
          441  +            <p><label>&nbsp;</label>
          442  +              <select name="admin_DATE_FORMAT_MY">' . $datestyle_my . '
          443  +              </select>' . $choices_text[2] . ' ' . $choices_text[3] . '</p>
          444  +            <p><label>&nbsp;</label>
          445  +              <select name="admin_DATE_FORMAT_MD">' . $datestyle_md . '
          446  +              </select>' . $choices_text[2] . ' ' . $choices_text[0] . '</p>
          447  +            <p><label>&nbsp;</label>
          448  +              <select name="admin_DATE_FORMAT_TASK">' . $datestyle_tk . '
          449  +              </select>' . translate ( 'Small Task Date' ) . '</p>
          450  +            <p><label title="' . tooltip ( 'display-week-starts-on' ) . '">'
          451  +   . translate ( 'Week starts on' ) . ':</label>
          452  +              <select name="admin_WEEK_START" id="admin_WEEK_START">'
          453  +   . $start_wk_on . '
          454  +              </select></p>
          455  +            <p><label title="' . tooltip ( 'display-weekend-starts-on' ) . '">'
          456  +   . translate ( 'Weekend starts on' ) . ':</label>
          457  +              <select name="admin_WEEKEND_START" id="admin_WEEKEND_START">'
          458  +   . $start_wkend_on . '
          459  +              </select></p>
          460  +            <p><label title="' . tooltip ( 'time-format-help' ) . '">'
          461  +   . translate ( 'Time format' ) . ':</label>' . print_radio ( 'TIME_FORMAT',
          462  +    array ( '12' => translate ( '12 hour' ), '24' => translate ( '24 hour' ) ) )
          463  +   . '</p>
          464  +            <p><label title="' . tooltip ( 'timed-evt-len-help' ) . '">'
          465  +   . translate ( 'Specify timed event length by' ) . ':</label>'
          466  +   . print_radio ( 'TIMED_EVT_LEN',
          467  +    array ( 'D' => translate ( 'Duration' ), 'E' => translate ( 'End Time' ) ) )
          468  +   . '</p>
          469  +            <p><label for="admin_WORK_DAY_START_HOUR" title="'
          470  +   . tooltip ( 'work-hours-help' ) . '">' . translate ( 'Work hours' )
          471  +   . ':</label>' . translate ( 'From' ) . '
          472  +              <select name="admin_WORK_DAY_START_HOUR" id="admin_WORK_DAY_START_HOUR">'
          473  +   . $work_hr_start . '
          474  +              </select>' . translate ( 'to' ) . '
          475  +              <select name="admin_WORK_DAY_END_HOUR" id="admin_WORK_DAY_END_HOUR">'
          476  +   . $work_hr_end . '
          477  +              </select></p>
          478  +          </fieldset>
          479  +          <fieldset>
          480  +            <legend>' . translate ( 'Appearance' ) . '</legend>
          481  +            <p><label for="admin_STARTVIEW" title="'
          482  +   . tooltip ( 'preferred-view-help' ) . '">' . translate ( 'Preferred view' )
          483  +   . ':</label>
          484  +              <select name="admin_STARTVIEW" id="admin_STARTVIEW">' . $prefer_vu
          485  +   . $user_vu . '
          486  +              </select></p>
          487  +            <p><label>' . translate ( 'Allow top menu' ) . ':</label>'
          488  +   . print_radio ( 'MENU_ENABLED' ) . '</p>
          489  +            <p><label>' . translate ( 'Date Selectors position' ) . ':</label>'
          490  +   . print_radio ( 'MENU_DATE_TOP', array ( 'Y' => $topStr, 'N' => $bottomStr ) )
          491  +   . '</p>
          492  +            <p><label for="admin_MENU_THEME" title="'
          493  +   . tooltip ( 'menu-themes-help' ) . '">' . translate ( 'Menu theme' )
          494  +   . ':</label>
          495  +              <select name="admin_MENU_THEME" id="admin_MENU_THEME">' . $option
          496  +   . 'none"' . $selected . '>' . translate ( 'None' ) . '</option>'
          497  +   . $menu_theme_list . '
          498  +              </select></p>
          499  +            <p><label for="admin_FONTS" title="' . tooltip ( 'fonts-help' )
          500  +   . '">' . translate ( 'Fonts' )
          501  +   . ':</label><input type="text" size="40" name="admin_FONTS" id="admin_FONTS" value="'
          502  +   . htmlspecialchars ( $s['FONTS'] ) . '" /></p>
          503  +            <p><label title="' . tooltip ( 'display-sm_month-help' ) . '">'
          504  +   . translate ( 'Display small months' ) . ':</label>'
          505  +   . print_radio ( 'DISPLAY_SM_MONTH' ) . '</p>
          506  +            <p><label title="' . tooltip ( 'display-weekends-help' ) . '">'
          507  +   . translate ( 'Display weekends' ) . ':</label>'
          508  +   . print_radio ( 'DISPLAY_WEEKENDS' ) . '</p>
          509  +            <p><label title="' . tooltip ( 'display-long-daynames-help' ) . '">'
          510  +   . translate ( 'Display long day names' ) . ':</label>'
          511  +   . print_radio ( 'DISPLAY_LONG_DAYS' ) . '</p>
          512  +            <p><label title="' . tooltip ( 'display-alldays-help' ) . '">'
          513  +   . translate ( 'Display all days in month view' ) . ':</label>'
          514  +   . print_radio ( 'DISPLAY_ALL_DAYS_IN_MONTH' ) . '</p>
          515  +            <p><label title="' . tooltip ( 'display-week-number-help' ) . '">'
          516  +   . translate ( 'Display week number' ) . ':</label>'
          517  +   . print_radio ( 'DISPLAY_WEEKNUMBER' ) . '</p>
          518  +            <p><label title="' . tooltip ( 'display-desc-print-day-help' ) . '">'
          519  +   . translate ( 'Display description in printer day view' ) . ':</label>'
          520  +   . print_radio ( 'DISPLAY_DESC_PRINT_DAY' ) . '</p>
          521  +            <p><label title="' . tooltip ( 'yearly-shows-events-help' ) . '">'
          522  +   . translate ( 'Display days with events in bold in month and year views' )
          523  +   . ':</label>' . print_radio ( 'BOLD_DAYS_IN_YEAR' ) . '</p>
          524  +            <p><label title="' . tooltip ( 'display-minutes-help' ) . '">'
          525  +   . translate ( 'Display 00 minutes always' ) . ':</label>'
          526  +   . print_radio ( 'DISPLAY_MINUTES' ) . '</p>
          527  +            <p><label title="' . tooltip ( 'display-end-times-help' ) . '">'
          528  +   . translate ( 'Display end times on calendars' ) . ':</label>'
          529  +   . print_radio ( 'DISPLAY_END_TIMES' ) . '</p>
          530  +            <p><label title="' . tooltip ( 'allow-view-add-help' ) . '">'
          531  +   . translate ( 'Include add event link in views' ) . ':</label>'
          532  +   . print_radio ( 'ADD_LINK_IN_VIEWS' ) . '</p>
          533  +            <p><label title="' . tooltip ( 'lunar-help' ) . '">'
          534  +   . translate ( 'Display Lunar Phases in month view' ) . ':</label>'
          535  +   . print_radio ( 'DISPLAY_MOON_PHASES' ) . '</p>
          536  +          </fieldset>
          537  +          <fieldset>
          538  +            <legend>' . translate ( 'Restrictions' ) . '</legend>
          539  +            <p><label title="' . tooltip ( 'allow-view-other-help' ) . '">'
          540  +   . translate ( 'Allow viewing other users calendars' ) . ':</label>'
          541  +   . print_radio ( 'ALLOW_VIEW_OTHER' ) . '</p>
          542  +            <p><label title="' . tooltip ( 'require-approvals-help' ) . '">'
          543  +   . translate ( 'Require event approvals' ) . ':</label>'
          544  +   . print_radio ( 'REQUIRE_APPROVALS' ) . '</p>
          545  +            <p><label title="' . tooltip ( 'display-unapproved-help' ) . '">'
          546  +   . translate ( 'Display unapproved' ) . ':</label>'
          547  +   . print_radio ( 'DISPLAY_UNAPPROVED' ) . '</p>
          548  +            <p><label title="' . tooltip ( 'conflict-check-help' ) . '">'
          549  +   . translate ( 'Check for event conflicts' ) . ':</label>'
          550  +  /* This control is logically reversed. */
          551  +   . print_radio ( 'ALLOW_CONFLICTS',
          552  +    array ( 'N' => translate ( 'Yes' ), 'Y' => translate ( 'No' ) ) ) . '</p>
          553  +            <p><label title="' . tooltip ( 'conflict-months-help' ) . '">'
          554  +   . translate ( 'Conflict checking months' ) . ':</label>
          555  +              <input type="text" size="3" '
          556  +   . 'name="admin_CONFLICT_REPEAT_MONTHS" value="'
          557  +   . htmlspecialchars ( $s['CONFLICT_REPEAT_MONTHS'] ) . '" /></p>
          558  +            <p><label title="' . tooltip ( 'conflict-check-override-help' )
          559  +   . '">' . translate ( 'Allow users to override conflicts' ) . ':</label>'
          560  +   . print_radio ( 'ALLOW_CONFLICT_OVERRIDE' ) . '</p>
          561  +            <p><label title="' . tooltip ( 'limit-appts-help' ) . '">'
          562  +   . translate ( 'Limit number of timed events per day' ) . ':</label>'
          563  +   . print_radio ( 'LIMIT_APPTS' ) . '</p>
          564  +            <p><label title="' . tooltip ( 'limit-appts-number-help' ) . '">'
          565  +   . translate ( 'Maximum timed events per day' ) . ':</label>
          566  +              <input type="text" size="3" name="admin_LIMIT_APPTS_NUMBER" value="'
          567  +   . htmlspecialchars ( $s['LIMIT_APPTS_NUMBER'] ) . '" /></p>
          568  +            <p><label title="' . tooltip ( 'crossday-help' ) . '">'
          569  +   . translate ( 'Disable Cross-Day Events' ) . ':</label>'
          570  +   . print_radio ( 'DISABLE_CROSSDAY_EVENTS' ) . '</p>
          571  +          </fieldset>
          572  +          <fieldset>
          573  +            <legend>' . translate ( 'Events' ) . '</legend>
          574  +            <p><label title="' . tooltip ( 'disable-location-field-help' ) . '">'
          575  +   . translate ( 'Disable Location field' ) . ':</label>'
          576  +   . print_radio ( 'DISABLE_LOCATION_FIELD' ) . '</p>
          577  +            <p><label title="' . tooltip ( 'disable-url-field-help' ) . '">'
          578  +   . translate ( 'Disable URL field' ) . ':</label>'
          579  +   . print_radio ( 'DISABLE_URL_FIELD' ) . '</p>
          580  +            <p><label title="' . tooltip ( 'disable-priority-field-help' ) . '">'
          581  +   . translate ( 'Disable Priority field' ) . ':</label>'
          582  +   . print_radio ( 'DISABLE_PRIORITY_FIELD' ) . '</p>
          583  +            <p><label title="' . tooltip ( 'disable-access-field-help' ) . '">'
          584  +   . translate ( 'Disable Access field' ) . ':</label>'
          585  +   . print_radio ( 'DISABLE_ACCESS_FIELD' ) . '</p>
          586  +            <p><label title="' . tooltip ( 'disable-participants-field-help' )
          587  +   . '">' . translate ( 'Disable Participants field' ) . ':</label>'
          588  +   . print_radio ( 'DISABLE_PARTICIPANTS_FIELD' ) . '</p>
          589  +            <p><label title="' . tooltip ( 'disable-repeating-field-help' )
          590  +   . '">' . translate ( 'Disable Repeating field' ) . ':</label>'
          591  +   . print_radio ( 'DISABLE_REPEATING_FIELD' ) . '</p>
          592  +            <p><label title="' . tooltip ( 'allow-html-description-help' )
          593  +   . '">' . translate ( 'Allow HTML in Description' ) . ':</label>'
          594  +   . print_radio ( 'ALLOW_HTML_DESCRIPTION' ) . '</p>
          595  +          </fieldset>
          596  +          <fieldset>
          597  +            <legend>' . translate ( 'Popups' ) . '</legend>
          598  +            <p><label title="' . tooltip ( 'disable-popups-help' ) . '">'
          599  +   . translate ( 'Disable Pop-Ups' ) . ':</label>'
          600  +   . print_radio ( 'DISABLE_POPUPS', '', 'popup_handler' ) . '</p>
          601  +            <div id="pop">
          602  +              <p><label title="' . tooltip ( 'popup-includes-siteextras-help' )
          603  +   . '">' . translate ( 'Display Site Extras in popup' ) . ':</label>'
          604  +   . print_radio ( 'SITE_EXTRAS_IN_POPUP' ) . '</p>
          605  +              <p><label title="' . tooltip ( 'popup-includes-participants-help' )
          606  +   . '">' . translate ( 'Display Participants in popup' ) . ':</label>'
          607  +   . print_radio ( 'PARTICIPANTS_IN_POPUP' ) . '</p>
          608  +            </div>
          609  +          </fieldset>
          610  +          <fieldset>
          611  +            <legend>' . translate ( 'Miscellaneous' ) . '</legend>
          612  +            <p><label title="' . tooltip ( 'remember-last-login-help' ) . '">'
          613  +   . translate ( 'Remember last login' ) . ':</label>'
          614  +   . print_radio ( 'REMEMBER_LAST_LOGIN' ) . '</p>
          615  +            <p><label title="' . tooltip ( 'summary_length-help' ) . '">'
          616  +   . translate ( 'Brief Description Length' )
          617  +   . ':</label><input type="text" size="3" name="admin_SUMMARY_LENGTH" value="'
          618  +   . $s['SUMMARY_LENGTH'] . '" /></p>
          619  +            <p><label for="admin_USER_SORT_ORDER" title="'
          620  +   . tooltip ( 'user_sort-help' ) . '">' . translate ( 'User Sort Order' )
          621  +   . ':</label>
          622  +              <select name="admin_USER_SORT_ORDER" id="admin_USER_SORT_ORDER">'
          623  +   . $option . 'cal_lastname, cal_firstname" '
          624  +   . ( $s['USER_SORT_ORDER'] == 'cal_lastname, cal_firstname' ? $selected : '' )
          625  +   . '>' . translate ( 'Lastname, Firstname' ) . '</option>' . $option
          626  +   . 'cal_firstname, cal_lastname" '
          627  +   . ( $s['USER_SORT_ORDER'] == 'cal_firstname, cal_lastname' ? $selected : '' )
          628  +   . '>' . translate ( 'Firstname, Lastname' ) . '</option>
          629  +              </select></p>
          630  +          </fieldset>
          631  +        </div>
          632  +<!-- END SETTINGS -->
          633  +
          634  +<!-- BEGIN PUBLIC ACCESS -->
          635  +        <div id="tabscontent_public">
          636  +          <p><label title=" ' . tooltip ( 'allow-public-access-help' ) . '">'
          637  +   . translate ( 'Allow public access' ) . ':</label>'
          638  +   . print_radio ( 'PUBLIC_ACCESS', '', 'public_handler' ) . '</p>
          639  +          <div id="pa">
          640  +            <p><label title="' . tooltip ( 'public-access-default-visible' )
          641  +   . '">' . translate ( 'Public access visible by default' ) . ':</label>'
          642  +   . print_radio ( 'PUBLIC_ACCESS_DEFAULT_VISIBLE' ) . '</p>
          643  +            <p><label title="' . tooltip ( 'public-access-default-selected' )
          644  +   . '">' . translate ( 'Public access is default participant' ) . ':</label>'
          645  +   . print_radio ( 'PUBLIC_ACCESS_DEFAULT_SELECTED' ) . '</p>
          646  +            <p><label title="' . tooltip ( 'public-access-view-others-help' )
          647  +   . '">' . translate ( 'Public access can view other users' ) . ':</label>'
          648  +   . print_radio ( 'PUBLIC_ACCESS_OTHERS' ) . '</p>
          649  +            <p><label title="' . tooltip ( 'public-access-can-add-help' ) . '">'
          650  +   . translate ( 'Public access can add events' ) . ':</label>'
          651  +   . print_radio ( 'PUBLIC_ACCESS_CAN_ADD' ) . '</p>
          652  +            <p><label title="' . tooltip ( 'public-access-add-requires-approval-help' )
          653  +   . '">' . translate ( 'Public access new events require approval' ) . ':</label>'
          654  +   . print_radio ( 'PUBLIC_ACCESS_ADD_NEEDS_APPROVAL' ) . '</p>
          655  +            <p><label title="' . tooltip ( 'public-access-sees-participants-help' )
          656  +   . '">' . translate ( 'Public access can view participants' ) . ':</label>'
          657  +   . print_radio ( 'PUBLIC_ACCESS_VIEW_PART' ) . '</p>
          658  +            <p><label title="' . tooltip ( 'public-access-override-help' ) . '">'
          659  +   . translate ( 'Override event name/description for public access' )
          660  +   . ':</label>' . print_radio ( 'OVERRIDE_PUBLIC' ) . '</p>
          661  +            <p><label title="' . tooltip ( 'public-access-override-text-help' )
          662  +   . '">' . translate ( 'Text to display to public access' )
          663  +   . ':</label><input name="admin_OVERRIDE_PUBLIC_TEXT" value="'
          664  +   . $s['OVERRIDE_PUBLIC_TEXT'] . '" size="25" /></p>
          665  +            <p><label title="' . tooltip ( 'public-access-captcha-help' ) . '">'
          666  +   . translate ( 'Require CAPTCHA validation for public access new events' )
          667  +   . ':</label>' . print_radio ( 'ENABLE_CAPTCHA' ) . '</p>
          668  +           <div style="clear:both;"></div>
          669  +          </div>
          670  +        </div>
          671  +
          672  +<!-- BEGIN USER ACCESS CONTROL -->
          673  +        <p id="tabscontent_uac"><label title="' . tooltip ( 'uac-enabled-help' )
          674  +   . '">' . translate ( 'User Access Control enabled' ) . ':</label>'
          675  +   . print_radio ( 'UAC_ENABLED' ) . '</p>
          676  +
          677  +<!-- BEGIN GROUPS -->
          678  +        <div id="tabscontent_groups">
          679  +          <p><label title="' . tooltip ( 'groups-enabled-help' ) . '">'
          680  +   . translate ( 'Groups enabled' ) . ':</label>'
          681  +   . print_radio ( 'GROUPS_ENABLED' ) . '</p>
          682  +          <p><label title="' . tooltip ( 'user-sees-his-group-help' ) . '">'
          683  +   . translate ( 'User sees only his groups' ) . ':</label>'
          684  +   . print_radio ( 'USER_SEES_ONLY_HIS_GROUPS' ) . '</p>
          685  +        </div>
          686  +
          687  +<!-- BEGIN NONUSER -->
          688  +        <div id="tabscontent_nonuser">
          689  +          <p><label title="' . tooltip ( 'nonuser-enabled-help' ) . '">'
          690  +   . translate ( 'Nonuser enabled' ) . ':</label>'
          691  +   . print_radio ( 'NONUSER_ENABLED' ) . '</p>
          692  +          <p><label title="' . tooltip ( 'nonuser-list-help' ) . '">'
          693  +   . translate ( 'Nonuser list' ) . ':</label>'
          694  +   . print_radio ( 'NONUSER_AT_TOP', array ( 'Y' => $topStr, 'N' => $bottomStr ) )
          695  +   . '</p>
          696  +        </div>
          697  +
          698  +        <div id="tabscontent_other">
          699  +<!-- BEGIN UPCOMING EVENTS -->
          700  +   <fieldset><legend>' . translate('Upcoming Events') . '</legend>
          701  +   ' . htmlspecialchars ( $SERVER_URL ) . 'upcoming.php<br/>
          702  +   <p><label title="' . tooltip ( 'upcoming-events-help' ) . '">'
          703  +   . translate ( 'Enabled' ) . ':</label>'
          704  +   . print_radio ( 'UPCOMING_EVENTS', '', '', 'N' ) . '</p>
          705  +
          706  +   <p><label title="' . tooltip ( 'upcoming-events-allow-override' ) .  '">'
          707  +   . translate ( 'Allow user override' ) . ':</label>'
          708  +   . print_radio ( 'UPCOMING_ALLOW_OVR', '', '', 'N' ) . '</p>
          709  +
          710  +     <p><label title="' . tooltip ( 'upcoming-events-display-caticons' ) .  '">'
          711  +   . translate ( 'Display category icons' ) . ':</label>'
          712  +   . print_radio ( 'UPCOMING_DISPLAY_CAT_ICONS', '', '', 'Y' ) . '</p>
          713  +
          714  +     <p><label title="' . tooltip ( 'upcoming-events-display-layers' ) .  '">'
          715  +   . translate ( 'Display layers' ) . ':</label>'
          716  +   . print_radio ( 'UPCOMING_DISPLAY_LAYERS', '', '', 'N' ) . '</p>
          717  +
          718  +     <p><label title="' . tooltip ( 'upcoming-events-display-links' ) .  '">'
          719  +   . translate ( 'Display links to events' ) . ':</label>'
          720  +   . print_radio ( 'UPCOMING_DISPLAY_LINKS', '', '', 'Y' ) . '</p>
          721  +
          722  +     <p><label title="' . tooltip ( 'upcoming-events-display-popups' ) .  '">'
          723  +   . translate ( 'Display event popups' ) . ':</label>'
          724  +   . print_radio ( 'UPCOMING_DISPLAY_POPUPS', '', '', 'Y' ) . '</p>
          725  +   </fieldset>
          726  +
          727  +<!-- BEGIN REPORTS -->
          728  +          <p><label title="' . tooltip ( 'reports-enabled-help' ) . '">'
          729  +   . translate ( 'Reports enabled' ) . ':</label>'
          730  +   . print_radio ( 'REPORTS_ENABLED' ) . '</p>
          731  +
          732  +<!-- BEGIN PUBLISHING -->
          733  +          <p><label title="' . tooltip ( 'subscriptions-enabled-help' ) . '">'
          734  +   . translate ( 'Allow remote subscriptions' ) . ':</label>'
          735  +   . print_radio ( 'PUBLISH_ENABLED' ) . '</p>'
          736  +  /* Determine if allow_url_fopen is enabled. */
          737  +   . ( preg_match ( '/(On|1|true|yes)/i', ini_get ( 'allow_url_fopen' ) ) ? '
          738  +          <p><label title="' . tooltip ( 'remotes-enabled-help' ) . '">'
          739  +     . translate ( 'Allow remote calendars' ) . ':</label>'
          740  +     . print_radio ( 'REMOTES_ENABLED' ) . '</p>' : '' ) . '
          741  +          <p><label title="' . tooltip ( 'rss-enabled-help' ) . '">'
          742  +   . translate ( 'Enable RSS feed' ) . ':</label>'
          743  +   . print_radio ( 'RSS_ENABLED' ) . '</p>
          744  +
          745  +<!-- BEGIN CATEGORIES -->
          746  +          <p><label title="' . tooltip ( 'categories-enabled-help' ) . '">'
          747  +   . translate ( 'Categories enabled' ) . ':</label>'
          748  +   . print_radio ( 'CATEGORIES_ENABLED' ) . '</p>
          749  +          <p><label title="' . tooltip ( 'icon_upload-enabled-help' ) . '">'
          750  +   . translate ( 'Category Icon Upload enabled' ) . ':</label>'
          751  +   . print_radio ( 'ENABLE_ICON_UPLOADS' ) . '' . ( ! is_dir ( 'icons/' )
          752  +    /* translate ( 'Requires' ) translate ( 'folder to exist' ) */
          753  +    ? str_replace ( 'XXX', 'icons',
          754  +      translate ( '(Requires XXX folder to exist.)' ) ) : '' ) . '</p>
          755  +
          756  +<!-- DISPLAY TASK PREFERENCES -->
          757  +          <p><label title="' . tooltip ( 'display-tasks-help' ) . '">'
          758  +   . translate ( 'Display small task list' ) . ':</label>'
          759  +   . print_radio ( 'DISPLAY_TASKS' ) . '</p>
          760  +          <p><label title="' . tooltip ( 'display-tasks-in-grid-help' ) . '">'
          761  +   . translate ( 'Display tasks in Calendars' ) . ':</label>'
          762  +   . print_radio ( 'DISPLAY_TASKS_IN_GRID' ) . '</p>
          763  +
          764  +<!-- BEGIN EXT PARTICIPANTS -->
          765  +          <p><label title="' . tooltip ( 'allow-external-users-help' ) . '">'
          766  +   . translate ( 'Allow external users' ) . ':</label>'
          767  +   . print_radio ( 'ALLOW_EXTERNAL_USERS', '', 'eu_handler' ) . '</p>
          768  +          <div id="eu">
          769  +            <p><label title="' . tooltip ( 'external-can-receive-notification-help' )
          770  +   . '">' . translate ( 'External users can receive email notifications' )
          771  +   . ':</label>' . print_radio ( 'EXTERNAL_NOTIFICATIONS' ) . '</p>
          772  +            <p><label title="' . tooltip ( 'external-can-receive-reminder-help' )
          773  +   . '">' . translate ( 'External users can receive email reminders' )
          774  +   . ':</label>' . print_radio ( 'EXTERNAL_REMINDERS' ) . '</p>
          775  +          </div>
          776  +
          777  + <!-- BEGIN SELF REGISTRATION -->
          778  +          <p><label title="' . tooltip ( 'allow-self-registration-help' ) . '">'
          779  +   . translate ( 'Allow self-registration' ) . ':</label>'
          780  +   . print_radio ( 'ALLOW_SELF_REGISTRATION', '', 'sr_handler' ) . '</p>
          781  +          <div id="sr">
          782  +            <p><label title="' . tooltip ( 'use-blacklist-help' ) . '">'
          783  +   . translate ( 'Restrict self-registration to blacklist' ) . ':</label>'
          784  +   . print_radio ( 'SELF_REGISTRATION_BLACKLIST' ) . '</p>
          785  +            <p><label title="' . tooltip ( 'allow-self-registration-full-help' )
          786  +   . '">' . translate ( 'Use self-registration email notifications' )
          787  +   . ':</label>' . print_radio ( 'SELF_REGISTRATION_FULL' ) . '</p><br />
          788  +          </div>
          789  +
          790  +<!-- TODO add account aging feature. -->
          791  +
          792  +<!-- BEGIN ATTACHMENTS/COMMENTS -->
          793  +        <div><p><label title="' 
          794  +   . tooltip ( 'allow-attachment-help' ) . '">'
          795  +   . translate ( 'Allow file attachments to events' ) . ':</label>'
          796  +   . print_radio ( 'ALLOW_ATTACH', '', 'attach_handler' )
          797  +    . '</p><p id="at1" style="margin-left:25%"><strong>Note: </strong>'
          798  +   . translate ( 'Admin and owner can always add attachments if enabled.' )
          799  +   . '<br />' . print_checkbox ( array ( 'ALLOW_ATTACH_PART', 'Y', $partyStr ) )
          800  +   . print_checkbox ( array ( 'ALLOW_ATTACH_ANY', 'Y', $anyoneStr ) )
          801  +   . '</p><br/><p><label title="' 
          802  +   . tooltip ( 'allow-comments-help' ) . '">'
          803  +   . translate ( 'Allow comments to events' ) . ':</label>'
          804  +   . print_radio ( 'ALLOW_COMMENTS', '', 'comment_handler' )
          805  +   . '</p><p id="com1" style="margin-left:25%"><strong>Note: </strong>'
          806  +   . translate ( 'Admin and owner can always add comments if enabled.' )
          807  +   . '<br />' . print_checkbox ( array ( 'ALLOW_COMMENTS_PART', 'Y', $partyStr ) )
          808  +   . print_checkbox ( array ( 'ALLOW_COMMENTS_ANY', 'Y', $anyoneStr ) )
          809  +   . '</p><br /></div></div>
          810  +
          811  +<!-- BEGIN EMAIL -->
          812  +        <div id="tabscontent_email">
          813  +          <p><label title="' . tooltip ( 'email-enabled-help' ) . '">'
          814  +   . translate ( 'Email enabled' ) . ':</label>'
          815  +   . print_radio ( 'SEND_EMAIL', '', 'email_handler' ) . '</p>
          816  +          <div id="em">
          817  +            <p><label title="' . tooltip ( 'email-default-sender' ) . '">'
          818  +   . translate ( 'Default sender address' )
          819  +   . ':</label><input type="text" size="30" name="admin_EMAIL_FALLBACK_FROM" value="'
          820  +   . htmlspecialchars ( $EMAIL_FALLBACK_FROM ) . '" /></p>
          821  +            <p><label title="' . tooltip ( 'email-mailer' ) . '">'
          822  +   . translate ( 'Email Mailer' ) . ':</label>
          823  +              <select name="admin_EMAIL_MAILER" onchange="email_handler()">'
          824  +   . $option . 'smtp" ' . ( $s['EMAIL_MAILER'] == 'smtp' ? $selected : '' )
          825  +   . '>SMTP</option>' . $option . 'mail" '
          826  +   . ( $s['EMAIL_MAILER'] == 'mail' ? $selected : '' ) . '>PHP mail</option>'
          827  +   . $option . 'sendmail" '
          828  +   . ( $s['EMAIL_MAILER'] == 'sendmail' ? $selected : '' ) . '>sendmail</option>
          829  +              </select></p>
          830  +            <div id="em_smtp">
          831  +              <p><label title="' . tooltip ( 'email-smtp-host' ) . '">'
          832  +   . translate ( 'SMTP Host name(s)' )
          833  +   . ':</label><input type="text" size="50" name="admin_SMTP_HOST" value="'
          834  +   . $s['SMTP_HOST'] . '" /></p>
          835  +              <p><label title="' . tooltip ( 'email-smtp-port' ) . '">'
          836  +   . translate ( 'SMTP Port Number' )
          837  +   . ':</label><input type="text" size="4" name="admin_SMTP_PORT" value="'
          838  +   . $s['SMTP_PORT'] . '" /></p>
          839  +              <p><label title="' . tooltip ( 'email-smtp-auth' ) . '">'
          840  +   . translate ( 'SMTP Authentication' ) . ':</label>'
          841  +   . print_radio ( 'SMTP_AUTH', '', 'email_handler' ) . '</p>
          842  +              <div id="em_auth">
          843  +                <p><label title="' . tooltip ( 'email-smtp-username' ) . '">'
          844  +   . translate ( 'SMTP Username' )
          845  +   . ':</label><input type="text" size="30" name="admin_SMTP_USERNAME" value="'
          846  +   . ( empty ( $s['SMTP_USERNAME'] ) ? '' : $s['SMTP_USERNAME'] ) . '" /></p>
          847  +                <p><label title="' . tooltip ( 'email-smtp-password' ) . '">'
          848  +   . translate ( 'SMTP Password' )
          849  +   . ':</label><input type="text" size="30" name="admin_SMTP_PASSWORD" value="'
          850  +   . ( empty ( $s['SMTP_PASSWORD'] ) ? '' : $s['SMTP_PASSWORD'] ) . '" /></p>
          851  +              </div>
          852  +            </div>
          853  +            <p class="bold">' . translate ( 'Default user settings' ) . ':</p>'
          854  +   . "<blockquote id=\"default-user-settings\">\n"
          855  +   . '<p><label title="' . tooltip ( 'email-format' ) . '">'
          856  +   . translate ( 'Email format preference' ) . ':</label>'
          857  +   . print_radio ( 'EMAIL_HTML',
          858  +     array ( 'Y'=> translate ( 'HTML' ),
          859  +             'N'=>translate ( 'Plain Text' ) )  ) . '</p>' 
          860  +   . '<p><label title="' . tooltip ( 'email-include-ics' ) . '">'
          861  +   . translate ( 'Include iCalendar attachments' ) . ':</label>'
          862  +   . print_radio ( 'EMAIL_ATTACH_ICS' ) . '</p>' 
          863  +   . '<p><label title="' . tooltip ( 'email-event-reminders-help' ) . '">'
          864  +   . translate ( 'Event reminders' ) . ':</label>'
          865  +   . print_radio ( 'EMAIL_REMINDER' ) . '</p>' 
          866  +   . '<p><label title="' . tooltip ( 'email-event-added' ) . '">'
          867  +   . translate ( 'Events added to my calendar' ) . ':</label>'
          868  +   . print_radio ( 'EMAIL_EVENT_ADDED' ) . '</p>
          869  +            <p><label title="' . tooltip ( 'email-event-updated' ) . '">'
          870  +   . translate ( 'Events updated on my calendar' ) . ':</label>'
          871  +   . print_radio ( 'EMAIL_EVENT_UPDATED' ) . '</p>
          872  +            <p><label title="' . tooltip ( 'email-event-deleted' ) . '">'
          873  +   . translate ( 'Events removed from my calendar' ) . ':</label>'
          874  +   . print_radio ( 'EMAIL_EVENT_DELETED' ) . '</p>
          875  +            <p><label title="' . tooltip ( 'email-event-rejected' ) . '">'
          876  +   . translate ( 'Event rejected by participant' ) . ':</label>'
          877  +   . print_radio ( 'EMAIL_EVENT_REJECTED' ) . '</p>
          878  +            <p><label title="' . tooltip ( 'email-event-create' ) . '">'
          879  +   . translate ( 'Event that I create' ) . ':</label>'
          880  +   . print_radio ( 'EMAIL_EVENT_CREATE' ) . '</p>
          881  +          </blockquote>
          882  +          </div>
          883  +        </div>
          884  +
          885  +<!-- BEGIN COLORS -->
          886  +        <div id="tabscontent_colors">
          887  +          <fieldset>
          888  +            <legend>' . translate ( 'Color options' ) . '</legend>
          889  +<!-- BEGIN EXAMPLE MONTH -->
          890  +            <div style="float:right; width:45%; margin:0; background:'
          891  +   . $BGCOLOR . '">
          892  +              <p class="bold" style="text-align:center; color:' . $H2COLOR
          893  +   . ';">' . date_to_str ( date ( 'Ymd' ), $DATE_FORMAT_MY, false ) . '</p>'
          894  +   . display_month ( date ( 'm' ), date ( 'Y' ), true ) . '
          895  +            </div>
          896  +<!-- END EXAMPLE MONTH -->
          897  +            <p><label>' . translate ( 'Allow user to customize colors' )
          898  +   . ':</label>' . print_radio ( 'ALLOW_COLOR_CUSTOMIZATION' ) . '</p>
          899  +            <p><label title="' . tooltip ( 'gradient-colors' ) . '">'
          900  +   . translate ( 'Enable gradient images for background colors' ) . ':</label>'
          901  +   . ( function_exists ( 'imagepng' ) || function_exists ( 'imagegif' )
          902  +    ? print_radio ( 'ENABLE_GRADIENTS' ) : translate ( 'Not available' ) )
          903  +   . '</p><br />' . $color_sets . '
          904  +          </fieldset>
          905  +          <fieldset>
          906  +            <legend>' . translate ( 'Background Image options' ) . '</legend>
          907  +            <p><label for="admin_BGIMAGE" title="' . tooltip ( 'bgimage-help' )
          908  +   . '">' . translate ( 'Background Image' )
          909  +   . ':</label><input type="text" size="75" name="admin_BGIMAGE" id="admin_BGIMAGE" value="'
          910  +   . ( empty ( $s['BGIMAGE'] ) ? '' : htmlspecialchars ( $s['BGIMAGE'] ) ) . '" /></p>
          911  +            <p><label for="admin_BGREPEAT" title="' . tooltip ( 'bgrepeat-help' )
          912  +   . '">' . translate ( 'Background Repeat' )
          913  +   . ':</label><input type="text" size="30" name="admin_BGREPEAT" id="admin_BGREPEAT" value="'
          914  +   . ( empty ( $s['BGREPEAT'] ) ? '' : $s['BGREPEAT'] ) . '" /></p>
          915  +          </fieldset>
          916  +        </div>
          917  +      </div>
          918  +      <div style="clear:both;">
          919  +        <input type="submit" value="' . $saveStr . '" name="" />
          920  +      </div>
          921  +    </form>';
          922  +  ob_end_flush ();
          923  +} else // if $error
          924  +  echo print_error ( $error, true );
          925  +echo print_trailer ();
          926  +
          927  +?>

Added adminhome.php.

            1  +<?php
            2  +/* $Id: adminhome.php,v 1.40.2.1 2008/03/07 13:36:38 cknudsen Exp $
            3  +
            4  + Page Description:
            5  +  Serves as the home page for administrative functions.
            6  + Input Parameters:
            7  +  None
            8  + Security:
            9  +  Users will see different options available on this page.
           10  + */
           11  +include_once 'includes/init.php';
           12  +
           13  +define ( 'COLUMNS', 3 );
           14  +
           15  +print_header ( '', '
           16  +    <style type="text/css">
           17  +      table.admin,
           18  +      .admin td a {
           19  +        background:' . $CELLBG . '
           20  +      }
           21  +      table.admin {
           22  +        border:1px solid #000;
           23  +        padding:5px
           24  +      }
           25  +      table.admin td {
           26  +        padding:20px
           27  +      }
           28  +      table.admin td,
           29  +      .admin td a {
           30  +        text-align:center
           31  +      }
           32  +      .admin td a {
           33  +        border:1px solid #EEE;
           34  +        border-color:#EEE #777 #777 #EEE;
           35  +        padding:10px
           36  +      }
           37  +      .admin td a:hover {
           38  +        border-color:#777 #EEE #EEE #777
           39  +        background:#AAA;
           40  +      }
           41  +    </style>
           42  +'
           43  +  );
           44  +
           45  +$assistStr = translate ( 'Assistants' );
           46  +$prefStr = translate ( 'Preferences' );
           47  +$names = $links = array ();
           48  +/* Disabled for now...will move to menu when working properly
           49  +if ( $is_admin && ! empty ( $SERVER_URL ) &&
           50  +    access_can_access_function ( ACCESS_SYSTEM_SETTINGS ) ) {
           51  +  $names[] = translate ( 'Control Panel' );
           52  +  $links[] = 'controlpanel.php';
           53  +}
           54  +*/
           55  +if ( $is_nonuser_admin ) {
           56  +  if ( ! access_is_enabled () ||
           57  +      access_can_access_function ( ACCESS_PREFERENCES ) ) {
           58  +    $names[] = $prefStr;
           59  +    $links[] = 'pref.php?user=' . $user;
           60  +  }
           61  +
           62  +  if ( $single_user != 'Y' ) {
           63  +    if ( ! access_is_enabled () ||
           64  +        access_can_access_function ( ACCESS_ASSISTANTS ) ) {
           65  +      $names[] = $assistStr;
           66  +      $links[] = 'assistant_edit.php?user=' . $user;
           67  +    }
           68  +  }
           69  +} else {
           70  +  if ( ( $is_admin && ! access_is_enabled () ) || ( access_is_enabled () &&
           71  +        access_can_access_function ( ACCESS_SYSTEM_SETTINGS ) ) ) {
           72  +    $names[] = translate ( 'System Settings' );
           73  +    $links[] = 'admin.php';
           74  +  }
           75  +
           76  +  if ( ! access_is_enabled () ||
           77  +      access_can_access_function ( ACCESS_PREFERENCES ) ) {
           78  +    $names[] = $prefStr;
           79  +    $links[] = 'pref.php';
           80  +  }
           81  +
           82  +  $names[] = ( $is_admin ? translate ( 'Users' ) : translate ( 'Account' ) );
           83  +  $links[] = 'users.php';
           84  +
           85  +  if ( access_is_enabled () &&
           86  +      access_can_access_function ( ACCESS_ACCESS_MANAGEMENT ) ) {
           87  +    $names[] = translate ( 'User Access Control' );
           88  +    $links[] = 'access.php';
           89  +  }
           90  +
           91  +  if ( $single_user != 'Y' ) {
           92  +    if ( ! access_is_enabled () ||
           93  +        access_can_access_function ( ACCESS_ASSISTANTS ) ) {
           94  +      $names[] = $assistStr;
           95  +      $links[] = 'assistant_edit.php';
           96  +    }
           97  +  }
           98  +
           99  +  if ( $CATEGORIES_ENABLED == 'Y' ) {
          100  +    if ( ! access_is_enabled () ||
          101  +        access_can_access_function ( ACCESS_CATEGORY_MANAGEMENT ) ) {
          102  +      $names[] = translate ( 'Categories' );
          103  +      $links[] = 'category.php';
          104  +    }
          105  +  }
          106  +
          107  +  if ( ! access_is_enabled () ||
          108  +      access_can_access_function ( ACCESS_VIEW_MANAGEMENT ) ) {
          109  +    $names[] = translate ( 'Views' );
          110  +    $links[] = 'views.php';
          111  +  }
          112  +
          113  +  if ( ! access_is_enabled () ||
          114  +      access_can_access_function ( ACCESS_LAYERS ) ) {
          115  +    $names[] = translate ( 'Layers' );
          116  +    $links[] = 'layers.php';
          117  +  }
          118  +
          119  +  if ( $REPORTS_ENABLED == 'Y' &&
          120  +    ( ! access_is_enabled () ||
          121  +        access_can_access_function ( ACCESS_REPORT ) ) ) {
          122  +    $names[] = translate ( 'Reports' );
          123  +    $links[] = 'report.php';
          124  +  }
          125  +
          126  +  if ( $is_admin ) {
          127  +    $names[] = translate ( 'Delete Events' );
          128  +    $links[] = 'purge.php';
          129  +  }
          130  +  /*
          131  + This Activity Log link shows ALL activity for ALL events, so you really need
          132  + to be an admin user for this. Enabling "Activity Log" in UAC just gives you
          133  + access to the log for your _own_ events or other events you have access to.
          134  + */
          135  +  if ( $is_admin && ( ! access_is_enabled () ||
          136  +        access_can_access_function ( ACCESS_ACTIVITY_LOG ) ) ) {
          137  +    $names[] = translate ( 'Activity Log' );
          138  +    $links[] = 'activity_log.php';
          139  +
          140  +    $names[] = translate ( 'System Log' );
          141  +    $links[] = 'activity_log.php?system=1';
          142  +  }
          143  +
          144  +  if ( ( $is_admin || ! access_is_enabled () ) ||
          145  +    ( access_is_enabled && 
          146  +    access_can_access_function ( ACCESS_SECURITY_AUDIT ) ) ) {
          147  +    $names[] = translate ( 'Security Audit' );
          148  +    $links[] = 'security_audit.php';
          149  +  }
          150  +
          151  +  if ( $is_admin && ! empty ( $PUBLIC_ACCESS ) && $PUBLIC_ACCESS == 'Y' ) {
          152  +    $names[] = translate ( 'Public Preferences' );
          153  +    $links[] = 'pref.php?public=1';
          154  +  }
          155  +
          156  +  if ( $is_admin && ! empty ( $PUBLIC_ACCESS ) && $PUBLIC_ACCESS == 'Y' &&
          157  +    $PUBLIC_ACCESS_CAN_ADD == 'Y' && $PUBLIC_ACCESS_ADD_NEEDS_APPROVAL == 'Y' ) {
          158  +    $names[] = translate ( 'Unapproved Public Events' );
          159  +    $links[] = 'list_unapproved.php?user=__public__';
          160  +  }
          161  +}
          162  +
          163  +echo '
          164  +    <h2>' . translate ( 'Administrative Tools' ) . '</h2>
          165  +    <table class="admin">';
          166  +
          167  +for ( $i = 0, $cnt = count ( $names ); $i < $cnt; $i++ ) {
          168  +  echo ( $i % COLUMNS == 0 ? '
          169  +      <tr>' : '' ) . '
          170  +        <td>' . ( ! empty ( $links[$i] ) ? '<a href="' . $links[$i] . '">' : '' )
          171  +   . $names[$i] . ( ! empty ( $links[$i] ) ? '</a>' : '' ) . '</td>'
          172  +   . ( $i % COLUMNS == COLUMNS - 1 ? '
          173  +      </tr>' : '' );
          174  +}
          175  +
          176  +if ( $i % COLUMNS != 0 ) {
          177  +  while ( $i % COLUMNS != 0 ) {
          178  +    echo '
          179  +        <td>&nbsp;</td>';
          180  +    $i++;
          181  +  }
          182  +}
          183  +echo '
          184  +      </tr>
          185  +    </table>
          186  +    ' . print_trailer ();
          187  +
          188  +?>

Added ajax.php.

            1  +<?php
            2  +/* $Id: ajax.php,v 1.16.2.9 2012/03/03 01:54:14 cknudsen Exp $
            3  + *
            4  + * Description
            5  + * This is the handler for Ajax httpXmlRequests.
            6  + */
            7  +require_once 'includes/classes/WebCalendar.class';
            8  +
            9  +$WebCalendar = new WebCalendar ( __FILE__ );
           10  +
           11  +include 'includes/translate.php';
           12  +include 'includes/config.php';
           13  +include 'includes/dbi4php.php';
           14  +include 'includes/formvars.php';
           15  +include 'includes/functions.php';
           16  +require_valide_referring_url ();
           17  +
           18  +$WebCalendar->initializeFirstPhase ();
           19  +
           20  +include 'includes/' . $user_inc;
           21  +include 'includes/access.php';
           22  +include 'includes/validate.php';
           23  +
           24  +$WebCalendar->initializeSecondPhase ();
           25  +
           26  +load_global_settings ();
           27  +load_user_preferences ();
           28  +$WebCalendar->setLanguage ();
           29  +
           30  +$cat_id = getValue ( 'cat_id', '-?[0-9,\-]*', true );
           31  +$name = getPostValue ( 'name' );
           32  +$page = getPostValue ( 'page' );
           33  +
           34  +// We're processing edit_remotes Calendar ID field.
           35  +if ( $page == 'edit_remotes' || $page == 'edit_nonuser' ) {
           36  +  $res = dbi_execute ( 'SELECT cal_login FROM webcal_nonuser_cals
           37  +    WHERE cal_login = ?', array ( $NONUSER_PREFIX . $name ) );
           38  +  if ( $res ) {
           39  +    $row = dbi_fetch_row ( $res );
           40  +    // Presuming we are using '_NUC_' as $NONUSER_PREFIX.
           41  +    if ( $name == substr ( $row[0], strlen ( $NONUSER_PREFIX ) ) )
           42  +      // translate ( 'Duplicate Name' )
           43  +      echo str_replace ( 'XXX', $name, translate ( 'Duplicate Name XXX', true ) );
           44  +  }
           45  +} elseif ( $page == 'register' || $page == 'edit_user' ) {
           46  +  // We're processing username field.
           47  +  $res = dbi_execute ( 'SELECT cal_login FROM webcal_user WHERE cal_login = ?',
           48  +    array ( $name ) );
           49  +  if ( $res ) {
           50  +    $row = dbi_fetch_row ( $res );
           51  +    // translate ( 'Username already exists.' )
           52  +    if ( $row[0] == $name )
           53  +      echo str_replace ( 'XXX', $name,
           54  +        translate ( 'Username XXX already exists.', true ) );
           55  +  }
           56  +} elseif ( $page == 'email' ) {
           57  +  // We're processing email field from any page.
           58  +  $res = dbi_execute ( 'SELECT cal_email FROM webcal_user WHERE cal_email = ?',
           59  +    array ( $name ) );
           60  +  if ( $res ) {
           61  +    $row = dbi_fetch_row ( $res );
           62  +    // translate ( 'Email address already exists.' )
           63  +    if ( $row[0] == $name )
           64  +      echo str_replace ( 'XXX', $name,
           65  +        translate ( 'Email address XXX already exists.', true ) );
           66  +  }
           67  +} elseif ( $page == 'minitask' ) {
           68  +  $name = ( ! empty ( $name ) ? $name : 0 );
           69  +  require_once 'includes/classes/Event.class';
           70  +  require_once 'includes/classes/RptEvent.class';
           71  +  include_once 'includes/gradient.php';
           72  +  $column_array = array ( 'we.cal_priority', 'we.cal_name',
           73  +    'we.cal_due_date', 'weu.cal_percent' );
           74  +  $task_filter = ' ORDER BY ' . $column_array[$name % 4]
           75  +   . ( $name > 3 ? ' ASC' : ' DESC' );
           76  +  echo display_small_tasks ( $cat_id );
           77  +}
           78  +
           79  +?>

Added approve_entry.php.

            1  +<?php
            2  +/* $Id: approve_entry.php,v 1.50.2.5 2012/02/28 02:07:45 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +require_valide_referring_url ();
            5  +require ( 'includes/classes/WebCalMailer.class' );
            6  +
            7  +$error = '';
            8  +
            9  +if ( $readonly == 'Y' )
           10  +  $error = print_not_auth (4);
           11  +// Give user a chance to add comments to approval email.
           12  +if ( getPostValue ( 'comments' ) != '' ) {
           13  +  $comments = getPostValue ( 'comments' );
           14  +  $cancel = getPostValue ( 'cancel' );
           15  +} else
           16  +if ( empty ( $ret ) ) {
           17  +  $q_string = ( ! empty ( $_SERVER['QUERY_STRING'] )
           18  +    ? '?' . $_SERVER['QUERY_STRING'] : '' );
           19  +
           20  +  print_header ();
           21  +  echo '
           22  +    <form action="approve_entry.php' . $q_string
           23  +   . '" method="post" name="add_comments">
           24  +      <table border="0" cellspacing="5">
           25  +        <tr>
           26  +          <td align="center" valign="bottom"><h3>'
           27  +   . translate ( 'Additional Comments (optional)' ) . '</h3></td>
           28  +        <tr>
           29  +        <tr>
           30  +          <td align="center"><textarea name="comments" rows="5" '
           31  +   . 'cols="60"></textarea></td>
           32  +        </tr>
           33  +        <tr>
           34  +          <td align="center">
           35  +            <input type="submit" value="' . translate ( 'Approve and Send' )
           36  +   . '" />&nbsp;&nbsp;&nbsp;
           37  +            <input type="submit" value="' . translate ( 'Approve and Exit' )
           38  +   . '" />
           39  +          </td>
           40  +        </tr>
           41  +        <tr>
           42  +          <td>'
           43  +  . translate ( '(Your comments will be emailed to the event creator.)' ) . '</td>
           44  +        </tr>
           45  +      </table>
           46  +    </form>
           47  +  </body>
           48  +</html>
           49  +';
           50  +  exit;
           51  +}
           52  +
           53  +$user = getValue ( 'user' );
           54  +$type = getValue ( 'type' );
           55  +$id = getValue ( 'id' );
           56  +
           57  +// Allow administrators to approve public events.
           58  +$app_user = ( $PUBLIC_ACCESS == 'Y' && ! empty ( $public ) && $is_admin
           59  +  ? '__public__' : ( $is_assistant || $is_nonuser_admin ? $user : $login ) );
           60  +// If User Access Control is enabled, we check to see if they are
           61  +// allowed to approve for the specified user.
           62  +if ( access_is_enabled () && ! empty ( $user ) && $user != $login &&
           63  +    access_user_calendar ( 'approve', $user ) )
           64  +  $app_user = $user;
           65  +
           66  +if ( empty ( $error ) && $id > 0 )
           67  +  update_status ( 'A', $app_user, $id, $type );
           68  +
           69  +if ( ! empty ( $comments ) && empty ( $cancel ) ) {
           70  +  $mail = new WebCalMailer;
           71  +  // Email event creator to notify that it was approved with comments.
           72  +  // Get the name of the event.
           73  +  $res = dbi_execute ( 'SELECT cal_name, cal_description, cal_date, cal_time,
           74  +    cal_create_by FROM webcal_entry WHERE cal_id = ?', array ( $id ) );
           75  +  if ( $res ) {
           76  +    $row = dbi_fetch_row ( $res );
           77  +    $name = $row[0];
           78  +    $description = $row[1];
           79  +    $fmtdate = $row[2];
           80  +    $time = sprintf ( "%06d", $row[3] );
           81  +    $creator = $row[4];
           82  +    dbi_free_result ( $res );
           83  +  }
           84  +
           85  +  $eventstart = date_to_epoch ( $fmtdate . $time );
           86  +  // TODO figure out if creator wants approved comment email.
           87  +  // Check UAC.
           88  +  $send_user_mail = ( access_is_enabled ()
           89  +    ? access_user_calendar ( 'email', $creator, $login ) : 'Y' );
           90  +
           91  +  $htmlmail = get_pref_setting ( $creator, 'EMAIL_HTML' );
           92  +  user_load_variables ( $creator, 'temp' );
           93  +  $user_TIMEZONE = get_pref_setting ( $creator, 'TIMEZONE' );
           94  +  set_env ( 'TZ', $user_TIMEZONE );
           95  +  $user_language = get_pref_setting ( $creator, 'LANGUAGE' );
           96  +  if ( $send_user_mail == 'Y' && strlen ( $tempemail ) && $SEND_EMAIL != 'N' ) {
           97  +    reset_language ( empty ( $user_language ) || ( $user_language == 'none' )
           98  +      ? $LANGUAGE : $user_language );
           99  +
          100  +    // translate ( 'Hello' )
          101  +    $msg = str_replace ( 'XXX', $tempfullname, translate ( 'Hello, XXX.' ) )
          102  +    // translate ( 'An appointment has been approved and comments added by' )
          103  +    . "\n\n" . str_replace ( 'XXX', $login_fullname,
          104  +      translate ( 'XXX has approved an appointment and added comments.' ) ) . "\n\n"
          105  +    // translate ( 'The subject was' )
          106  +    . str_replace ( 'XXX', $name, translate ( 'Subject XXX' ) ) . "\n"
          107  +    // translate ( 'The description is' )
          108  +    . str_replace ( 'XXX', $description, translate ( 'Description XXX' ) ) . "\n"
          109  +    // translate ( 'Date' )
          110  +    . str_replace ( 'XXX', date_to_str ( $fmtdate ), translate ( 'Date XXX' ) )
          111  +    // translate ( 'Time' )
          112  +    . ' ' . ( empty ( $hour ) && empty ( $minute )
          113  +      ? '' : str_replace ( 'XXX',
          114  +        // Display using user's GMT offset and display TZID.
          115  +        display_time ( '', 2, $eventstart,
          116  +          get_pref_setting ( $creator, 'TIME_FORMAT' ) ),
          117  +        translate ( 'Time XXX' ) ) ) . "\n";
          118  +
          119  +    if ( ! empty ( $SERVER_URL ) ) {
          120  +      // DON'T change & to &amp; here. email will handle it
          121  +      $url = $SERVER_URL . 'view_entry.php?id=' . $id . '&em=1';
          122  +      if ( $htmlmail == 'Y' )
          123  +        $url = activate_urls ( $url );
          124  +
          125  +      $msg .= "\n" . $url;
          126  +    }
          127  +    if ( ! empty ( $comments ) )
          128  +      // translate ( 'Comments' )
          129  +      $msg .= "\n\n" . str_replace ( 'XXX', $comments,
          130  +        translate ( 'Comments XXX' ) );
          131  +
          132  +    $from = ( strlen ( $login_email ) ? $login_email : $EMAIL_FALLBACK_FROM );
          133  +    // Send mail.
          134  +    $mail->WC_Send ( $login_fullname, $tempemail,
          135  +      $tempfullname, $name, $msg, $htmlmail, $from );
          136  +    activity_log ( $id, $login, $creator, LOG_NOTIFICATION,
          137  +      str_replace ( 'XXX', $app_user,
          138  +        translate ( 'Approved w/Comments by XXX.' ) ) );
          139  +  }
          140  +}
          141  +// Return to login TIMEZONE.
          142  +set_env ( 'TZ', $TIMEZONE );
          143  +if ( empty ( $error ) && empty ( $mailerError ) ) {
          144  +  do_redirect ( ! empty ( $ret ) && $ret == 'listall'
          145  +    ? 'list_unapproved.php'
          146  +    : ( ( ! empty ( $ret ) && $ret == 'list'
          147  +        ? 'list_unapproved.php?'
          148  +        : 'view_entry.php?id=' . $id . '&amp;' ) . 'user=' . $app_user ) );
          149  +  exit;
          150  +}
          151  +// Process errors.
          152  +$mail->MailError ( $mailerError, $error );
          153  +
          154  +?>

Added assistant_edit.php.

            1  +<?php
            2  +/* $Id: assistant_edit.php,v 1.38 2007/07/28 19:21:57 bbannon Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +if ( empty ( $login ) || $login == '__public__' ) {
            6  +  // Do not allow public access.
            7  +  do_redirect ( empty ( $STARTVIEW ) ? 'month.php' : "$STARTVIEW" );
            8  +  exit;
            9  +}
           10  +
           11  +if ( $user != $login )
           12  +  $user = ( ( $is_admin || $is_nonuser_admin ) && $user ) ? $user : $login;
           13  +
           14  +print_header ( ( $GROUPS_ENABLED == 'Y'
           15  +    ? array ( 'js/assistant_edit.php/true' ) : '' ) );
           16  +
           17  +ob_start ();
           18  +
           19  +echo '
           20  +    <form action="assistant_edit_handler.php" method="post" '
           21  + . 'name="assistanteditform">' . ( $user ? '
           22  +      <input type="hidden" name="user" value="' . $user . '" />' : '' ) . '
           23  +      <h2>';
           24  +
           25  +$assistStr = translate ( 'Assistants' );
           26  +if ( $is_nonuser_admin ) {
           27  +  nonuser_load_variables ( $user, 'nonuser' );
           28  +  echo $nonuserfullname . ' ' . $assistStr . '<br />
           29  +      -- ' . translate ( 'Admin mode' ) . ' --';
           30  +} else
           31  +  echo translate ( 'Your assistants' );
           32  +
           33  +echo '</h2>
           34  +      ' . display_admin_link () . '
           35  +      <table>
           36  +        <tr>
           37  +          <td class="aligntop"><label for="users">'
           38  + . $assistStr . ':</label></td>
           39  +          <td>
           40  +            <select name="users[]" id="users" size="10" multiple="multiple">';
           41  +
           42  +// Get list of all users.
           43  +$users = get_my_users ();
           44  +// Get list of users for this view.
           45  +$res = dbi_execute ( 'SELECT cal_boss, cal_assistant FROM webcal_asst
           46  +   WHERE cal_boss = ?', array ( $user ) );
           47  +
           48  +if ( $res ) {
           49  +  while ( $row = dbi_fetch_row ( $res ) ) {
           50  +    $assistantuser[$row[1]] = 1;
           51  +  }
           52  +  dbi_free_result ( $res );
           53  +}
           54  +
           55  +for ( $i = 0, $cnt = count ( $users ); $i < $cnt; $i++ ) {
           56  +  $u = $users[$i]['cal_login'];
           57  +  if ( $u == $login || $u == '__public__' )
           58  +    continue;
           59  +  echo '
           60  +              <option value="' . $u . '"'
           61  +   . ( ! empty ( $assistantuser[$u] ) ? ' selected="selected"' : '' ) . '>'
           62  +   . $users[$i]['cal_fullname'] . '</option>';
           63  +}
           64  +
           65  +echo '
           66  +            </select>' . ( $GROUPS_ENABLED == 'Y' ? '
           67  +            <input type="button" onclick="selectUsers()" value="'
           68  +   . translate ( 'Select' ) . '..." />' : '' ) . '
           69  +          </td>
           70  +        </tr>
           71  +        <tr>
           72  +          <td colspan="2" class="aligncenter"><br /><input type="submit" '
           73  + . 'name="action" value="' . translate ( 'Save' ) . '" />
           74  +          </td>
           75  +        </tr>
           76  +      </table>
           77  +    </form>
           78  +    ';
           79  +
           80  +ob_end_flush ();
           81  +
           82  +echo print_trailer ();
           83  +
           84  +?>

Added assistant_edit_handler.php.

            1  +<?php
            2  +/* $Id: assistant_edit_handler.php,v 1.19.2.2 2012/02/28 02:07:45 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +require_valide_referring_url ();
            5  +
            6  +$user = getPostValue ( 'user' );
            7  +$users = getPostValue ( 'users' );
            8  +
            9  +$error = '';
           10  +if ( $user != $login )
           11  +  $user = ( ( $is_admin || $is_nonuser_admin ) && $user ) ? $user : $login;
           12  +# update user list
           13  +dbi_execute ( 'DELETE FROM webcal_asst WHERE cal_boss = ?', array ( $user ) );
           14  +if ( ! empty ( $users ) ) {
           15  +  for ( $i = 0, $cnt = count ( $users ); $i < $cnt; $i++ ) {
           16  +    dbi_execute ( 'INSERT INTO webcal_asst ( cal_boss, cal_assistant )
           17  +      VALUES ( ?, ? )', array ( $user, $users[$i] ) );
           18  +  }
           19  +}
           20  +
           21  +echo error_check ( 'assistant_edit.php'
           22  +   . ( ( $is_admin || $is_nonuser_admin ) && $login != $user
           23  +    ? '?user=' . $user : '' ) );
           24  +
           25  +?>

Added availability.php.

            1  +<?php
            2  +/* $Id: availability.php,v 1.24.2.3 2008/04/04 18:07:40 umcesrjones Exp $
            3  + * Page Description:
            4  + * Display a timebar view of a single day.
            5  + *
            6  + * Input Parameters:
            7  + * month (*) - specify the starting month of the timebar
            8  + * day (*)   - specify the starting day of the timebar
            9  + * year (*)  - specify the starting year of the timebar
           10  + * users (*) - csv of users to include
           11  + * (*) required field
           12  + *
           13  + * Security:
           14  + * Must have "allow view others" enabled ($ALLOW_VIEW_OTHER) in
           15  + *   System Settings unless the user is an admin user ($is_admin).
           16  + */
           17  +
           18  +include_once 'includes/init.php';
           19  +// Don't allow users to use this feature if "allow view others" is disabled.
           20  +if ( $ALLOW_VIEW_OTHER == 'N' && ! $is_admin )
           21  +  // not allowed...
           22  +  exit;
           23  +
           24  +
           25  +$users = getGetValue ( 'users' );
           26  +$year = getGetValue ( 'year' );
           27  +$month = getGetValue ( 'month' );
           28  +$day = getGetValue ( 'day' );
           29  +
           30  +// Input args in URL.
           31  +// users: list of comma-separated users.
           32  +// translate ( 'Program Error' ) translate ( 'No XXX specified!' )
           33  +$noXStr = translate ( 'Program Error No XXX specified!' );
           34  +if ( empty ( $users ) ) {
           35  +  echo str_replace ( 'XXX', translate ( 'user' ), $noXStr );
           36  +  exit;
           37  +} elseif ( empty ( $year ) ) {
           38  +  echo str_replace ( 'XXX', translate ( 'year' ), $noXStr );
           39  +  exit;
           40  +} elseif ( empty ( $month ) ) {
           41  +  echo str_replace ( 'XXX', translate ( 'month' ), $noXStr );
           42  +  exit;
           43  +} elseif ( empty ( $day ) ) {
           44  +  echo str_replace ( 'XXX', translate ( 'day' ), $noXStr );
           45  +  exit;
           46  +}
           47  +
           48  +print_header (
           49  +  array ( 'js/availability.php/false/' . "$month/$day/$year/"
           50  +   . getGetValue ( 'form' ) ), '', 'onload="focus();"', true, false, true );
           51  +
           52  +$next_url = $prev_url = '?users=' . $users;
           53  +$time = mktime ( 0, 0, 0, $month, $day, $year );
           54  +$date = date ( 'Ymd', $time );
           55  +$next_url .= strftime ( '&amp;year=%Y&amp;month=%m&amp;day=%d', $time + 86400 );
           56  +$prev_url .= strftime ( '&amp;year=%Y&amp;month=%m&amp;day=%d', $time - 86400 );
           57  +$span = ( $WORK_DAY_END_HOUR - $WORK_DAY_START_HOUR ) * 3 + 1;
           58  +
           59  +$users = explode ( ',', $users );
           60  +
           61  +$nextStr = translate ( 'Next' );
           62  +$prevStr = translate ( 'Previous' );
           63  +
           64  +echo '
           65  +    <div style="width:99%;">
           66  +      <a title="' . $prevStr . '" class="prev" href="' . $prev_url
           67  + . '"><img src="images/leftarrow.gif" class="prev" alt="'
           68  + . $prevStr . '" /></a>
           69  +      <a title="' . $nextStr . '" class="next" href="' . $next_url
           70  + . '"><img src="images/rightarrow.gif" class="next" alt="'
           71  + . $nextStr . '" /></a>
           72  +      <div class="title">
           73  +        <span class="date">';
           74  +printf ( "%s, %s %d, %d", weekday_name ( strftime ( "%w", $time ) ),
           75  +  month_name ( $month - 1 ), $day, $year );
           76  +echo '</span><br />
           77  +      </div>
           78  +    </div><br />
           79  +    <form action="availability.php" method="post">
           80  +      ' . daily_matrix ( $date, $users ) . '
           81  +    </form>
           82  +    ' . print_trailer ( false, true, true );
           83  +
           84  +?>

Added category.php.

            1  +<?php
            2  +/* $Id: category.php,v 1.45.2.4 2013/01/24 21:10:18 cknudsen Exp $ */
            3  +
            4  +include_once 'includes/init.php';
            5  +// Load user and global cats.
            6  +load_user_categories ();
            7  +
            8  +if ( $CATEGORIES_ENABLED == 'N' ) {
            9  +  send_to_preferred_view ();
           10  +  exit;
           11  +}
           12  +
           13  +$catIcon = $catname = $error = $idStr = '';
           14  +$catIconStr = translate ( 'Category Icon' );
           15  +$globalStr = translate ( 'Global' );
           16  +$icon_path = 'icons/';
           17  +// If editing, make sure they are editing their own (or they are an admin user).
           18  +if ( ! empty ( $id ) ) {
           19  +  if ( empty ( $categories[$id] ) )
           20  +    $error =
           21  +    str_replace ( 'XXX', $id, translate ( 'Invalid entry id XXX.' ) );
           22  +
           23  +  $catcolor = $categories[$id]['cat_color'];
           24  +  $catname = $categories[$id]['cat_name'];
           25  +  $catowner = $categories[$id]['cat_owner'];
           26  +  $catIcon = $icon_path . 'cat-' . $id . '.gif';
           27  +  $idStr = '<input name="id" type="hidden" value="' . $id . '" />';
           28  +} else
           29  +  $catcolor = '#000000';
           30  +
           31  +$showIcon = ( ! empty ( $catIcon ) && file_exists ( $catIcon )
           32  +  ? 'visible' : 'hidden' );
           33  +
           34  +print_header ( array ( 'js/visible.php' ) );
           35  +
           36  +ob_start ();
           37  +
           38  +echo '
           39  +    <h2>' . translate ( 'Categories' ) . '</h2>
           40  +    ' . display_admin_link ();
           41  +
           42  +$add = getGetValue ( 'add' );
           43  +if ( empty ( $add ) )
           44  +  $add = 0;
           45  +// Adding/Editing category.
           46  +if ( ( ( $add == '1' ) || ( ! empty ( $id ) ) ) && empty ( $error ) ) {
           47  +  echo '
           48  +    <form action="category_handler.php" method="post" name="catform" '
           49  +   . 'enctype="multipart/form-data">' . $idStr . '
           50  +      <table cellspacing="2" cellpadding="3">
           51  +        <tr>
           52  +          <td width="25%"><label for="catname">' . translate ( 'Category Name' )
           53  +   . '</label></td>
           54  +          <td colspan="3"><input type="text" name="catname" size="20" value="'
           55  +   . htmlspecialchars ( $catname ) . '" /></td>
           56  +        </tr>' . ( $is_admin && empty ( $id ) ? '
           57  +        <tr>
           58  +          <td><label for="isglobal">' . $globalStr . ':</label></td>
           59  +          <td colspan="3">
           60  +            <label><input type="radio" name="isglobal" value="N" '
           61  +     . ( ! empty ( $catowner ) || empty ( $id ) ? ' checked = "checked"' : '' )
           62  +     . ' />&nbsp;' . translate ( 'No' ) . '</label>&nbsp;&nbsp;
           63  +            <label><input type="radio" name="isglobal" value="Y" '
           64  +     . ( empty ( $catowner ) && ! empty ( $id ) ? ' checked = "checked"' : '' )
           65  +     . ' />&nbsp;' . translate ( 'Yes' ) . '</label>
           66  +          </td>
           67  +        </tr>' : '' ) . '
           68  +        <tr>
           69  +          <td>'
           70  +   . print_color_input_html ( 'catcolor', translate ( 'Color' ), $catcolor )
           71  +   . '</td>
           72  +        </tr>
           73  +        <tr id="cat_icon" style="visibility: ' . $showIcon . '">
           74  +          <td><label>' . $catIconStr . ':</label></td>
           75  +          <td colspan="3"><img src="' . $catIcon
           76  +   . '" name="urlpic" id="urlpic" alt="' . $catIconStr . '" /></td>
           77  +        </tr>
           78  +        <tr id="remove_icon" style="visibility: ' . $showIcon . '">
           79  +          <td><label for="delIcon">' . translate ( 'Remove Icon' )
           80  +   . '</label></td>
           81  +          <td colspan="3"><input type="checkbox" name="delIcon" value="Y" /></td>
           82  +        </tr>
           83  +        <tr>
           84  +          <td colspan="4">
           85  +            <label for="FileName">' . ( is_dir ( $icon_path ) &&
           86  +    ( $ENABLE_ICON_UPLOADS == 'Y' || $is_admin )
           87  +    ? translate ( 'Add Icon to Category' ) . '</label><br />&nbsp;&nbsp;&nbsp;'
           88  +     . translate ( 'Upload' ) . '&nbsp;<span style="font-size:small;">'
           89  +     . translate ( 'gif 3kb max' ) . '</span>:
           90  +            <input type="file" name="FileName" id="fileupload" size="45" '
           91  +     . 'maxlength="50" value=""/>
           92  +          </td>
           93  +        </tr>
           94  +        </tr>
           95  +          <td colspan="4">
           96  +            <input type="hidden" name="urlname" size="50" />&nbsp;&nbsp;&nbsp;
           97  +            <input type="button" value="'
           98  +     . translate ( 'Search for existing icons' )
           99  +     . '" onclick="window.open( \'icons.php\', \'icons\',\''
          100  +     . 'dependent,menubar=no,scrollbars=n0,height=300,width=400,outerHeight=320'
          101  +     . ',outerWidth=420\' );" />
          102  +          </td>
          103  +        </tr>
          104  +        </tr>
          105  +          <td colspan="4">' : '' ) // end test of ENABLE_ICON_UPLOADS
          106  +  . '
          107  +            <input type="submit" name="action" value="'
          108  +   . ( $add == '1' ? translate ( 'Add' ) : translate ( 'Save' ) ) . '" />'
          109  +   . ( ! empty ( $id ) ? '
          110  +            <input type="submit" name="delete" value="'
          111  +     . translate ( 'Delete' ) . '" onclick="return confirm( '
          112  +     . str_replace ( 'XXX', translate ( 'entry', true ),
          113  +      translate ( 'Are you sure you want to delete this XXX?', true ) )
          114  +     . '\' )" />' : '' ) . '
          115  +          </td>
          116  +        </tr>
          117  +      </table>
          118  +    </form>';
          119  +} else
          120  +if ( empty ( $error ) ) {
          121  +  // Displaying Categories.
          122  +  $global_found = false;
          123  +  if ( ! empty ( $categories ) ) {
          124  +    echo '
          125  +    <ul>';
          126  +    foreach ( $categories as $K => $V ) {
          127  +      if ( $K < 1 )
          128  +        continue;
          129  +      $catIcon = $icon_path . 'cat-' . $K . '.gif';
          130  +      $catStr = '<span style="color: '
          131  +       . ( ! empty ( $V['cat_color'] ) ? $V['cat_color'] : '#000000' )
          132  +       . ';">' . htmlentities ( $V['cat_name'] ) . '</span>';
          133  +      echo '
          134  +      <li>' . ( $V['cat_owner'] == $login || $is_admin
          135  +        ? '<a href="category.php?id=' . $K . '">' . $catStr . '</a>' : $catStr );
          136  +
          137  +      if ( empty ( $V['cat_owner'] ) ) {
          138  +        echo '<sup>*</sup>';
          139  +        $global_found = true;
          140  +      }
          141  +
          142  +      echo ( file_exists ( $catIcon ) ? '<img src="' . $catIcon . '" alt="'
          143  +         . $catIconStr . '" title="' . $catIconStr . '" />' : '' ) . '</li>';
          144  +    }
          145  +    echo '
          146  +    </ul>';
          147  +  }
          148  +  echo ( $global_found ? '<br /><br />
          149  +    <sup>*</sup> ' . $globalStr : '' ) . '
          150  +    <p><a href="category.php?add=1">' . translate ( 'Make New Category' )
          151  +   . '</a></p><br />';
          152  +}
          153  +ob_end_flush ();
          154  +echo ( ! empty ( $error ) ? print_error ( $error ) : '' ) . print_trailer ();
          155  +
          156  +?>

Added category_handler.php.

            1  +<?php
            2  +/* $Id: category_handler.php,v 1.33.2.7 2013/01/24 21:10:18 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +require_valide_referring_url ();
            5  +
            6  +$icon_max_size = '3000';
            7  +$icon_path = 'icons/';
            8  +
            9  +/* Rename any icons associated with this cat_id. */
           10  +function renameIcon ( $id ) {
           11  +  global $icon_path;
           12  +  $bakIcon = $catIcon = $icon_path . 'cat-';
           13  +  $bakIcon .= date ( 'YmdHis' ) . '.gif';
           14  +  $catIcon .= $id . '.gif';
           15  +  if ( file_exists ( $catIcon ) )
           16  +    rename ( $catIcon, $bakIcon );
           17  +}
           18  +
           19  +// Does the category belong to the user?
           20  +$is_my_event = false;
           21  +$id = getValue ( 'id' );
           22  +$catname = getValue ( 'catname' );
           23  +// prohibit any html in category name (including <script>)
           24  +$catname = strip_tags ( $catname );
           25  +$catcolor = getValue ( 'catcolor' );
           26  +$isglobal = getValue ( 'isglobal' );
           27  +$delIcon = getPostValue ( 'delIcon' );
           28  +if ( empty ( $id ) )
           29  +  $is_my_event = true; // New event.
           30  +else {
           31  +  $res = dbi_execute ( 'SELECT cat_id, cat_owner FROM webcal_categories
           32  +    WHERE cat_id = ?', array ( $id ) );
           33  +  if ( $res ) {
           34  +    $row = dbi_fetch_row ( $res );
           35  +
           36  +    $is_my_event = ( $row[0] == $id && $row[1] == $login ||
           37  +      ( empty ( $row[1] ) && $is_admin ) );
           38  +
           39  +    dbi_free_result ( $res );
           40  +  } else
           41  +    $error = db_error ();
           42  +}
           43  +
           44  +if ( ! empty ( $_FILES['FileName'] ) )
           45  +  $file = $_FILES['FileName'];
           46  +
           47  +// Make sure we clear $file if no file was upoaded.
           48  +if ( ! empty ( $file['tmp_name'] ) && $file['tmp_name'] == 'none' )
           49  +  $file = '';
           50  +
           51  +if ( ! $is_my_event )
           52  +  $error = print_not_auth (5);
           53  +
           54  +$delete = getPostValue ( 'delete' );
           55  +if ( empty ( $error ) && ! empty ( $delete ) ) {
           56  +  // Delete this category.
           57  +  if ( ! dbi_execute ( 'DELETE FROM webcal_categories
           58  +    WHERE cat_id = ? AND ( cat_owner = ?'
           59  +       . ( $is_admin ? ' OR cat_owner IS NULL )' : ' )' ),
           60  +        array ( $id, $login ) ) ) {
           61  +    $error = db_error ();
           62  +  }
           63  +
           64  +  if ( ! dbi_execute ( 'DELETE FROM webcal_entry_categories
           65  +    WHERE cat_id = ? AND ( cat_owner = ?'
           66  +       . ( $is_admin ? ' OR cat_owner IS NULL )' : ' )' ),
           67  +        array ( $id, $login ) ) ) {
           68  +    $error = db_error ();
           69  +  }
           70  +  // Rename any icons associated with this cat_id.
           71  +  renameIcon ( $id );
           72  +} else if ( empty ( $error ) && empty ( $catname ) ) {
           73  +  $error = translate ( 'Category name is required' );
           74  +} else if ( empty ( $error ) ) {
           75  +  if ( ! empty ( $id ) ) {
           76  +    # Update (don't let them change global status).
           77  +    if ( ! dbi_execute ( 'UPDATE webcal_categories
           78  +      SET cat_name = ?, cat_color = ? WHERE cat_id = ?',
           79  +        array ( $catname, $catcolor, $id ) ) )
           80  +      $error = db_error ();
           81  +
           82  +    if ( ! empty ( $delIcon ) && $delIcon == 'Y' )
           83  +      renameIcon ( $id );
           84  +  } else {
           85  +    // Add new category.
           86  +    // Get new id.
           87  +    $res = dbi_execute ( 'SELECT MAX( cat_id ) FROM webcal_categories' );
           88  +    if ( $res ) {
           89  +      $row = dbi_fetch_row ( $res );
           90  +      $id = $row[0] + 1;
           91  +      dbi_free_result ( $res );
           92  +      $catowner = ( $is_admin
           93  +        ? ( $isglobal == 'Y' ? null : $login )
           94  +        : $login );
           95  +
           96  +      if ( ! dbi_execute ( 'INSERT INTO webcal_categories ( cat_id, cat_owner,
           97  +        cat_name, cat_color ) VALUES ( ?, ?, ?, ? )',
           98  +          array ( $id, $catowner, $catname, $catcolor ) ) )
           99  +        $error = db_error ();
          100  +    } else
          101  +      $error = db_error ();
          102  +  }
          103  +  if ( empty ( $delIcon ) && is_dir( $icon_path ) && ( !
          104  +        empty ( $ENABLE_ICON_UPLOADS ) && $ENABLE_ICON_UPLOADS == 'Y' ||
          105  +        $is_admin ) ) {
          106  +    // Save icon if uploaded.
          107  +    if ( ! empty ( $file['tmp_name'] ) ) {
          108  +      if ( $file['type'] == 'image/gif' && $file['size'] <= $icon_max_size ) {
          109  +        // $icon_props = getimagesize ( $file['tmp_name']  );
          110  +        // print_r ($icon_props );
          111  +        $path_parts = pathinfo ( $_SERVER['SCRIPT_FILENAME'] );
          112  +        $fullIcon = $path_parts['dirname'] . '/'
          113  +         . $icon_path . 'cat-' . $id . '.gif';
          114  +        renameIcon ( $id );
          115  +        $file_result = move_uploaded_file ( $file['tmp_name'], $fullIcon );
          116  +        // echo "Upload Result:" . $file_result;
          117  +      } else
          118  +      if ( $file['size'] > $icon_max_size )
          119  +        $error = translate ( 'File size exceeds maximum.' );
          120  +      else
          121  +      if ( $file['type'] != 'image/gif' )
          122  +        $error = translate ( 'File is not a gif image.' );
          123  +    }
          124  +    // Copy icon if local file specified.
          125  +    $urlname = getPostvalue ( 'urlname' );
          126  +    if ( ! empty ( $urlname ) && file_exists ( $icon_path . $urlname ) )
          127  +      copy ( $icon_path . $urlname, $icon_path . 'cat-' . $id . '.gif' );
          128  +  }
          129  +}
          130  +
          131  +if ( empty ( $error ) )
          132  +  do_redirect ( 'category.php' );
          133  +
          134  +print_header ();
          135  +echo print_error ( $error ) . print_trailer ();
          136  +
          137  +?>

Added catsel.php.

            1  +<?php
            2  +/* $Id: catsel.php,v 1.22.2.4 2013/01/24 21:10:19 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +// load user and global cats
            6  +load_user_categories ();
            7  +
            8  +$catList = $catNames = $error = '';
            9  +
           10  +if ( $CATEGORIES_ENABLED == 'N' )
           11  +  exit;
           12  +
           13  +$cats = getGetValue ( 'cats' );
           14  +$form = getGetValue ( 'form' );
           15  +
           16  +$eventcats = explode ( ',', $cats );
           17  +
           18  +$availCatStr = translate ( 'AVAILABLE CATEGORIES' );
           19  +$availCatFiller = str_repeat( '&nbsp;', ( 30 - strlen ( $availCatStr ) ) / 2 );
           20  +if ( strlen ( $availCatStr ) < 30 )
           21  +  $availCatStr = $availCatFiller . $availCatStr . $availCatFiller ;
           22  +
           23  +$entryCatStr = translate ( 'ENTRY CATEGORIES' );
           24  +$entryCatFiller = str_repeat( '&nbsp;', ( 30 - strlen ( $entryCatStr ) ) / 2 );
           25  +if ( strlen ( $entryCatStr ) < 30 )
           26  +  $entryCatStr = $entryCatFiller . $entryCatStr . $entryCatFiller ;
           27  +
           28  +print_header ( array ( 'js/catsel.php/false/' . $form ),
           29  +  '', '', true, false, true );
           30  +
           31  +ob_start ();
           32  +
           33  +echo '
           34  +    <table align="center" border="0" width="90%">
           35  +      <tr>
           36  +        <th colspan="3">' . translate ( 'Categories' ) . '</th>
           37  +      </tr>
           38  +      <form action="" method="post" name="editCategories" '
           39  + . 'onSubmit="sendCats( this )">
           40  +      <tr>
           41  +        <td valign="top">';
           42  +
           43  +if ( ! empty ( $categories ) ) {
           44  +  echo '
           45  +          <select name="cats[]" size="10">
           46  +            <option disabled>' . $availCatStr . '</option>';
           47  +
           48  +  foreach ( $categories as $K => $V ) {
           49  +    // None is index -1 and needs to be ignored
           50  +    if ( $K > 0 && ( $V['cat_owner'] == $login || $is_admin ||
           51  +        substr ( $form, 0, 4 ) == 'edit' ) ) {
           52  +      $tmpStr = $K .
           53  +        '" name="' . htmlentities ( $V['cat_name'] ) .
           54  +        '">' . htmlentities ( $V['cat_name'] );
           55  +      echo '
           56  +            <option value="' . ( empty ( $V['cat_owner'] )
           57  +        ? "-$tmpStr" . '<sup>*</sup>' : $tmpStr ) . '</option>';
           58  +    }
           59  +  }
           60  +  echo '
           61  +          </select>';
           62  +}
           63  +echo '
           64  +        </td>
           65  +        <td valign="center"><input type="button" value=">>" onclick="selAdd()"'
           66  + . ' /></td>
           67  +        <td align="center" valign="top">
           68  +          <select name="eventcats[]" size="9" multiple>
           69  +            <option disabled>' . $entryCatStr . '</option>';
           70  +
           71  +if ( strlen ( $cats ) ) {
           72  +  foreach ( $eventcats as $K ) {
           73  +    // disable if not creator and category is Global
           74  +    $show_ast = '';
           75  +    $disabled = ( empty ( $categories[abs ( $K )]['cat_owner'] ) &&
           76  +      substr ( $form, 0, 4 ) != 'edit' ? 'disabled' : '' );
           77  +    if ( empty ( $categories[abs ( $K )]['cat_owner'] ) ) {
           78  +      $show_ast = '*';
           79  +    }
           80  +    echo '
           81  +            <option value="' . "$K\" $disabled>"
           82  +     . htmlentities ( $categories[abs ( $K )]['cat_name'] ) . $show_ast . '</option>';
           83  +  }
           84  +}
           85  +
           86  +ob_end_flush ();
           87  +
           88  +echo '
           89  +          </select>
           90  +          <input type="button" value="' . translate ( 'Remove' )
           91  + . '" onclick="selRemove()" />
           92  +        </td>
           93  +      </tr>
           94  +      <tr>
           95  +        <td valign="top" align="right">*' . translate ( 'Global Category' )
           96  + . '&nbsp;&nbsp;&nbsp;<input type="button" value="' . translate ( 'OK' )
           97  + . '" onclick="sendCats()" /></td>
           98  +        <td colspan="2" align="left">&nbsp;&nbsp;<input type="button" value="'
           99  + . translate ( 'Cancel' ) . '" onclick="window.close()" /></td>
          100  +      </tr>
          101  +      </form>
          102  +    </table>
          103  +    ' . print_trailer ( false, true, true );
          104  +
          105  +?>

Added colors.php.

            1  +<?php
            2  +/* $Id: colors.php,v 1.33.2.2 2007/08/06 02:28:29 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +$color = getGetValue ( 'color' );
            5  +if ( empty ( $color ) )
            6  +  exit;
            7  +
            8  +$addcustomStr = translate ( 'Add Custom' );
            9  +$basicStr = translate ( 'Basic Colors' );
           10  +$cancelStr = translate ( 'Cancel' );
           11  +$currentStr = translate ( 'Current Color' );
           12  +$customStr = translate ( 'Custom Colors' );
           13  +$oldStr = translate ( 'Old Color' );
           14  +$okStr = '&nbsp;&nbsp;&nbsp;' . translate ( 'OK' ). '&nbsp;&nbsp;&nbsp;';
           15  +print_header ( array ( 'js/colors.php/true' ), '',
           16  +  'onload="fillhtml(); setInit();"', true, false, true );
           17  +
           18  +/*
           19  +  HTML Color Editor v1.2 (c) 2000 by Sebastian Weber <webersebastian@yahoo.de>
           20  +  Modified by Ray Jones for inclusion into WebCalendar.
           21  +  NOTE: In-line CSS styles must remain in this file for proper operation
           22  +*/
           23  +
           24  +echo <<<EOT
           25  +    <form action="colors.php" name="colorpicker">
           26  +      <input type="hidden" id="colorcell" value="{$color}" />
           27  +      <table cellspacing="2" cellpadding="0" align="center">
           28  +        <tr>
           29  +          <td colspan="3">
           30  +            <img height="1" src="images/blank.gif" border="0" alt="" /></td>
           31  +        </tr>
           32  +        <tr>
           33  +          <td align="center">{$basicStr}</td>
           34  +<!-- COLORS PICTURE -->
           35  +          <td rowspan="5" width="220" align="center">
           36  +            <img id="colorpic" height="192" width="192" src="images/colors.jpg"
           37  +              onclick="setFromImage(event);" alt="" /></td>
           38  +<!-- ***** SLIDER **** -->
           39  +          <td rowspan="5">
           40  +            <table cellspacing="0" cellpadding="0" width="24"
           41  +              onclick="setFromSlider(event);">
           42  +              <tr>
           43  +                <td id="slider"></td>
           44  +              </tr>
           45  +            </table>
           46  +          </td>
           47  +        </tr>
           48  +        <tr>
           49  +<!--  BASIC COLORS PALETTE  -->
           50  +          <td align="center" id="colorchoices"></td>
           51  +        </tr>
           52  +        <tr>
           53  +          <td align="center">{$customStr}</td>
           54  +        </tr>
           55  +        <tr>
           56  +<!--  Custom Colors  -->
           57  +          <td align="center" id="colorcustom"></td>
           58  +        </tr>
           59  +        <tr>
           60  +          <td align="center"><input type="button" value="{$addcustomStr}"
           61  +            onclick="definePreColor()" /></td>
           62  +        </tr>
           63  +        <tr>
           64  +          <td valign="top" colspan="3">
           65  +            <table cellpadding="2" cellspacing="0" width="100%">
           66  +              <tr align="center">
           67  +                <td colspan="2" height="30" valign="bottom">{$currentStr}</td>
           68  +                <td valign="bottom">{$oldStr}</td>
           69  +              </tr>
           70  +              <tr>
           71  +<!-- RGB INPUT -->
           72  +                <td class="boxtop boxleft boxbottom" valign="top" align="right">
           73  +                  R: <input id="rgb_r" type="text" size="3" maxlength="3"
           74  +                    value="255" onchange="setFromRGB()" /><br />
           75  +                  G: <input id="rgb_g" type="text" size="3" maxlength="3"
           76  +                    value="255" onchange="setFromRGB()" /><br />
           77  +                  B: <input id="rgb_b" type="text" size="3" maxlength="3"
           78  +                    value="255" onchange="setFromRGB()" /><br />
           79  +                  HTML: <input id="htmlcolor" type="text" size="6" maxlength="6"
           80  +                    value="FFFFFF" onchange="setFromHTML()" />
           81  +                </td>
           82  +                <td class="boxtop boxright boxbottom" width="120">
           83  +          <table id="thecell" bgcolor="#ffffff" align="center"
           84  +border="1" cellspacing="0" cellpadding="0">
           85  +                    <tr>
           86  +                      <td><img src="images/blank.gif" width="55" height="53" border="0" alt="" /></td>
           87  +                    </tr>
           88  +                  </table>
           89  +                </td>
           90  +                <td valign="middle" align="center" class="boxtop boxright
           91  +                  boxbottom">
           92  +<!--  Display New Color  -->
           93  +        <table id="theoldcell" bgcolor="#ffffff" border="1" cellspacing="0" cellpadding="0">
           94  +                    <tr>
           95  +            <td><img src="images/blank.gif" width="55" height="53" border="0" alt="" /></td>
           96  +                    </tr>
           97  +                  </table>
           98  +                </td>
           99  +              </tr>
          100  +            </table>
          101  +          </td>
          102  +        </tr>
          103  +        <tr>
          104  +          <td colspan="3" align="center" height="30">
          105  +            <input type="button"
          106  +              value="&nbsp;&nbsp;&nbsp;{$okStr}&nbsp;&nbsp;&nbsp;"
          107  +              onclick="transferColor(); window.close()"
          108  +              />&nbsp;&nbsp;&nbsp;<input type="button"
          109  +              value="{$cancelStr}" onclick="window.close()" />
          110  +          </td>
          111  +        </tr>
          112  +      </table>
          113  +    </form>
          114  +<img id="cross" src="images/cross.gif" alt="" style="position:absolute; left:0px; top:0px" />
          115  +<img id="sliderarrow" src="images/arrow.gif" alt="" style="position:absolute; left:0px; top:0px" />
          116  +  </body>
          117  +</html>
          118  +EOT;
          119  +
          120  +?>

Added controlpanel.php.

            1  +<?php
            2  +/* $Id: controlpanel.php,v 1.12.2.4 2011/04/27 00:27:35 rjones6061 Exp $
            3  + *
            4  + * Description:
            5  + * This page generates the JNLP contents
            6  + * that Java Web Start uses to start the application.
            7  + *
            8  + * For more info on Java Web Start:
            9  + *  http://www.java.com/en/download/faq/5000070700.xml
           10  + *
           11  + * This starts up the us.k5n.webcalendar.ui.ControlPanel.Main application.
           12  + * The ControlPanel application may eventually take over as the
           13  + * primary way of administering parts of WebCalendar.
           14  + *
           15  + * Security:
           16  + * This page doesn't really need securing since it just passes info to the
           17  + * web start app. The web start app then does its own authenticating since
           18  + * the web services require authentication to do anything.
           19  + *
           20  + **************************************************************************/
           21  +
           22  +require_once 'includes/classes/WebCalendar.class';
           23  +require_once 'includes/classes/Event.class';
           24  +require_once 'includes/classes/RptEvent.class';
           25  +
           26  +$WebCalendar = new WebCalendar ( __FILE__ );
           27  +
           28  +include 'includes/translate.php';
           29  +include 'includes/config.php';
           30  +include 'includes/dbi4php.php';
           31  +include 'includes/formvars.php';
           32  +include 'includes/functions.php';
           33  +
           34  +$WebCalendar->initializeFirstPhase ();
           35  +
           36  +include 'includes/' . $user_inc;
           37  +
           38  +$WebCalendar->initializeSecondPhase ();
           39  +
           40  +load_global_settings ();
           41  +
           42  +$WebCalendar->setLanguage ();
           43  +
           44  +// Set content type for java web start
           45  +header ( "Content-type: application/x-java-jnlp-file" );
           46  +
           47  +// Make sure app name is set
           48  +$appStr = generate_application_name ();
           49  +
           50  +echo '<?xml version="1.0" encoding="utf-8"?>
           51  +<jnlp
           52  +  spec="1.0+"
           53  +  codebase="' . $SERVER_URL . '"
           54  +  href="controlpanel.php">
           55  +  <information>
           56  +    <title>' . translate ( 'Control Panel' ) . ': ' . htmlentities ( $appStr );
           57  +
           58  +?></title>
           59  +    <vendor>k5n.us</vendor>
           60  +    <homepage href="http://www.k5n.us"/>
           61  +    <description>WebCalendar Control Panel</description>
           62  +    <!-- <icon href="images/xxx.gif"/> -->
           63  +  </information>
           64  +  <security>
           65  +  </security>
           66  +  <resources>
           67  +    <j2se version="1.4+"/>
           68  +    <jar href="ws/webcalendar.jar"/>
           69  +  </resources>
           70  +  <application-desc main-class="us.k5n.webcalendar.ui.ControlPanel.Main"
           71  +   width="600" height="500">
           72  +    <argument>-url=<?php echo $SERVER_URL . '</argument>'
           73  + . ( $use_http_auth
           74  +  ? '
           75  +    <argument>-httpusername=' . $login . '</argument>'
           76  +  : ( ! empty ( $login ) ? '
           77  +    <argument>-user=' . $login . '</argument>' : '' ) )
           78  +
           79  +?>
           80  +  </application-desc>
           81  +</jnlp>

Added css_cacher.php.

            1  +<?php
            2  +/* $Id: css_cacher.php,v 1.18.2.2 2007/11/13 19:37:28 umcesrjones Exp $ */
            3  +define ( '_ISVALID', true );
            4  +
            5  +include 'includes/translate.php';
            6  +include 'includes/config.php';
            7  +include 'includes/dbi4php.php';
            8  +include 'includes/formvars.php';
            9  +include 'includes/functions.php';
           10  +
           11  +do_config ( 'includes/settings.php' );
           12  +include 'includes/' . $user_inc;
           13  +include_once 'includes/access.php';
           14  +include_once 'includes/validate.php';
           15  +include_once 'includes/gradient.php';
           16  +
           17  +load_global_settings ();
           18  +
           19  +@session_start ();
           20  +$login = ( empty ( $_SESSION['webcal_login'] )
           21  +  ? '__public__' : $_SESSION['webcal_login'] );
           22  +$login = ( empty ( $_SESSION['webcal_tmp_login'] )
           23  +  ? $login : $_SESSION['webcal_tmp_login'] );
           24  +// .
           25  +// If calling script uses 'guest', we must also.
           26  +if ( ! empty ( $_GET['login'] ) )
           27  +  $login = $_GET['login'];
           28  +else
           29  +if ( ! empty ( $_REQUEST['login'] ) )
           30  +  $login = $_REQUEST['login'];
           31  +
           32  +if ( substr ( $login, 0, 10 ) == '__public__' )
           33  +  $login = '__public__';
           34  +	
           35  +load_user_preferences ( $login );
           36  +// .
           37  +// We will cache CSS as default, but override from admin and pref
           38  +// by incrementing the webcalendar_csscache cookie value.
           39  +$cookie = ( isset ( $_COOKIE['webcalendar_csscache'] )
           40  +  ? $_COOKIE['webcalendar_csscache'] : 0 );
           41  +
           42  +header ( 'Content-type: text/css' );
           43  +header ( 'Last-Modified: ' . date ( 'r', mktime ( 0, 0, 0 ) + $cookie ) );
           44  +// .
           45  +// If we are calling from admin or pref, expire CSS now.
           46  +if ( empty ( $_SESSION['webcal_tmp_login'] ) ) {
           47  +  header ( 'Expires: ' . date ( 'D, j M Y H:i:s', time () + 86400 ) . ' UTC' );
           48  +  header ( 'Cache-Control: Public' );
           49  +  header ( 'Pragma: Public' );
           50  +}
           51  +
           52  +if ( ini_get ( 'zlib.output_compression' ) != 1 )
           53  +  ob_start( 'ob_gzhandler' );
           54  +
           55  +include_once ( 'includes/styles.php' );
           56  +
           57  +unset ( $_SESSION['webcal_tmp_login'] );
           58  +
           59  +?>

Added datesel.php.

            1  +<?php
            2  +/* $Id: datesel.php,v 1.54.2.2 2007/08/06 02:28:29 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +$fday = getGetValue ( 'fday' );
            6  +$fmonth = getGetValue ( 'fmonth' );
            7  +$fyear = getGetValue ( 'fyear' );
            8  +
            9  +$form = getGetValue ( 'form' );
           10  +$date = getGetValue ( 'date' );
           11  +
           12  +if ( strlen ( $date ) > 0 ) {
           13  +  $thisyear = substr ( $date, 0, 4 );
           14  +  $thismonth = substr ( $date, 4, 2 );
           15  +} else {
           16  +  $thisyear = date ( 'Y' );
           17  +  $thismonth = date ( 'm' );
           18  +}
           19  +
           20  +$href = 'href="datesel.php?form=' . $form . '&amp;fday=' . $fday
           21  + . '&amp;fmonth=' . $fmonth . '&amp;fyear=' . $fyear . '&amp;date=';
           22  +
           23  +$nextdate = $href . date ( 'Ym01"', mktime ( 0, 0, 0, $thismonth + 1, 1, $thisyear ) );
           24  +$nextStr = translate ( 'Next' );
           25  +
           26  +$prevdate = $href . date ( 'Ym01"', mktime ( 0, 0, 0, $thismonth - 1, 1, $thisyear ));
           27  +$previousStr = translate ( 'Previous' );
           28  +
           29  +$monthStr = month_name ( $thismonth - 1 );
           30  +
           31  +$wkstart = get_weekday_before ( $thisyear, $thismonth );
           32  +
           33  +$monthstartYmd = date ( 'Ymd', mktime ( 0, 0, 0, $thismonth, 1, $thisyear ) );
           34  +$monthendYmd = date ( 'Ymd', mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear ) );
           35  +
           36  +print_header ( '','', '', true, false, true, true, true );
           37  +
           38  +//build weekday names
           39  +$wkdys = '';
           40  +for ( $i = 0; $i < 7; $i++ ) {
           41  +  $wkdys .= '<td>' . weekday_name ( ( $i + $WEEK_START ) % 7, 'D' ) . '</td>';
           42  +}
           43  +//build month grid
           44  +$mdays = '';
           45  +for ( $i = $wkstart; date ( 'Ymd', $i ) <= $monthendYmd; $i += 604800 ) {
           46  +  $mdays .= '
           47  +             <tr>';
           48  +  for ( $j = 0; $j < 7; $j++ ) {
           49  +    $date = $i + ( $j * 86400 ) + 43200;
           50  +    $dateYmd = date ( 'Ymd', $date );
           51  +    $mdays .= '
           52  +               <td'
           53  +     . ( ( $dateYmd >= $monthstartYmd && $dateYmd <= $monthendYmd ) ||
           54  +      $DISPLAY_ALL_DAYS_IN_MONTH == 'Y'
           55  +      ? ' class="field"><a href="javascript:sendDate(\''
           56  +       . $dateYmd . '\')">' . date ( 'j', $date ) . '</a>'
           57  +      : '>' ) . '</td>';
           58  +  }
           59  +  $mdays .= '
           60  +             </tr>';
           61  +}
           62  +
           63  +$mdays .= '
           64  +             </table>
           65  +            </td>
           66  +          </tr>
           67  +      </table>
           68  +    </div>
           69  +    ';
           70  +
           71  +echo <<<EOT
           72  +    <div align="center">
           73  +      <table class="aligncenter" width="100%">
           74  +        <tr>
           75  +          <td align="center" valign="top">
           76  +            <table class="aligncenter" cellpadding="3" cellspacing="2">
           77  +              <tr>
           78  +                <td><a title="{$previousStr}" class="prev" {$prevdate}>
           79  +                  <img src="images/leftarrowsmall.gif"
           80  +                     alt="{$previousStr}" /></a></td>
           81  +                <th colspan="5">&nbsp;{$monthStr}&nbsp;{$thisyear}&nbsp;</th>
           82  +                <td><a title="{$nextStr}"class="next" {$nextdate}>
           83  +                  <img src="images/rightarrowsmall.gif"
           84  +                     alt="{$nextStr}" /></a></td>
           85  +              </tr>
           86  +              <tr class="day">
           87  +               {$wkdys}
           88  +              </tr>
           89  +              {$mdays}
           90  +
           91  +  <!--we'll leave this javascript here to speed things up-->
           92  +  <script language="javascript" type="text/javascript">
           93  +  <!-- <![CDATA[
           94  +  function sendDate ( date ) {
           95  +    year = date.substring ( 0, 4 );
           96  +    month = date.substring ( 4, 6 );
           97  +    day = date.substring ( 6, 8 );
           98  +    sday = window.opener.document.{$form}.{$fday};
           99  +    smonth = window.opener.document.{$form}.{$fmonth};
          100  +    syear = window.opener.document.{$form}.{$fyear};
          101  +    sday.selectedIndex = day - 1;
          102  +    smonth.selectedIndex = month - 1;
          103  +    for ( i = 0; i < syear.length; i++ ) {
          104  +      if ( syear.options[i].value == year ) {
          105  +        syear.selectedIndex = i;
          106  +      }
          107  +    }
          108  +    window.close ();
          109  +  }
          110  +  //]]> -->
          111  +  </script>
          112  +EOT;
          113  +
          114  +echo print_trailer ( false, true, true );
          115  +
          116  +?>

Added day.php.

            1  +<?php
            2  +/* $Id: day.php,v 1.78.2.4 2008/03/31 21:03:41 umcesrjones Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +//check UAC
            6  +if ( ! access_can_access_function ( ACCESS_DAY ) || 
            7  +  ( ! empty ( $user ) && ! access_user_calendar ( 'view', $user ) )  )
            8  +  send_to_preferred_view ();
            9  +  
           10  +load_user_layers ( $user != $login && $is_nonuser_admin ? $user : '' );
           11  +
           12  +load_user_categories ();
           13  +
           14  +$wday = strftime ( '%w', mktime ( 0, 0, 0, $thismonth, $thisday, $thisyear ) );
           15  +$now = mktime ( 23, 59, 59, $thismonth, $thisday, $thisyear );
           16  +$nowYmd = date ( 'Ymd', $now );
           17  +
           18  +$next = mktime ( 0, 0, 0, $thismonth, $thisday + 1, $thisyear );
           19  +$nextday = date ( 'd', $next );
           20  +$nextmonth = date ( 'm', $next );
           21  +$nextyear = date ( 'Y', $next );
           22  +$nextYmd = date ( 'Ymd', $next );
           23  +
           24  +$prev = mktime ( 0, 0, 0, $thismonth, $thisday - 1, $thisyear );
           25  +$prevday = date ( 'd', $prev );
           26  +$prevmonth = date ( 'm', $prev );
           27  +$prevyear = date ( 'Y', $prev );
           28  +$prevYmd = date ( 'Ymd', $prev );
           29  +
           30  +if ( empty ( $TIME_SLOTS ) )
           31  +  $TIME_SLOTS = 24;
           32  +
           33  +$boldDays = ( $BOLD_DAYS_IN_YEAR == 'Y' );
           34  +
           35  +$startdate = mktime ( 0, 0, 0, $thismonth, 0, $thisyear );
           36  +$enddate = mktime ( 23, 59, 59, $thismonth + 1, 0, $thisyear );
           37  +
           38  +$printerStr = $unapprovedStr = '';
           39  +
           40  +/* Pre-Load the repeated events for quckier access */
           41  +$repeated_events = read_repeated_events ( empty ( $user )
           42  +  ? $login : $user, $startdate, $enddate, $cat_id );
           43  +
           44  +/* Pre-load the non-repeating events for quicker access */
           45  +$events = read_events ( empty ( $user )
           46  +  ? $login : $user, $startdate, $enddate, $cat_id );
           47  +
           48  +if ( empty ( $DISPLAY_TASKS_IN_GRID ) || $DISPLAY_TASKS_IN_GRID == 'Y' )
           49  +  /* Pre-load tasks for quicker access */
           50  +  $tasks = read_tasks ( ! empty ( $user ) && strlen ( $user ) && $is_assistant
           51  +    ? $user : $login, $now, $cat_id );
           52  +
           53  +$smallTasks = ( $DISPLAY_TASKS == 'Y' ? '<div id="minitask">
           54  +           ' . display_small_tasks ( $cat_id ) . '
           55  +          </div>' : '' );
           56  +$dayStr = print_day_at_a_glance ( $nowYmd, ( empty ( $user )
           57  +    ? $login : $user ), $can_add );
           58  +$navStr = display_navigation ( 'day' );
           59  +$smallMonthStr = display_small_month ( $thismonth, $thisyear, true );
           60  +if ( empty ( $friendly ) ) {
           61  +  $unapprovedStr = display_unapproved_events (
           62  +    $is_assistant || $is_nonuser_admin ? $user : $login );
           63  +  $printerStr = generate_printer_friendly ( 'day.php' );
           64  +}
           65  +$eventinfo = ( empty ( $eventinfo ) ? '' : $eventinfo );
           66  +$trailerStr = print_trailer ();
           67  +print_header ( array ( 'js/popups.php/true' ), generate_refresh_meta (), '',
           68  +  false, false, false, false );
           69  +
           70  +echo <<<EOT
           71  +
           72  +    <table width="100%" cellpadding="1">
           73  +      <tr>
           74  +        <td width="80%">
           75  +          {$navStr}
           76  +        </td>
           77  +        <td class="aligntop" rowspan="2">
           78  +          <!-- START MINICAL -->
           79  +          <div class="minicalcontainer">
           80  +            {$smallMonthStr}
           81  +          </div>
           82  +          {$smallTasks}
           83  +        </td>
           84  +      </tr>
           85  +      <tr>
           86  +        <td>
           87  +          {$dayStr}
           88  +        </td>
           89  +      </tr>
           90  +    </table>
           91  +    {$eventinfo}
           92  +    {$unapprovedStr}
           93  +    {$printerStr}
           94  +    {$trailerStr}
           95  +EOT;
           96  +
           97  +?>

Added del_entry.php.

            1  +<?php
            2  +/* $Id: del_entry.php,v 1.75.2.5 2012/02/28 02:07:45 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +require ( 'includes/classes/WebCalMailer.class' );
            5  +$mail = new WebCalMailer;
            6  +
            7  +require_valide_referring_url ();
            8  +
            9  +$can_edit = $my_event = false;
           10  +$other_user = '';
           11  +
           12  +// First, check to see if this user should be able to delete this event.
           13  +if ( $id > 0 ) {
           14  +  // Then see who has access to edit this entry.
           15  +  $can_edit = ( $is_admin || $readonly != 'Y' );
           16  +
           17  +  // If assistant is doing this, then we need to switch login to user in the SQL.
           18  +  $query_params = array ();
           19  +  $query_params[] = $id;
           20  +  $sql = 'SELECT we.cal_id, we.cal_type FROM webcal_entry we,
           21  +    webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ? ';
           22  +  if ( ! $is_admin ) {
           23  +    $sql .= ' AND ( we.cal_create_by = ? OR weu.cal_login = ? )';
           24  +    $sqlparm = ( $is_assistant ? $user : $login );
           25  +    $query_params[] = $sqlparm;
           26  +    $query_params[] = $sqlparm;
           27  +  }
           28  +  $res = dbi_execute ( $sql, $query_params );
           29  +  if ( $res ) {
           30  +    $row = dbi_fetch_row ( $res );
           31  +    if ( $row && $row[0] > 0 )
           32  +      $can_edit = true;
           33  +
           34  +    $activity_type = $row[1];
           35  +    dbi_free_result ( $res );
           36  +  }
           37  +}
           38  +if ( strpos ( 'EM', $activity_type ) !== false ) {
           39  +  $log_delete = LOG_DELETE;
           40  +  $log_reject = LOG_REJECT;
           41  +} else {
           42  +  $log_delete = LOG_DELETE_T;
           43  +  $log_reject = LOG_REJECT_T;
           44  +}
           45  +// See who owns the event. Owner should be able to delete.
           46  +$res = dbi_execute ( 'SELECT cal_create_by FROM webcal_entry WHERE cal_id = ?',
           47  +  array ( $id ) );
           48  +if ( $res ) {
           49  +  $row = dbi_fetch_row ( $res );
           50  +  $owner = $row[0];
           51  +  dbi_free_result ( $res );
           52  +
           53  +  if ( $owner == $login || $is_assistant && $user == $owner || $is_nonuser_admin )
           54  +    $can_edit = $my_event = true;
           55  +
           56  +  // Check UAC.
           57  +  if ( access_is_enabled () && ! $is_admin )
           58  +    $can_edit = access_user_calendar ( 'edit', $owner );
           59  +}
           60  +
           61  +// If the user is the event creator or their assistant
           62  +// allow them to delete the event from another user's calendar.
           63  +// It's essentially the same thing as editing the event and removing the
           64  +// user from the participants list.
           65  +if ( $my_event && ! empty ( $user ) && $user != $login && ! $is_assistant )
           66  +  $other_user = $user;
           67  +
           68  +if ( $readonly == 'Y' )
           69  +  $can_edit = false;
           70  +
           71  +// If User Access Control is enabled, check to see if the current
           72  +// user is allowed to delete events from the other user's calendar.
           73  +if ( ! $can_edit && access_is_enabled () && ! empty ( $user ) &&
           74  +    access_user_calendar ( 'edit', $user ) )
           75  +  $can_edit = true;
           76  +
           77  +if ( ! $can_edit )
           78  +  $error = print_not_auth (6);
           79  +
           80  +// Is this a repeating event?
           81  +$event_repeats = false;
           82  +$res = dbi_execute ( 'SELECT COUNT( cal_id ) FROM webcal_entry_repeats
           83  +  WHERE cal_id = ?', array ( $id ) );
           84  +if ( $res ) {
           85  +  $row = dbi_fetch_row ( $res );
           86  +  if ( $row[0] > 0 )
           87  +    $event_repeats = true;
           88  +
           89  +  dbi_free_result ( $res );
           90  +}
           91  +$override_repeat = false;
           92  +if ( ! empty ( $date ) && $event_repeats && ! empty ( $override ) )
           93  +  $override_repeat = true;
           94  +
           95  +if ( $id > 0 && empty ( $error ) ) {
           96  +  if ( ! empty ( $date ) )
           97  +    $thisdate = $date;
           98  +  else {
           99  +    $res = dbi_execute ( 'SELECT cal_date FROM webcal_entry WHERE cal_id = ?',
          100  +      array ( $id ) );
          101  +    if ( $res ) {
          102  +      // date format is 19991231
          103  +      $row = dbi_fetch_row ( $res );
          104  +      $thisdate = $row[0];
          105  +    }
          106  +  }
          107  +
          108  +  // Only allow delete of webcal_entry & webcal_entry_repeats
          109  +  // if owner or admin, not participant.
          110  +  // If a user was specified, then only delete that user (not here) even if we
          111  +  // are the owner or an admin.
          112  +  if ( ( $is_admin || $my_event ) && ! $other_user ) {
          113  +    // Email participants that the event was deleted.
          114  +    // First, get list of participants (with status Approved or Waiting on approval).
          115  +    $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_user
          116  +      WHERE cal_id = ? AND cal_status IN ( \'A\', \'W\' )', array ( $id ) );
          117  +    $partlogin = array ();
          118  +    if ( $res ) {
          119  +      while ( $row = dbi_fetch_row ( $res ) ) {
          120  +        $partlogin[] = $row[0];
          121  +      }
          122  +      dbi_free_result ( $res );
          123  +    }
          124  +    // Get event name.
          125  +    $res = dbi_execute ( 'SELECT cal_name, cal_date, cal_time FROM webcal_entry
          126  +      WHERE cal_id = ?', array ( $id ) );
          127  +    if ( $res ) {
          128  +      $row = dbi_fetch_row ( $res );
          129  +      $name = $row[0];
          130  +      $fmtdate = $row[1];
          131  +      $time = sprintf ( "%06d", $row[2] );
          132  +      dbi_free_result ( $res );
          133  +    }
          134  +
          135  +    $eventstart = date_to_epoch ( $fmtdate . $time );
          136  +    $TIME_FORMAT = 24;
          137  +    for ( $i = 0, $cnt = count ( $partlogin ); $i < $cnt; $i++ ) {
          138  +      // Log the deletion.
          139  +      activity_log ( $id, $login, $partlogin[$i], $log_delete, '' );
          140  +      // Check UAC.
          141  +      $can_email = ( access_is_enabled ()
          142  +        ? access_user_calendar ( 'email', $partlogin[$i], $login ) : false );
          143  +
          144  +      // Don't email the logged in user.
          145  +      if ( $can_email && $partlogin[$i] != $login ) {
          146  +        set_env ( 'TZ', get_pref_setting ( $partlogin[$i], 'TIMEZONE' ) );
          147  +        $user_language = get_pref_setting ( $partlogin[$i], 'LANGUAGE' );
          148  +        user_load_variables ( $partlogin[$i], 'temp' );
          149  +        if ( ! $is_nonuser_admin && $partlogin[$i] != $login &&
          150  +          get_pref_setting ( $partlogin[$i], 'EMAIL_EVENT_DELETED' ) == 'Y' &&
          151  +            boss_must_be_notified ( $login, $partlogin[$i] ) && !
          152  +            empty ( $tempemail ) && $SEND_EMAIL != 'N' ) {
          153  +          reset_language ( empty ( $user_language ) || $user_language == 'none'
          154  +            ? $LANGUAGE : $user_language );
          155  +          // Use WebCalMailer class.
          156  +          $mail->WC_Send ( $login_fullname, $tempemail, $tempfullname, $name,
          157  +            str_replace ( 'XXX', $tempfullname, translate ( 'Hello, XXX.' ) )
          158  +             . ".\n\n" . str_replace ( 'XXX', $login_fullname,
          159  +              // translate ( 'An appointment has been canceled for you by' )
          160  +              translate ( 'XXX has canceled an appointment.' ) ) . "\n"
          161  +             . str_replace ( 'XXX', $name, translate ( 'Subject XXX' ) ) . "\"\n"
          162  +             . str_replace ( 'XXX', date_to_str ( $thisdate ),
          163  +              translate ( 'Date XXX' ) ) . "\n"
          164  +             . ( ! empty ( $eventtime ) && $eventtime != '-1'
          165  +              ? str_replace ( 'XXX', display_time ( '', 2, $eventstart,
          166  +                  get_pref_setting ( $partlogin[$i], 'TIME_FORMAT' ) ),
          167  +                translate ( 'Time XXX' ) ) : '' ) . "\n\n",
          168  +            // Apply user's GMT offset and display their TZID.
          169  +            get_pref_setting ( $partlogin[$i], 'EMAIL_HTML' ), $login_email );
          170  +        }
          171  +      }
          172  +    }
          173  +
          174  +    // Instead of deleting from the database...
          175  +    // mark it as deleted by setting the status for each participant to "D"
          176  +    // (instead of "A"/Accepted, "W"/Waiting-on-approval or "R"/Rejected).
          177  +    if ( $override_repeat ) {
          178  +      dbi_execute ( 'INSERT INTO webcal_entry_repeats_not
          179  +        ( cal_id, cal_date, cal_exdate ) VALUES ( ?, ?, ? )',
          180  +        array ( $id, $date, 1 ) );
          181  +      // Should we log this to the activity log???
          182  +    } else {
          183  +      // If it's a repeating event, delete any event exceptions that were entered.
          184  +      if ( $event_repeats ) {
          185  +        $res = dbi_execute ( 'SELECT cal_id FROM webcal_entry WHERE cal_group_id = ?',
          186  +          array ( $id ) );
          187  +        if ( $res ) {
          188  +          $ex_events = array ();
          189  +          while ( $row = dbi_fetch_row ( $res ) ) {
          190  +            $ex_events[] = $row[0];
          191  +          }
          192  +          dbi_free_result ( $res );
          193  +          for ( $i = 0, $cnt = count ( $ex_events ); $i < $cnt; $i++ ) {
          194  +            $res = dbi_execute ( 'SELECT cal_login FROM
          195  +              webcal_entry_user WHERE cal_id = ?', array ( $ex_events[$i] ) );
          196  +            if ( $res ) {
          197  +              $delusers = array ();
          198  +              while ( $row = dbi_fetch_row ( $res ) ) {
          199  +                $delusers[] = $row[0];
          200  +              }
          201  +              dbi_free_result ( $res );
          202  +              for ( $j = 0, $cnt = count ( $delusers ); $j < $cnt; $j++ ) {
          203  +                // Log the deletion.
          204  +                activity_log ( $ex_events[$i], $login, $delusers[$j],
          205  +                  $log_delete, '' );
          206  +                dbi_execute ( 'UPDATE webcal_entry_user SET cal_status = ?
          207  +                  WHERE cal_id = ? AND cal_login = ?',
          208  +                  array ( 'D', $ex_events[$i], $delusers[$j] ) );
          209  +              }
          210  +            }
          211  +          }
          212  +        }
          213  +      }
          214  +
          215  +      // Now, mark event as deleted for all users.
          216  +      dbi_execute ( 'UPDATE webcal_entry_user SET cal_status = \'D\' WHERE cal_id = ?',
          217  +        array ( $id ) );
          218  +
          219  +      // Delete External users for this event
          220  +      dbi_execute ( 'DELETE FROM webcal_entry_ext_user WHERE cal_id = ?',
          221  +        array ( $id ) );
          222  +    }
          223  +  } else {
          224  +    // Not the owner of the event, but participant or noncal_admin.
          225  +    // Just  set the status to 'D' instead of deleting.
          226  +    $del_user = ( ! empty ( $other_user ) ? $other_user : $login );
          227  +    if ( ! empty ( $user ) && $user != $login ) {
          228  +      if ( $is_admin || $my_event || ( $can_edit && $is_assistant ) ||
          229  +          ( access_is_enabled () &&
          230  +            access_user_calendar ( 'edit', $user ) ) ) {
          231  +        $del_user = $user;
          232  +      } else
          233  +        // Error: user cannot delete from other user's calendar.
          234  +        $error = print_not_auth (6);
          235  +    }
          236  +    if ( empty ( $error ) ) {
          237  +      if ( $override_repeat ) {
          238  +        dbi_execute ( 'INSERT INTO webcal_entry_repeats_not
          239  +          ( cal_id, cal_date, cal_exdate ) VALUES ( ?, ?, ? )',
          240  +          array ( $id, $date, 1 ) );
          241  +        // Should we log this to the activity log???
          242  +      } else {
          243  +        dbi_execute ( 'UPDATE webcal_entry_user SET cal_status = ?
          244  +          WHERE cal_id = ? AND cal_login = ?', array ( 'D', $id, $del_user ) );
          245  +        activity_log ( $id, $login, $login, $log_reject, '' );
          246  +      }
          247  +    }
          248  +  }
          249  +}
          250  +
          251  +$ret = getValue ( 'ret' );
          252  +$return_view = get_last_view ();
          253  +
          254  +if ( ! empty ( $ret ) ) {
          255  +  if ( $ret == 'listall' )
          256  +    $url = 'list_unapproved.php';
          257  +  else
          258  +  if ( $ret == 'list' )
          259  +    $url = 'list_unapproved.php' . ( empty ( $user ) ? '' : '?user=' . $user );
          260  +} else
          261  +if ( ! empty ( $return_view ) )
          262  +  do_redirect ( $return_view );
          263  +else
          264  +  $url = get_preferred_view ( '', empty ( $user ) ? '' : 'user=' . $user );
          265  +
          266  +// Return to login TIMEZONE.
          267  +set_env ( 'TZ', $TIMEZONE );
          268  +if ( empty ( $error ) && empty ( $mailerError ) ) {
          269  +  do_redirect ( $url );
          270  +  exit;
          271  +}
          272  +// Process errors.
          273  +$mail->MailError ( $mailerError, $error );
          274  +
          275  +?>

Added del_layer.php.

            1  +<?php
            2  +/* $Id: del_layer.php,v 1.20.2.2 2012/02/28 02:07:45 cknudsen Exp $ */
            3  +include_once 'includes/init.php';
            4  +
            5  +require_valide_referring_url ();
            6  +
            7  +$id = getGetValue ( 'id' );
            8  +
            9  +if ( $ALLOW_VIEW_OTHER != 'Y' || empty ( $id ) ) {
           10  +  print_header ();
           11  +  echo print_not_auth (7) . print_trailer ();
           12  +  exit;
           13  +}
           14  +$id = getGetValue ( 'id' );
           15  +$updating_public = false;
           16  +if ( $is_admin && ! empty ( $public ) && $PUBLIC_ACCESS == 'Y' ) {
           17  +  $updating_public = true;
           18  +  $layer_user = '__public__';
           19  +} else
           20  +  $layer_user = $login;
           21  +
           22  +load_user_layers ( $layer_user, 1 );
           23  +
           24  +if ( strlen ( $layers[$id]['cal_layeruser'] ) > 0 &&
           25  +    ( $is_admin || $readonly == 'N' ) ) {
           26  +  $layeruser = $layers[$id]['cal_layeruser'];
           27  +
           28  +  dbi_execute ( 'DELETE FROM webcal_user_layers WHERE cal_login = ?
           29  +    AND cal_layeruser = ?', array ( $layer_user, $layeruser ) );
           30  +}
           31  +
           32  +  do_redirect ( 'layers.php' . ( $updating_public ? '?public=1' : '' ) );
           33  +
           34  +?>

Added doc.php.

            1  +<?php
            2  +/* $Id: doc.php,v 1.20.2.4 2011/04/27 00:27:35 rjones6061 Exp $
            3  + *
            4  + * Description:
            5  + *  Obtain a binary object from the database and send it back to
            6  + *  the browser using the correct mime type.
            7  + *
            8  + * Input Parameters:
            9  + *  blid(*) - The unique identifier for this blob
           10  + * (*) required field
           11  + */
           12  +include_once 'includes/init.php';
           13  +include_once 'includes/classes/Doc.class';
           14  +
           15  +$blid = getValue ( 'blid', '-?[0-9]+', true );
           16  +$error = $res = '';
           17  +$invalidIDStr = translate ( 'Invalid entry id XXX.' );
           18  +
           19  +if ( empty ( $blid ) )
           20  +  $error = translate ( 'Invalid blob id' );
           21  +else {
           22  +  $res = dbi_execute ( Doc::getSQLForDocId ( $blid ) );
           23  +  if ( ! $res )
           24  +   $error = db_error ();
           25  +}
           26  +
           27  +if ( empty ( $error ) ) {
           28  +  $row = dbi_fetch_row ( $res );
           29  +  if ( ! $row )
           30  +    $error = str_replace ( 'XXX', $blid, $invalidIDStr );
           31  +  else {
           32  +    $doc = new Doc ( $row );
           33  +    $description = $doc->getDescription ();
           34  +    $filedata = $doc->getData ();
           35  +    $filename = $doc->getName ();
           36  +    $id = $doc->getId ();
           37  +    $mimetype = $doc->getMimeType ();
           38  +    $owner = $doc->getLogin ();
           39  +    $size = $doc->getSize ();
           40  +    $type = $doc->getType ();
           41  +  }
           42  +  dbi_free_result ( $res );
           43  +}
           44  +
           45  +// Make sure this user is allowed to look at this file.
           46  +// If the blob is associated with an event, then the user must be able
           47  +// to view the event in order to access this file.
           48  +// TODO: move all this code (and code in view_entry.php) to a common
           49  +// function named can_view_event or something similar.
           50  +$can_view = false;
           51  +$is_my_event = false;
           52  +$is_private = $is_confidential = false;
           53  +$log = getGetValue ( 'log' );
           54  +$show_log = ! empty ( $log );
           55  +
           56  +if ( empty ( $id ) )
           57  +  $can_view = true; // not associated with an event
           58  +
           59  +if ( ! empty ( $id ) && empty ( $error ) ) {
           60  +  if ( $is_admin || $is_nonuser_admin || $is_assistant )
           61  +    $can_view = true;
           62  +
           63  +  if ( empty ( $id ) || $id <= 0 || ! is_numeric ( $id ) )
           64  +    $error = str_replace ( 'XXX', $id, $invalidIDStr );
           65  +
           66  +  if ( empty ( $error ) ) {
           67  +    // is this user a participant or the creator of the event?
           68  +    $res = dbi_execute ( 'SELECT we.cal_id FROM webcal_entry we,
           69  +      webcal_entry_user weu WHERE we.cal_id = weu.cal_id AND we.cal_id = ?
           70  +      AND ( we.cal_create_by = ? OR weu.cal_login = ? )',
           71  +      array ( $id, $login, $login ) );
           72  +    if ( $res ) {
           73  +      $row = dbi_fetch_row ( $res );
           74  +      if ( $row && $row[0] > 0 ) {
           75  +        $can_view = true;
           76  +        $is_my_event = true;
           77  +      }
           78  +      dbi_free_result ( $res );
           79  +    }
           80  +
           81  +    if ( ($login != '__public__') && ($PUBLIC_ACCESS_OTHERS == 'Y') ) {
           82  +      $can_view = true;
           83  +    }
           84  +    if ( ! $can_view ) {
           85  +      $check_group = false;
           86  +      // if not a participant in the event, must be allowed to look at
           87  +      // other user's calendar.
           88  +      if ( $login == '__public__' ) {
           89  +        if ( $PUBLIC_ACCESS_OTHERS == 'Y' )
           90  +          $check_group = true;
           91  +      } else {
           92  +        if ( $ALLOW_VIEW_OTHER == 'Y' )
           93  +          $check_group = true;
           94  +      }
           95  +      // If $check_group is true now, it means this user can look at the
           96  +      // event only if they are in the same group as some of the people in
           97  +      // the event.
           98  +      // This gets kind of tricky. If there is a participant from a different
           99  +      // group, do we still show it?  For now, the answer is no.
          100  +      // This could be configurable somehow, but how many lines of text would
          101  +      // it need in the admin page to describe this scenario?  Would confuse
          102  +      // 99.9% of users.
          103  +      // In summary, make sure at least one event participant is in one of
          104  +      // this user's groups.
          105  +      $my_users = get_my_users ();
          106  +      $cnt = count ( $my_users );
          107  +      if ( is_array ( $my_users ) && $cnt ) {
          108  +        $sql = 'SELECT we.cal_id FROM webcal_entry we, webcal_entry_user weu
          109  +          WHERE we.cal_id = weu.cal_id AND we.cal_id = ?
          110  +          AND weu.cal_login IN ( ';
          111  +        $query_params = array ();
          112  +      $query_params[] = $id;
          113  +      for ( $i = 0; $i < $cnt; $i++ ) {
          114  +          if ( $i > 0 ) {
          115  +            $sql .= ', ';
          116  +          }
          117  +          $sql .= '?';
          118  +          $query_params[] = $my_users[$i]['cal_login'];
          119  +        }
          120  +        $res = dbi_execute ( $sql . ' )', $query_params );
          121  +        if ( $res ) {
          122  +          $row = dbi_fetch_row ( $res );
          123  +          if ( $row && $row[0] > 0 )
          124  +            $can_view = true;
          125  +
          126  +          dbi_free_result ( $res );
          127  +        }
          128  +      }
          129  +      // If we didn't indicate we need to check groups, then this user
          130  +      // can't view this event.
          131  +      if ( ! $check_group && ! access_is_enabled ()  )
          132  +        $can_view = false;
          133  +    }
          134  +  }
          135  +  $hide_details = ( $login == '__public__' &&
          136  +    ! empty ( $OVERRIDE_PUBLIC ) && $OVERRIDE_PUBLIC == 'Y' );
          137  +
          138  +  // If they still cannot view, make sure they are not looking at a nonuser
          139  +  // calendar event where the nonuser is the _only_ participant.
          140  +  if ( empty ( $error ) && ! $can_view && ! empty ( $NONUSER_ENABLED ) &&
          141  +    $NONUSER_ENABLED == 'Y' ) {
          142  +    $nonusers = get_nonuser_cals ();
          143  +    $nonuser_lookup = array ();
          144  +    for ( $i = 0, $cnt = count ( $nonusers ); $i < $cnt; $i++ ) {
          145  +      $nonuser_lookup[$nonusers[$i]['cal_login']] = 1;
          146  +    }
          147  +    $res = dbi_execute ( 'SELECT cal_login FROM webcal_entry_user
          148  +      WHERE cal_id = ? AND cal_status in ( \'A\', \'W\' )', array ( $id ) );
          149  +    $found_nonuser_cal = $found_reg_user = false;
          150  +    if ( $res ) {
          151  +      while ( $row = dbi_fetch_row ( $res ) ) {
          152  +        if ( ! empty ( $nonuser_lookup[$row[0]] ) )
          153  +          $found_nonuser_cal = true;
          154  +        else
          155  +          $found_reg_user = true;
          156  +      }
          157  +      dbi_free_result ( $res );
          158  +    }
          159  +    // Does this event contain only nonuser calendars as participants?
          160  +    // If so, then grant access.
          161  +    if ( $found_nonuser_cal && ! $found_reg_user )
          162  +      $can_view = true;
          163  +  }
          164  +  if ( empty ( $error ) && ! $can_view )
          165  +    $error = print_not_auth (8);
          166  +}
          167  +
          168  +if ( ! empty ( $error ) ) {
          169  +  print_header ();
          170  +  echo print_error ( $error, true) . print_trailer ();
          171  +  exit;
          172  +}
          173  +
          174  +$disp = ( $type == 'A' ? 'attachment' : 'inline' );
          175  +
          176  +// Print out data now.
          177  +Header ( 'Content-Length: ' . $size );
          178  +Header ( 'Content-Type: ' . $mimetype );
          179  +
          180  +$description = preg_replace ( "/\n\r\t+/", ' ', $description );
          181  +Header ( 'Content-Description: ' . $description );
          182  +
          183  +// Don't allow spaces in filenames.
          184  +//$filename = preg_replace ( "/\n\r\t+/", "_", $filename );
          185  +//Header ( "Content-Disposition: $disp; filename=$filename" );
          186  +Header ( 'Content-Disposition: filename=' . $filename );
          187  +
          188  +echo $filedata;
          189  +exit;
          190  +
          191  +?>

Added docadd.php.

            1  +<?php
            2  +/* $Id: docadd.php,v 1.20.2.3 2007/11/12 15:40:30 umcesrjones Exp $
            3  + *
            4  + * Page Description:
            5  + *  This page will handle adding blobs into the database. It will
            6  + *  present the form page on a GET and handle updating the database
            7  + *  on a POST.
            8  + *  This includes:
            9  + *    Add comment to an event
           10  + *    Add attachment to an event
           11  + *
           12  + * Input Parameters:
           13  + *  For GET:
           14  + *    id - event id (optional for some types)
           15  + *    type - C=comment, A=attachment
           16  + *  For POST:
           17  + *    id - event id (optional for some types)
           18  + *    type - C=comment, A=attachment
           19  + *    description - (for type=C and A)
           20  + *    comment - (for type=C)
           21  + *    FileName - (for type=A)
           22  + *
           23  + * Comments:
           24  + *  TODO: add email notification when attachment or comment is added
           25  + */
           26  +include_once 'includes/init.php';
           27  +
           28  +$id = getValue ( 'id', '-?[0-9]+' );
           29  +$type = getValue ( 'type' );
           30  +$user = getValue ( 'user' );
           31  +$error = '';
           32  +
           33  +switch ( $type ) {
           34  +  case 'C':
           35  +    if ( empty ( $id ) )
           36  +      $error = 'No id specified';
           37  +    $title = translate ( 'Add Comment' );
           38  +    break;
           39  +  case 'A':
           40  +    if ( empty ( $id ) )
           41  +      $error = 'No id specified';
           42  +    $title = translate ( 'Add Attachment' );
           43  +    $upload = ini_get ( 'file_uploads' );
           44  +    $upload_enabled = ! empty ( $upload ) &&
           45  +      preg_match ( "/(On|1|true|yes)/i", $upload );
           46  +    if ( ! $upload_enabled ) {
           47  +      $error = 'You must enable file_uploads in php.ini';
           48  +    }
           49  +    break;
           50  +  default:
           51  +    $error = 'Invalid type';
           52  +    break;
           53  +}
           54  +
           55  +$can_add = false;
           56  +if ( $is_admin )
           57  +  $can_add = true;
           58  +
           59  +// Get event details if this is associated with an event
           60  +if ( empty ( $error ) && ! empty ( $id ) ) {
           61  +  // is this user a participant or the creator of the event?
           62  +  $res = dbi_execute ( 'SELECT we.cal_id
           63  +    FROM webcal_entry we, webcal_entry_user weu
           64  +    WHERE we.cal_id = weu.cal_id AND we.cal_id = ?
           65  +    AND ( we.cal_create_by = ? OR weu.cal_login = ? )',
           66  +    array ( $id, $login, $login ) );
           67  +  if ( $res ) {
           68  +    $row = dbi_fetch_row ( $res );
           69  +    if ( $row && $row[0] > 0 )
           70  +      $is_my_event = true; // user is participant
           71  +
           72  +    dbi_free_result ( $res );
           73  +  }
           74  +}
           75  +
           76  +if ( $type == 'A' ) {
           77  +  if ( empty ( $ALLOW_ATTACH ) || $ALLOW_ATTACH != 'Y' )
           78  +    $error = print_not_auth (9);
           79  +  else if ( empty ( $error ) && $ALLOW_ATTACH_PART == 'Y' && $is_my_event )
           80  +    $can_add = true;
           81  +  else if ( $ALLOW_ATTACH_ANY == 'Y' )
           82  +    $can_add = true;
           83  +} else if ( $type == 'C' ) {
           84  +  if ( empty ( $ALLOW_COMMENTS ) || $ALLOW_COMMENTS != 'Y' )
           85  +    $error = print_not_auth (10);
           86  +  else if ( empty ( $error ) && $ALLOW_COMMENTS_PART == 'Y' && $is_my_event )
           87  +    $can_add = true;
           88  +  else if ( $ALLOW_COMMENTS_ANY == 'Y' )
           89  +    $can_add = true;
           90  +}
           91  +//check UAC
           92  +if ( access_is_enabled () ) {
           93  +  $can_add = $can_add || access_user_calendar ( 'edit', $user );
           94  +}
           95  +
           96  +if ( ! $can_add )
           97  +  $error = print_not_auth (6);
           98  +
           99  +if ( ! empty ( $error ) ) {
          100  +  print_header ();
          101  +  echo print_error ( $error );
          102  +  echo print_trailer ();
          103  +  exit;
          104  +}
          105  +
          106  +// Handle possible POST first
          107  +if ( empty ( $REQUEST_METHOD ) )
          108  +  $REQUEST_METHOD = $_SERVER['REQUEST_METHOD'];
          109  +if ( $REQUEST_METHOD == 'POST' ) {
          110  +
          111  +  // get next id first
          112  +  $res = dbi_execute ( 'SELECT MAX( cal_blob_id ) FROM webcal_blob' );
          113  +  if ( ! $res )
          114  +    die_miserable_death ( str_replace ( 'XXX', dbi_error (),
          115  +      translate ( 'Database error XXX.' ) ) );
          116  +       $row = dbi_fetch_row ( $res );
          117  +  $nextid = ( ! empty ( $row ) ? $row[0] + 1 :  1 );
          118  +  dbi_free_result ( $res );
          119  +
          120  +  if ( $type == 'C' ) {
          121  +    // Comment
          122  +    $description = getValue ( 'description' );
          123  +    $comment = getValue ( 'comment' );
          124  +    if ( ! dbi_execute ( 'INSERT INTO webcal_blob ( cal_blob_id, cal_id,
          125  +      cal_login, cal_name, cal_description, cal_size, cal_mime_type, cal_type,
          126  +      cal_mod_date, cal_mod_time, cal_blob )
          127  +      VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )', array ( $nextid, $id, $login,
          128  +        NULL, $description, 0, 'text/plain', 'C', date ( 'Ymd' ), date ( 'His' ),
          129  +        NULL ) ) )
          130  +      $error = db_error ();
          131  +    else {
          132  +      if ( ! dbi_update_blob ( 'webcal_blob', 'cal_blob',
          133  +        "cal_blob_id = $nextid", $comment ) )
          134  +        $error = db_error ();
          135  +      else {
          136  +        // success!  redirect to view event page
          137  +        activity_log ( $id, $login, $login, LOG_COMMENT, '' );
          138  +        do_redirect ( "view_entry.php?id=$id" );
          139  +      }
          140  +    }
          141  +  } else if ( $type == 'A' ) {
          142  +    // Attachment
          143  +    $description = getValue ( 'description' );
          144  +    if ( ! empty ( $_FILES['FileName'] ) )
          145  +      $file = $_FILES['FileName'];
          146  +    if ( empty ( $file['file'] ) )
          147  +      $error = 'File Upload error!<br />';
          148  +
          149  +    //print_r ( $file ); exit;
          150  +    $mimetype = $file['type'];
          151  +    $filesize = $file['size'];
          152  +    $filename = $file['name'];
          153  +    $tmpfile = $file['tmp_name'];
          154  +    if ( empty ( $description ) )
          155  +      $description = $filename;
          156  +
          157  +    $data = '';
          158  +    $fd = @fopen ( $tmpfile, 'r' );
          159  +    if ( ! $fd )
          160  +      die_miserable_death ( "Error reading temp file: $tmpfile" );
          161  +    if ( ! empty ( $error ) ) {
          162  +      while ( ! feof ( $fd ) ) {
          163  +        $data .= fgets ( $fd, 4096 );
          164  +      }
          165  +    }
          166  +    fclose ( $fd );
          167  +
          168  +    $comment = getValue ( 'description' );
          169  +    if ( ! dbi_execute ( 'INSERT INTO webcal_blob ( cal_blob_id, cal_id,
          170  +      cal_login, cal_name, cal_description, cal_size, cal_mime_type, cal_type,
          171  +      cal_mod_date, cal_mod_time, cal_blob )
          172  +      VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )', array ( $nextid, $id, $login,
          173  +        $filename, $description, $filesize, $mimetype, 'A', date ( 'Ymd' ),
          174  +        date ( 'His' ), NULL ) ) )
          175  +      $error = db_error ();
          176  +    else {
          177  +      if ( ! dbi_update_blob ( 'webcal_blob', 'cal_blob',
          178  +        "cal_blob_id = $nextid", $data ) ) {
          179  +        $error = db_error ();
          180  +      } else {
          181  +        // success!  redirect to view event page
          182  +        activity_log ( $id, $login, $login, LOG_ATTACHMENT, $filename );
          183  +        do_redirect ( "view_entry.php?id=$id" );
          184  +      }
          185  +    }
          186  +  } else {
          187  +    die_miserable_death ( 'Unsupported type' ); // programmer error
          188  +  }
          189  +
          190  +  if ( ! empty ( $error ) ) {
          191  +    print_header ();
          192  +    echo print_error ( $error );
          193  +    echo print_trailer ();
          194  +    exit;
          195  +  }
          196  +}
          197  +
          198  +print_header ();
          199  +?>
          200  +<h2><?php echo $title;?></h2>
          201  +
          202  +<?php if ( $type == 'C' ) {
          203  +  // Comment
          204  +?>
          205  +<form action="docadd.php" method="post" name="docform">
          206  +<input type="hidden" name="id" value="<?php echo $id?>" />
          207  +<input type="hidden" name="type" value="C" />
          208  +
          209  +<table>
          210  +
          211  +<tr><td class="aligntop"><label for="description">
          212  +  <?php etranslate ( 'Subject' )?>:</label></td>
          213  +  <td><input type="text" name="description" size="50" maxlength="127" /></td></tr>
          214  +<!-- TODO: htmlarea or fckeditor support -->
          215  +<tr><td class="aligntop"><label for="comment">
          216  +  <?php etranslate ( 'Comment' )?>:</label></td>
          217  +  <td><textarea name="comment" rows="15" cols="60" wrap="auto"></textarea></td></tr>
          218  +<tr><td colspan="2">
          219  +<input type="submit" value="<?php etranslate ( 'Add Comment' )?>" /></td></tr>
          220  +</table>
          221  +</form>
          222  +
          223  +<?php } else if ( $type == 'A' ) {
          224  +  // Attachment
          225  +?>
          226  +<form action="docadd.php" method="post" name="docform" enctype="multipart/form-data">
          227  +<input type="hidden" name="id" value="<?php echo $id?>" />
          228  +<input type="hidden" name="type" value="A" />
          229  +<table>
          230  +<tr class="browse"><td>
          231  + <label for="fileupload"><?php etranslate ( 'Upload file' );?>:</label></td><td>
          232  + <input type="file" name="FileName" id="fileupload" size="45" maxlength="50" />
          233  +<tr><td class="aligntop"><label for="description">
          234  +  <?php etranslate ( 'Description' )?>:</label></td>
          235  +  <td><input type="text" name="description" size="50" maxlength="127" /></td></tr>
          236  +
          237  +<tr><td colspan="2">
          238  +<input type="submit" value="<?php etranslate ( 'Add Attachment' )?>" /></td></tr>
          239  +
          240  +</table>
          241  +</form>
          242  +
          243  +<?php }
          244  +echo print_trailer (); ?>
          245  +

Added docdel.php.

            1  +<?php
            2  +/* $Id: docdel.php,v 1.14.2.4 2011/04/27 00:27:35 rjones6061 Exp $
            3  + *
            4  + * Page Description:
            5  + *  This page will handle deletion of an entry in webcal_blob.
            6  + *  This could be a comment or an attachment.
            7  + *
            8  + * Input Parameters:
            9  + *  For GET:
           10  + *    blid - unique id, corresponds to webcal_blob.cal_blob_id
           11  + *
           12  + * Security:
           13  + *  Only the creator of the comment, the creator of the associated
           14  + *  event, or an admin can delete.
           15  + *  (An assistant can also delete their boss' documents.)
           16  + * Comments:
           17  + *  TODO: perhaps add email notification on this
           18  + */
           19  +include_once 'includes/init.php';
           20  +include_once 'includes/classes/Doc.class';
           21  +
           22  +$blid = getValue ( 'blid', '-?[0-9]+', true );
           23  +$can_delete = false; // until proven otherwise
           24  +$error = $name = $owner = $type = '';
           25  +$event_id = -1;
           26  +
           27  +if ( $is_admin )
           28  +  $can_delete = true;
           29  +
           30  +$res = dbi_execute ( Doc::getSQLForDocId ( $blid ) );
           31  +if ( ! $res )
           32  +  $error = db_error ();
           33  +else {
           34  +  if ( $row = dbi_fetch_row ( $res ) ) {
           35  +    $doc = new Doc ( $row );
           36  +    $event_id = $doc->getEventId ();
           37  +    $name = $doc->getName ();
           38  +    $owner = $doc->getLogin ();
           39  +    $type = $doc->getType ();
           40  +    if ( $owner == $login || user_is_assistant ( $login, $owner ) )
           41  +      $can_delete = true;
           42  +  } else
           43  +    // document not found
           44  +    $error = str_replace ( 'XXX', $blid, translate ( 'Invalid entry id XXX.' ) );
           45  +
           46  +  dbi_free_result ( $res );
           47  +}
           48  +
           49  +if ( empty ( $error ) && ! $can_delete && $event_id > 0 ) {
           50  +  // See if current user is creator of associated event
           51  +  $res = dbi_execute ( 'SELECT cal_create_by FROM webcal_entry WHERE cal_id = ?',
           52  +    array ( $event_id ) );
           53  +  if ( $res ) {
           54  +    if ( $row = dbi_fetch_row ( $res ) ) {
           55  +      $event_owner = $row[0];
           56  +      if ( $event_owner == $login || user_is_assistant ( $login, $event_owner ) )
           57  +        $can_delete = true;
           58  +    }
           59  +    dbi_free_result ( $res );
           60  +  }
           61  +}
           62  +
           63  +if ( empty ( $error ) && ! $can_delete )
           64  +  $error = print_not_auth (6);
           65  +
           66  +if ( empty ( $error ) && $can_delete ) {
           67  +  if ( ! dbi_execute ( 'DELETE FROM webcal_blob WHERE cal_blob_id = ?',
           68  +      array ( $blid ) ) )
           69  +    $error = db_error ();
           70  +  else {
           71  +    if ( $event_id > 0 ) {
           72  +      $removeStr = translate ( 'Removed' );
           73  +      if ( $type == 'A' )
           74  +        activity_log ( $event_id, $login, $login, LOG_ATTACHMENT, $removeStr
           75  +         . ': ' . $name );
           76  +      elseif ( $type == 'C' )
           77  +        activity_log ( $event_id, $login, $login, LOG_COMMENT, $removeStr );
           78  +    }
           79  +    if ( $event_id > 0 )
           80  +      do_redirect ( 'view_entry.php?id=' . $event_id );
           81  +
           82  +    do_redirect ( get_preferred_view () );
           83  +  }
           84  +}
           85  +// Some kind of error...
           86  +print_header ();
           87  +echo print_error ( $error ) . print_trailer ();
           88  +
           89  +?>

Added docs/WebCalendar-SysAdmin.html.

            1  +<?xml version="1.0" encoding="utf-8"?>
            2  +<!DOCTYPE html
            3  +    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            4  +    "DTD/xhtml1-transitional.dtd">
            5  +    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
            6  +     <head>
            7  +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            8  +<title>WebCalendar System Administrator's Guide</title>
            9  +<style type="text/css">
           10  +body {
           11  + background-color: #FFFFFF;
           12  + font-family: Arial, Helvetica, sans-serif;
           13  +}
           14  +a {
           15  + text-decoration: none;
           16  +}
           17  +dt {
           18  + font-weight: bold;
           19  + margin-left: 25px;
           20  + margin-top: 20px;
           21  +}
           22  +.valid {
           23  + border-width: 0px;
           24  +}
           25  +pre {
           26  + font-family: courier, monospace;
           27  + font-size: 14px;
           28  + border: 1px solid #0000FF;
           29  + background-color: #EEEEFF;
           30  + padding: 4px;
           31  + margin-left: 25px;
           32  + margin-right: 25px;
           33  +}
           34  +td {
           35  + background-color: #ddd;
           36  + border: 1px solid #bbb;
           37  + color: #000;
           38  + vertical-align: top;
           39  +}
           40  +th {
           41  + background-color: #eee;
           42  + border: 1px solid #ccc;
           43  + color: #000;
           44  +}
           45  +.colorheader {
           46  + background-color: #000000;
           47  + color: #FFFFFF;
           48  + margin-left: 3px;
           49  + margin-right: 3px;
           50  + padding: 2px;
           51  +}
           52  +.newwin {
           53  + border-width: 0px;
           54  +}
           55  +.ptip {
           56  +  background: #ddd;
           57  +  padding: 5px;
           58  +  border: 1px solid #aaa;
           59  +}
           60  +.tip {
           61  + font-weight: bold;
           62  + background-color: #FFFF00;
           63  + border: 1px solid #000000;
           64  + padding: 1px;
           65  + padding-left: 5px;
           66  + padding-right: 5px;
           67  + margin-right: 10px;
           68  +}
           69  +.note {
           70  + font-weight: bold;
           71  + background-color: blue;
           72  + color: #FFFFFF;
           73  + border: 1px solid #000000;
           74  + padding: 2px;
           75  +}
           76  +hr {
           77  + margin-bottom: 7px;
           78  +}
           79  +h2 {
           80  + background-color: #191970;
           81  + color: #FFFFFF;
           82  + padding: 5px;
           83  +}
           84  +.top {
           85  + text-align: right;
           86  +}
           87  +</style>
           88  +</head>
           89  +<body>
           90  +<h1>WebCalendar System Administrator's Guide</h1>
           91  +<p><strong>WebCalendar Version: 1.2.7</strong></p>
           92  +
           93  +<h2>Table of Contents</h2>
           94  +<ul>
           95  + <li><a href="#intro">Introduction</a></li>
           96  + <li><a href="#requirements">System Requirements</a></li>
           97  + <li><a href="#fileunpacking">File Unpacking</a></li>
           98  + <li><a href="#appsetup">Application Installation</a></li>
           99  + <li><a href="#eventcal">Configuring as Event Calendar</a></li>
          100  + <li><a href="#users">Creating Users</a></li>
          101  + <li><a href="#reminders">Setting Up Email Reminders</a></li>
          102  + <li><a href="#systemsettings">System Settings</a></li>
          103  + <li><a href="#siteextras">Custom Event Fields</a></li>
          104  + <li><a href="#faq">FAQ</a></li>
          105  + <li><a href="#trouble">Troubleshooting</a></li>
          106  + <li><a href="#help">Getting Help</a></li>
          107  + <li><a href="#license">Licensing</a></li>
          108  + <li><a href="#glossary">Glossary</a></li>
          109  + <li><a href="#appendixA">Appendix A: Database Setup with phpMyAdmin</a></li>
          110  + <li><a href="#appendixB">Appendix B: Database Setup</a></li>
          111  + <li><a href="#appendixC">Appendix C: Setting Up Reminders on Windows</a></li>
          112  + <li><a href="#appendixD">Appendix D: Displaying Upcoming Events on Your Site</a></li>
          113  + <li><a href="#appendixE">Appendix E: How To Configure for LDAP</a></li>
          114  + <li><a href="#appendixF">Appendix F: Manual Installation</a></li>
          115  + <li><a href="#appendixG">Appendix G: Error Codes</a></li>
          116  +</ul>
          117  +<hr />
          118  +
          119  +<a name="intro"></a>
          120  +<h2>Introduction</h2>
          121  +
          122  +<p>WebCalender is an open source PHP-based multi-user calendar.</p>
          123  +
          124  + <p><strong>Features:</strong></p>
          125  + <ul>
          126  +  <li>Multi-user support</li>
          127  +  <li>Group support</li>
          128  +  <li>View day-at-glance</li>
          129  +  <li>View month-at-glance</li>
          130  +  <li>View week-at-glance</li>
          131  +  <li>View year-at-glance</li>
          132  +  <li>View another user's calendar</li>
          133  +  <li>View multiple users' calendars at the same time</li>
          134  +  <li>View one or more users' calendar via layers on top of your own calendar</li>
          135  +  <li>Public calendar (that requires no login) where anonymous users
          136  +    submit events that are approved by an administrator</li>
          137  +  <li>Add/Edit/Delete users</li>
          138  +  <li>Add/Edit/Delete events/todos</li>
          139  +  <li>Repeating events</li>
          140  +  <li>Custom event fields</li>
          141  +  <li>Search interface for calendar entries</li>
          142  +  <li>User-configurable preferences for colors, 12/24 time format,
          143  +    Week start on Sun or Mon, default work hours</li>
          144  +  <li>Online help</li>
          145  +  <li>Checks for scheduling conflicts</li>
          146  +  <li>Support for multiple timezones</li>
          147  +  <li>Users can accept or reject events added by another user to their calendar</li>
          148  +  <li>Email reminders</li>
          149  +  <li>Email notifications for new events</li>
          150  +  <li>Support for 30 different languages:
          151  +  <ul>
          152  +   <li>Basque</li>
          153  +   <li>Bulgarian</li>
          154  +   <li>Catalan</li>
          155  +   <li>繁體中文(Big5)</li>
          156  +   <li>简体中文(GB2312)</li>
          157  +   <li>Czech</li>
          158  +   <li>Danish</li>
          159  +   <li>Deutsche (German)</li>
          160  +   <li>English</li>
          161  +   <li>Espa&#241;ol (Spanish)</li>
          162  +   <li>Estonian</li>
          163  +   <li>Fran&#231;ais (French)</li>
          164  +   <li>Galician</li>
          165  +   <li>Greek</li>
          166  +   <li>Hollands (Dutch)</li>
          167  +   <li>Holo (Taiwanese)</li>
          168  +   <li>Hungarian</li>
          169  +   <li>Icelandic</li>
          170  +   <li>Italiano (Italian)</li>
          171  +   <li>Japanese (EUCJP, SJIS)</li>
          172  +   <li>Korean</li>
          173  +   <li>Norsk (Norwegian)</li>
          174  +   <li>Polish</li>
          175  +   <li>Portuguese</li>
          176  +   <li>Portuguese/Brazil</li>
          177  +   <li>Romanian</li>
          178  +   <li>Русско (Russian)</li>
          179  +   <li>Suomalainen (Finnish)</li>
          180  +   <li>Svensk (Swedish)</li>
          181  +   <li>Turkish</li>
          182  +   <li>Welsh</li>
          183  +  </ul>
          184  + </li>
          185  + <li>Exporting to and importing from:
          186  +  <ul>
          187  +   <li>Palm Pilot</li>
          188  +   <li>iCalendar</li>
          189  +   <li>vCalendar</li>
          190  +   <li>hCalendar (import only, requires PHP5)</li>
          191  +  </ul>
          192  + </li>
          193  + <li>Authentication using:
          194  +  <ul>
          195  +   <li>web-based</li>
          196  +   <li>HTTP authentication</li>
          197  +   <li>LDAP</li>
          198  +   <li>NIS</li>
          199  +   <li>IMAP</li>
          200  +   <li>support for external application authentication ( Postnuke, Joomla ) </li>
          201  +  </ul>
          202  + </li>
          203  + <li>Activity log that tracks:
          204  +  <ul>
          205  +   <li>event creation</li>
          206  +   <li>event updates</li>
          207  +   <li>event acceptance</li>
          208  +   <li>event rejection</li>
          209  +   <li>email notifications</li>
          210  +   <li>email reminders</li>
          211  +   </ul>
          212  + </li>
          213  + <li>Synchronization and Syndication:
          214  +   <ul>
          215  +   <li>Two-way authenticated iCalendar (ics) sync </li>
          216  +   <li>Anonymous iCalendar (ics) publishing</li>
          217  +   <li>RSS 2.0 feed </li>
          218  +   </ul>
          219  + </li>
          220  +</ul>
          221  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          222  +<hr />
          223  +
          224  +<a name="requirements"></a>
          225  +<h2>System Requirements</h2>
          226  + <ul>
          227  +  <li>PHP 4.1 - PHP 5: some features specific version:
          228  +    <ul>
          229  +      <li>two-way iCalendar sync: PHP 4.3+ </li>
          230  +      <li>hCalendar importing: PHP 5+ </li>
          231  +    </ul>
          232  +  </li>
          233  +  <li>Database (see <a href="#database">below</a>)</li>
          234  +  <li>CSS-enabled browser:
          235  +    <ul>
          236  +      <li>Microsoft Internet Explorer </li>
          237  +      <li>Mozilla Firefox </li>
          238  +      <li>Opera </li>
          239  +      <li>Apple Safari </li>
          240  +    </ul>
          241  +  </li>
          242  +  <li>JavaScript-enabled browser</li>
          243  +  <li>If not using HTTP-based authentication,
          244  +      then browser cookies are required</li>
          245  + </ul>
          246  + <p><strong>Recommended:</strong></p>
          247  + <ul>
          248  +  <li>pilot-link (if exporting to Palm):
          249  +  <a href="http://sourceforge.net/project/?group_id=2158">http://sourceforge.net/project/?group_id=2158</a>&nbsp;<a href="http://sourceforge.net/project/?group_id=2158" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
          250  + </ul>
          251  + <p><a name="database">You must have one of the following databases installed</a>:</p>
          252  + <ul>
          253  +  <li>MySQL</li>
          254  +  <li>Oracle 8+</li>
          255  +  <li>PostgreSQL</li>
          256  +  <li>Interbase</li>
          257  +  <li>MS SQL Server</li>
          258  +  <li>SQLLite (PHP5)</li>
          259  +  <li>IBM DB2 </li>
          260  +  <li>ODBC</li>
          261  + </ul>
          262  +
          263  + <p class="ptip"><span class="tip">TIP</span>PHP ODBC includes support for Adabas D, Solid
          264  +   and Sybase SQL Anywhere as well as ODBC. PHP5 comes bundled with
          265  +   SQLite support. SQLite is an embedded file-based database. If your
          266  +   hosting service supports PHP5, you should be able to create as
          267  +   many SQLite databases as you like (since each database is just
          268  +   a file).</p>
          269  + <p>For the database you choose, you must have its drivers built into
          270  +  PHP. For example, to use MySQL, PHP must be compiled with MySQL
          271  +  support (which is the default setting when installing PHP).
          272  +  See the PHP pages (<a href="http://www.php.net">www.php.net</a>&nbsp;<a href="http://www.php.net" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>)
          273  +  for more information on setting up PHP.</p>
          274  + <p>No optional PHP packages (other than MySQL) are required for this
          275  +  application. However, PHP should be compiled with <tt>--enable-track-vars</tt>
          276  +  on some systems.</p>
          277  + <p class="ptip"><span class="tip">TIP</span>If you want to use gradient background
          278  +   images, PHP must be compiled with the GD library. </p>
          279  +
          280  +  <p>You can run PHP either as a CGI or an Apache module. You'll get better
          281  +  performance with PHP setup as a module. Not only will you not have to
          282  +  deal with the CGI performance hit, but you'll be able to use PHP's
          283  +  database connection pooling. Additionally, this application can use
          284  +  a form/cookie-based authentication or traditional HTTP authentication.
          285  +  For traditional HTTP authentication, PHP must be built as an Apache
          286  +  module.</p>
          287  + <p>If you are planning on using email reminders, you will need to build
          288  +  PHP as a CGI in order to run the <tt>send_reminders.php</tt> script. I would
          289  +  strongly recommend building a module-based PHP for your web server
          290  +  and then a second PHP build to create the CGI version.</p>
          291  + <p class="ptip"><span class="tip">TIP</span> Some Linux distributions come with both a module-based PHP
          292  +  with Apache and a standalone PHP binary.
          293  +  Check for <tt>/usr/bin/php</tt> to see if you already have the
          294  +  PHP standalone executable. If it's there, you can use
          295  +  the following command to see what version of PHP you have:
          296  +  <br /><br />
          297  +  <tt style="margin-left: 50px;">/usr/bin/php -v</tt>
          298  + </p>
          299  +
          300  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          301  +<hr />
          302  +
          303  +<a name="fileunpacking"></a>
          304  +<h2>File Unpacking</h2>
          305  + <p>Unpack the calendar software in its own directory somewhere where
          306  +  your web server will find it. (See your web server documentation for information.)</p>
          307  + <p>By default, unpacking WebCalendar will create its own directory
          308  +  when you unpack it. The new directory name will typically
          309  +  contain the version name (such as <tt>WebCalendar-1.2.7</tt>).
          310  +  You can rename this directory after unpacking the files if you
          311  +  prefer a directory name like <tt>calendar</tt> or <tt>webcalendar</tt>.
          312  +  Keep in mind that unless you remap the directory (via your web server's
          313  +  configuration settings), it will be part of the URL for the calendar.</p>
          314  + <div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          315  +<hr />
          316  +
          317  +<a name="appsetup"></a>
          318  + <h2>Application Installation</h2>
          319  +
          320  + <p>WebCalendar now includes an installation script that will guide you through
          321  + the entire installation process.
          322  + It should run automatically when first accessing
          323  + a new installation or when a major version upgrade has been performed.
          324  + The installation
          325  + script can always be rerun if needed by adding <tt>install/index.php</tt>
          326  + to your base WebCalendar URL. </p>
          327  +
          328  + <h3>WebCalendar Installation Wizard: Step 1</h3>
          329  + <p>When first run, the installation script will prompt you for a
          330  + <em>Configuration Wizard Password</em> that will protect against unauthorized
          331  + tampering. Until this password is set, your WebCalendar installation and possibly your database are vulnerable to attack. Once, you've set your password, be sure
          332  + to write it down. If forgotten, the only way to recover is to manually edit the
          333  + <tt>install/settings.php</tt> file.</p>
          334  +
          335  + <p>The installation script will now check several prerequisites and report the
          336  + results. Any item that appears in <font color="#FF0000">RED</font> should be
          337  +  corrected before continuing.</p>
          338  +
          339  + <table cellpadding="2">
          340  + <tr><th>Prerequisite Failed</th><th>Recommended Solution</th></tr>
          341  + <tr>
          342  +   <td>PHP 4.1.0 or greater</td>
          343  +   <td>Upgrade your PHP installation</td>
          344  + </tr>
          345  + <tr>
          346  +   <td>Safe Mode* = Off</td>
          347  +   <td>If possible, change this setting in your <tt>php.ini</tt> file to <tt>Off</tt>.</td>
          348  + </tr>
          349  + <tr>
          350  +   <td>Safe Mode Allowed Vars*</td>
          351  +   <td>If unable to to set Safe Mode Off, then set safe_mode_allowed_vars to contain
          352  +   <tt>TZ</tt> in your <tt>php.ini</tt> file.
          353  +   </td>
          354  +  </tr>
          355  +  <tr><td colspan="2">* NOTE: If neither of the these settings pass testing, then
          356  +   your WebCalendar installation will be restricted to using the server's timezone
          357  +   setting only.</td>
          358  + </tr>
          359  + <tr>
          360  +   <td>File Uploads</td>
          361  +   <td>If disabled, then some features of WebCalendar will not function. This setting is configurable in your <tt>php.ini</tt> or <tt>httpd.conf</tt> files as <tt>file_uploads</tt></td>
          362  + </tr>
          363  + <tr>
          364  +   <td>CRYPT_STD_DES</td>
          365  +   <td>This setting should be able to be ignored. We now support multiple <tt>crypt</tt>
          366  +   algorithms. If this setting is not enabled and you experience difficulties logging in,
          367  +    please notify the WebCalendar development team.</td>
          368  + </tr>
          369  + <tr>
          370  +   <td>GD</td>
          371  +   <td>This library is required only if gradient background images are desired. Normally, PHP must be compiled with this option. Some installations only require it be enabled in your
          372  +   <tt>php.ini</tt> file.</td>
          373  + </tr>
          374  + <tr>
          375  +   <td>Session Check</td>
          376  +   <td>PHP Sessions are used during the installation process and are required
          377  +     for proper operation. Sessions can be configured in your <tt>php.ini</tt> file.
          378  +     If it's not possible to enable sessions, then you must manually install WebCalendar.
          379  +     Details are available in
          380  +   <a href="#appendixF">Appendix F</a></td>
          381  + </tr>
          382  + <tr>
          383  +   <td>Settings.php Status</td>
          384  +   <td>The installation script was either unable to create, or unable to write
          385  +     to your settings.php file. You will need to modify the permissions of the <tt>includes</tt>
          386  +    directory. On Linux/UNIX, you should change this directory to be read/write
          387  +     for all users (<tt>chmod 777 includes</tt>). On Windows, change this directory
          388  +      to have full access for all users using Windows Explorer.</td>
          389  + </tr>
          390  +
          391  + </table>
          392  + <h3>WebCalendar Installation Wizard: STEP 2</h3>
          393  +
          394  + <p>The installation script can create your WebCalendar database as well as create all the required tables and pre-populate them with the basic configuration data. These features are only available when using fully supported database types. See
          395  + <a href="#appendixB">Appendix B</a> to manually create your database if needed.</p>
          396  +
          397  + <p><strong>Database Status</strong></p>
          398  + <p>Displays the current status of your database settings as well the supported
          399  + databases for your PHP installation.</p>
          400  +
          401  + <p><strong>Database Settings</strong></p>
          402  +<p>To configure your database access. Set the values for:</p>
          403  + <table class="distinguish">
          404  +  <tr><th>Displayed Value</th><th>settings.php value</th><th>Comments</th></tr>
          405  +  <tr><td>
          406  +   Database Type</td><td>db_type</td>
          407  +  <td>
          408  +   One of "mysql", "oracle", "postgresql", "odbc",
          409  +   &quot;mssql&quot;, sqllite, db2,
          410  +   or "ibase"
          411  +  </td>
          412  +  </tr>
          413  +  <tr><td>
          414  +   Server</td><td>db_host</td><td>
          415  +   The hostname that database is running on.
          416  +   (Use localhost if it's the same machine as
          417  +   the web server.) (This variable is not used with ODBC, enter 'none')
          418  +   (Use 'none' if your db server does not use a TCP socket to connect)
          419  +   (If using a special PORT, you can specify it as HOST:PORT)
          420  +  </td></tr>
          421  +  <tr><td>
          422  +   Login</td><td>db_login</td><td>
          423  +   The database login
          424  +   (Not used for SQLite.)
          425  +  </td></tr>
          426  +  <tr><td>
          427  +   Database Name</td><td>db_password</td><td>
          428  +   The database password for the above login<br />
          429  +   (Use 'none' if your db server does not use a TCP socket to connect.)
          430  +   (Not used for SQLite.)
          431  +  </td></tr>
          432  +  <tr><td>
          433  +   Database Name</td><td>db_database</td><td>
          434  +   The name of the database that the calendar
          435  +   tables reside in. ("intranet" in the <a href="#dbsetup">examples above</a>.)
          436  +   For ODBC, this should be the DSN.
          437  +   For SQLite, this is the filename that will be used.
          438  +  </td></tr>
          439  +  <tr><td>
          440  +   Connection Persistence</td><td>db_persistent</td><td>
          441  +   Enable use of persistent (pooled) database connections.
          442  +   This should typically be enabled. This setting may be disabled for CGI installations.
          443  +  </td></tr>
          444  +  <tr><td>
          445  +   Database Cache Directory</td><td>db_cachedir</td>
          446  +   <td>
          447  +   To enable caching of database query results, enter a writable directory. This
          448  +     directory should NOT be in the webserver document path to prevent unauthorized
          449  +     access to cached  sensitive data such as passwords hashes and private event
          450  +     details.
          451  +    To disable this feature, leave this field blank.
          452  +    However, this feature is recommended to enhance your system's performance.
          453  +  </td>
          454  +  </tr>
          455  + </table>
          456  + <p>Click the <font color="#FF0000">Test Settings</font> button to perform the test your settings.</p>
          457  +
          458  + <p>Click the <font color="#FF0000">Create</font> button to have the installation
          459  +   script create your database. This option will only be available for fully
          460  +   supported database types. Retest your database settings if prompted to do
          461  +   so.</p>
          462  +
          463  + <p class="ptip"><span class="tip">TIP</span>If this step does not complete
          464  +   properly, then you will have to manually create your database. Detailed instructions
          465  +   can be found in <a href="#appendixB">Appendix B</a>. Then rerun the installation
          466  +   script to continue the installation.</p>
          467  +
          468  + <h3>WebCalendar Installation Wizard: STEP 3</h3>
          469  + <p>In this section we will perform the required database changes to bring your database up to the required level If you are using a fully supported database, this step will be performed automatically for you If not, the required SQL can be displayed and you should be able to cut &amp; paste it into your database server query window.</p>
          470  +
          471  + <p><strong>Database Status</strong></p>
          472  + <p>This should display the current installed version of WebCalendar as well as the version being installed.</p>
          473  +
          474  + <p><font color="#FF0000"><strong>The following database actions are required</strong>
          475  + </font></p>
          476  +
          477  + <p>If using a fully supported database type, clicking the <strong>Update Database</strong> button  will create any tables required for this installation or upgrade. If this feature is
          478  + not supported, then this button will not be available.</p>
          479  +
          480  +<p>The <strong>Display Required SQL</strong> button will always be available
          481  +  and if clicked will display the required SQL text that can then be cut &amp; pasted
          482  +  into the SQL query window of your database program. If using the approach,
          483  +  please rerun the installation script after completing your required database
          484  +  updates.</p>
          485  +
          486  + <p class="ptip"><span class="tip">TIP</span>If this step does not complete properly,
          487  +   then you will have to manually create your database tables. Detailed instructions
          488  +   can be found in <a href="#appendixF">Appendix F</a>. Then rerun the installation
          489  +   script to continue the  installation.</p>
          490  +
          491  + <h3>WebCalendar Installation Wizard: STEP 4</h3>
          492  +
          493  +<p><strong>Timezone Conversion</strong></p>
          494  +<p>If upgrading WebCalendar from a previous version, you may be prompted to perform a Timezone Conversion. WebCalendar version 1.0.4 and earlier stored event date and time in the server's
          495  +timezone. As of v1.1.0, all event date and time information is stored as UTC time. So, a one-time conversion of existing events will required to prevent event displayed times from
          496  +appearing incorrectly.</p>
          497  +
          498  +<p><strong>Application Settings</strong></p>
          499  +
          500  +<p>Create Default Admin Account: If checked, a DEFAULT ADMINISTRATOR account will be created with username:admin password:admin</p>
          501  +
          502  +<p>Application Name: The default value <strong>Title</strong> will be translated into
          503  + <strong>WebCalendar</strong> into the user's language. Any other entry will not be
          504  +translated unless entries are made into the appropriate language.txt files.</p>
          505  +
          506  +<p>Server URL: This should be the full URL to access your WebCalendar installation.The trailing "/" is required for proper operation. If this field is left blank, WebCalendar will
          507  +calculate the proper value and store it in the database.</p>
          508  +
          509  +<p>User Authentication: You can configure the calendar to run in single-user<a href="#g_singleuser">*</a> mode or
          510  + multi-user<a href="#g_multiuser">*</a> mode. If this is your first time using the
          511  + calendar, it's easier to try single-user. You can always switch to multi-user
          512  + later. Leave <tt>single_user</tt> set to "false" (the default) for multi-user or set
          513  + it to "true" and set the value of <tt>single_user_login</tt> to a login name of your liking
          514  + to set the system to single-user mode. (And be sure to set the value of
          515  + <tt>single_user_login</tt> to the login that you would choose if you decide to switch
          516  + to multi-user mode some day.)</p>
          517  + <p><span class="note">Note:</span> If you do decide to switch from single-user mode to multi-user mode, make sure you add in a user to the system for the login you set the
          518  +  <tt>single_user_login</tt> variable to. You will need to do this via the
          519  +  database (mysql, sqlplus, etc.)  Look in the <tt>tables-mysql.sql</tt>
          520  +  (or <tt>tables-oracle.sql</tt>, etc.) to see the example of adding in the "admin" user.</p>
          521  + <p>If you are setting up a multi-user calendar, you will need to choose
          522  +  how your users are authenticated. You must change the settings of
          523  +  <tt>use_http_auth</tt> and <tt>user_inc</tt>
          524  +  to setup which authentication method to use.</p>
          525  + <p>You currently have five choices:</p>
          526  + <ol>
          527  +  <li>Web-based authentication (login/passwords verified in the WebCalendar database):<br />
          528  +   <tt>use_http_auth = false</tt><br />
          529  +   <tt>user_inc = user.php</tt>
          530  +  </li>
          531  +  <li>HTTP-based authentication (login/passwords verified by the web server):<br />
          532  +   <tt>use_http_auth = true</tt><br />
          533  +   <tt>user_inc = user.php</tt><br />
          534  +   ... and don't forget to setup your web server to handle user
          535  +   authentication.<br />
          536  +          <span class="note">Note:</span> In order to use HTTP-based authentication,
          537  +    PHP must be setup as a module for your server rather than a CGI.
          538  +  </li>
          539  +  <li>NIS-based authentication (login/passwords verified by NIS):<br />
          540  +   <tt>use_http_auth = false</tt><br />
          541  +   <tt>user_inc = user-nis.php</tt><br />
          542  +   Additional configuration settings will need to be set
          543  +   in <tt>includes/user-nis.php</tt>.
          544  +  </li>
          545  +  <li>LDAP-based authentication (login/passwords verified by LDAP server):<br />
          546  +   <tt>use_http_auth = false</tt><br />
          547  +   <tt>user_inc = user-ldap.php</tt><br />
          548  +   Additional configuration settings will need to be set
          549  +   in <tt>includes/user-ldap.php</tt>.
          550  +  </li>
          551  +  <li>IMAP-based authentication (login/passwords verified by IMAP server):<br />
          552  +   <tt>use_http_auth = false</tt><br />
          553  +   <tt>user_inc = user-imap.php</tt><br />
          554  +   Additional configuration settings will need to be set
          555  +   in <tt>includes/user-imap.php</tt>.
          556  +  </li>
          557  + </ol>
          558  +
          559  +<p>Read-Only: Determines whether events can be added to your WebCalendar.</p>
          560  +
          561  +<p>Environment: Normally set this <strong>Production</strong>. Development will allow
          562  +more verbose sql logging and should not be used unless needed.</p>
          563  +
          564  +<p>After saving your settings, you should be provided with a
          565  +<strong>Launch WebCalendar</strong>  button that will open WebCalendar in a separate
          566  +browser window.</p>
          567  +
          568  +<p><strong>Congratulations! You have successfully installed WebCalendar on
          569  +your system.</strong></p>
          570  +
          571  +    <p>Keep in mind that if you want to use reminders, you will need to
          572  +  setup the <tt>send_reminders.php</tt> script (see below) and keep your admin
          573  +  setting for "Email enabled" set to "Yes" on the admin settings page.</p>
          574  +    <p>At this point, your WebCalendar installation should be up and running.
          575  +  To access WebCalendar open up your favorite web browser and
          576  +  type in the URL. The URL will depend on where you installed WebCalendar.</p>
          577  +
          578  + <p class="ptip"><span class="tip">TIP</span> On a multi-user system, the only user account created
          579  + during installation has the username of "admin" and a password of "admin". You should create
          580  + a new admin account and delete this one for security reasons.</p>
          581  +
          582  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          583  +
          584  +<hr />
          585  +
          586  +<a name="eventcal"></a>
          587  +<h2>Configuring as Event Calendar</h2>
          588  +
          589  +<p>
          590  +  If you intend to use WebCalendar as an event calendar, you will
          591  +  need to enable "Public Access" in the System Settings with the following
          592  +  steps:</p>
          593  +   <ul>
          594  +    <li>Login to WebCalendar as an administrator (the default username is
          595  +        'admin' and password 'admin'). </li>
          596  +   <li>Click on the "Admin" link at the bottom of any page.</li>
          597  +   <li>Click on the "System Settings" button.</li>
          598  +   <li>Click on the "Public Access" tab.</li>
          599  +   <li>Select "Yes" for "Allow public access".</li>
          600  +  </ul>
          601  +<p>This will allow users to access WebCalendar without a username and
          602  +password. Only events that are created with the "Public User" as
          603  +an event participant will show up in your event calendar for users
          604  +who have not logged in. If events are not showing up on your public
          605  +calendar, make sure the events have the "Public User" as a participant
          606  +and the event has been approved.
          607  +</p>
          608  +
          609  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          610  +
          611  +<hr />
          612  +
          613  +<a name="users"></a>
          614  + <h2>Creating Users</h2>
          615  + <p>After logging in as an admin user (the initial username is "admin" with
          616  +  password "admin"), you will see a common set of links at the bottom
          617  +  of each page. Follow these steps to create a new user:</p>
          618  + <ol>
          619  +  <li>Login to WebCalendar as an admin user</li>
          620  +  <li>Click on the "Admin" link at the bottom of any WebCalendar page</li>
          621  +  <li>Click on the "Users" button</li>
          622  +  <li>Click on the "Add New User" link</li>
          623  +  <li>Fill out the form with details for the new user (email address is optional)</li>
          624  +  <li>Click on the "Save" button</li>
          625  + </ol>
          626  + <p class="ptip"><span class="tip">TIP</span> On a single-user system, you do not need to create any users.</p>
          627  + <p class="ptip"><span class="tip">TIP</span> For an event calendar, you do not need to create a user for the "public user".</p>
          628  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          629  +<hr />
          630  +
          631  +<a name="reminders"></a>
          632  + <h2>Setting Up Email Reminders</h2>
          633  + <p>PHP does not come with a utility for executing time-based jobs.
          634  +  So, in order to check periodically for email reminders, a shell
          635  +  script was written in PHP. You will need two things to get this working:</p>
          636  + <ol>
          637  +  <li>You should have a version of PHP built as a CGI (so that you can run
          638  +    php from the command line). This does not mean you must build all
          639  +    of PHP as a CGI. You can still build PHP as a module for your web
          640  +  server and then build the CGI-based PHP later.<br />
          641  +    <span class="note">Note:</span> Many Linux distributions and some Windows LAMP packages
          642  +    come with the PHP built for CGI.</li>
          643  +  <li>You must setup cron (on Linux/UNIX) or something like cron for Windows
          644  +  to run the <tt>send_reminders.php</tt> script periodically.</li>
          645  + </ol>
          646  + <p>Building PHP as a CGI is outside the scope of these instructions. But,
          647  +  if you read the PHP instructions, you'll see that the default build
          648  +  settings will build the CGI-based PHP. If you really can't do this
          649  +  (perhaps you don't have permission to install anything new on the
          650  +  system), skip down a couple of paragraphs to an alternate solution
          651  +  that does not require PHP CGI.</p>
          652  + <p>For Linux/UNIX users, add the following line to the crontab entry of
          653  +  a user. (This would be the same user that the web server
          654  +  process runs as.)</p>
          655  + <pre><tt>1 * * * * cd /some/directory/webcalendar/tools; ./send_reminders.php</tt></pre>
          656  +    <p>Of course, replace the directory location to wherever the
          657  +  <tt>send_reminders.php</tt> file can be found. If you moved this out of the
          658  +  tools directory (which is recommended for security reasons),
          659  +  be sure to update <tt>send_reminders.php</tt> since it needs
          660  +  to know where to find other WebCalendar files.</p>
          661  +    <p>If you cannot setup PHP as a CGI or have no idea how, you can leave
          662  +  <tt>send_reminders.php</tt> in its current location and access it via a URL.
          663  +  IMHO, this is not the best choice, but it still works. Setup a cron
          664  +  job to access the URL. For Linux/UNIX users, add the following line to
          665  +  the crontab entry of a user.</p>
          666  + <pre><tt>1 * * * * wget http://yourserverhere/webcalendardirectoryhere/tools/send_reminders.php &gt; /dev/null</tt></pre>
          667  +<p>Some users have reported the following works better for their configuration.</p>
          668  +<pre><tt>1 * * * * wget -q -O /dev/null http://yourserverhere/webcalendardirectoryhere/tools/send_reminders.php</tt>
          669  +</pre>
          670  +  <p>You should test this from the command line first to make sure your setup is
          671  +  correct. If you do not have <tt>wget</tt> installed on your system, you can use
          672  +  any tool (lynx, perl script, etc.) that is capable of making an HTTP request for this.</p>
          673  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
          674  +<hr />
          675  +
          676  +<a name="systemsettings"></a>
          677  + <h2>System Settings</h2>
          678  + <p>System Settings allows the administrator to control what features are available to users
          679  + as well as default values for certain features.</p>
          680  + <p>Many of these settings can be overridden by users in their Preferences (such
          681  +   as color). These user configurable settings are identified by
          682  +  <strong><em>Italics</em></strong>.</p>
          683  + <h3>Settings</h3>
          684  + <dl>
          685  +  <dt>Application Name</dt>
          686  +  <dd>Specifies the document title (typically displayed in the window title bar
          687  +  of most browsers)</dd>
          688  +  <dt>Server URL</dt>
          689  +  <dd>Specifies the base URL of the calendar. This information is needed to
          690  +  accurately include URLs in email messages (Notifications and Reminders).</dd>
          691  +  <dt>Home URL</dt>
          692  +  <dd>Specifies the URL to return to when exiting WebCalendar. If set, a new menu option will
          693  +  become visible in the menu.</dd>
          694  +  <dt><em>Language</em></dt>
          695  +   <dd>Specifies the default language setting for all users.</dd>
          696  +  <dt>Server Timezone Selection</dt>
          697  +   <dd>Allows you to manually set your server's WebCalendar timezone selection. This has
          698  +   no effect on the OS Timezone settings.</dd>
          699  +  <dt>Allow user to use themes</dt>
          700  +   <dd>Allows users to have access to pre-defined themes that can set color or user preference
          701  +   settings. There are a few examples available in the <tt>themes</tt> folder.</dd>
          702  +  <dt><em>Themes</em></dt>
          703  +   <dd>The default theme that will be applied to all users unless they make their own
          704  +   changes.</dd>
          705  +  <dt>Allow top menu</dt>
          706  +   <dd>Turns on the NEW menu system for all users.</dd>
          707  +  <dt>Date Selectors position</dt>
          708  +   <dd>Determines position of Date Pulldown Selectors. Either inside the NEW
          709  +     menu or in their original location at the bottom of the calendar.</dd>
          710  +   <dt><em>Menu theme</em></dt>
          711  +   <dd>Theme to be used with NEW menu.</dd>
          712  +  <dt><em>Fonts</em></dt>
          713  +   <dd>Specifies your preferred font. Multiple font names should be comma-separated.</dd>
          714  +  <dt><em>Custom script/stylesheet</em></dt>
          715  +   <dd>Place any custom stylesheet information or JavaScript that will
          716  +       be included on all WebCalendar pages.</dd>
          717  +  <dt><em>Custom header</em></dt>
          718  +   <dd>The custom header allows you to specify HTML to be placed after
          719  +       the &lt;body&gt; tag but before any WebCalendar content and
          720  +       included on all WebCalendar pages.</dd>
          721  +  <dt><em>Custom trailer</em></dt>
          722  +   <dd>The custom trailer allows you to specify HTML to be placed after
          723  +       the WebCalendar content but before the &lt;/body&gt; tag and
          724  +       included on all WebCalendar pages.</dd>
          725  + <dt>Allow external file for header/script/trailer</dt>
          726  +   <dd>If enabled, then the Custom header and Custom trailer settings
          727  +       can specify a filename on the server rather than HTML.</dd>
          728  +  <dt>Allow user to override header/trailer</dt>
          729  +   <dd>If enabled, then users can add their own custom HTML for
          730  +       both the header (top of the page) and trailer (bottom of the page)
          731  +       to customize the appearance of all pages.</dd>
          732  +  <dt><em>Preferred View</em></dt>
          733  +   <dd>Specify if users should see the day, week, month, or year after logging in.</dd>
          734  +  <dt><em>Display small months</em></dt>
          735  +   <dd>Specifies whether small months are included in month, week, day views.</dd>
          736  +  <dt><em>Display weekends</em></dt>
          737  +   <dd>Specifies whether weekends are included in month, week, day, and views.</dd>
          738  +  <dt><em>Display all days in month view</em></dt>
          739  +   <dd>Specifies whether the complete month grid is filled with days from previous and
          740  +   next month.</dd>
          741  +  <dt>Display days with events in bold in month and year views</dt>
          742  +   <dd>Highlights and bolds the text for days containing events in the mini-calendars
          743  +   used in day, month and year calendars.</dd>
          744  +  <dt><em>Display description in printer day view</em></dt>
          745  +   <dd>If enabled, then the "printer friendly" view of the day view will include full event
          746  +    descriptions rather than just the event name.</dd>
          747  +  <dt>Display Common Use Date/Times as GMT</dt>
          748  +   <dd>Sets the timezone to used for General Purpose dates. Either GMT of the Server
          749  +   timezone will be selected.</dd>
          750  +   <dt><em>Date format</em></dt>
          751  +   <dd>Specifies the default format for displaying dates. These are defined in
          752  +     file
          753  +   <tt>includes/date_formats.php</tt> and if <strong>LANGUAGE DEFINED</strong> is selected
          754  +   then the format will be adjusted based on the format in the user's language.txt file.</dd>
          755  +   <dt><em>Time format</em></dt>
          756  +   <dd>Specifies the default time format as either 12-hour (3:45pm) or 24-hour (15:14)</dd>
          757  +   <dt><em>Display 00 minutes always</em></dt>
          758  +   <dd>Specifies whether times on the hour ( 10:00 ) are displayed with trailing 00.</dd>
          759  +  <dt><em>Entry interval</em></dt>
          760  +  <dd>Specify the default options for entry start and stop times. This values will also
          761  +  determine the display resolution of timebar views as well as user availability.</dd>
          762  +  <dt><em>Time interval</em></dt>
          763  +  <dd>Specify the default number of minutes each time block represents in the day and
          764  +  week display</dd>
          765  +  <dt><em>Auto-refresh calendars</em></dt>
          766  +  <dd>If set to "yes," the day, week, and month pages will automatically
          767  +  reload after a specified duration</dd>
          768  +  <dt><em>Auto-refresh time</em></dt>
          769  +  <dd>Specifies how long to wait before the auto-refresh should force a page
          770  +  to be reloaded</dd>
          771  +  <dt>Require event approvals</dt>
          772  +  <dd>If enabled, then events added to one user's calendar by another
          773  +      user will require approval.</dd>
          774  +  <dt><em>Display unapproved</em></dt>
          775  +  <dd>Specifies whether events that have been added to a calendar but not yet
          776  +  approved should display on the calendar (in a different color)</dd>
          777  +  <dt><em>Display week number</em></dt>
          778  +   <dd>Specifies whether the week number should be displayed in month and week views</dd>
          779  +  <dt><em>Week starts on</em></dt>
          780  +   <dd>Specifies if week start on Sunday or Monday</dd>
          781  +  <dt><em>Work hours</em></dt>
          782  +   <dd>Specifies the default time range to display in day and week views</dd>
          783  +  <dt>Disable Pop-Ups</dt>
          784  +   <dd>Determines whether event pop-ups are displayed.</dd>
          785  +  <dt>Disable Location field</dt>
          786  +   <dd>Determines whether to use the Location field for events.</dd>
          787  +  <dt>Disable Priority field</dt>
          788  +   <dd>If enabled, the Priority field will not be used</dd>
          789  +  <dt>Disable Access field</dt>
          790  +   <dd>If enabled, the Access field will not be used</dd>
          791  +  <dt>Disable Participants field</dt>
          792  +  <dd>If enabled, the Participants field will not be used, and users will not be
          793  +  able to add events to any calendar other than their own.</dd>
          794  +  <dt>Disable Repeating field</dt>
          795  +   <dd>If enabled, users will not be able to create repeating events</dd>
          796  +  <dt>Display Site Extras in popup</dt>
          797  +  <dd>If enabled, custom event fields configured in <tt>site_extras.php</tt>
          798  +      will appear in the mouse-over popups containing additional
          799  +      event information.</dd>
          800  +  <dt>Display Participants in popup</dt>
          801  +  <dd>If enabled, event participants will be included in popup details.</dd>
          802  +  <dt>Allow HTML in Description</dt>
          803  +  <dd>Allow the use of HTML in the description field when creating events. In addition, with the addition of either of two optional packages (HTMLArea or FCKEditor), you can have a WYSIWYG interface. These packages are available on <a href="http://www.k5n.us/webcalendar.php?topic=Add-Ons">WebCalendar's Home Page</a></dd>
          804  +  <dt>Allow viewing other user's calendars</dt>
          805  +   <dd>If enabled, users will be able to view the calendar of another user</dd>
          806  +  <dt>Include add event link in views</dt>
          807  +  <dd>If enabled, Views will include a link to quickly add events to the
          808  +  specified user's calendar.</dd>
          809  +  <dt>Remember last login</dt>
          810  +   <dd>If enabled, when a returning calendar user reaches the login page, their login name will be pre-filled with the last login username that they entered. (The password field will still be blank.)</dd>
          811  +  <dt>Check for event conflicts</dt>
          812  +   <dd>Specifies if the system should check for scheduling conflicts when a user adds or updates an event.</dd>
          813  +  <dt>Conflict checking months</dt>
          814  +   <dd>If conflict checking is enabled, this specifies how many months past the initial date the system will check for conflicts when a user adds or updates a repeating event.</dd>
          815  +  <dt>Allow users to override conflicts</dt>
          816  +   <dd>If enabled, users will be warned when there is an event conflict and be presented with the option of scheduling the event anyhow.</dd>
          817  +  <dt>Limit number of timed events per day</dt>
          818  +   <dd>If enabled, users can be limited to a specific number of timed events per day</dd>
          819  +  <dt>Maximum timed events per day</dt>
          820  +   <dd>Specifies that maximum number of events that can be scheduled in one day of any one user.</dd>
          821  +   <dt>Specify timed event length by</dt>
          822  +   <dd>Allows you to configure event lengths to be specified
          823  +       by either duration or end time.</dd>
          824  +   <dt>Brief Description Length</dt>
          825  +   <dd>Specifies the maximum numbers of characters to display in calendar views.</dd>
          826  +   <dt><em>Display Lunar Phases in month view</em></dt>
          827  +   <dd>Show Lunar Calendar icons in month view. This will not use existing event space.</dd>
          828  +   <dt><em>Disable Cross-Day Events</em></dt>
          829  +   <dd>Determines whether to display events that cross user's day boundary as
          830  +     multiple  events.</dd>
          831  + </dl>
          832  + <h3>Public Access</h3>
          833  + <dl>
          834  +   <dt>Allow public access</dt>
          835  +  <dd>If enabled, anonymous users will be able to view the public access calendar without logging in.</dd>
          836  +  <dt>Public access visible by default</dt>
          837  +  <dd>If enabled, user's can go to the public access page without having to select it.</dd>
          838  +  <dt>Public access is default participant</dt>
          839  +  <dd>If enabled, public access will be added to every event  created.</dd>
          840  +  <dt>Public access can view other users</dt>
          841  +  <dd>If enabled, public access user's will be able to see the calendar of other WebCalendar users. <font color="#FF0000">Use with caution!</font></dd>
          842  +  <dt>Public access can add events</dt>
          843  +  <dd>If enabled, anonymous users will be able to submit new events</dd>
          844  +  <dt>Public access new events require approval</dt>
          845  +  <dd>If enabled, events submitted to the public access calendar (by anonymous users) will require approval by an admin user. If not enabled, then new events will appear on the public access calendar as soon as they are submitted.</dd>
          846  +  <dt> Public access can view participants</dt>
          847  +  <dd>If enabled, public access users can view the names of other participants for any event that public access is a participant. <font color="#FF0000">Use with caution!</font></dd>
          848  +  <dt>Override event name/description for public access</dt>
          849  +  <dd>If enabled, the value of the following setting will be used to mask the name and description of events.</dd>
          850  +  <dt>Text to display to public access</dt>
          851  +  <dd>Text to display as explained above.</dd>
          852  + </dl>
          853  +  <h3>User Access Control</h3>
          854  + <dl>
          855  +  <dt> User Access Control enabled</dt>
          856  +   <dd>User Access Control provides more advanced control of
          857  +       user access permissions.
          858  +       If enabled, a "User Access Control" button will appear on the
          859  +   main Admin page and/or on the Settings menu of the NEW top menu. This page
          860  +   will allow you to configure: </dd>
          861  +   <dd>
          862  +     <ul>
          863  +       <li>which functions in the system each user can access </li>
          864  +       <li>which user calendars each user can access
          865  +           (user A can edit events on user B's calendar, etc.)</li>
          866  +       </ul>
          867  +   </dd>
          868  + </dl>
          869  + <h3>Groups</h3>
          870  + <dl>
          871  +  <dt>Groups enabled</dt>
          872  +   <dd>Specifies if group features should be enabled</dd>
          873  +  <dt>User sees only his group</dt>
          874  +   <dd>If enabled, users will be unaware of any users that are not in the same group as the user.</dd>
          875  + </dl>
          876  + <h3>NonUser Calendars</h3>
          877  + <dl>
          878  +  <dt>Nonuser Calendars Enabled</dt>
          879  +   <dd>If enabled, you may create "nonuser calendars" in WebCalendar.
          880  +     A nonuser calendar is a calendar without a user login. It can
          881  +     be used to manage a resource like a conference room's availability.
          882  +     Or it can be used to place common events (like holidays) that multiple
          883  +     users may want to access as a layer.
          884  +     You will need to enable nonuser calendars in order to subscribe
          885  +     to remote iCalendar URLs from within WebCalendar (allowing the events
          886  +     from an iCalendar or hCalendar file elsewhere on the net to appear in your
          887  +     WebCalendar calendar.)
          888  +   </dd>
          889  +   <dt>Display in participants list at</dt>
          890  +   <dd>If enabled, then nonuser calendars can be selected as
          891  +       participants to events.</dd>
          892  + </dl>
          893  + <h3>Other</h3>
          894  + <dl>
          895  +  <dt>Reports enabled</dt>
          896  +   <dd>If enabled, user's will be able to create and generate reports.</dd>
          897  +  <dt><em>Allow remote subscriptions</em></dt>
          898  +   <dd>If enabled, user's will be able enable their own subscription settings. There are currently two main ways to publish events with WebCalendar.</dd>
          899  +   <dd>
          900  +      <ul style="margin-left:70px;"><li ><strong>publish.php</strong> will provide outbound publishing to a calendar client</li>
          901  +   <li><strong>icalclient.php</strong> will provide two-way full synchronization between WebCalendar and another calendar client such as Sunbird, Apple iCal.
          902  +      (PHP 4.3+ required)</li>
          903  +      </ul></dd>
          904  +
          905  + <dt>Allow remote calendars</dt>
          906  +   <dd>If enabled, user's will be able to add a special type Non-User Calendar
          907  +     that includes a URL that point to the remote location. The user can manually
          908  +     synchronize the remote calendars if desired. In addition, <tt>tool/reload_remotes.php</tt>
          909  +     can be set up as a cron job to automatically reload all remote calendars
          910  +     as desired. Currently both iCalendar and hCalendar calendars can be consumed
          911  +     by WebCalendar. The  calendar type should be automatically detected based
          912  +     on the URL and calendar content. Users will need to create a layer to make
          913  +     a remote calendar visible on their calendars, just like regular Non-User
          914  +     Calendars.</dd>
          915  +   <dt>Enable RSS feed</dt>
          916  +   <dd>If enabled, a link is added to all pages that permits some browsers to
          917  +     create a persistent RSS feed to that page. Currently, only Firefox and IE
          918  +     7.0 supports this functionality. Also, the setting will enable the use of
          919  +     the rss.php script generate RSS feeds to RSS clients. User's will also be
          920  +     required to enable this feature in their respective preference settings.</dd>
          921  +   <dt>Categories enabled</dt>
          922  +   <dd>Specifies if category features should be enabled</dd>
          923  +   <dt>Category Icon Upload enabled</dt>
          924  +   <dd>Specifies if category icons can be uploaded by users. This requires that
          925  +     a folder named <tt>icons</tt> exist in the WebCalendar directory.</dd>
          926  +  <dt><em>Display small task list</em></dt>
          927  +   <dd>If enabled, a small task window will be displayed in the month and day calendars. These tasks are compatible with the VTODO component of RFC2445 (iCalendar)</dd>
          928  +  <dt><em>Display tasks in Calendars</em></dt>
          929  +   <dd>If enabled, tasks are displayed along with events in calendars. The date they appear is the due date but if the due date has passed without the task being completed, the task will shift to the current day.</dd>
          930  +<!--  <dt>Export VTIMEZONE in iCalendar (ics) files</dt>
          931  +   <dd>If enabled, a complete VTIMEZONE component will be exported with iCalendar (ics) files as necessary. This function requires considerable processing time, so it should not be enabled unless needed.</dd>
          932  +-->
          933  +  <dt>Allow external users</dt>
          934  +  <dd>If enabled, the create/edit event page will contain a text area to include
          935  +  the names (and optional email address) of event participants that are not calendar users.</dd>
          936  +  <dt>External users can receive email notifications</dt>
          937  +  <dd>If enabled, event participants entered into the External Participants area will receive email notifications at the same time as calendar users (if an email address was specified for the External Participant).</dd>
          938  +  <dt>External users can receive email reminders</dt>
          939  +  <dd>If enabled, event participants entered into the External Participants area will receive email reminders at the same time as calendar users (if an email address was specified for the External Participant).</dd>
          940  +  <dt>Allow self-registration</dt>
          941  +   <dd>If enabled, new users are permitted to setup their own accounts and log into WebCalendar without admin intervention. <font color="#FF0000">Use with caution!</font></dd>
          942  +  <dt>Restrict self-registration to blacklist</dt>
          943  +   <dd>If enabled, admin can configure the includes/blacklist.php to restrict or permit self-registration based on the user's IP. This will restrict access to existing users or new user's set up by admin. Details and examples are available in the top of the file.</dd>
          944  +   <dt>Generate passwords and send to new users</dt>
          945  +   <dd>If enabled, self-registration user's will be emailed a randomly generated password that they can then use to access WebCalendar normally. Hopefully, this will prevent some spammers and hackers from misusing the self-registration process.</dd>
          946  +   <dt>Allow file attachments to events</dt>
          947  +   <dd>If enabled, attachments can be uploaded and associated with events. The
          948  +     attachments are stored in the database, so care should be taken if performance
          949  +     is an issue. Additionally, permission may extended to participants and/or
          950  +     anyone.</dd>
          951  +   <dt>Allow comments to events</dt>
          952  +   <dd>If enabled, comments can be associated with events. Additionally,
          953  +   permission may extended to participants and/or anyone. </dd>
          954  + </dl>
          955  + <h3>Email</h3>
          956  + <dl>
          957  +  <dt>Email enabled</dt>
          958  +   <dd>Specifies if email functionality should be enabled. If set to "No," then no email messages will be sent at any time.</dd>
          959  +  <dt>Default sender address</dt>
          960  +   <dd>Specifies the email originator to use when the system sends out email Notifications and Reminders</dd>
          961  +  <dt>Email Mailer</dt>
          962  +   <dd>Specifies the email program to use. (PHP mail, SMTP, or sendmail)</dd>
          963  +  <dt>SMTP Host name(s)</dt>
          964  +   <dd>Specifies the SMTP server name(s) or IP(s) if SMTP is selected above.</dd>
          965  +  <dt>SMTP Port Number</dt>
          966  +   <dd>Specifies the SMTP port number if SMTP is selected above. Default is 25.</dd>
          967  +  <dt>SMTP Authentication</dt>
          968  +   <dd>Specifies whether authentication is required if SMTP is selected above. Additionally,
          969  +   <strong>SMTP Username</strong> and <strong>SMTP Password</strong> will be required.</dd>
          970  +  <dt>Event reminders</dt>
          971  +     <dd>Specifies if email reminders for events that include a reminder should be sent</dd>
          972  +  <dt>Events added to my calendar</dt>
          973  +     <dd>Specifies if the system should send email when an event is added</dd>
          974  +  <dt>Events updated on my calendar</dt>
          975  +     <dd>Specifies if the system should send email when an event is updated</dd>
          976  +  <dt>Events removed from my calendar</dt>
          977  +     <dd>Specifies if the system should send email when an event is deleted</dd>
          978  +  <dt>Event rejected by participant</dt>
          979  +     <dd>Specifies if the system should send email when a participant to an event rejects the event</dd>
          980  + </dl>
          981  + <h3>Colors</h3>
          982  + <dl>
          983  +  <dt>Allow user to customize colors</dt>
          984  +   <dd>Specifies whether color settings should be available to users in their Preferences</dd>
          985  +  <dt> Enable gradient images for background colors</dt>
          986  +     <dd>If enabled, the background of calendar table cells will be rendered with a gradient image based on the background color selected for that cell type. This option requires that php be compiled with the <strong>gd module</strong>.</dd>
          987  +     <dt>Document background</dt>
          988  +     <dd>Specifies the background color of all pages</dd>
          989  +  <dt>Document title</dt>
          990  +     <dd>Specifies the color of page title on each page</dd>
          991  +  <dt>Document text</dt>
          992  +     <dd>Specifies the default text color on each page</dd>
          993  +  <dt>My event text</dt>
          994  +     <dd>Specifies the default text color for the user's events</dd>
          995  +  <dt>Table grid color</dt>
          996  +     <dd>Specifies color of the lines that make HTML table grids on each page</dd>
          997  +  <dt>Table header background</dt>
          998  +     <dd>Specifies the default background for the heading of any HTML table</dd>
          999  +  <dt>Table header text</dt>
         1000  +     <dd>Specifies the default text color for the heading of any HTML table</dd>
         1001  +  <dt>Table cell background</dt>
         1002  +     <dd>Specifies the background color for table cells</dd>
         1003  +  <dt>Table cell background for current day</dt>
         1004  +     <dd>Specifies the background color for the table cell containing the current
         1005  +       date (<strong>today</strong>) </dd>
         1006  +     <dt>Table cell background for days with events</dt>
         1007  +   <dd>Specifies the background color of table cells containing events. This
         1008  +     setting will not override the <strong>today</strong> setting and
         1009  +     if identical to <strong>today</strong>, will be ignored. </dd>
         1010  +   <dt>Table cell background for weekend</dt>
         1011  +   <dd>Specifies the background color for table cells that represent a Saturday or Sunday</dd>
         1012  +   <dt>Table cell background for other month</dt>
         1013  +   <dd>Specifies the background color for table cells of other month days.</dd>
         1014  +  <dt>Week number color</dt>
         1015  +   <dd>Specifies the text color for week numbers (if enabled)</dd>
         1016  +  <dt>Event popup background</dt>
         1017  +   <dd>Specifies the background color of event popup areas</dd>
         1018  +  <dt>Event popup text</dt>
         1019  +   <dd>Specifies the text color of event popup areas</dd>
         1020  + </dl>
         1021  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1022  +<hr />
         1023  +
         1024  +<a name="siteextras"></a>
         1025  + <h2>Custom Event Fields</h2>
         1026  + <p>You may want to customize the event-specific fields found in
         1027  +  the <tt>includes/site_extras.php</tt> field.
         1028  +  If this is your first time using the calendar, you can skip
         1029  +  this step and come back later since this step
         1030  +  is <em>optional</em>.</p>
         1031  + <p>You can use this feature to add extra
         1032  +  fields to your calendar events. For example, you can add a URL,
         1033  +  a contact email address, or a pulldown containing predefined attributes.</p>
         1034  + <p>When defining a new custom field, the following types listed below
         1035  +  are available. "Arg 1" and "Arg 2" have different meaning depending on the type
         1036  +  of field. In some cases, "Arg 1" and "Arg 2" are not used.</p>
         1037  + <center>
         1038  +  <table style="width: 100%;">
         1039  +   <tr><th>
         1040  +    Type</th><th>
         1041  +    Description</th><th>
         1042  +    Arg 1</th><th>
         1043  +    Arg 2
         1044  +   </th></tr>
         1045  +   <tr><td>
         1046  +    <tt>EXTRA_TEXT</tt></td><td>
         1047  +    Allows the user to enter a single line of text</td><td>
         1048  +    Specifies the size of the text form element as it would appear in the
         1049  +    following ("NN" would be replaced with Arg 1):<br />
         1050  +    &nbsp;&nbsp; <tt>&lt;input&nbsp;size="NN"&nbsp;...</tt></td><td>
         1051  +    N/A
         1052  +   </td></tr>
         1053  +   <tr><td>
         1054  +    <tt>EXTRA_MULTILINETEXT</tt></td><td>
         1055  +    Allows the user to enter multiple lines of text</td><td>
         1056  +    Specifies how many characters wide the textform element should be as it
         1057  +    would appear in the following ("NN" would be replaced with Arg 1):<br />
         1058  +    &nbsp;&nbsp; <tt>&lt;textarea&nbsp;cols="NN"&nbsp;...</tt></td><td>
         1059  +    Specifies how many lines long the textform element should be as it would
         1060  +    appear in the following ("NN" would be replaced with Arg 1):<br />
         1061  +    &nbsp;&nbsp; <tt>&lt;textarea&nbsp;rows="NN"&nbsp;...</tt>
         1062  +   </td></tr>
         1063  +   <tr><td>
         1064  +    <tt>EXTRA_URL</tt></td><td>
         1065  +    Allows the user to enter a single line of text and will be displayed as a
         1066  +    link when viewed</td><td>
         1067  +    N/A</td><td>
         1068  +    N/A
         1069  +   </td></tr>
         1070  +   <tr><td>
         1071  +    <tt>EXTRA_DATE</tt></td><td>
         1072  +    Allows the user to select a date using the standard date selection form
         1073  +    elements</td><td>
         1074  +    N/A</td><td>
         1075  +    N/A
         1076  +   </td></tr>
         1077  +   <tr><td>
         1078  +    <tt>EXTRA_EMAIL</tt></td><td>
         1079  +    Allows the user to enter a single line of text and will be displayed as
         1080  +    a mailto URL link</td><td>
         1081  +    N/A</td><td>
         1082  +    N/A
         1083  +   </td></tr>
         1084  +   <tr><td>
         1085  +    <tt>EXTRA_USER</tt></td><td>
         1086  +    Allows selection of a WebCalendar user from a pulldown list</td><td>
         1087  +    N/A</td><td>
         1088  +    N/A
         1089  +   </td></tr>
         1090  +   <tr><td>
         1091  +    <tt>EXTRA_RADIO</tt></td><td>
         1092  +    Allows selection of a single item from a group of radio buttons</td><td>
         1093  +    Specifies the list of available options using the PHP <tt>array</tt></td><td>
         1094  +   The default item that will be selected (from list above)
         1095  +   </td></tr>
         1096  +   <tr><td>
         1097  +    <tt>EXTRA_SELECTION_LIST</tt></td><td>
         1098  +    Presents the user with a selection list (single selection) to choose from</td><td>
         1099  +    Specifies the list of available options using the PHP <tt>array</tt>
         1100  +    function</td><td>
         1101  +    0 indicates single selection, 1 indicates multiple selection and
         1102  +    also the maximum size
         1103  +   </td></tr>
         1104  +   <tr><td>
         1105  +    <tt>EXTRA_CHECKBOX</tt></td><td>
         1106  +    Will display a checkbox control</td><td>
         1107  +    N/A</td><td>
         1108  +    N/A
         1109  +   </td></tr>
         1110  +  </table>
         1111  + </center>
         1112  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1113  +<hr />
         1114  +
         1115  +<a name="faq"></a>
         1116  + <h2>Frequently Asked Questions</h2>
         1117  + <dl>
         1118  +<!-- cek: leave these comments here... extractfaqs.pl looks for them -->
         1119  +<!-- START FAQ: Installation/Setup -->
         1120  +  <dt>How do I setup PHP, MySQL and Apache on Windows?</dt>
         1121  +   <dd>The easiest way to do this is to try one of the prepackaged bundles that will install all of these for you:
         1122  +    <ul>
         1123  +   <li><a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a>&nbsp;<a href="http://www.apachefriends.org/en/xampp.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1124  +   <li><a href="http://www.foxserv.net/">FoxServ</a>&nbsp;<a href="http://www.foxserv.net" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1125  +   <li><a href="http://www.sokkit.net/">Sokkit</a>&nbsp;<a href="http://www.sokkit.net" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a> (formerly PHPTriad)</li>
         1126  +    </ul>
         1127  +  </dd>
         1128  +  <dt>How do I setup PHP, MySQL and Apache on Mac OS X?</dt>
         1129  +   <dd>You can use the built-in Apache/PHP installed on Mac OS X.
         1130  +       However, this does not inlude MySQL.  An easier way to
         1131  +       setup WebCalendar would be to use one of the following
         1132  +       packages:
         1133  +    <ul>
         1134  +   <li><a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a>&nbsp;<a href="http://www.apachefriends.org/en/xampp.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1135  +    </ul>
         1136  +  </dd>
         1137  + <dt>How do I setup PHP, MySQL and Apache on UNIX/Linux?</dt>
         1138  +  <dd>There are many online instructions on how to do this. Here are a few:
         1139  +    <ul>
         1140  +   <li><a href="http://www.onlamp.com/pub/a/php/2000/11/17/php_admin.html">ONLamp.com: Basic Installation of PHP on a Unix System</a>&nbsp;<a href="http://www.onlamp.com/pub/a/php/2000/11/17/php_admin.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1141  +   <li><a href="http://www.devshed.com/Server_Side/PHP/SoothinglySeamless/">Developer Shed: The Soothingly Seamless Setup of Apache, SSL, MySQL and PHP</a>&nbsp;<a href="http://www.devshed.com/Server_Side/PHP/SoothinglySeamless/" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1142  +   <li><a href="http://www.linuxhelp.net/guides/lamp/">Linux Help: LAMP Guide</a>&nbsp;<a href="http://www.linuxhelp.net/guides/lamp/" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1143  +   <li><a href="http://www.php.net/manual/en/installation.php">PHP.net</a>&nbsp;<a href="http://www.php.net/manual/en/installation.php" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></li>
         1144  +    </ul>
         1145  +  </dd>
         1146  + <dt>I've finished the install. What is the login to WebCalendar?</dt>
         1147  +  <dd>After the initial creation of the database tables, there will
         1148  +    be a single user account created with the username "admin" and
         1149  +    the password set to "admin" as well.
         1150  +    <br /><span class="note">Note:</span> This account is intended to get your started.
         1151  +    You should create a new admin account and delete this one.</dd>
         1152  + <dt><a name="samplepublic">I want to use WebCalendar as an events calendar for
         1153  +    my organization. How do I set it up to do this?</a></dt>
         1154  +  <dd>You will want to setup WebCalendar to use public access.
         1155  +    <ol>
         1156  +    <li>Setup your <tt>settings.php</tt> file as a multi-user
         1157  +      system (see <a href="#appsetup">instructions</a>).</li>
         1158  +    <li>In System Settings, set "Allow public access" to "Yes."</li>
         1159  +    <li>If you want people to be able to submit new events
         1160  +      through public access, set "Public access can add events"
         1161  +      to "Yes."</li>
         1162  +    <li>If you set "Public access can add events" to "Yes",
         1163  +      set the setting for "Public access new events
         1164  +      require approval" to your liking. If you set this to "Yes,"
         1165  +      an admin user will need to approve any new events before
         1166  +      they will appear on the public access calendar.</li>
         1167  +    <li>Login using one of the accounts you have setup.
         1168  +       Add a new event, and select "Public User" as one of the
         1169  +       participants.</li>
         1170  +    <li>If you have enabled "Require event approvals" in your
         1171  +       System Settings, then you will need to approve the new
         1172  +       event. Choose the "Unapproved Events" at the bottom
         1173  +       of any page (you must be an admin user to access this).
         1174  +       You will be presented with a list of unapproved events
         1175  +       (for both the current user and for the Public User account).
         1176  +       Approve the new event for the Public User.</li>
         1177  +    <li>Go to the Login page. You will see a "Access public calendar"
         1178  +       link that will bring you to the calendar for public access.</li>
         1179  +    <li>By default, the index.php page should send users to
         1180  +       the public calendar.</li>
         1181  +    </ol>
         1182  +  </dd>
         1183  +
         1184  + <dt>How can I add holidays to the calendar?</dt>
         1185  + <dd>There is no built-in support for holidays because it is
         1186  + not necessary. You can add holidays into WebCalendar by importing
         1187  + one of the many iCalendar holiday files that are freely available.
         1188  + A good resource for free iCalendar files is
         1189  + <a href="http://www.icalshare.com">iCalShare
         1190  +        <img src="newwin.gif" alt="new" class="newwin" /></a>.
         1191  + For example, the U.S. holiday iCalendar file can be downloaded from:
         1192  + <blockquote>
         1193  + <a href="http://icalshare.com/article.php?story=20020912105939521">http://icalshare.com/article.php?story=20020912105939521
         1194  +        <img src="newwin.gif" alt="new" class="newwin" /></a> </blockquote>
         1195  + If you don't want each individual user to have to import
         1196  + the holiday calendar, you can use nonuser calendars.
         1197  + First, make sure nonuser calendars are enabled in your
         1198  + system settings. Then, from Admin-&gt;Users, you can
         1199  + access nonuser calendars. Create a new nonuser calendar
         1200  + (such as "usholidays"). Then, notify your users that they
         1201  + can add this nonuser calendar as a layer to their own
         1202  + calendar in order to see the holidays. </dd>
         1203  +
         1204  + <dt>Why are deleted events still present in the database?</dt>
         1205  +  <dd>When you delete an event from your calendar, it is not
         1206  +    deleted from the database. Instead, it is marked as deleted.
         1207  +    This allows the system administrator access to information
         1208  +    even after it is deleted.</dd>
         1209  + <dt>Can I setup more than one public calendar?</dt>
         1210  +  <dd>You cannot directly setup two public calendars. However,
         1211  +    there are two options for emulating this type of functionality:
         1212  +    <ul>
         1213  +    <li>You can <a href="WebCalendar-UserManual.html#categories">create global categories</a> and point users to the calendar with only a certain category displayed.</li>
         1214  +    <li>You can setup multiple NonUser calendars and enable
         1215  +        public access viewing of other users' calendars.
         1216  +        You can then link directly to the calendar of one of
         1217  +        the NonUser calendars, or you can
         1218  +        <a href="WebCalendar-UserManual.html#views">setup a view</a>
         1219  +        that contains the calendar of one or more of the NonUser calendars.</li>
         1220  +    </ul>
         1221  +   </dd>
         1222  + <dt>How do I change the title "Public Access" at the top of
         1223  + the calendar?</dt>
         1224  +  <dd>In the file <tt>translations/English-US.txt</tt>,
         1225  +  change the line that says "Public Access" to what you want
         1226  +  it to say on the right side.<br /><br />Example:
         1227  +  <pre>Public Access: Foobar Event Calendar</pre>
         1228  +  </dd>
         1229  + <dt>Can I embed WebCalendar as a component on another web page?</dt>
         1230  +  <dd>WebCalendar is meant to be run as a standalone web application.
         1231  +    You can customize the appearance of WebCalendar to match your existing
         1232  +    site.
         1233  +    To do this, In System Settings, set both "Custom header" and
         1234  +  "Custom trailer" to "Yes" and press the "Edit" button to enter the
         1235  +    header and trailer content.
         1236  +    <br />
         1237  +    If you are looking to just include a list of upcoming events in one
         1238  +    of your web pages, you can use the <tt>upcoming.php</tt> page in
         1239  +    WebCalendar to do this. Edit the top of this file to configure options.
         1240  +    (These settings will likely move into System Settings in subsequent release.)
         1241  +    You can then use an <tt>iframe</tt> elsewhere on your web site as
         1242  +    in the example below:
         1243  +    <pre>&lt;iframe height="250" width="300" scrolling="yes" src="upcoming.php"&gt;&lt;/iframe&gt;</pre>
         1244  +    Include this HTML anywhere on any of your pages.
         1245  +    By default, the events from the public calendar will be loaded (so
         1246  +    you must have "Public Access" enabled in System Settings).
         1247  +    You can override this with another user's calendar.
         1248  +    (See <tt>upcoming.php</tt> for instructions on this.)
         1249  +    <br /><br />
         1250  +    If you would like to display a small calendar (like the ones on the month view), you can add the
         1251  +    following example. There are some configuration options available in the top of this file as well.
         1252  +    You can then use an <tt>iframe</tt> elsewhere on your web site as
         1253  +    in the example below:
         1254  +    <pre>&lt;iframe height="200" width="180" scrolling="yes" src="minical.php"&gt;&lt;/iframe&gt;</pre>
         1255  +  </dd>
         1256  + <dt>How do I customize the appearance of WebCalendar so that it matches
         1257  +     the rest of my site?</dt>
         1258  +  <dd>You can customize the appearance of WebCalendar to match your existing
         1259  +    site.
         1260  +    To do this, In System Settings, set both "Custom header" and
         1261  +    "Custom trailer" to "Yes", and press the "Save" button.
         1262  +    Then click on the "Edit" button to enter your site content.
         1263  +    The custom header will be included after the document's HTML
         1264  +    <code>&lt;body&gt;</code> tag but before any WebCalendar content.
         1265  +    The custom trailer will be included after the WebCalendar content
         1266  +    and before the document's HTML <code>&lt;/body&gt;</code> tag.
         1267  +    If you want to add JavaScript or Stylesheet data, you can use
         1268  +    the "Custom script/stylesheet" option on the same System Settings page.
         1269  +    Any content entered will be included within the document's HTML
         1270  +    <code>&lt;head&gt;</code> section. </dd>
         1271  + <dt>How do I add a new translation?</dt>
         1272  +  <dd>
         1273  +  It's a fairly simple process. If you've ever translated a C-based app
         1274  +     that used GNU's gettext tool, then you'll have no problem. The I18N
         1275  +     support was based on GNU's <a href="http://www.gnu.org/software/gettext/gettext.html">gettext</a>&nbsp;<a href="http://www.gnu.org/software/gettext/gettext.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>. Here's what you need to do.
         1276  +     <ol>
         1277  +     <li>look in the "translations" directory</li>
         1278  +     <li>copy the <tt>English-US.txt</tt> file into what you'd like to call your
         1279  +       language data file. (e.g. <tt>cp English-US.txt French.txt</tt>)</li>
         1280  +     <li>Now translate all the text to the _right_ of the ": " into the
         1281  +       new language. Do <em>not</em> alter the text to the left of the ": ".</li>
         1282  +     <li>When you're done making changes, move into the "tools" directory.
         1283  +       Run the <tt>check_translation.pl</tt> script on your new data file to make
         1284  +       sure you have all the needed translations.
         1285  +       (e.g. <tt>perl check_translation.pl French</tt>)</li>
         1286  +     <li>Add the new language to both the $languages array and the
         1287  +       $browser_languages arrays defined in <tt>includes/translate.php</tt>.</li>
         1288  +     <li>Test it out... </li>
         1289  +  <li>Post a copy of your translation (along with your changes to <tt>includes/translate.php</tt>) to the <a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=303870">SourceForge Patches</a>&nbsp;<a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=303870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a> for WebCalendar.</li>
         1290  +     </ol>
         1291  +  </dd>
         1292  + <dt>How do I update an existing translation?</dt>
         1293  +  <dd>Just open up the translation file in the <tt>translations</tt> directory
         1294  +     with your favorite text editor (like vi, vim, emacs, pico, Notepad, etc.).
         1295  +     In particular look for places where missing translations are indicated.
         1296  +     All missing translations should be marked with a
         1297  +  "&lt;&lt;&nbsp;MISSING&nbsp;&gt;&gt;" note.
         1298  +  and typically the English version of the translation will also be included on the following line (as in the example below):
         1299  +    <pre># &lt;&lt; MISSING &gt;&gt;
         1300  +# Edit:
         1301  +#</pre><br />
         1302  +  For some text, an abbreviation may be used rather than the English text.
         1303  +  In those cases, the full text will be noted as in the following example:
         1304  +  <pre># &lt;&lt; MISSING &gt;&gt;
         1305  +# custom-script-help:
         1306  +# English text: Allows entry of custom Javascript or stylesheet text that
         1307  +# will be inserted into the HTML "head" section of every page.
         1308  +#</pre><br />
         1309  +     When you're done making changes, move into the <tt>tools</tt> directory.
         1310  +       Run the <tt>check_translation.pl</tt> script on your new data file to make
         1311  +       sure you have all the needed translations:
         1312  +  <pre><tt>perl check_translation.pl French</tt></pre>
         1313  +     Post a copy of your translation to the
         1314  +  <a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=303870">SourceForge Patches</a>&nbsp;<a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=303870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a> for WebCalendar.</dd>
         1315  +<dt>During Import, I receive this error: Unknown Timezone: XXXXX defaulting to GMT.</dt>
         1316  +<dd>This is a notice that your import file contained unknown timezone information.
         1317  +  WebCalendar will simply save the event or task as GMT. You are encouraged to
         1318  +  submit these notices as <a href="https://sourceforge.net/projects/webcalendar/">Bug Reports to SourceForge</a>, so that WebCalendar can improve its TZID support.</dd>
         1319  +
         1320  +<!-- END FAQ -->
         1321  + </dl>
         1322  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1323  +<hr />
         1324  +
         1325  +<a name="trouble"></a>
         1326  + <h2>Troubleshooting</h2>
         1327  +    <dl>
         1328  +<!-- cek: leave these comments here... extractfaqs.pl looks for them -->
         1329  +<!-- START FAQ: Troubleshooting -->
         1330  + <dt>I get error messages about undefined variables when I try to view any page.</dt>
         1331  +  <dd>On newer versions of PHP, the default setting of PHP is to display
         1332  +    messages when an undefined variable is referenced. To prevent
         1333  +    these messages from being displayed, change the setting of <tt>error_reporting</tt>
         1334  +    in your <tt>php.ini</tt> file to be:
         1335  +    <pre>error_reporting = E_ALL &amp; ~E_NOTICE</pre>
         1336  +    Alternately, you can disable any error messages from being displayed
         1337  +    in the browser and have them logged to a file. (See the comments
         1338  +    included in the <tt>php.ini</tt> file for instructions on how to do this.)</dd>
         1339  + <dt><a name="dbCacheError">I receive an error message saying "Error removing temporary file" or "Cache error".</a></dt>
         1340  +   <dd>This indicates that a file in your database cache directory could not be
         1341  +   deleted or created.
         1342  +   The quickest solution to this problem is to not use the database
         1343  +   cache.  Simply remote the <tt>db_cachedir</tt> line from
         1344  +   <tt>includes/settings.php</tt> with a simple text editor.
         1345  +   This error is most common when the <tt>send_reminders.php</tt> script
         1346  +   is run from a cron job under a different system account than the
         1347  +   PHP application server is running under.  This causes files created by
         1348  +   the <tt>send_reminders.php</tt> script to be owned by a different
         1349  +   user than normal, preventing the PHP application from being able to
         1350  +   remove the files when needed.
         1351  +</dd>
         1352  + <dt>I receive an error message saying "Failed opening 'includes/...' for inclusion ..."</dt>
         1353  +   <dd>You may have to modify the <tt>include_path</tt> setting
         1354  +       in your <tt>php.ini</tt> file. Most users do not need to do this,
         1355  +       but some PHP installs seem to require it. You will need to
         1356  +       add the WebCalendar directory to the list of directories
         1357  +       for <tt>include_path</tt>.</dd>
         1358  + <dt>I get an error message from PHP saying "Call to undefined function: ..."</dt>
         1359  +  <dd>This tells you that your version of PHP is missing something that
         1360  +    WebCalendar needs. If the function mentioned is a database login
         1361  +  function (<em>ociplogin</em>, <em>mysql_pconnect</em>, <em>ibase_connect</em>, <em>pg_pconnect</em>),
         1362  +  then you probably do not have the needed support for your database
         1363  +  compiled into PHP.
         1364  +    If the function is not a database connect call, then check the
         1365  +    <a href="http://www.php.net/manual/en/">PHP manual</a>&nbsp;<a href="http://www.php.net/manual/en/" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>
         1366  +    to see if the function requires a specific version of PHP. You
         1367  +    may have an out-dated version of PHP that requires upgrading.</dd>
         1368  + <dt>When I try and view certain pages, nothing happens for 30 seconds, then I get a time-out error.</dt>
         1369  +  <dd>On slower or very busy servers, it can take some time for the server
         1370  +    to get all the events. Most PHP installations have a built-in timeout
         1371  +    out of 30 seconds and will interrupt any request that takes longer than
         1372  +    that. This is most likely to happen on the year-long custom report or
         1373  +    on the month view when layers are being used. If you have access,
         1374  +    you can increase the time-out value for PHP in the <tt>php.ini</tt>
         1375  +    file by changing the setting of the <tt>max_execution_time</tt> setting.</dd>
         1376  + <dt>I get an error message that says "Can't connect to local MySQL server through socket '/tmp/mysql.sock'."</dt>
         1377  +  <dd>This is a PHP/MySQL configuration issue. The value of <tt>mysql.default_socket</tt>
         1378  +  in your <tt>php.ini</tt> file must match the value of <tt>socket</tt> in your
         1379  +  <tt>my.cnf</tt> file. Edit the <tt>php.ini</tt> file to fix this problem.</dd>
         1380  + <dt>I am not receiving any email messages from WebCalendar.</dt>
         1381  +  <dd>WebCalendar sends two types of email messages:
         1382  +    Notifications<a href="#g_notification">*</a> and Reminders<a href="#g_reminder">*</a>.
         1383  +  Check the following if you are not receiving any email:
         1384  +    <ol>
         1385  +   <li>You have defined a valid SMTP server in your PHP configuration file
         1386  +    <tt>php.ini</tt>. (The setting is "SMTP" in the "mail_function" section.)</li>
         1387  +   <li>In WebCalendar's System Settings, you have set the "Email Enabled" setting to "Yes".</li>
         1388  +   <li>In WebCalendar's System Settings, make sure you have the "Default sender address"
         1389  +   to something.
         1390  +   <br /><span class="note">Note:</span>
         1391  +          Some mail system will reject mail that has a "From" address
         1392  +          that is a different domain from the originating SMTP server.
         1393  +          So, if your SMTP server is smtp.mydomain.com and your "Default sender address"
         1394  +   is calendar@someotherdomain.com, some mail systems may bounce the mail back.</li>
         1395  +       <li>For a Notification, make sure you have the type of Notification
         1396  +           set to "Yes" in the user's Preferences.</li>
         1397  +       <li>For a Reminder:
         1398  +    <ul>
         1399  +            <li>Make sure you have "Event reminders" set to "Yes" in the user's Preferences.</li>
         1400  +     <li>Make sure you have <a href="#reminders">setup a cron job</a> to periodically
         1401  +      run the <tt>send_reminders.php</tt> script.</li>
         1402  +    </ul>
         1403  +   </li>
         1404  +    </ol>
         1405  +  </dd>
         1406  + <dt>Some of the pages are displaying text in English rather than &lt;insert your language here></dt>
         1407  +  <dd>The translations have been submitted at various points of WebCalendar development.
         1408  +   Some have not been updated to include newer features.</dd>
         1409  + <dt>The text that I entered in the <a href="#siteextras">Custom Event Fields</a> is not being translated
         1410  +  to different languages.</dt>
         1411  +  <dd>You will need to add an entry in each of the translation files for any text you add
         1412  +   into the Custom Event Fields.</dd>
         1413  + <dt>How do I get the most recent version of WebCalendar?</dt>
         1414  +  <dd>You can download the latest public release from SourceForge's
         1415  +  <a href="http://sourceforge.net/project/showfiles.php?group_id=3870">file list for WebCalendar</a>&nbsp;<a href="http://sourceforge.net/project/showfiles.php?group_id=3870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>.
         1416  +  <br />
         1417  +    You can download the latest development code from the CVS server using
         1418  +  the <a href="http://sourceforge.net/cvs/?group_id=3870">instructions provided by SourceForge</a>&nbsp;<a href="http://sourceforge.net/cvs/?group_id=3870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>. (You will need a CVS client to do this.)</dd>
         1419  + <dt>How do I install a patch file listed on SourceForge's
         1420  +    <a href="http://sourceforge.net/tracker?group_id=3870&amp;atid=303870">list of WebCalendar patches</a>&nbsp;<a href="http://sourceforge.net/tracker?group_id=3870&amp;atid=303870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>?</dt>
         1421  +  <dd>Most patches are distributed as context diffs. That means they were produced using the UNIX <tt>diff</tt> command with the <tt>-C</tt> option. The patches are intended to be used with the <a href="http://www.fsf.org/software/patch/patch.html">GNU patch</a>&nbsp;<a href="http://www.fsf.org/software/patch/patch.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a> program. This program is standard on most Linux systems and can be obtained as part of the <a href="http://www.cygwin.com">Cygwin</a>&nbsp;<a href="http://www.cygwin.com" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a> package for Windows. Mac OS X will have the patch program installed if they install the developer tools CD.</dd>
         1422  + <dt>I forgot/lost my admin password. How can I reset it?</dt>
         1423  +  <dd>The easiest way is to admin a new admin user and then use that
         1424  +    new user to reset the password for your old admin account.
         1425  +    Assuming you have deleted the original 'admin' login, you can use
         1426  +    the following SQL to insert a new admin user into the database:
         1427  +    <pre>INSERT INTO webcal_user ( cal_login, cal_passwd, cal_lastname,
         1428  +cal_firstname, cal_is_admin ) VALUES
         1429  +( 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator',
         1430  +'Default', 'Y' );</pre>
         1431  +    This will add a user with login 'admin' and password 'admin' to the database.
         1432  +    If you still have a user named 'admin', then replace 'admin' in the above
         1433  +    SQL with a different username.
         1434  +  </dd>
         1435  + <dt>I get a database error indicating table <tt>webcal_config</tt> does not exist.</dt>
         1436  +  <dd>This is the first table that WebCalendar tries to access, so it
         1437  +   typically means one of the following:
         1438  +   <ul>
         1439  +    <li>You have not created the database tables as described in the instructions</li>
         1440  +    <li>You have the wrong database name specified in your
         1441  +    <tt>includes/settings.php</tt> file</li>
         1442  +   </ul>
         1443  +  </dd>
         1444  + <dt>I get a database error from MySQL that says "Client does not support authentication protocol."</dt>
         1445  +  <dd>From the MySQL 5.0 Reference Manual:
         1446  +  <blockquote>MySQL 5.0 uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients. If you upgrade the server from 4.0, attempts to connect to it with an older client may fail with the following message:
         1447  +  <br /><br />
         1448  +  Client does not support authentication protocol requested
         1449  +  by server; consider upgrading MySQL client
         1450  +  </blockquote>
         1451  +  The <a href="http://dev.mysql.com/doc/refman/5.0/en/old-client.html">MySQL
         1452  +    Reference Manual</a> has solutions for this problem.
         1453  +  </dd>
         1454  +
         1455  +<!-- END FAQ -->
         1456  +</dl>
         1457  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1458  +<hr />
         1459  +
         1460  +<a name="help"></a>
         1461  + <h2>Getting Help</h2>
         1462  + <p>Try the Help/Troubleshooting forum for WebCalendar, hosted at SourceForge.net:</p>
         1463  + <pre><a href="https://sourceforge.net/forum/forum.php?forum_id=11588">https://sourceforge.net/forum/forum.php?forum_id=11588</a>&nbsp;<a href="http://sourceforge.net/forum/forum.php?forum_id=11588" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a></pre>
         1464  + <p>If you encounter a bug, please check the
         1465  +  <a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=103870">list of open and pending bugs</a>&nbsp;<a href="http://sourceforge.net/tracker/?group_id=3870&amp;atid=103870" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>.
         1466  +  If you do <strong>not</strong> see anything similar, submit a new bug.</p>
         1467  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1468  +<hr />
         1469  +
         1470  +<a name="license"></a>
         1471  + <h2>Licensing</h2>
         1472  + <p>WebCalendar is distributed under the open source
         1473  +  <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License</a>&nbsp;<a href="http://www.gnu.org/licenses/gpl.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>.
         1474  +  If you have questions about this license, please
         1475  +  read their <a href="http://www.gnu.org/licenses/gpl-faq.html">GPL FAQ</a>&nbsp;<a href="http://www.gnu.org/licenses/gpl-faq.html" title="Open in new window" target="_new"><img src="newwin.gif" alt="new" class="newwin" /></a>.</p>
         1476  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1477  +<hr />
         1478  +
         1479  +<a name="glossary"></a>
         1480  + <h2>Glossary</h2>
         1481  + <dl>
         1482  +  <dt><a name="g_activitylog">Activity Log</a></dt>
         1483  +   <dd>A summary of recent updates to calendar data</dd>
         1484  +  <dt><a name="g_assistant">Assistant</a></dt>
         1485  +   <dd>A calendar user that has been designated by another calendar user
         1486  +    (the Boss) to help manage their calendar</dd>
         1487  +  <dt><a name="g_boss">Boss</a></dt>
         1488  +   <dd>A calendar user that has designated another calendar user
         1489  +    (the Assistant) to help manage his calendar</dd>
         1490  +  <dt><a name="g_externaluser">External User</a></dt>
         1491  +   <dd>A calendar participant that does not have a calendar user account</dd>
         1492  +  <dt><a name="g_group">Group</a></dt>
         1493  +   <dd>A mechanism of dividing up a large set of users into smaller sets of users</dd>
         1494  +  <dt><a name="g_imap">IMAP</a></dt>
         1495  +   <dd>Internet Message Access Protocol, an optional method of user authentication.</dd>
         1496  +  <dt><a name="g_layer">Layer</a></dt>
         1497  +   <dd>A function that allows a user to overlay another user's calendar
         1498  +    on top of his own calendar so that the standard day, week and month
         1499  +    pages show both his own and the layered user's events</dd>
         1500  +  <dt><a name="g_ldap">LDAP</a></dt>
         1501  +   <dd>LDAP (Lightweight Directory Access Protocol) is an Internet protocol
         1502  +    used to maintain user directories</dd>
         1503  +   <dt><a name="g_mulituser">Multi-User Mode</a></dt>
         1504  +   <dd>When WebCalendar is configured in Multi-User Mode,
         1505  +    there can be multiple user accounts, each with his
         1506  +    own calendar. Unless Public Access is enabled, all users
         1507  +    will be required to login before they can access the system.</dd>
         1508  +  <dt><a name="g_nis">NIS</a></dt>
         1509  +   <dd>NIS (Network Information Service) is a UNIX-based user authentication
         1510  +    system for managing user directories in a network</dd>
         1511  +  <dt><a name="g_nonuser">NonUser Calendar</a></dt>
         1512  +   <dd>A participant to a calendar event that is not a calendar user. This is typically used either as a resource (conference room,
         1513  +  laptop computer) that needs to be shared or as a shared calendar
         1514  +  that other users overlay onto their own calendar using layers (company-wide calendar,
         1515  +  holiday calendar, etc.)</dd>
         1516  +  <dt><a name="g_notification">Notification</a></dt>
         1517  +   <dd>An email message that is sent when an event is added, removed
         1518  +    or updated in the user's calendar by another user</dd>
         1519  +  <dt><a name="g_preferredview">Preferred View</a></dt>
         1520  +   <dd>The standard page (day, week, month or year) that will
         1521  +    be presented to the user after logging in
         1522  +    (set in user <a href="#pref">Preferences</a>)</dd>
         1523  +  <dt><a name="g_preferredview">Public Access</a></dt>
         1524  +   <dd>A <a href="#systemsettings">System Setting</a> that will allow anonymous users
         1525  +    to access the calendar.
         1526  +    See the <a href="#samplepublic">simple instructions</a> for
         1527  +    setting this up in the <a href="#faq">FAQ section</a>.
         1528  +    (Requires WebCalendar to be configured in Multi-User Mode).</dd>
         1529  +  <dt><a name="g_reminder">Reminder</a></dt>
         1530  +   <dd>An email message that is sent before an event to remind
         1531  +    the participant</dd>
         1532  +  <dt><a name="g_singleuser">Single-User Mode</a></dt>
         1533  +   <dd>When WebCalendar is configured in Single-User Mode,
         1534  +    there is no concept of users. You will be managing a single
         1535  +    calendar and no login will be required.
         1536  +    Anyone accessing this calendar will have full privileges to
         1537  +    view, add, edit and delete all events.</dd>
         1538  +  <dt><a name="g_timeinterval">Time Interval</a></dt>
         1539  +   <dd>The amount of time each "block" will represent in
         1540  +    either the day or week view
         1541  +    (set in user <a href="#pref">Preferences</a>)</dd>
         1542  +  <dt><a name="g_uac">User Access Control (UAC)</a></dt>
         1543  +   <dd>The fully configurable feature to allow extremely granular
         1544  +   access control to user. This control applies to system options and
         1545  +   features as well as other user's calendars.</dd>
         1546  +  <dt><a name="g_view">View</a></dt>
         1547  +   <dd>A customized page that presents the events of selected users</dd>
         1548  +  <dt><a name="g_workhours">Work Hours</a></dt>
         1549  +   <dd>The default hours to show in the week and day view where
         1550  +    events are displayed in blocks of time (set in
         1551  +    user <a href="#pref">Preferences</a>)</dd>
         1552  + </dl>
         1553  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1554  +<hr />
         1555  +
         1556  +<a name="appendixA"></a>
         1557  + <h2>Appendix A: Using phpMyAdmin</h2>
         1558  +<p>
         1559  +If you have <a href="http://www.phpmyadmin.net">phpMyAdmin</a>
         1560  +installed and configured to manage your MySQL database, use the
         1561  +following steps to setup WebCalendar.
         1562  +(The following information is based on phpMyAdmin version 2.6.1.)</p>
         1563  +<ol>
         1564  +<li>On the initial phpMyAdmin page, under the "MySQL" heading, the first
         1565  +  option should be "Create new database."  Enter the name you have
         1566  +  chosen for the database and press the "Create" button.
         1567  +  (The default database name used by WebCalendar is "intranet".)
         1568  +  After pressing the "Create" button, it should say:
         1569  +  "Database &lt;your database name here&gt; has been created." </li>
         1570  +<li>Click on the home icon (the small house) in the left-side
         1571  +   navigation. This will bring you back to your phpMyAdmin home page.</li>
         1572  +<li>(Optional) Create new MySQL user. If you already have
         1573  +    a MySQL login that you would like to use, you can skip this step.</li>
         1574  +<li><ul>
         1575  +  <li>Click on the "Privileges" link under the "MySQL" heading.</li>
         1576  +  <li>Below any existing users listed, click on the link "Add a new User."</li>
         1577  +  <li>Fill in the details of your new database user.
         1578  +      The default username for WebCalendar is "webcalendar"
         1579  +      with a password of "webcal01".
         1580  +      Leave the "Host" field set to "Any host".</li>
         1581  +  <li>From the list of "Global privileges", be sure to select:
         1582  +      SELECT, INSERT, UPDATE, DELETE, FILE, CREATE, ALTER, INDEX, DROP </li>
         1583  +  <li>Click on the "Go" button.</li>
         1584  +  <li>You should see a page that says "You have added a new user."</li>
         1585  +</ul></li>
         1586  +<li>Click on the "Databases" tab at the top of the page.</li>
         1587  +<li>From the list of databases on the page, click on the name
         1588  +    of the database that you created.</li>
         1589  +<li>Click on the "SQL" tab at the top of the page.</li>
         1590  +<li>At the bottom of the page, there is an area to upload a SQL file.
         1591  +    Click on the "Browse" button and select the <tt>tables-mysql.sql</tt>
         1592  +    file in the WebCalendar toplevel directory.
         1593  +    Then, press the "Go" button.</li>
         1594  +<li>The top of the page should say "Your SQL-query has been executed
         1595  +    successfully."</li>
         1596  +<li>You have now finished creating the WebCalendar database tables.</li>
         1597  +
         1598  +</ol>
         1599  +
         1600  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1601  +<hr />
         1602  +
         1603  +<a name="appendixB"></a>
         1604  + <h2>Appendix B: Database Setup</h2>
         1605  + <p>There are three steps in setting up the database:</p>
         1606  + <ol>
         1607  +  <li>Creating the database</li>
         1608  +  <li>Creating the user</li>
         1609  +  <li>Creating the required tables</li>
         1610  + </ol>
         1611  + <p>Follow the steps outlined below for the database you are using.
         1612  +  When complete, a single user account will be created
         1613  +  with the <strong>login "admin" and password "admin"</strong>, which you are encouraged
         1614  +  to use to create your own account.</p>
         1615  + <p><span class="note">Note:</span> In the examples below, text in <strong>bold</strong>
         1616  +  represents text that you must type in.</p>
         1617  +         <p><span class="note">Security:</span> The default values for database, login, and
         1618  +  password (<strong>intranet</strong>, <strong>webcalendar</strong>, and <strong>webcal01</strong>) are for demonstration purposes only
         1619  +  and should never be used in a production environment.</p>
         1620  + <h3 class="colorheader">MySQL</h3>
         1621  + <p>The following will create a database named "intranet".</p>
         1622  +<pre><strong>mysqladmin create intranet</strong></pre>
         1623  + <p>Next, create the database user account that will be used to access the database.</p>
         1624  + <pre><strong>mysql --user=root mysql</strong>
         1625  +mysql&gt; <strong>GRANT ALL PRIVILEGES ON *.* TO webcalendar@localhost
         1626  +IDENTIFIED BY 'webcal01' WITH GRANT OPTION;</strong>
         1627  +mysql&gt; <strong>FLUSH PRIVILEGES;</strong>
         1628  +mysql&gt; <strong>QUIT</strong></pre>
         1629  + <p>If you will be accessing MySQL from a different machine than
         1630  +  the one running the web server, repeat the command above
         1631  +  and replace 'localhost' with the hostname of the other machine.</p>
         1632  + <p>Create the calendar tables using the supplied <tt>tables-mysql.sql</tt> file:</p>
         1633  + <pre><strong>mysql intranet &lt; tables-mysql.sql</strong></pre>
         1634  + <p>In the above example, "intranet" is the name of your database.</p>
         1635  +
         1636  + <p><span class="note">Note:</span> If you are using
         1637  + <a href="http://www.phpmyadmin.net">phpMyAdmin</a> to
         1638  + manage your MySQL database, follow the
         1639  + instructions in <a href="#appendixA">Appendix A</a>.</p>
         1640  +
         1641  + <h3 class="colorheader">Oracle</h3>
         1642  + <p>The following will create a tablespace named "webcalendar".
         1643  +  From the command line, startup sqlplus and
         1644  +  issue the following command:</p>
         1645  + <pre><strong>sqlplus</strong>
         1646  +SQL&gt; <strong>CREATE TABLESPACE webcalendar
         1647  +DATAFILE 'webcalendar.dat' SIZE 10M
         1648  +AUTOEXTEND ON NEXT 10M MAXSIZE 40M;</strong></pre>
         1649  + <p>Next, create the database user account that will be used to access the database.</p>
         1650  + <pre><strong>sqlplus</strong>
         1651  +SQL&gt; <strong>CREATE USER webcalendar IDENTIFIED BY webcal01
         1652  +DEFAULT TABLESPACE webcalendar;</strong>
         1653  +SQL&gt; <strong>GRANT dba TO webcalendar;</strong>
         1654  +SQL&gt; <strong>quit</strong></pre>
         1655  + <p>Create the calendar tables using the supplied <tt>tables-oracle.sql</tt> file:</p>
         1656  + <pre><strong>sqlplus webcalendar/webcal01</strong>
         1657  +SQL&gt; <strong>@tables-oracle;</strong>
         1658  +SQL&gt; <strong>quit</strong></pre>
         1659  +
         1660  + <h3 class="colorheader">PostgreSQL</h3>
         1661  + <p>The following will create a database named "webcalendar".
         1662  +  From the command line as the psql user: issue the following commands:</p>
         1663  +  <pre>$ <strong>su postgres</strong>
         1664  +# <strong>createdb webcalendar</strong>
         1665  +# <strong>createuser --no-createdb --no-adduser -P webcalendar</strong>
         1666  +# <strong>psql webcalendar webcalendar</strong>
         1667  +<strong>\i tables-postgres.sql</strong>
         1668  +<strong>\q</strong></pre>
         1669  +
         1670  + <h3 class="colorheader">Interbase</h3>
         1671  + <p>The following will create a database named "WEBCAL.gdb".
         1672  +  From the command line, startup usql and
         1673  +  issue the following command:</p>
         1674  + <pre><strong>CREATE DATABASE 'WEBCAL.gdb';</strong></pre>
         1675  +
         1676  + <p>Create the calendar tables using the supplied <tt>tables-ibase.sql</tt> file:</p>
         1677  + <pre><strong>isql
         1678  +connect /path/WEBCAL.gdb;
         1679  +input path/table-ibase.sql;</strong></pre>
         1680  +
         1681  + <h3 class="colorheader">ODBC</h3>
         1682  + <p>Setup will depend on which database you are using.
         1683  +  When it comes time to create the tables,
         1684  +  the <tt>tables-postgres.sql</tt> file should work for most
         1685  +  databases.</p>
         1686  +   <h3 class="colorheader">MSSQL</h3>
         1687  + <p>Create a database, <strong>intranet,</strong>  and add a user, <strong>webcalendar</strong>, to access this database. The user should be granted public, db_datareader,
         1688  +   and db_datawriter privileges. Open SQL Query Analyzer then open
         1689  +   the file <tt>tables-postgres.sql</tt>. Make sure you have identified <strong>intranet</strong> as the target database and Execute the contents of the sql file.</p>
         1690  +          <div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1691  +
         1692  +<a name="appendixC"></a>
         1693  +<h2>Appendix C: Setting Up Reminders on Windows</h2>
         1694  +
         1695  +<p>You have two options to choose from when setting up email
         1696  +   reminders on a Windows platform.
         1697  +   You can either install a cron package for Windows,
         1698  +   or you can use the Windows Task Scheduler.</p>
         1699  +
         1700  +<h3>Installing a Cron Package</h3>
         1701  +<p>
         1702  +If you install a cron package for Windows, you will need to setup
         1703  +to setup a cron job.
         1704  +(UNIX cron is a tool for used to run tasks as specified times anywhere
         1705  +from every minute to once a year.)</p>
         1706  +<p>
         1707  +First, you should create a <tt>sendreminders.bat</tt> file
         1708  +that contains a single line:</p>
         1709  +<pre>C:\your\path\to\php.exe C:\your\path\to\webcalendar\tools\send_reminders.php</pre>
         1710  +<p>You can place this <tt>sendreminders.bat</tt> file anywhere on your
         1711  +file system.</p>
         1712  +<p>Next, you need to setup the cron job.
         1713  +The crontab entry should look like
         1714  +the following (replace with the correct path to your
         1715  +newly created <tt>sendreminders.bat</tt> file):</p>
         1716  +
         1717  +<pre>1 * * * * C:\your\path\to\sendreminders.bat</pre>
         1718  +
         1719  +<p>The "1 * * * *" will tell the cron schedule to run this task
         1720  +at 1 after the hour all day long (12:01am, 1:01am, 2:01am, etc.)
         1721  +If you only want to run it once per day, you could use:</p>
         1722  +<pre>1 4 * * * C:\your\path\to\sendreminders.bat</pre>
         1723  +<p>This would tell the cron scheduler to run the task at 4:01am
         1724  +every day.
         1725  +For more information about the syntax of cron, check the documentation
         1726  +for the package you have installed or
         1727  +view the UNIX man page for crontab
         1728  +(like <a href="http://www.rt.com/man/crontab.5.html"
         1729  +  target="_blank">this one</a>).</p>
         1730  +
         1731  +<p>There are many cron packages for Windows available.
         1732  +   Below is a list of packages to choose from.
         1733  +   (Note: use at your own risk. These links are provided
         1734  +   for information only.)</p>
         1735  +
         1736  +<ul>
         1737  +  <li><a href="http://cronw.sourceforge.net/"
         1738  +    target="_blank">CRONw</a> (open source) </li>
         1739  +  <li><a href="http://www.gold-software.com/VisualCron-review11507.htm"
         1740  +    target="_blank">VisualCron</a> (freeware)</li>
         1741  +  <li><a href="http://www.nncron.ru"
         1742  +    target="_blank">nnCron</a> (freeware and commercial versions)</li>
         1743  +  <li><a href="http://surguy.net/articles/icron.xml"
         1744  +    target="_blank">iCron</a> </li>
         1745  +  <li><a href="http://p.clark.home.mindspring.com/jcron/index.html"
         1746  +    target="_blank">jCron</a> (freeware) </li>
         1747  +</ul>
         1748  +
         1749  +<h3>Using the Windows Task Schedule</h3>
         1750  +
         1751  +<p>Follow the steps listed below to setup a new task
         1752  +   in the Windows Task Scheduler.
         1753  +   (These instructions were created with Windows XP Professional.
         1754  +   Other versions of Windows might be different.)</p>
         1755  +
         1756  +<ol>
         1757  +
         1758  +<li>Create a new batch file called <tt>sendreminders.bat</tt>.
         1759  +    The contents of this file should be a single line:
         1760  +    <pre>C:\your\path\to\php.exe C:\your\path\to\webcalendar\tools\send_reminders.php</pre>
         1761  +  </li>
         1762  +
         1763  +<li>On Windows XP, go to Control Panel</li>
         1764  +<li>Double-click on "Scheduled Tasks."
         1765  +  This brings up a window that says "Scheduled Task Wizard" </li>
         1766  +
         1767  +<li>Click on "Browse..." </li>
         1768  +
         1769  +<li>Select the location of your newly created
         1770  +    <tt>sendreminders.bat</tt> file.</li>
         1771  +<li>Click on "Open" </li>
         1772  +
         1773  +<li>Change the name of the task. "WebCalendar Reminders" is a good name.
         1774  +  </li>
         1775  +
         1776  +<li>Select how often to perform this task. Select "Daily." </li>
         1777  +<li>Click on "Next" </li>
         1778  +
         1779  +<li>Select the start time, then click "Next".
         1780  +    If you are planning on sending out reminders throughout the
         1781  +    day, pick a time shortly after midnight. </li>
         1782  +
         1783  +<li> Enter your user password as required. Click on "Next." </li>
         1784  +
         1785  +<li> Select the checkbox "Open advanced properties". </li>
         1786  +<li> Click on "Finish." </li>
         1787  +
         1788  +<li> Under the "Schedule" tab, click on "Advanced." </li>
         1789  +
         1790  +<li> Click on "Repeat Task" and fill in the details of how often
         1791  +     the job should run.
         1792  +     For example, you can set it to run "every 15 minutes", then
         1793  +     click on "until" and set that time to 11:30pm.
         1794  +  </li>
         1795  +</ol>
         1796  +
         1797  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1798  +<hr />
         1799  +
         1800  +<a name="appendixD"></a>
         1801  +<h2>Appendix D: Displaying Upcoming Events on Your Site</h2>
         1802  +
         1803  +<p>
         1804  +If you would like to list upcoming events somewhere on a page on your site
         1805  +(someplace other than the WebCalendar pages),
         1806  +you can use the <tt>upcoming.php</tt> page to do this.
         1807  +This page is intended to be included in other pages using the
         1808  +<tt>iframe</tt> tag.</p>
         1809  +<p>You may need to modify some of the variables near the top of
         1810  +<tt>upcoming.php</tt> with a text editor:</p>
         1811  +<table border="0" style="margin-left: 20px; margin-right: 20px;">
         1812  +
         1813  +<tr><td valign="top">$public_must_be_enabled</td>
         1814  +  <td>
         1815  +      Specifies if Public Access must be enabled in System Settings
         1816  +      for this page to be viewed.
         1817  +      <br />Default setting: false
         1818  +  </td></tr>
         1819  +
         1820  +<tr><td valign="top">$display_link</td>
         1821  +  <td>
         1822  +      Specifies if events should have a link to the URL
         1823  +      within WebCalendar to view the event.
         1824  +      <br />Default setting: true
         1825  +  </td></tr>
         1826  +
         1827  +<tr><td valign="top">$link_target</td>
         1828  +  <td>
         1829  +      Specifies the name of the window that be used for
         1830  +      the link target.
         1831  +      <br />Default setting: _top
         1832  +  </td></tr>
         1833  +
         1834  +<tr><td valign="top">$numDays</td>
         1835  +  <td>
         1836  +      Specifies how many days of events should be listed.
         1837  +      <br />Can override this by passing "num" in within the URL
         1838  +           with "upcoming.php?num=60"
         1839  +      <br />Default setting: 30
         1840  +  </td></tr>
         1841  +
         1842  +<tr><td valign="top">$maxEvents</td>
         1843  +  <td>
         1844  +      Specifies the maximum number of events to list.
         1845  +      <br />Default setting: 10
         1846  +  </td></tr>
         1847  +
         1848  +<tr><td valign="top">$username</td>
         1849  +  <td>
         1850  +      The login of the calendar to display upcoming events for.
         1851  +      If you want to see upcoming events for user login "joe",
         1852  +      then you would change this to "joe".
         1853  +      <br />Default setting: __public__ (The public calendar)
         1854  +  </td></tr>
         1855  +
         1856  +<tr><td valign="top">$allow_user_override</td>
         1857  +  <td>
         1858  +      Specifies whether the calendar user can be specified in the URL
         1859  +      (in which case the $username setting will be ignored) using
         1860  +      a URL like "upcoming.php?user=joe".
         1861  +      <br />Default setting: true
         1862  +  </td></tr>
         1863  +
         1864  +<tr><td valign="top">$load_layers</td>
         1865  +  <td>
         1866  +      Specifies if the calendar user's layers should also be
         1867  +      included in the upcoming events.
         1868  +      <br />Note: Layers must be enabled in the user's preferences.
         1869  +      <br />Default setting: true
         1870  +  </td></tr>
         1871  +
         1872  +<tr><td valign="top">$cat_id</td>
         1873  +  <td>
         1874  +      Specifies a category id to filter events on.
         1875  +      <br />Note: Categories must be enabled in System Settings.
         1876  +      <br />Default setting: (empty)
         1877  +  </td></tr>
         1878  +
         1879  +</table>
         1880  +
         1881  +<p>Below is an example of how you would include <tt>upcoming.php</tt>
         1882  +   in a simple HTML page.</p>
         1883  +<pre>
         1884  +&lt;html&gt;&lt;head&gt;&lt;title&gt;ACME Home Page&lt;/title&gt;&lt;/head&gt;
         1885  +&lt;body&gt;
         1886  +&lt;h1&gt;Welcome to the ACME Home Page&lt;/h1&gt;
         1887  +&lt;h2&gt;News&lt;/h2&gt;
         1888  +&lt;p&gt;No news....&lt;/p&gt;
         1889  +&lt;h2&gt;Upcoming Events&lt;/h2&gt;
         1890  +&lt;iframe src="upcoming.php" width="400" height="400" name="califrame"&gt;&lt;/iframe&gt;
         1891  +&lt;/body&gt;
         1892  +&lt;/html&gt;
         1893  +</pre>
         1894  +
         1895  +<p><span class="tip">TIP</span>
         1896  +  The <a href="http://www.w3schools.com/tags/tag_iframe.asp"
         1897  +  target="_blank">W3 Schools</a> site provides documentation
         1898  +  about the different options that you can use
         1899  +  with the <tt>iframe</tt> tag.</p>
         1900  +
         1901  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1902  +<hr />
         1903  +
         1904  +<a name="appendixE"></a>
         1905  +<h2>Appendix E: How To Configure for LDAP</h2>
         1906  +
         1907  +<p>Configuring WebCalendar to use an existing LDAP directory is fairly
         1908  +simple. It is know to work with OpenLDAP and Novell Edirectory and
         1909  +should work with other systems as well.
         1910  +<br />
         1911  +<span class="note">Note:</span>
         1912  +If you use LDAP, the group functionality of WebCalendar does not yet work.</p>
         1913  +
         1914  +<p>To configure WebCalendar to use LDAP, do the following:</p>
         1915  +<ol>
         1916  + <li>Configure <tt>settings.php</tt></li>
         1917  + <li>Configure <tt>includes/user-ldap.php</tt></li>
         1918  +</ol>
         1919  +
         1920  +<p>The first step is to set WebCalendar to use LDAP authentication in
         1921  +<tt>settings.php</tt>. Instructions on to do this can be found in the
         1922  +<a href="#appsetup">Application Installation</a> section above.
         1923  +In summary, the following should be set:<br />
         1924  +<tt>use_http_auth = false</tt><br />
         1925  +<tt>user_inc = user-ldap.php</tt><br /></p>
         1926  +
         1927  +<p>The next step is a little more work and involves editing the
         1928  +<tt>includes/user-ldap.php</tt> file with a text editor. You will have
         1929  +to set several configuration variables. If you don't know what to set
         1930  +the variables to, consult your LDAP system administrator. Documentation
         1931  +exists for all variables in the file. Finally, users have gotten LDAP
         1932  +working with OpenLDAP and Novell Edirectory by just changing the
         1933  +following:</p>
         1934  +
         1935  +<table border="0" style="margin-left: 20px; margin-right: 20px;">
         1936  +
         1937  +<tr><td valign="top">$ldap_server</td>
         1938  +  <td>
         1939  +      FQDN or IP address of the LDAP server (or localhost).
         1940  +      <br />ex. 'ldapserver.company.com'
         1941  +  </td></tr>
         1942  +
         1943  +<tr><td valign="top">$ldap_base_dn</td>
         1944  +  <td>
         1945  +      Specifies the base DN used to search for users
         1946  +      <br />ex. 'ou=people,dc=company,dc=com' or 'o=context,ou=subcontext'
         1947  +  </td></tr>
         1948  +
         1949  +<tr><td valign="top">$ldap_admin_group_name</td>
         1950  +  <td>
         1951  +      Specifies a group (complete DN) with admin rights for WebCalendar
         1952  +      <br />You might have to create one in LDAP
         1953  +      <br />ex. 'cn=it,ou=group,dc=company,dc=com'
         1954  +  </td></tr>
         1955  +
         1956  +</table>
         1957  +
         1958  +<h3>Using SSL with LDAP</h3>
         1959  +<p>If the LDAP server will accept connections over SSL, simply add 'ldaps://'
         1960  +to the beginning of <tt>$ldap_server</tt>.<br />Example: ldaps://ldapserver.company.com</p>
         1961  +
         1962  +<h3>Using TLS with LDAP</h3>
         1963  +<p>If the LDAP server is set up to use TLS,  set <tt>$ldap_start_tls = true</tt>.</p>
         1964  +
         1965  +<h3>Using LDAPv3</h3>
         1966  +<p>If the LDAP server uses protocol version 3,  set
         1967  +<tt>$set_ldap_version = true</tt>
         1968  +and <tt>$ldap_version = '3'</tt>.</p>
         1969  +
         1970  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1971  +<hr />
         1972  +
         1973  +<a name="appendixF"></a>
         1974  +<h2>Appendix F: Manual Installation</h2>
         1975  +
         1976  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         1977  +<hr />
         1978  +<h3>TODO</h3>
         1979  +
         1980  +<a name="appendixG"></a>
         1981  +<h2>Appendix G: Error Codes</h2>
         1982  +<p>These error codes will be used along with the print_not_auth () function to give an idea of the what the problem might be without displaying site sensitive information.</p>
         1983  +<p><span class="note">Note:</span> <tt>mode=dev</tt> must be set in includes/settings.php for these error numbers to be displayed</p>
         1984  +<ul>
         1985  +<li style="list-style:decimal">ACCESS NOT ENABLED (UAC)</li>
         1986  +<li style="list-style:decimal">ACCESS ACTIVITY LOG (UAC)</li>
         1987  +<li style="list-style:decimal">Not Admin</li>
         1988  +<li style="list-style:decimal">Read Only (setting.php)</li>
         1989  +<li style="list-style:decimal">Not my event</li>
         1990  +<li style="list-style:decimal">Can not edit (UAC)</li>
         1991  +<li style="list-style:decimal">Allow View Others (System Settings)</li>
         1992  +<li style="list-style:decimal">Can not view (UAC)</li>
         1993  +<li style="list-style:decimal">Allow Attachment (System Settings)</li>
         1994  +<li style="list-style:decimal">Allow Comment (System Settings)</li>
         1995  +<li style="list-style:decimal">REMOTES ENABLED (System Settings)</li>
         1996  +<li style="list-style:decimal">REPORTS ENABLED (System Settings)</li>
         1997  +<li style="list-style:decimal">Report user not allowed</li>
         1998  +<li style="list-style:decimal">Report not yours</li>
         1999  +<li style="list-style:decimal">ACCESS USER MANAGEMENT (UAC)</li>
         2000  +<li style="list-style:decimal">Admin can not add user (user.php)</li>
         2001  +<li style="list-style:decimal">ACCESS ACCOUNT INFO (UAC)</li>
         2002  +<li style="list-style:decimal">User can not update password (user.php)</li>
         2003  +<li style="list-style:decimal">FREEBUSY ENABLED (System Settings)</li>
         2004  +<li style="list-style:decimal">PUBLISH ENABLED (System Settings)</li>
         2005  +<li style="list-style:decimal">Public must be enabled</li>
         2006  +<li style="list-style:decimal">Single User (settings.php)</li>
         2007  +<li style="list-style:decimal">HTTP Auth (settings.php)</li>
         2008  +<li style="list-style:decimal">Non-User calendar not public</li>
         2009  +<li style="list-style:decimal">USER PUBLISH ENABLED (System Settings)</li>
         2010  +<li style="list-style:decimal">ALLOW SELF REGISTRATION (System Settings)</li>
         2011  +<li style="list-style:decimal">Report ID</li>
         2012  +<li style="list-style:decimal">RSS ENABLED (System Settings)</li>
         2013  +<li style="list-style:decimal">USER RSS ENABLED (User preferences)</li>
         2014  +<li style="list-style:decimal">Categories not enabled (System Settings)</li>
         2015  +<li style="list-style:decimal">Event deleted for this user</li>
         2016  +<li style="list-style:decimal">User not participant</li>
         2017  +<li style="list-style:decimal">Event status empty</li>
         2018  +<li style="list-style:decimal">View name empty</li>
         2019  +<li style="list-style:decimal">PUBLIC ACCESS OTHERS (System Settings)</li>
         2020  +<li style="list-style:decimal">Invalid IP (blacklist.php)</li>
         2021  +</ul>
         2022  +<div class="top"><a href="#" target="_top">↑&nbsp;top</a></div>
         2023  +<hr />
         2024  +<p>
         2025  + <a href="http://validator.w3.org/check?uri=referer"><img
         2026  +  src="http://www.w3.org/Icons/valid-xhtml10"
         2027  +  alt="Valid XHTML 1.0!" class="valid" /></a></p>
         2028  +</body>
         2029  +</html>

Added docs/newwin.gif.

cannot compute difference between binary files

Added edit_entry.php.

            1  +<?php
            2  +/* $Id: edit_entry.php,v 1.203.2.13 2012/02/28 02:49:39 cknudsen Exp $
            3  + *
            4  + * Description:
            5  + * Presents page to edit/add an event/task/journal
            6  + *
            7  + * Notes:
            8  + * A SysAdmin can enable HTML for event full descriptions. If one of the
            9  + * supported HTML edit widgets is also installed, users can use WYSIWYG editing.
           10  + * See the WebCalendar page at
           11  + * http://www.k5n.us/webcalendar.php?topic=Add-Ons
           12  + * for download and install instructions for these packages.
           13  + */
           14  +include_once 'includes/init.php';
           15  +
           16  +/* Generate HTML for a time selection for use in a form.
           17  + *
           18  + * @param string $prefix Prefix to use in front of form element names
           19  + * @param string $time   Currently selected time in HHMMSS
           20  + * @param bool $trigger  Add onchange event trigger that
           21  + *                       calls javascript function $prefix_timechanged ()
           22  + *
           23  + * @return string HTML for the selection box
           24  + */
           25  +function time_selection ( $prefix, $time = '', $trigger = false ) {
           26  +  global $checked, $ENTRY_SLOTS, $selected, $TIME_FORMAT, $WORK_DAY_START_HOUR;
           27  +
           28  +  $amsel = $pmsel = $ret = '';
           29  +  $trigger_str = ( $trigger ? 'onchange="' . $prefix . 'timechanged() ' : '' );
           30  +
           31  +  if ( ! isset ( $time ) && $time != 0 ) {
           32  +    $hour = $WORK_DAY_START_HOUR;
           33  +    $minute = 0;
           34  +  } else {
           35  +    $hour = floor ( $time / 10000 );
           36  +    $minute = ( ( $time / 100 ) % 100 ) % 60;
           37  +  }
           38  +  if ( $TIME_FORMAT == '12' ) {
           39  +    $maxhour = 12;
           40  +    if ( $hour < 12 || $hour == 24 )
           41  +      $amsel = $checked;
           42  +    else
           43  +      $pmsel = $checked;
           44  +
           45  +    $hour %= 12;
           46  +    if ( $hour == 0 )
           47  +      $hour = 12;
           48  +  } else {
           49  +    $maxhour = 24;
           50  +    $hour = sprintf ( "%02d", $hour );
           51  +  }
           52  +  $minute = sprintf ( "%02d", $minute );
           53  +  $ret .= '
           54  +            <select ' . 'name="' . $prefix . 'hour" id="' . $prefix . 'hour" '
           55  +   . $trigger_str . '>';
           56  +  for ( $i = 0; $i < $maxhour; $i++ ) {
           57  +    $ihour = ( $TIME_FORMAT == '24' ? sprintf ( "%02d", $i ) : $i );
           58  +    if ( $i == 0 && $TIME_FORMAT == '12' )
           59  +      $ihour = 12;
           60  +
           61  +    $ret .= '
           62  +              <option value="' . "$i\"" . ( $ihour == $hour ? $selected : '' )
           63  +     . ">$ihour" . '</option>';
           64  +  }
           65  +  $ret .= '
           66  +            </select>:
           67  +            <select ' . 'name="' . $prefix . 'minute" id="' . $prefix
           68  +   . 'minute" ' . $trigger_str . '>';
           69  +  // We use $TIME_SLOTS to populate the minutes pulldown.
           70  +  $found = false;
           71  +  for ( $i = 0; $i < 60; ) {
           72  +    $imin = sprintf ( "%02d", $i );
           73  +    $isselected = '';
           74  +    if ( $imin == $minute ) {
           75  +      $found = true;
           76  +      $isselected = $selected;
           77  +    }
           78  +    $ret .= '
           79  +              <option value="' . "$i\"$isselected>$imin" . '</option>';
           80  +    $i += ( 1440 / $ENTRY_SLOTS );
           81  +  }
           82  +  // We'll add an option with the exact time if not found above.
           83  +  return $ret . ( $found ? '' : '
           84  +              <option value="' . "$minute\" $selected>$minute" . '</option>' ) . '
           85  +            </select>' . ( $TIME_FORMAT == '12' ? '
           86  +            <label><input type="radio" name="' . $prefix . 'ampm" id="'
           87  +     . $prefix . 'ampmA" value="0" ' . $amsel . ' />&nbsp;' . translate ( 'am' )
           88  +     . '</label>
           89  +            <label><input type="radio" name="' . $prefix . 'ampm" id="'
           90  +     . $prefix . 'ampmP" value="12" ' . $pmsel . ' />&nbsp;' . translate ( 'pm' )
           91  +     . '</label>' : '
           92  +            <input type="hidden" name="' . $prefix . 'ampm" value="0" />' );
           93  +}
           94  +
           95  +$daysStr = translate ( 'days' );
           96  +$hoursStr = translate ( 'hours' );
           97  +$minutStr = translate ( 'minutes' );
           98  +$saveStr = translate ( 'Save' );
           99  +
          100  +load_user_categories ();
          101  +
          102  +// Default for using tabs is enabled.
          103  +if ( empty ( $EVENT_EDIT_TABS ) )
          104  +  $EVENT_EDIT_TABS = 'Y'; // default
          105  +
          106  +$useTabs = ( $EVENT_EDIT_TABS == 'Y' );
          107  +// Make sure this is not a read-only calendar.
          108  +$can_edit = false;
          109  +$others_complete = 'yes';
          110  +$checked = ' checked="checked"';
          111  +$selected = ' selected="selected"';
          112  +
          113  +// Public access can only add events, not edit.
          114  +if ( empty ( $login ) || ( $login == '__public__' && $id > 0 ) )
          115  +  $id = 0;
          116  +
          117  +$eType = getGetValue ( 'eType' );
          118  +if ( empty ( $eType ) )
          119  +  $eType = 'event';
          120  +
          121  +$copy = getValue ( 'copy', '[01]' );
          122  +$date = getValue ( 'date', '-?[0-9]+' );
          123  +$day = getValue ( 'day', '-?[0-9]+' );
          124  +$month = getValue ( 'month', '-?[0-9]+' );
          125  +$year = getValue ( 'year', '-?[0-9]+' );
          126  +
          127  +if ( empty ( $date ) && empty ( $month ) ) {
          128  +  if ( empty ( $year ) )
          129  +    $year = date ( 'Y' );
          130  +
          131  +  $month = date ( 'm' );
          132  +
          133  +  if ( empty ( $day ) )
          134  +    $day = date ( 'd' );
          135  +
          136  +  $date = sprintf ( "%04d%02d%02d", $year, $month, $day );
          137  +}
          138  +
          139  +$BodyX = 'onload="onLoad();"';
          140  +$INC = array ( 'js/edit_entry.php/false/' . $user, 'js/visible.php' );
          141  +$textareasize = '15';
          142  +
          143  +// Can we use HTMLArea or FCKEditor? (Relax! That's the authors initials.)
          144  +// Note: HTMLArea has been discontinued, so FCKEditor is preferred.
          145  +$use_fckeditor = $use_htmlarea = false;
          146  +
          147  +if ( $ALLOW_HTML_DESCRIPTION == 'Y' ) {
          148  +  // Allow HTML in description.
          149  +  // If they have installed an HTML edit widget, make use of it.
          150  +  if ( file_exists ( 'includes/FCKeditor-2.0/fckeditor.js' ) &&
          151  +      file_exists ( 'includes/FCKeditor-2.0/fckconfig.js' ) ) {
          152  +    $textareasize = '20';
          153  +    $use_fckeditor = true;
          154  +  } else
          155  +  if ( file_exists ( 'includes/htmlarea/htmlarea.php' ) ) {
          156  +    $BodyX = 'onload="onLoad();initEditor();';
          157  +    $INC[] = 'htmlarea/core.php/true';
          158  +    $INC[] = 'htmlarea/htmlarea.php/true';
          159  +    $use_htmlarea = true;
          160  +  }
          161  +}
          162  +
          163  +$byday = $bymonth = $bymonthday = $bysetpos = $participants = array ();
          164  +$exceptions = $inclusions = $reminder = array ();
          165  +$byweekno = $byyearday = $catList = $catNames = $external_users = $rpt_count = '';
          166  +
          167  +$create_by = $login;
          168  +
          169  +//This is the default per RFC2445
          170  +//We could override it and use $byday_names[$WEEK_START]
          171  +$wkst = 'MO';
          172  +
          173  +$real_user = ( ( ! empty ( $user ) && strlen ( $user ) ) &&
          174  +  ( $is_assistant || $is_admin ) ) ? $user : $login;
          175  +
          176  +print_header ( $INC, '', $BodyX, false, false, false, true );
          177  +
          178  +ob_start ();
          179  +
          180  +if ( $readonly == 'Y' || $is_nonuser )
          181  +  $can_edit = false;
          182  +else
          183  +if ( ! empty ( $id ) && $id > 0 ) {
          184  +  // First see who has access to edit this entry.
          185  +  if ( $is_admin )
          186  +    $can_edit = true;
          187  +
          188  +  $res = dbi_execute ( 'SELECT cal_create_by, cal_date, cal_time, cal_mod_date,
          189  +    cal_mod_time, cal_duration, cal_priority, cal_type, cal_access, cal_name,
          190  +    cal_description, cal_group_id, cal_location, cal_due_date, cal_due_time,
          191  +    cal_completed, cal_url FROM webcal_entry WHERE cal_id = ?', array ( $id ) );
          192  +  if ( $res ) {
          193  +    $row = dbi_fetch_row ( $res );
          194  +    // If current user is creator of event, then they can edit.
          195  +    if ( $row[0] == $login )
          196  +      $can_edit = true;
          197  +
          198  +    $cal_date = ( ! empty ( $override ) && ! empty ( $date )
          199  +      ? $date // Leave $cal_date to what was set in URL with date=YYYYMMDD.
          200  +      : $row[1] );
          201  +
          202  +    $create_by = $row[0];
          203  +    if ( ( $user == $create_by ) && ( $is_assistant || $is_nonuser_admin ) )
          204  +      $can_edit = true;
          205  +
          206  +    $cal_time = sprintf ( "%06d", $row[2] );
          207  +    $due_date = $row[13];
          208  +    $due_time = $row[14];
          209  +
          210  +    $calTS = date_to_epoch ( $cal_date . $cal_time );
          211  +    // Don't adjust for All Day entries.
          212  +    if ( $cal_time > 0 || ( $cal_time == 0 && $row[5] != 1440 ) ) {
          213  +      $cal_date = date ( 'Ymd', $calTS );
          214  +      $cal_time = date ( 'His', $calTS );
          215  +    }
          216  +    $hour = floor ( $cal_time / 10000 );
          217  +    $minute = ( $cal_time / 100 ) % 100;
          218  +
          219  +    $dueTS = date_to_epoch ( $due_date . $due_time );
          220  +    $due_date = date ( 'Ymd', $dueTS );
          221  +    $due_time = date ( 'His', $dueTS );
          222  +    $due_hour = floor ( $due_time / 10000 );
          223  +    $due_minute = ( $due_time / 100 ) % 100;
          224  +
          225  +    $priority = $row[6];
          226  +    $type = $row[7];
          227  +    $access = $row[8];
          228  +    $name = $row[9];
          229  +    $description = $row[10];
          230  +    $parent = $row[11];
          231  +    $location = $row[12];
          232  +    $completed = ( empty ( $row[15] ) ? date ( 'Ymd' ) : $row[15] );
          233  +    $cal_url = $row[16];
          234  +
          235  +    // What kind of entry are we dealing with?
          236  +    if ( strpos ( 'EM', $type ) !== false )
          237  +      $eType = 'event';
          238  +    elseif ( strpos ( 'JO', $type ) !== false )
          239  +      $eType = 'journal';
          240  +    elseif ( strpos ( 'NT', $type ) !== false )
          241  +      $eType = 'task';
          242  +
          243  +    // Public access has no access to tasks.
          244  +    // translate ( 'You are not authorized to edit this task' )
          245  +    if ( $login == '__public__' && $eType == 'task' )
          246  +      echo str_replace ( 'XXX', translate ( 'task' ),
          247  +        translate ( 'You are not authorized to edit this XXX.' ) );
          248  +
          249  +    // Check UAC.
          250  +    if ( access_is_enabled () )
          251  +      $can_edit =
          252  +      access_user_calendar ( 'edit', $create_by, $login, $type, $access );
          253  +
          254  +    $day = $cal_date % 100;
          255  +    $month = ( $cal_date / 100 ) % 100;
          256  +    $year = intval ( $cal_date / 10000 );
          257  +
          258  +    $time = $row[2];
          259  +
          260  +    if ( $time >= 0 )
          261  +      $duration = $row[5];
          262  +    else {
          263  +      $duration = '';
          264  +      $hour = -1;
          265  +    }
          266  +
          267  +    // Check for repeating event info...
          268  +    // but not if we're overriding a single entry of an already repeating event...
          269  +    // confusing, eh?
          270  +    if ( ! empty ( $override ) ) {
          271  +      $rpt_end = 0;
          272  +      $rpt_end_date = $cal_date;
          273  +      $rpt_freq = 1;
          274  +      $rpt_type = 'none';
          275  +    } else {
          276  +      $res = dbi_execute ( 'SELECT cal_id, cal_type, cal_end, cal_endtime,
          277  +        cal_frequency, cal_byday, cal_bymonth, cal_bymonthday, cal_bysetpos,
          278  +        cal_byweekno, cal_byyearday, cal_wkst, cal_count
          279  +        FROM webcal_entry_repeats WHERE cal_id = ?', array ( $id ) );
          280  +      if ( $res ) {
          281  +        if ( $row = dbi_fetch_row ( $res ) ) {
          282  +          $rpt_type = $row[1];
          283  +          $rpt_end = ( $row[2] > 0 ? date_to_epoch ( $row[2] . $row[3] ) : 0 );
          284  +
          285  +          if ( empty ( $row[2] ) ) {
          286  +            $rpt_end_date = $cal_date;
          287  +            $rpt_end_time = $cal_time;
          288  +          } else {
          289  +            $rpt_endTS = date_to_epoch ( $row[2] . $row[3] );
          290  +            $rpt_end_date = date ( 'Ymd', $rpt_endTS );
          291  +            $rpt_end_time = date ( 'His', $rpt_endTS );
          292  +          }
          293  +          $rpt_freq = $row[4];
          294  +          if ( ! empty ( $row[5] ) )
          295  +            $byday = explode ( ',', $row[5] );
          296  +
          297  +          $bydayStr = $row[5];
          298  +          if ( ! empty ( $row[6] ) )
          299  +            $bymonth = explode ( ',', $row[6] );
          300  +
          301  +          if ( ! empty ( $row[7] ) )
          302  +            $bymonthday = explode ( ',', $row[7] );
          303  +
          304  +          $bymonthdayStr = $row[7];
          305  +          if ( ! empty ( $row[8] ) )
          306  +            $bysetpos = explode ( ',', $row[8] );
          307  +
          308  +          $bysetposStr = $row[8];
          309  +          $byweekno = $row[9];
          310  +          $byyearday = $row[10];
          311  +          $wkst = $row[11];
          312  +          $rpt_count = $row[12];
          313  +
          314  +          // Check to see if Weekends Only is applicable.
          315  +          $weekdays_only = ( $rpt_type == 'daily' && $byday == 'MO,TU,WE,TH,FR' );
          316  +        }
          317  +        dbi_free_result ( $res );
          318  +      }
          319  +    }
          320  +
          321  +    $res = dbi_execute ( 'SELECT cal_login, cal_percent, cal_status
          322  +      FROM webcal_entry_user WHERE cal_id = ?', array ( $id ) );
          323  +    if ( $res ) {
          324  +      while ( $row = dbi_fetch_row ( $res ) ) {
          325  +        $overall_percent[] = $row;
          326  +        if ( $login == $row[0] || ( $is_admin && $user == $row[0] ) ) {
          327  +          $task_percent = $row[1];
          328  +          $task_status = $row[2];
          329  +        }
          330  +      }
          331  +      dbi_free_result ( $res );
          332  +    }
          333  +
          334  +    // Determine if Expert mode needs to be set.
          335  +    $expert_mode = ( count ( $byday ) || count ( $bymonth ) ||
          336  +      count ( $bymonthday ) || count ( $bysetpos ) ||
          337  +      isset ( $byweekno ) || isset ( $byyearday ) || isset ( $rpt_count ) );
          338  +
          339  +    // Get Repeat Exceptions.
          340  +    $res = dbi_execute ( 'SELECT cal_date, cal_exdate
          341  +      FROM webcal_entry_repeats_not WHERE cal_id = ?', array ( $id ) );
          342  +    if ( $res ) {
          343  +      while ( $row = dbi_fetch_row ( $res ) ) {
          344  +        if ( $row[1] == 1 )
          345  +          $exceptions[] = $row[0];
          346  +        else
          347  +          $inclusions[] = $row[0];
          348  +      }
          349  +      dbi_free_result ( $res );
          350  +    }
          351  +  }
          352  +  if ( $CATEGORIES_ENABLED == 'Y' ) {
          353  +    $catById = get_categories_by_id ( $id, $real_user, true );
          354  +    if ( ! empty ( $catById ) ) {
          355  +      $catNames = implode ( ', ', $catById );
          356  +      $catList = implode ( ',', array_keys ( $catById ) );
          357  +    }
          358  +  } //end CATEGORIES_ENABLED test
          359  +
          360  +  // Get reminders.
          361  +  $reminder = getReminders ( $id );
          362  +  $reminder_offset = ( empty ( $reminder ) ? 0 : $reminder['offset'] );
          363  +    
          364  +    $rem_status = ( count ( $reminder ));
          365  +  $rem_use_date = ( ! empty ( $reminder['date'] ) );
          366  +
          367  +  // Get participants.
          368  +  $res = dbi_execute ( 'SELECT cal_login, cal_status FROM webcal_entry_user WHERE cal_id = ?
          369  +    AND cal_status IN ( \'A\', \'W\' )', array ( $id ) );
          370  +  if ( $res ) {
          371  +    while ( $row = dbi_fetch_row ( $res ) ) {
          372  +      $participants[$row[0]] = 1;
          373  +      $selectedStatus[$row[0]] = $row[1];
          374  +    }
          375  +    dbi_free_result ( $res );
          376  +  }
          377  +  // Not allowed for tasks or journals.
          378  +  if ( $eType == 'event' && !
          379  +    empty ( $ALLOW_EXTERNAL_USERS ) && $ALLOW_EXTERNAL_USERS == 'Y' )
          380  +    $external_users = event_get_external_users ( $id );
          381  +} else {
          382  +  // ##########   New entry   ################
          383  +  $id = 0; // To avoid warnings below about use of undefined var.
          384  +
          385  +  // We'll use $WORK_DAY_START_HOUR and $WORK_DAY_END_HOUR
          386  +  // as our starting and due times.
          387  +  $cal_time = $WORK_DAY_START_HOUR . '0000';
          388  +  $completed = '';
          389  +  $due_hour = $WORK_DAY_END_HOUR;
          390  +  $due_minute = $task_percent = 0;
          391  +  $due_time = $WORK_DAY_END_HOUR . '0000';
          392  +  $overall_percent = array ();
          393  +
          394  +  // Get category if passed in URL as cat_id.
          395  +  $cat_id = getValue ( 'cat_id', '-?[0-9,\-]*', true );
          396  +  if ( ! empty ( $cat_id ) ) {
          397  +    $res = dbi_execute ( 'SELECT cat_name FROM webcal_categories
          398  +      WHERE cat_id = ? AND ( cat_owner = ? OR cat_owner IS NULL )',
          399  +      array ( $cat_id, $real_user ) );
          400  +    if ( $res ) {
          401  +      $row = dbi_fetch_row ( $res );
          402  +      $catNames = $row[0];
          403  +      $catList = $cat_id;
          404  +    }
          405  +  }
          406  +
          407  +  // Reminder settings.
          408  +  $reminder_offset = ( $REMINDER_WITH_DATE == 'N' ? $REMINDER_OFFSET : 0 );
          409  +
          410  +    $rem_status = ( $REMINDER_DEFAULT == 'Y' );
          411  +  $rem_use_date = ( $reminder_offset == 0 && $REMINDER_WITH_DATE == 'Y' );
          412  +            
          413  +  if ( $eType == 'task' )
          414  +    $hour = $WORK_DAY_START_HOUR;
          415  +
          416  +  // Anything other then testing for strlen breaks either hour=0 or no hour in URL.
          417  +  if ( strlen ( $hour ) )
          418  +    $time = $hour * 100;
          419  +  else
          420  +    $hour = $time = -1;
          421  +
          422  +  if ( ! empty ( $defusers ) ) {
          423  +    $tmp_ar = explode ( ',', $defusers );
          424  +    for ( $i = 0, $cnt = count ( $tmp_ar ); $i < $cnt; $i++ ) {
          425  +      $participants[$tmp_ar[$i]] = 1;
          426  +    }
          427  +  }
          428  +
          429  +  //Add the logged in user if none other supplied
          430  +  if ( count ( $participants )  == 0 )
          431  +    $participants[$login] = 1;
          432  +
          433  +  if ( $readonly == 'N' ) {
          434  +    // Is public allowed to add events?
          435  +    if ( $login == '__public__'  && $PUBLIC_ACCESS_CAN_ADD != 'Y' )
          436  +        $can_edit = false;
          437  +    else
          438  +      $can_edit = true;
          439  +  }
          440  +}
          441  +$dateYmd = date ( 'Ymd' );
          442  +$thisday = $day;
          443  +$thismonth = $month;
          444  +$thisyear = $year;
          445  +if ( empty ( $rpt_type ) || ! $rpt_type )
          446  +  $rpt_type = 'none';
          447  +
          448  +// Avoid error for using undefined vars.
          449  +if ( ! isset ( $hour ) && $hour != 0 )
          450  +  $hour = -1;
          451  +else
          452  +if ( isset ( $hour ) && $hour >= 0 )
          453  +  $cal_time = ( $hour * 10000 ) + ( isset ( $minute ) ? $minute * 100 : 0 );
          454  +
          455  +if ( empty ( $access ) )
          456  +  $access = '';
          457  +
          458  +if ( empty ( $cal_url ) )
          459  +  $cal_url = '';
          460  +
          461  +if ( empty ( $description ) || $description == '<br />' )
          462  +  $description = '';
          463  +
          464  +if ( empty ( $duration ) )
          465  +  $duration = 0;
          466  +
          467  +if ( $duration == 1440 && $time == 0 ) {
          468  +  $duration = $hour = $minute = '';
          469  +  $allday = 'Y';
          470  +} else
          471  +  $allday = 'N';
          472  +
          473  +if ( empty ( $location ) )
          474  +  $location = '';
          475  +
          476  +if ( empty ( $name ) )
          477  +  $name = '';
          478  +
          479  +if ( empty ( $priority ) )
          480  +  $priority = 5;
          481  +
          482  +if ( empty ( $rpt_end_date ) )
          483  +  $rpt_end_date = 0;
          484  +
          485  +if ( empty ( $rpt_end_time ) )
          486  +  $rpt_end_time = 0;
          487  +
          488  +if ( empty ( $rpt_freq ) )
          489  +  $rpt_freq = 0;
          490  +
          491  +if ( empty ( $cal_date ) ) {
          492  +  $cal_date = ( ! empty ( $date ) && $eType != 'task' ? $date : $dateYmd );
          493  +
          494  +  if ( empty ( $due_date ) )
          495  +    $due_date = $dateYmd;
          496  +}
          497  +if ( empty ( $thisyear ) )
          498  +  $thisdate = $dateYmd;
          499  +else {
          500  +  $thisdate = sprintf ( "%04d%02d%02d", $thisyear,
          501  +    empty ( $thismonth ) ? date ( 'm' ) : $thismonth,
          502  +    empty ( $thisday ) ? date ( 'd' ) : $thisday );
          503  +}
          504  +
          505  +if ( empty ( $cal_date ) || ! $cal_date )
          506  +  $cal_date = $thisdate;
          507  +
          508  +if ( empty ( $due_date ) || ! $due_date )
          509  +  $due_date = $thisdate;
          510  +
          511  +// Setup to display user's timezone difference if Admin or Assistant.
          512  +// Even though event is stored in GMT,
          513  +// an Assistant may need to know that the boss is in a different Timezone.
          514  +if ( $is_assistant || $is_admin && ! empty ( $user ) ) {
          515  +  $tz_offset = date ( 'Z', date_to_epoch ( $cal_date . $cal_time ) );
          516  +  $user_TIMEZONE = get_pref_setting ( $user, 'TIMEZONE' );
          517  +  set_env ( 'TZ', $user_TIMEZONE );
          518  +  $user_tz_offset = date ( 'Z', date_to_epoch ( $cal_date . $cal_time ) );
          519  +  if ( $tz_offset != $user_tz_offset ) { // Different TZ_Offset.
          520  +    user_load_variables ( $user, 'temp' );
          521  +    $tz_diff = ( $user_tz_offset - $tz_offset ) / 3600;
          522  +    $abs_diff = abs ( $tz_diff );
          523  +    // translate ( 'is in a different timezone than you are. Currently' )
          524  +    // translate ( 'hour ahead of you' ) translate ( 'hour behind you' )
          525  +    // translate ( 'hours ahead of you' ) translate ( 'hours behind you' )
          526  +    // translate ( 'XXX is in a different timezone (ahead)' )
          527  +    // translate ( 'XXX is in a different timezone (behind)' )
          528  +    // Line breaks in translates below are to bypass update_translation.pl.
          529  +    $TZ_notice = str_replace ( 'XXX',
          530  +      array ( $tempfullname,
          531  +        // TODO show hh:mm instead of abs.
          532  +        $abs_diff . ' ' . translate ( 'hour'
          533  +           . ( $abs_diff == 1 ? '' : 's' ) ),
          534  +        translate ( 'Time entered here is based on your Timezone.' ) ),
          535  +      translate ( 'XXX is in a different timezone ('
          536  +         . ( $tz_diff > 0 ? 'ahead)' : 'behind)' ) ) );
          537  +  }
          538  +  // Return to $login TIMEZONE.
          539  +  set_env ( 'TZ', $TIMEZONE );
          540  +}
          541  +
          542  +$eType_label = ' ( ' . translate ( $eType ) . ' )';
          543  +
          544  +echo '
          545  +    <h2>' . ( $id ? translate ( 'Edit Entry' ) : translate ( 'Add Entry' ) )
          546  + . $eType_label . '&nbsp;<img src="images/help.gif" alt="' . translate ( 'Help' )
          547  + . '" class="help" onclick="window.open( \'help_edit_entry.php'
          548  + . ( empty ( $id ) ? '?add=1' : '' )
          549  + . '\', \'cal_help\', \'dependent,menubar,scrollbars,height=400,width=400,'
          550  + . 'innerHeight=420,outerWidth=420\' );" /></h2>';
          551  +
          552  +if ( $can_edit ) {
          553  +  $tabs_ar = array ( 'details', translate ( 'Details' ) );
          554  +  if ( $DISABLE_PARTICIPANTS_FIELD != 'Y' ) {
          555  +    $tabs_ar[] = 'participants';
          556  +    $tabs_ar[] = translate ( 'Participants' );
          557  +  }
          558  +  if ( $DISABLE_REPEATING_FIELD != 'Y' ) {
          559  +    $tabs_ar[] = 'pete';
          560  +    $tabs_ar[] = translate ( 'Repeat' );
          561  +  }
          562  +  if ( $DISABLE_REMINDER_FIELD != 'Y' ) {
          563  +    $tabs_ar[] = 'reminder';
          564  +    $tabs_ar[] = translate ( 'Reminders' );
          565  +  }
          566  +
          567  +  $tabs = '';
          568  +  for ( $i = 0, $cnt = count ( $tabs_ar ); $i < $cnt; $i++ ) {
          569  +    $tabs .= '
          570  +        <span class="tab'
          571  +     . ( $i > 0 ? 'bak' : 'for' )
          572  +     . '" id="tab_' . $tabs_ar[$i]
          573  +     . '"><a href="#tab' . $tabs_ar[$i] . '" onclick="return showTab( \''
          574  +     . $tabs_ar[$i] . '\' )">' . $tabs_ar[++$i] . '</a></span>';
          575  +  }
          576  +  echo '
          577  +    <form action="edit_entry_handler.php" method="post" name="editentryform" '
          578  +   . 'id="editentryform">
          579  +      <input type="hidden" name="eType" value="' . $eType . '" />'
          580  +   . ( ! empty ( $id ) && ( empty ( $copy ) || $copy != '1' ) ? '
          581  +      <input type="hidden" name="cal_id" value="' . $id . '" />' : '' )
          582  +  /* We need an additional hidden input field. */ . '
          583  +      <input type="hidden" name="entry_changed" value="" />'
          584  +  // Are we overriding an entry from a repeating event...
          585  +  . ( empty ( $override ) ? '' : '
          586  +      <input type="hidden" name="override" value="1" />
          587  +      <input type="hidden" name="override_date" value="' . $cal_date . '" />' )
          588  +  // If assistant, need to remember boss = user.
          589  +  . ( $is_assistant || $is_nonuser_admin || ! empty ( $user ) ? '
          590  +      <input type="hidden" name="user" value="' . $user . '" />' : '' )
          591  +  // If has cal_group_id was set, need to set parent = $parent.
          592  +  . ( empty ( $parent ) ? '' : '
          593  +      <input type="hidden" name="parent" value="' . $parent . '" />' ) . '
          594  +
          595  +<!-- TABS -->' . ( $useTabs ? '
          596  +      <div id="tabs">' . $tabs . '
          597  +      </div>' : '' ) . '
          598  +
          599  +<!-- TABS BODY -->' . ( $useTabs ? '
          600  +      <div id="tabscontent">
          601  +<!-- DETAILS -->
          602  +        <a name="tabdetails"></a>
          603  +        <div id="tabscontent_details">' : '
          604  +      <fieldset>
          605  +        <legend>' . translate ( 'Details' ) . '</legend>' ) . '
          606  +          <table border="0" summary="">
          607  +