vcl-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r845747 - in /websites/staging/vcl/trunk/content: ./ confluence_export/web-code-overview.html dev/web-code-overview.html
Date Wed, 09 Jan 2013 15:34:16 GMT
Author: buildbot
Date: Wed Jan  9 15:34:16 2013
New Revision: 845747

Staging update by buildbot for vcl

    websites/staging/vcl/trunk/content/   (props changed)

Propchange: websites/staging/vcl/trunk/content/
--- cms:source-revision (original)
+++ cms:source-revision Wed Jan  9 15:34:16 2013
@@ -1 +1 @@

Added: websites/staging/vcl/trunk/content/dev/web-code-overview.html
--- websites/staging/vcl/trunk/content/dev/web-code-overview.html (added)
+++ websites/staging/vcl/trunk/content/dev/web-code-overview.html Wed Jan  9 15:34:16 2013
@@ -0,0 +1,323 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+ 2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+  <link href="/css/vcl.css" rel="stylesheet" type="text/css">
+  <link href="/css/code.css" rel="stylesheet" type="text/css">
+  <title>Apache VCL - Web Code Overview</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  <div id="sitetitle">
+    <table width="100%" border="0" cellspacing="0" cellpadding="5">
+      <tr>
+         <td><a href="/index.html"><img src="/img/vcl-logo.png" height="100"
align="left" alt="Apache VCL logo"></a></td>
+         <td><a href=""><img src="/img/asf-logo.png"
align="right" alt="Apache Software Foundation logo"></a></td>
+      </tr>
+    </table>
+  </div>
+  <div id="navigation"> 
+  <ul>
+<li><a href="/info/about.html">What is VCL?</a></li>
+<li><a href="/info/features.html">Features</a></li>
+<li><a href="/info/architecture.html">Architecture</a></li>
+<li><a href="/info/use-cases.html">Use Cases</a></li>
+<li><a href="/downloads/download.cgi">Download</a></li>
+<li><a href="">License</a></li>
+<li><a href="/info/faq.html">FAQ</a></li>
+<li><a href="/docs/index.html">Documentation</a><ul>
+<li><a href="/docs/using-vcl.html">Using VCL</a></li>
+<li><a href="/docs/image-creation.html">Image Creation</a></li>
+<li><a href="/docs/administration.html">Administration</a></li>
+<li><a href="/docs/installation.html">Installation</a></li>
+<li><a href="/docs/deployment-planning.html">Deployment Planning</a></li>
+<li><a href="/comm/index.html">Community</a><ul>
+<li><a href="/comm/index.html#getInvolved">Getting Involved</a></li>
+<li><a href="/comm/index.html#mail-list">Mailing Lists</a></li>
+<li><a href="/comm/index.html#how-do-i-join-the-project">How can I Join</a></li>
+<li><a href="/comm/wiki.html">Wiki</a></li>
+<li><a href="/dev/index.html">Development</a><ul>
+<li><a href="/dev/jira.html">Issue Tracking</a></li>
+<li><a href="/dev/code-documentation.html">Code Documentation</a></li>
+<li><a href="/dev/roadmap.html">Roadmap</a></li>
+<li><a href="">Apache Software Foundation</a><ul>
+<li><a href="">Thanks</a></li>
+<li><a href="">Become a Sponsor</a></li>
+  </div>
+  <div id="content">
+    <h1 class="title">Web Code Overview</h1>
+    <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>
+<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
+<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>
+<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
+<li>$repeatProtect - boolean - used in cases where a "sequence loop" can occur</li>
+<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="">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>
+<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
+<p>So, if your mode is named "examplemode", you could end up with these two lines being
+<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
+<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
+<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>
+<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>
+<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
+<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;;
+<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
+print &quot;Select one of these options:&quot;;
+printSelectInput(&quot;theoption&quot;, <span class="p">$</span><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
+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
+print &quot;<span class="nt">&lt;/FORM&gt;</span>\n&quot;;
+<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
+<span class="p">}</span>
+<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
+<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
+<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
+<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;;
+<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
+      <span class="n">url:</span><span class="s">&#39;index.php&#39;</span><span
+      <span class="n">load:</span> <span class="n">JS_AJexampleCB</span><span
+      <span class="n">error:</span> <span class="n">errorHandler</span><span
+      <span class="n">content:</span> <span class="p">{</span><span
class="n">continuation:</span> <span class="n">contid</span><span
+      <span class="n">timeout:</span> <span class="mi">15000</span>
+   <span class="p">});</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
+<span class="p">}</span>
+<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
+<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
+<p>to the $noHTMLwrappers array:</p>
+<div class="codehilite"><pre><span class="s">&#39;AJexample&#39;</span>
+<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>
+<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
+<span class="k">case</span> <span class="s">&#39;submitAddGroup&#39;</span><span
+<span class="k">case</span> <span class="s">&#39;submitDeleteGroup&#39;</span><span
+<span class="k">case</span> <span class="s">&#39;examplemode&#39;</span><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
+   <span class="n">break</span><span class="p">;</span>
+<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
+<span class="k">case</span> <span class="s">&#39;submitAddGroup&#39;</span><span
+<span class="k">case</span> <span class="s">&#39;submitDeleteGroup&#39;</span><span
+<span class="k">case</span> <span class="s">&#39;examplemode&#39;</span><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
+<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
+<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,
+            <span class="o">.</span>        <span class="s">&quot;prettyname
+            <span class="o">.</span> <span class="s">&quot;FROM image
+            <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>
+<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>
+<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
+<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
+<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
+<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
+<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
+<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">
+    <div class="copyright">
+      <p>
+        Copyright &copy; 2012 The Apache Software Foundation, Licensed under 
+        the <a href="">Apache License, Version
+        <br />
+        Apache and the Apache feather logo are trademarks of The Apache Software Foundation.
+      </p>
+    </div>
+  </div>

View raw message