Author: buildbot
Date: Wed Jan  9 15:28:44 2013
New Revision: 845744

Log:
Staging update by buildbot for vcl

Modified:
    websites/staging/vcl/trunk/content/   (props changed)
    websites/staging/vcl/trunk/content/docs/themes.html

Propchange: websites/staging/vcl/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jan  9 15:28:44 2013
@@ -1 +1 @@
-1430877
+1430888

Modified: websites/staging/vcl/trunk/content/docs/themes.html
==============================================================================
--- websites/staging/vcl/trunk/content/docs/themes.html (original)
+++ websites/staging/vcl/trunk/content/docs/themes.html Wed Jan  9 15:28:44 2013
@@ -78,199 +78,234 @@
   
   <div id="content">
     <h1 class="title">Themes</h1>
-    <div class="toc">
+    <h2 id="general-overview">General Overview</h2>
+<p>The code is broken up into multiple files, based on sections of the site 
(as divided up by the navigation area). There are also several general purpose 
files:</p>
 <ul>
-<li><a href="#overview">Overview</a></li>
-<li><a href="#file-system-structure">File system structure</a></li>
-<li><a href="#vcl-html-generation">VCL HTML generation</a></li>
-<li><a href="#understanding-pagephp">Understanding page.php</a></li>
-<li><a href="#path-references">Path references</a></li>
-<li><a href="#example-bare-minimal-theme">Example: bare minimal theme</a></li>
-<li><a href="#using-a-new-theme">Using a new theme</a></li>
-<li><a href="#tips-and-tricks">Tips and Tricks</a></li>
-</ul>
-</div>
-<h2 id="overview">Overview</h2>
-<p>Custom themes can be created in VCL for each affiliation. This allows a 
multi-site 
-installation of VCL to have themes that match each affiliation's primary web 
site
-theme. When a user logs in, the site will be displayed using the theme 
specified
-for that user's affiliation. Additionally, when using <a 
href="/docs/ldapauth.html">LDAP 
-authentication</a>, the login page for the affiliation will be 
-displayed with the theme matching that affiliation.</p>
-<h2 id="file-system-structure">File system structure</h2>
-<p>The themes are in a <strong>themes</strong> directory in the web code. If 
you installed your web
-frontend under a directory named <strong>vcl</strong>, you would look in 
vcl/themes. Each VCL 
-release comes with a <strong>default</strong> theme, which you should see at 
vcl/themes/default. 
-Typically, you would set up the following directory structure for a new 
theme:</p>
-<ul>
-<li>vcl/themes/mynewtheme</li>
-<li>vcl/themes/mynewtheme/page.php</li>
-<li>vcl/themes/mynewtheme/images</li>
-<li>vcl/themes/mynewtheme/js</li>
-<li>vcl/themes/mynewtheme/css</li>
-</ul>
-<p>The page.php file and css directory are the only ones that are required. 
After creating 
-the directory structure, you will need to go to the themes directory and run 
the
-copydojocss.sh script, passing it the name of the directory containing your 
new theme as
-an argument:</p>
-<div class="codehilite"><pre><span class="n">cd</span> <span 
class="n">vcl</span><span class="o">/</span><span class="n">themes</span>
-<span class="o">./</span><span class="n">copydojocss</span><span 
class="o">.</span><span class="n">sh</span> <span class="n">mynewtheme</span>
+<li>index.php -  This is the only file used in any URLs. It includes other 
files based on the passed in "mode".</li>
+<li>states.php - builds an array of modes, which function should be called for 
each mode, and the part of the site each mode belongs to</li>
+<li>utils.php - contains many functions that are common to several 
sections</li>
+<li>errors.php - contains an array of all errors that can be reported by the 
site. I'm not sure how useful it was do set it up this way, but it's where 
things currently are. errors.php also contains the debug function that is used 
if the current user has an adminlevel of ADMIN_DEVELOPER in the user table.</li>
+<li>secrets.php - contains all passwords/passphrases and secret and shared 
keys</li>
+<li>conf.php - contains all configuration variables that might need to be 
modified for each install base</li>
+<li>php5extras.php - anything that needs to be done differently when using 
php5 vs php4</li>
+</ul>
+<h2 id="site-security">Site Security</h2>
+<p>The initial handling of form data within the code was quite insecure, and 
several areas of the site are still this way. After learning more about web 
security, I developed a security model based on "continuations". All of the 
pages have been converted to using continuations.</p>
+<p>Deep linking into the site is only allowed for modes in the 
$actions['entry'] array in states.php. Anything else requires the submission of 
a continuation. For the most part, access to different parts of the site is 
controlled by what privileges you have in the Privileges section of the site. 
However, there are a few things controlled by a user's adminlevel field in the 
user table. The very earliest form of authorization was handled by the user's 
adminlevel field, and it has continued to be useful in a few situations.</p>
+<p>All form data passed in to the site should be verified very strictly. 
Unfortunately, that is not currently the case. All of the main pages available 
to the average user should have been updated to have strict validation, though 
other parts of the site have not made it yet. Most sections of the site have a 
single function (or a very small number of similar functions) that handle the 
processing of form data. This will make it easier to add better checks 
throughout the site as the number of locations needing to be modified is fairly 
small.</p>
+<h2 id="general-processing-flow">General Processing Flow</h2>
+<p>Every time someone views the site, it is through index.php. This file 
defines several global variables and includes conf.php, states.php, errors.php, 
and utils.php. It then creates a database connection and calls initGlobals(), 
which among other things, determines $mode. Based on $mode, index.php 
determines which function needs to be called and assigns it to $actionFunction. 
Next, checkAccess() is called, followed by sendHeaders() and printHTMLHeader() 
(which doesn't actually print the header if $mode is in $noHTMLwrappers). 
set_error_handler is called if the current user has an adminlevel of 
ADMIN_DEVELOPER. Next, $actionFunction is finally called, followed by 
disconnecting from the database, a call to printHTMLFooter(), and a call to 
semUnlock() to make sure the semaphore was unlocked if it was locked somewhere 
in the process.</p>
+<p>One thing worth noting that initGlobals() does is to include other files 
based on which mode is being processed. This helps to prevent the php script 
engine from having to process unnecessary files. It also adds a small layer of 
security because a section of code cannot be attacked if it has not been 
included.</p>
+<h2 id="continuations">Continuations</h2>
+<p>Continuations are how the site handles sequences of pages. It also helps 
keep people from getting to parts of the site they aren't allowed to access or 
shouldn't jump in to the middle of (i.e. by using the browser's back button). 
Continuations are created by calling addContinuationsEntry, which accepts up to 
6 arguments:</p>
+<ul>
+<li>$nextmode - the mode that should be used when the continuation is 
submitted</li>
+<li>$data - an array of any data that you would like to have available when 
the continuation is submitted</li>
+<li>$duration - how long from "now" that the continuation should be valid (in 
seconds)</li>
+<li>$deleteFromSelf - boolean - 1 if this is the start of a new sequence of 
pages, 0 if it will be a continuation of a sequence. If it is set to 0, then 
the "parent" continuation for this one is the continuation that the site is 
currently processing.</li>
+<li>$multicall - boolean - whether or not the continuation may be submitted 
more than once</li>
+<li>$repeatProtect - boolean - used in cases where a "sequence loop" can 
occur</li>
+</ul>
+<p>addContinuationsEntry returns a long encrypted string to be used as an 
identifier to be submitted (either as a hidden form field or in the URL for a 
GET link). What gets encrypted is a salt value, the id of the continuation that 
was created (or updated), the user's numeric id, and a timestamp. If the string 
gets tampered with, it will not decrypt properly. If someone tries to submit a 
continuation given to another user, their user ids won't match; so, it will be 
considered invalid.</p>
+<p>When a continuation is submitted, some checks are run and, if everything 
passes, whatever was submitted as $nextmode is the mode for which the site 
functions. One of those checks is that $duration has not expired; if it has, 
the user is given a notice that he has submitted expired data. Any data 
submitted as $data can be accessed by calling getContinuationsData() with a 
single argument being the index of the array that was passed to 
addContinuationsEntry. Additionally, getContinuationsData can be called with no 
arguments to get all of $data as a single array. If $multicall was set to 0, 
then the continuation is deleted. If $deleteFromSelf was also set to 0, then 
this continuation's parent will also be deleted. If $deleteFromSelf was set to 
0 for the parent, it's parent will be deleted, and so on until a continuation 
is reached that had $deleteFromSelf set to 1.</p>
+<h2 id="javascript-and-ajax">Javascript and AJAX</h2>
+<p>Efforts have been made to ensure the pages required for making and 
connecting to a reservation work without requiring any javascript. However, 
enhancements have been made to enrich those parts of the site if javascript is 
enabled. For some of the administrative parts of the site, javascript and AJAX 
have been used heavily, particularly the Privileges page. The <a 
href="http://dojotoolkit.org";>Dojo Toolkit</a> is what is being used for 
javascript widgets and to handle some of the AJAX.</p>
+<h2 id="a-few-examples">A Few Examples</h2>
+<h3 id="adding-a-link-to-the-navigation-area">Adding a link to the navigation 
area</h3>
+<p>Here are the steps that would need to be done to add a new section of the 
site.</p>
+<p>First, modify states.php to add a new mode.</p>
+<ol>
+<li>create a new $actions['mode'] with the name of your mode set to the name 
of the function that should be called</li>
+<li>create a new $actions['pages'] with the name of your mode set to the name 
of the section this mode belongs to. This is only an internal identifier used 
to associate modes together.</li>
+</ol>
+<p>So, if your mode is named "examplemode", you could end up with these two 
lines being added:</p>
+<div class="codehilite"><pre><span class="p">$</span><span 
class="nv">actions</span>[&#39;mode&#39;][&#39;examplemode&#39;] = <span 
class="nt">&lt;span</span> <span class="na">class=</span><span 
class="s">&quot;code-quote&quot;</span><span 
class="nt">&gt;</span>&quot;exampleFunc1&quot;<span 
class="nt">&lt;/span&gt;</span>;
+<span class="p">$</span><span 
class="nv">actions</span>[&#39;pages&#39;][&#39;examplemode&#39;] = <span 
class="nt">&lt;span</span> <span class="na">class=</span><span 
class="s">&quot;code-quote&quot;</span><span 
class="nt">&gt;</span>&quot;exampleSection&quot;<span 
class="nt">&lt;/span&gt;</span>;
 </pre></div>
 
 
-<h2 id="vcl-html-generation">VCL HTML generation</h2>
-<p>There are a few parts to how VCL generates the HTML for any given page. 
There are some
-important functions of which to be aware. The first two must be in the 
page.php file:</p>
-<ul>
-<li>getHeader - generates all content up to and including the opening of a div 
element 
-that will contain the main page content (typically what is to the right of the 
-navigation menu); this div element must have an <strong>id</strong> of 
<strong>content</strong>; must have 
-$refresh passed to it as an argument, which is then passed to getDojoHTML</li>
-<li>getFooter - closes the div element containing the main page content and 
generates any 
-remaining content to close out the HTML for the page</li>
-</ul>
-<p>These are functions that exist in utils.php that are available to be called 
from 
-getHeader and getFooter:</p>
-<ul>
-<li>getDojoHTML - returns a string of Dojo related style and javascript; needs 
to be 
-called in the &lt;head&gt; part of the page; needs to be passed $refresh as an 
argument</li>
-<li>getExtraCSS - returns an array of css files expected to exist in the 
vcl/css directory
-that need to be included for the current value of $mode; a link tag needs to 
be created
-for each of these files</li>
-<li>getSelectLanguagePulldown - returns the html for a form that has a select 
element for
-changing the locale of the site</li>
-<li>getNavMenu - returns a string of list items that make up the navigation 
part of the
-site; needs to be wrapped in &lt;ul&gt; tags; accepts 3 arguments:</li>
-<li>$inclogout - 0/1 - should a <strong>Logout</strong> item be at the bottom 
of the navigation list</li>
-<li>$inchome - 0/1 - should a <strong>HOME</strong> item be at the top of the 
navigation list</li>
-<li>$homeurl - (optional) - if $inchome is 1, use this as the href of the HOME 
link;
-if $inchome is 1 and $homeurl is not specified, HOME from conf.php is used</li>
-</ul>
-<h2 id="understanding-pagephp">Understanding page.php</h2>
-<p>As noted above, this file must contain getHeader and getFooter. 
<strong>getHeader</strong> must 
-contain these elements, all of which can be seen in the default theme's 
page.php file:</p>
-<ul>
-<li>opening html and head tags</li>
-<li>stylesheet link to "css/vcl.css"</li>
-<li>script tag with src="js/code.js"</li>
-<li>script block setting the javascript variable <em>cookiedomain</em> to the 
php define 
-<em>COOKIEDOMAIN</em> and setting usenls = 0</li>
-<li>a call to getDojoHTML($refresh) in the head section of the HTML</li>
-<li>a call to getExtraCSS() with a foreach to add a stylesheet link for each 
file in the 
-array returned by getExtraCSS()</li>
-<li>closing head tag</li>
-<li>body tag with its class set to the name of the theme</li>
-<li>an unordered list wrapping the string returned by a call to getNavMenu() - 
this should
-be inside an if conditional checking for $authed to be true</li>
-<li>must end with an opening div tag with an id of <em>content</em></li>
-</ul>
-<p><strong>getFooter</strong> must contain these elements:</p>
-<ul>
-<li>closing div tag for the content div element</li>
-<li>closing body and html tags</li>
-</ul>
-<h2 id="path-references">Path references</h2>
-<p>There are a few things to keep in mind with respect to path references. 
From a web 
-browser's perspective, all HTML generated by getHeader and getFooter will be 
part of the
-vcl/index.php file. So, any paths referenced in getHeader and getFooter need 
to be
-relative to that - example: &lt;img 
src="themes/mynewtheme/images/someimage.png"&gt;. Any
-files referenced in css files in the theme's css directory will be relative to 
that css 
-file. So, if you were to include a reference to an image in the theme's image 
directory 
-in a css file in the css directory, you would reference it relative to the css 
directory 
-- example: url(../images/someimage.png)</p>
-<h2 id="example-bare-minimal-theme">Example: bare minimal theme</h2>
-<p>This example shows the bare minimum that must be included. For a more 
detailed example,
-look at the default theme include in each release. We'll call the theme 
"minimal". First,
-we create a directory under the themes directory for it:</p>
-<div class="codehilite"><pre><span class="nb">mkdir</span> <span 
class="n">vcl</span><span class="sr">/themes/mi</span><span 
class="n">nimal</span>
+<p>While we're editing states.php, lets jump to the top and add our new mode 
to $actions['entry'] so that it can be called directly without having to 
already be on the site. Just add 'examplemode' as a new item at the end of the 
array.</p>
+<p>The next thing to do is to actually add the functions. Lets place them in a 
new file called 'examples.php' in the .ht-inc directory. Our first function can 
be really simple and just print out some text. So, create examples.php with 
this in it:</p>
+<div class="codehilite"><pre><span class="cp">&lt;?php</span>
+<span class="k">function</span> <span class="nf">exampleFunc1</span><span 
class="p">()</span> <span class="p">{</span>
+   <span class="k">print</span> <span class="o">&lt;</span><span 
class="nx">span</span> <span class="nx">class</span><span 
class="o">=</span><span class="s2">&quot;code-quote&quot;</span><span 
class="o">&gt;</span><span class="s2">&quot;exampleFunc1 successfully 
called.&lt;br&gt;</span><span class="se">\n</span><span 
class="s2">&quot;</span><span class="o">&lt;/</span><span 
class="nx">span</span><span class="o">&gt;</span><span class="p">;</span>
+<span class="p">}</span>
+<span class="cp">?&gt;</span>
 </pre></div>
 
 
-<p>Next, we create a css directory and run the copydojocss.sh script:</p>
-<div class="codehilite"><pre><span class="nb">mkdir</span> <span 
class="n">vcl</span><span class="sr">/themes/mi</span><span 
class="n">nimal</span><span class="o">/</span><span class="n">css</span>
-<span class="n">cd</span> <span class="n">vcl</span><span 
class="o">/</span><span class="n">themes</span>
-<span class="o">./</span><span class="n">copydojocss</span><span 
class="o">.</span><span class="n">sh</span> <span class="n">minimal</span>
+<p>There's one last thing we need to do before linking this in on the site. As 
described in the "General Processing Flow" section, initGlobals includes the 
required files based on the current mode's section. So, edit utils.php and 
scroll toward the end of it where files are included (using require_once) 
within a switch statement. In the switch statement, before the "default" case, 
add</p>
+<div class="codehilite"><pre><span class="k">case</span> <span 
class="s">&#39;exampleSection&#39;</span><span class="p">:</span>
+   <span class="n">require_once</span><span class="p">(</span><span 
class="s">&#39;.ht-inc/examples.php&#39;</span><span class="p">);</span>
+   <span class="n">break</span><span class="p">;</span>
 </pre></div>
 
 
-<p>Now, we create vcl/themes/minimal/page.php with this content:</p>
-<div class="codehilite"><pre>function getHeader(<span class="p">$</span><span 
class="nv">refresh</span>) <span class="err">{</span>
-    global <span class="p">$</span><span class="nv">user</span>, <span 
class="p">$</span><span class="nv">mode</span>, <span class="p">$</span><span 
class="nv">authed</span>, <span class="p">$</span><span 
class="nv">locale</span>, <span class="p">$</span><span 
class="nv">VCLversion</span>;
-    <span class="p">$</span><span class="nv">rt</span>  = &quot;<span 
class="cp">&lt;!DOCTYPE html&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;html&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;head&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;title&gt;</span>VCL<span 
class="nt">&lt;/title&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;link</span> <span class="na">rel=</span><span 
class="s">stylesheet</span> <span class="na">type=</span><span 
class="s">\&quot;text/css\&quot;</span> <span class="na">href=</span><span 
class="s">\&quot;css/vcl.css\&quot;</span><span class="nt">&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;link</span> <span class="na">rel=</span><span 
class="s">stylesheet</span> <span class="na">type=</span><span 
class="s">\&quot;text/css\&quot;</span> <span class="na">href=</span><span 
class="s">\&quot;themes/minimal/css/minimal.css\&quot;</span><span 
class="nt">&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;script</span> <span class="na">src=</span><span 
class="s">\&quot;js/code.js\&quot;</span> <span class="na">type=</span><span 
class="s">\&quot;text/javascript\&quot;</span><span 
class="nt">&gt;&lt;/script&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;script</span> <span class="na">type=</span><span 
class="s">\&quot;text/javascript\&quot;</span><span 
class="nt">&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;var 
cookiedomain = &#39;&quot; . COOKIEDOMAIN . &quot;&#39;;\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;/script&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= getDojoHTML(<span 
class="p">$</span><span class="nv">refresh</span>);
-    <span class="p">$</span><span class="nv">extracss</span> = getExtraCSS();
-    foreach(<span class="p">$</span><span class="nv">extracss</span> as <span 
class="p">$</span><span class="nv">file</span>)
-        <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;link</span> <span class="na">rel=</span><span 
class="s">stylesheet</span> <span class="na">type=</span><span 
class="s">\&quot;text/css\&quot;</span> <span class="na">href=</span><span 
class="s">\&quot;css/</span><span class="p">$</span><span 
class="nv">file</span><span class="s">\&quot;</span><span 
class="nt">&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;/head&gt;</span>\n\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;body</span> <span class="na">class=</span><span 
class="s">minimal</span><span class="nt">&gt;</span>\n\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;div</span> <span class="na">id=</span><span 
class="s">menulist</span><span class="nt">&gt;</span>\n&quot;;
-    if(<span class="p">$</span><span class="nv">authed</span>) <span 
class="err">{</span>
-        <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;ul&gt;</span>\n&quot;;
-        <span class="p">$</span><span class="nv">rt</span> .= getNavMenu(1, 1);
-        <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;/ul&gt;</span>\n&quot;;
-    }
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;/div&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;div</span> <span class="na">id=</span><span 
class="s">content</span><span class="nt">&gt;</span>\n&quot;;
-    return <span class="p">$</span><span class="nv">rt</span>;
+<p>Now, we're ready to actually add a link for this example function to the 
navigation area (of course, not all modes are linked to from the navigation 
area, but it is an easy example). To do this, edit utils.php and find the 
getNavMenu function close to the bottom of the file. We'll add our new mode to 
the end; so, find the "logout" part which should look something like this:</p>
+<div class="codehilite"><pre>if(<span class="p">$</span><span 
class="nv">inclogout</span>) <span class="err">{</span>
+   <span class="p">$</span><span class="nv">rt</span> .= 
menulistLI(&#39;authentication&#39;);
+   <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;a</span> <span class="na">href=</span><span 
class="s">\&quot;&quot;</span> <span class="err">.</span> <span 
class="err">BASEURL</span> <span class="err">.</span> <span 
class="err">SCRIPT</span> <span class="err">.</span> <span 
class="err">&quot;?</span><span class="na">mode=</span><span 
class="s">logout\&quot;</span><span class="nt">&gt;</span>&quot;;
+   <span class="p">$</span><span class="nv">rt</span> .= &quot;Logout<span 
class="nt">&lt;/a&gt;&lt;/li&gt;</span>\n&quot;;
 }
+</pre></div>
 
-function getFooter() <span class="err">{</span>
-    <span class="p">$</span><span class="nv">year</span> = date(&quot;Y&quot;);
-    <span class="p">$</span><span class="nv">rt</span>  = &quot;<span 
class="nt">&lt;/div&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;/body&gt;</span>\n&quot;;
-    <span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;/html&gt;</span>\n&quot;;
-    return <span class="p">$</span><span class="nv">rt</span>;
-}
+
+<p>We'll basically duplicate that (without the if conditional), changing a few 
things so that we add this right below it:</p>
+<div class="codehilite"><pre><span class="p">$</span><span 
class="nv">rt</span> .= menulistLI(&#39;exampleSection&#39;);
+<span class="p">$</span><span class="nv">rt</span> .= &quot;<span 
class="nt">&lt;a</span> <span class="na">href=</span><span 
class="s">\&quot;&quot;</span> <span class="err">.</span> <span 
class="err">BASEURL</span> <span class="err">.</span> <span 
class="err">SCRIPT</span> <span class="err">.</span> <span 
class="err">&quot;?</span><span class="na">mode=</span><span 
class="s">examplemode\&quot;</span><span class="nt">&gt;</span>&quot;;
+<span class="p">$</span><span class="nv">rt</span> .= &quot;Example 
Section<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>\n&quot;;
+</pre></div>
+
+
+<p>Viewing the site should now show "Example Section" right under "Logout" in 
the navigation area. Clicking "Example Section" should cause "exampleFunc1 
successfully called." to be displayed in the main content area of the site.</p>
+<h3 id="using-continuations-when-submitting-form-data">Using continuations 
when submitting form data</h3>
+<p>Let's modify examplefunc1 so that it prints some form data that gets 
submitted with a continuation.</p>
+<p>So, change the contents of examplefunc1 to be:</p>
+<div class="codehilite"><pre><span class="p">$</span><span 
class="nv">options</span> = array(0 =&gt; &quot;option1&quot;,
+                 1 =&gt; &quot;option2&quot;);
+print &quot;<span class="nt">&lt;FORM</span> <span 
class="na">action=</span><span class="s">\&quot;&quot;</span> <span 
class="err">.</span> <span class="err">BASEURL</span> <span 
class="err">.</span> <span class="err">SCRIPT</span> <span class="err">.</span> 
<span class="err">&quot;\&quot;</span> <span class="na">method=</span><span 
class="s">post</span><span class="nt">&gt;</span>\n&quot;;
+print &quot;Select one of these options:&quot;;
+printSelectInput(&quot;theoption&quot;, <span class="p">$</span><span 
class="nv">options</span>);
+<span class="p">$</span><span class="nv">cont</span> = 
addContinuationsEntry(&quot;submitFunc1Form&quot;, <span 
class="p">$</span><span class="nv">options</span>);
+print &quot;<span class="nt">&lt;INPUT</span> <span 
class="na">type=</span><span class="s">hidden</span> <span 
class="na">name=</span><span class="s">continuation</span> <span 
class="na">value=</span><span class="s">\&quot;</span><span 
class="p">$</span><span class="nv">cont</span><span 
class="s">\&quot;</span><span class="nt">&gt;</span>\n&quot;;
+print &quot;<span class="nt">&lt;INPUT</span> <span 
class="na">type=</span><span class="s">submit</span> <span 
class="na">value=</span><span class="s">Submit</span><span 
class="nt">&gt;</span>\n&quot;;
+print &quot;<span class="nt">&lt;/FORM&gt;</span>\n&quot;;
+</pre></div>
+
+
+<p>Now, we have a form that gets displayed when "Example Section" is clicked.  
Now, we need to add a function to process that form.  Add this function to 
examples.php:</p>
+<div class="codehilite"><pre><span class="n">function</span> <span 
class="n">submitFunc1Form</span><span class="p">()</span> <span 
class="p">{</span>
+   <span class="nv">$data</span> <span class="o">=</span> <span 
class="n">getContinuationVar</span><span class="p">();</span>
+   <span class="nv">$theoption</span> <span class="o">=</span> <span 
class="n">processInputVar</span><span class="p">(</span><span 
class="s">&quot;theoption&quot;</span><span class="p">,</span> <span 
class="n">ARG_NUMERIC</span><span class="p">);</span>
+   <span class="k">if</span><span class="p">(</span><span class="o">!</span> 
<span class="n">array_key_exists</span><span class="p">(</span><span 
class="nv">$theoption</span><span class="p">,</span> <span 
class="nv">$data</span><span class="p">))</span> <span class="p">{</span>
+      <span class="k">print</span> <span class="s">&quot;invalid option 
submitted\n&quot;</span><span class="p">;</span>
+      <span class="k">return</span><span class="p">;</span>
+   <span class="p">}</span>
+   <span class="k">print</span> <span class="s">&quot;The option you selected 
was: &quot;</span><span class="p">;</span>
+   <span class="k">print</span> <span 
class="s">&quot;{$data\[$theoption\]}&lt;br&gt;\n&quot;</span><span 
class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Next, we add this function to states.php:</p>
+<div class="codehilite"><pre><span class="nv">$actions</span><span 
class="p">[</span><span class="s">&#39;mode&#39;</span><span 
class="p">][</span><span class="s">&#39;submitFunc1Form&#39;</span><span 
class="p">]</span> <span class="o">=</span> <span 
class="s">&quot;submitFunc1Form&quot;</span><span class="p">;</span>
+<span class="nv">$actions</span><span class="p">[</span><span 
class="s">&#39;pages&#39;</span><span class="p">][</span><span 
class="s">&#39;submitFunc1Form&#39;</span><span class="p">]</span> <span 
class="o">=</span> <span class="s">&quot;exampleSection&quot;</span><span 
class="p">;</span>
 </pre></div>
 
 
-<p>Finally, we create a basic css file at 
vcl/themes/minimal/css/minimal.css:</p>
-<div class="codehilite"><pre><span class="c1">#menulist {</span>
-    <span class="n">float:</span> <span class="n">left</span><span 
class="p">;</span>
+<p>Now, click the "Example Section" link, select one of the options, and click 
Submit to see if it works.</p>
+<h3 id="using-ajax-to-dynamically-update-a-page">Using AJAX to dynamically 
update a page</h3>
+<p>AJAX is very useful for dynamically updating page content.  Let's add 
something to examplefunc1 that can be updated with an AJAX call.</p>
+<p>Add this to the end of examplefunc1:</p>
+<div class="codehilite"><pre>print &quot;<span 
class="nt">&lt;br&gt;&lt;br&gt;</span>\n&quot;;
+print &quot;<span class="nt">&lt;div</span> <span class="na">id=</span><span 
class="s">examplediv</span><span class="nt">&gt;</span>\n&quot;;
+print &quot;This will get dynamically changed.<span 
class="nt">&lt;br&gt;</span>\n&quot;;
+print &quot;<span class="nt">&lt;/div&gt;</span>\n&quot;;
+<span class="p">$</span><span class="nv">cont</span> = 
addContinuationsEntry(&quot;AJexample&quot;);
+print &quot;<span class="nt">&lt;a</span> <span 
class="na">onclick=</span><span class="s">\&quot;JS_AJexample(&#39;</span><span 
class="p">$</span><span class="nv">cont</span><span 
class="s">&#39;);\&quot;</span><span class="nt">&gt;</span>Click to &quot;;
+print &quot;update<span class="nt">&lt;/a&gt;&lt;br&gt;</span>\n&quot;;
+</pre></div>
+
+
+<p>Next, we need to add the javascript function we just referenced to code.js 
(in .ht-inc's parent directory) as well as a callback function that will be 
called when the results of the AJAX call are returned:</p>
+<div class="codehilite"><pre><span class="n">function</span> <span 
class="n">JS_AJexample</span><span class="p">(</span><span 
class="n">contid</span><span class="p">)</span> <span class="p">{</span>
+   <span class="n">dojo</span><span class="o">.</span><span 
class="n">xhrPost</span><span class="p">({</span>
+      <span class="n">url:</span><span 
class="s">&#39;index.php&#39;</span><span class="p">,</span>
+      <span class="n">load:</span> <span class="n">JS_AJexampleCB</span><span 
class="p">,</span>
+      <span class="n">error:</span> <span class="n">errorHandler</span><span 
class="p">,</span>
+      <span class="n">content:</span> <span class="p">{</span><span 
class="n">continuation:</span> <span class="n">contid</span><span 
class="p">},</span>
+      <span class="n">timeout:</span> <span class="mi">15000</span>
+   <span class="p">});</span>
 <span class="p">}</span>
 
-<span class="c1">#content {</span>
-    <span class="n">margin</span><span class="o">-</span><span 
class="n">left:</span> <span class="mi">15</span><span class="n">em</span><span 
class="p">;</span>
+<span class="n">function</span> <span class="n">JS_AJexampleCB</span><span 
class="p">(</span><span class="n">data</span><span class="p">,</span> <span 
class="n">ioArgs</span><span class="p">)</span> <span class="p">{</span>
+   <span class="nb">eval</span><span class="p">(</span><span 
class="n">data</span><span class="p">);</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Then, we need to add a few things to states.php:</p>
+<p>to the $actions array:</p>
+<div class="codehilite"><pre><span class="nv">$actions</span><span 
class="p">[</span><span class="s">&#39;mode&#39;</span><span 
class="p">][</span><span class="s">&#39;AJexample&#39;</span><span 
class="p">]</span> <span class="o">=</span> <span 
class="s">&quot;exampleFunc2&quot;</span><span class="p">;</span>
+<span class="nv">$actions</span><span class="p">[</span><span 
class="s">&#39;pages&#39;</span><span class="p">][</span><span 
class="s">&#39;AJexample&#39;</span><span class="p">]</span> <span 
class="o">=</span> <span class="s">&quot;exampleSection&quot;</span><span 
class="p">;</span>
+</pre></div>
+
+
+<p>to the $noHTMLwrappers array:</p>
+<div class="codehilite"><pre><span class="s">&#39;AJexample&#39;</span>
+</pre></div>
+
+
+<p>Now, we need to create exampleFunc2 (in examples.php):</p>
+<div class="codehilite"><pre><span class="n">function</span> <span 
class="n">exampleFunc2</span><span class="p">()</span> <span class="p">{</span>
+   <span class="k">print</span> <span 
class="s">&quot;document.getElementById(&#39;examplediv&#39;).innerHTML = 
&#39;Dynamic update&#39;;&quot;</span><span class="p">;</span>
 <span class="p">}</span>
 </pre></div>
 
 
-<h2 id="using-a-new-theme">Using a new theme</h2>
-<p>Themes are assigned on a per-affiliation basis in the affiliation table. 
This must
-be done directly in the database by setting the 
<strong>affiliation.theme</strong> field for an 
-affiliation to the name of a theme in the themes directory. For example, to 
use our new 
-<em>minimal</em> theme, you would set <strong>affiliation.theme</strong> to 
<strong>minimal</strong> for the desired
-affiliation.</p>
-<h2 id="tips-and-tricks">Tips and Tricks</h2>
-<p>The VCL web site has some administrative pages that can generate very large 
tables. If
-you want them to be completely wrapped in your theme, you will probably need 
to use 
-tables as part of you main layout instead of just using div elements and css. 
(Hopefully,
-all of those large tables will be converted to dojo grids like the Manage 
Groups page by
-the 2.4 release.)</p>
-<p>Mobile themes - If you would like to use a modified theme for mobile 
devices, you can add
-a section of code to the top of getHeader and getFooter that detects mobile 
devices
-based on $_SERVER['HTTP_USER_AGENT']. If a mobile browser is detected, you can 
then
-call a different function that generates mobile specific HTML and returns it 
to the
-calling function.  Here is an example that could be used in getHeader:</p>
-<div class="codehilite"><pre><span class="k">if</span><span 
class="p">(</span><span class="n">array_key_exists</span><span 
class="p">(</span><span class="s">&#39;HTTP_USER_AGENT&#39;</span><span 
class="p">,</span> <span class="nv">$_SERVER</span><span class="p">)</span> 
<span class="o">&amp;&amp;</span>
-     <span class="p">(</span><span class="n">eregi</span><span 
class="p">(</span><span class="s">&#39;iphone&#39;</span><span 
class="p">,</span> <span class="nv">$_SERVER</span><span 
class="p">[</span><span class="s">&#39;HTTP_USER_AGENT&#39;</span><span 
class="p">])</span> <span class="o">||</span>
-     <span class="n">eregi</span><span class="p">(</span><span 
class="s">&#39;android&#39;</span><span class="p">,</span> <span 
class="nv">$_SERVER</span><span class="p">[</span><span 
class="s">&#39;HTTP_USER_AGENT&#39;</span><span class="p">])))</span>
-   <span class="k">return</span> <span class="n">mobileHeader</span><span 
class="p">(</span><span class="nv">$refresh</span><span class="p">);</span>
+<p>Then, we do something we haven't seen before.  getDojoHTML (in utils.php) 
must be modified so that the correct dojo requires get set when we are in mode 
examplefunc1.  For a simple AJAX update, we only need the dojo.parser module to 
be loaded.  Since this is already loaded for some of the Group modes, just add 
another case statement under submitDeleteGroup so we have:</p>
+<div class="codehilite"><pre><span class="k">case</span> <span 
class="s">&#39;viewGroups&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span 
class="s">&#39;submitEditGroup&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span 
class="s">&#39;submitAddGroup&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span 
class="s">&#39;submitDeleteGroup&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span class="s">&#39;examplemode&#39;</span><span 
class="p">:</span>
+   <span class="nv">$dojoRequires</span> <span class="o">=</span> <span 
class="n">array</span><span class="p">(</span><span 
class="s">&#39;dojo.parser&#39;</span><span class="p">);</span>
+   <span class="n">break</span><span class="p">;</span>
+</pre></div>
+
+
+<p>We also have to add a case statement a little further down where the HTML 
is actually generated. Find "case 'submitDeleteGroup':" in the switch statement 
following the one we just modified, and add another case statement for 
examplemode so we have:</p>
+<div class="codehilite"><pre><span class="k">case</span> <span 
class="s">&#39;viewGroups&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span 
class="s">&#39;submitEditGroup&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span 
class="s">&#39;submitAddGroup&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span 
class="s">&#39;submitDeleteGroup&#39;</span><span class="p">:</span>
+<span class="k">case</span> <span class="s">&#39;examplemode&#39;</span><span 
class="p">:</span>
+   <span class="nv">$rt</span> <span class="o">.=</span> <span 
class="s">&quot;&lt;style type=\&quot;text/css\&quot;&gt;\n&quot;</span><span 
class="p">;</span>
+</pre></div>
+
+
+<p>Since we modified code.js, to test this, you will need to hold Shift and 
click the reload button in your browser to force your browser to reload 
code.js.  "Click to update" will not show up as a normal link, but it should 
still be clickable.  You can use CSS to make it look like a normal link or give 
it an href="#"  if you want.</p>
+<h2 id="a-word-about-using-tabs-for-code-indentation">A word about using tabs 
for code indentation</h2>
+<p>All of the code has been indented using tabs (rather than spaces) except 
where code wraps to more than one line, in which case a combination of tabs and 
spaces are used.  This allows someone editing the code to set his tab width to 
whatever he prefers, but still allows code that wraps to multiple lines to line 
up correctly.  To do this, when you want to wrap code to another line, put a 
newline at the end of the one you are on just as you normally would.  Next, tab 
over from the beginning of the line until you are even with where the initial 
line of code started, then use spaces to line up this line with something in 
the line above it that makes sense.  I'll give an example.  Almost all of the 
queries are written on multiple lines like this:</p>
+<div class="codehilite"><pre><span 
class="o">=====------------------------------</span>
+     <span class="nv">$query</span> <span class="o">=</span> <span 
class="s">&quot;SELECT id, &quot;</span>
+            <span class="o">.</span>        <span class="s">&quot;name, 
&quot;</span>
+            <span class="o">.</span>        <span class="s">&quot;prettyname 
&quot;</span>
+            <span class="o">.</span> <span class="s">&quot;FROM image 
&quot;</span>
+            <span class="o">.</span> <span class="s">&quot;WHERE id &lt; 400 
AND &quot;</span>
+            <span class="o">.</span>       <span class="s">&quot;OSid = 
3&quot;</span><span class="p">;</span>
+<span class="o">=====------------------------------</span>
+</pre></div>
+
+
+<p>In this example, whitespace indicated by the = marks should be made of 
tabs, whitespace indicated by the - marks should be made of spaces.</p>
+<h2 id="inline-code-documentation">Inline Code Documentation</h2>
+<p>Online documentation of the code is generated using Doxygen.  Each file 
that should be parsed to generate docs needs to have the following toward the 
top of it:</p>
+<div class="codehilite"><pre><span class="o">/**</span>
+ <span class="o">*</span> <span class="o">\</span><span class="n">file</span>
+ <span class="o">*/</span>
+</pre></div>
+
+
+<p>All functions should have a header above them that documents what it does.  
The header should include the name of the function, a description of any 
parameters passed in, a description of anything returned, and a brief 
description of what the function does.  The format of the header is:</p>
+<div class="codehilite"><pre><span 
class="sr">////////////////////////////////////////////////////////////////////</span><span
 class="o">/</span>
+<span class="sr">//</span><span class="o">/</span>
+<span class="sr">//</span><span class="o">/</span> <span 
class="o">\</span><span class="n">fn</span> <span 
class="n">nameOfFunction</span><span class="p">(</span><span 
class="nv">$param1</span><span class="p">,</span> <span 
class="nv">$param2</span><span class="p">)</span>
+<span class="sr">//</span><span class="o">/</span>
+<span class="sr">//</span><span class="o">/</span> <span 
class="o">\</span><span class="n">param</span> <span class="nv">$param1</span> 
<span class="o">-</span> <span class="n">description</span> <span 
class="n">of</span> <span class="n">param1</span>
+<span class="sr">//</span><span class="o">/</span> <span 
class="o">\</span><span class="n">param</span> <span class="nv">$param2</span> 
<span class="o">-</span> <span class="n">description</span> <span 
class="n">of</span> <span class="n">param2</span>
+<span class="sr">//</span><span class="o">/</span>
+<span class="sr">//</span><span class="o">/</span> <span 
class="o">\</span><span class="k">return</span> <span 
class="n">description</span> <span class="n">of</span> <span 
class="n">datastructure</span> <span class="n">returned</span>
+<span class="sr">//</span><span class="o">/</span>
+<span class="sr">//</span><span class="o">/</span> <span 
class="o">\</span><span class="n">brief</span> <span class="n">short</span> 
<span class="n">description</span> <span class="n">of</span> <span 
class="n">what</span> <span class="n">the</span> <span 
class="n">function</span> <span class="n">does</span>
+<span class="sr">//</span><span class="o">/</span>
+<span 
class="sr">////////////////////////////////////////////////////////////////////</span><span
 class="o">/</span>
 </pre></div>
 
 
-<p>mobileHeader would still need to meet all of the requirements of getHeader, 
but it
-would just generate mobile specific HTML. A similar block of code would then 
be 
-added to getFooter, calling a function named something like mobileFooter.</p>
+<p>If the function doesn't receive any parameters or doesn't return anything, 
those sections can be omitted.</p>
+<h2 id="authentication">Authentication</h2>
+<p>Authentication has been somewhat modularized.  When a user loads the site, 
the initGlobals function checks to see if the user is logged in.  If not, the 
mode in which the site should function gets set to "selectauth".  Here, the 
user is prompted to select an authentication method to use to log in.  
Authentication methods are configured in $authMethods which is in conf.php.  
There are currently three authentication types that can be handled: redirect, 
ldap, and local.  Redirect types send the user to another site to handle their 
authentication, with the expectation that a cookie will be set and that 
knowledge of how to interpret that cookie is handled in initGlobals.  If an 
ldap or local method is chosen, the user is directed to a page displayed by 
printLoginPageWithSkin() (in authentication.php as are most of the following 
functions).  This function sets up the skin for the page to match the 
affiliation defined in $authMethods, and then calls printLoginPage().  
printLogin
 Page() displays a form for the user to enter a userid and password.  The form 
is submitted and then processed by submitLogin().  If the authentication method 
is ldap based, ldapLogin() is called; if it is the local system, localLogin() 
is called.  Each of these functions tries to validate the user.  If it 
succeeds, a cookie named VCLAUTH is set, and the user is redirected to the main 
page of the site.  If it fails, the user is redirected back to the login page. 
<em>If you enter valid credentials, but still get redirected back to the login 
page, the first thing to check is whether or not the setcookie() call was 
reached, and if so, was the cookie actually set in your browser.</em></p>
   </div>
   
   <div id="footer">


Reply via email to