summaryrefslogtreecommitdiff
path: root/modules/documentation.module
blob: ae20534963a3ed24696f6daf17adf6136837740e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<?

$module = array("page" => "documentation_page");

function documentation_page() {
  ?>
  <H1>Documentation</H1>
  <SMALL><I>$Id$</I></SMALL>
 
  <H2>Chapter 1: installation guide</H2>

  <H3>System requirements</H3>
  <P>We assume that you have some working experience with Apache, MySQL and PHP.  The installation of these required packages is beyond the scope of this document.</P>
  <PRE>
   MySQL  -  http://mysql.com/
             (development with version 3.22.32)

   PHP4   -  http://php.net/
             (development with version 4.0.0)
         
   Apache -  http://apache.org/
             (development with version 1.3.14)
  </PRE>

  <H3>Installation process</H3>

  <H3>More than one engines on one machine</H3>

  <P>Apache supports both IP- and name-based virtual hosts (vhosts).  While running more than one engine (by using vhosts) can be very useful for development and testing purpose, it might even be more interesting for hosting companies.  Therefore, we tried to support vhosts in the best possible way in order to make life of any administrator easier.  We do so by making it possible to run an unlimited amount of vhosts on the same physical source tree, though by using different configuration files.  Moreover, you can setup multiple configuration files in your <CODE>includes</CODE>-directory.</P>
  <PRE>
   [drop@localhost drop]$ ls -l includes/*.conf
   -rw-rw-r--    1 drop    drop        includes/www.yourdomain1.com.conf
   -rw-rw-r--    1 drop    drop        includes/www.yourdomain2.com.conf
  </PRE>
  <P>The only thing left to be done is to setup the corresponding vhosts in your Apache configuration file.  Note that the <CODE>DocumentRoot</CODE> points to the same source tree twice:</P>
  <PRE>
   NameVirtualHost 127.0.0.1

   &lt;VirtualHost 127.0.0.1&gt;
     DocumentRoot /home/www/drop
     ServerName www.yourdomain1.com
   &lt;/VirtualHost&gt;

   &lt;VirtualHost 127.0.0.1&gt;
     DocumentRoot /home/www/drop
     ServerName www.yourdomain2.com
   &lt;/VirtualHost&gt;
  </PRE>

  <H2>Chapter 2: technical guide</H2>

  <H3>Theme system</H3>
  
  <P>Drop's theme system is simple, elegant, flexible and powerful.  It let you control all aspect of your drop site in terms of colors, markup, layout and even the position of most boxes.  You can leave boxes out, move them from right to left, up and down until it fit your needs.  Therefore, drop uses a theme class that has a handful of functions. The drop.org engine dynamically loads the correct theme class, instantiates it and then calls these class' functions where approriate.</P>
  <P>Let's illustrate this with an easy example. Say, to generate the main page, the drop.org engine would use something like:</P>
  <PRE>
   $theme = new Theme(); 
   $theme->header();   
     // displays the header of a page
   for each $article to be displayed { 
      $theme->article($article); 
        // displays a themed article or story
   } 
   $theme->footer(); 
     // displays the footer of a page
  </PRE>
  <P>We have similar functions for thinkgs like comments (i.e. <CODE>$theme->comment($comment)</CODE>), generic boxes (i.e. <CODE>$theme->box($topic, $body)</CODE>) and so on.</P>
  <P>This simple and straight-forward approach has proven to be both flexible and fast.  If you want to learn more about the theme system, we recommand you to look athe code of the existing themes.  It is pretty straight-forward and doesn't require any knowledge about the engine itself.</P>

  <H3>Modules</H3>
    
  <P>When developing drop.org it became clear that we wanted to have a system which is as modular as possible. A modular design will provide flexibility, adaptability, and continuity which in turn allows people to customize the site to their needs and likings.</P>
  <P>A drop module is simply a file containing a set of routines written in PHP.  When used, the module code executes entirely within the context of the site.  Hence it can use all the functions and access all variables and structures of the main engine.  In fact, a module is not any different from any other PHP file: it is more of a notion that automatically leads to good design principles and a good development model. Modularity better suits the open-source development model, because otherwise you can't easily have people working in parallel without risk of interference.</P>

  <P>The idea is to be able to run random code at given places in the engine.  This random code should then be able to do whatever needed to enhance the functionality.  The places where code can be executed are called "hooks" and are defined by a fixed interface.</P>
  <P>Even though we aim towards modularity, a basic rule is to avoid defined interfaces.  We are exceptionally careful when it comes down to adding interfaces because once you give an interface to developers they will start coding to it and once somebody starts coding to it you are stuck with it.</P>
  <P>In places where hooks are made available, the engine calls each module's exported functions.  This is done by iterating through the <CODE>modules</CODE> directory where all modules must reside.  Say your module is named <CODE>foo</CODE> (i.e. <CODE>./modules/foo.module</CODE>) and if there was a hook called <CODE>bar</CODE>, the engine will call <CODE>foo_bar()</CODE> if this was exported by your module.</P>
  <P>Each module has to declare an associative array named <CODE>$module</CODE> that serves as the list of hooks that a module wants to export or carry out.  Each entry in the array contains the name of a hook followed by the name of the exported function.</P>
  <P>In our above example, our associative array <CODE>$module</CODE> would look like:</P>
  <PRE>
    $module = array("bar" => "foo_bar");
  </PRE>
  
  <TABLE BORDER="1">
   <TR>
    <TH>Hook name</TH>
    <TH>Hook description</TH>
   </TR>
   <TR>
    <TD VALIGN="top"><CODE>page</CODE></TD>
    <TD VALIGN="top">If a module requires it's own page it should provide a function named <CODE>module_page</CODE>.  The page can then be publicly accessed via <CODE>http://www.yourdomain.com/module.php?mod=module</CODE> which will cause the engine to invoke <CODE>module_page</CODE> in order to generate the module's page.</TD>
   </TR>
   <TR>
    <TD VALIGN="top"><CODE>cron</CODE></TD>
    <TD VALIGN="top">Modules that require to schedule some commands to be executed on regular intervals can implement the <CODE>cron</CODE> interface: the engine will then call <CODE>module_cron</CODE> at the appropriate intervals defined by the administrator.  This interface is particulary handy to implement timers or to automate certain tasks like for instance database maintainance, recalculation of settings or parameters, automatic mailings and so on.</TD>
   </TR>
   <TR>
    <TD VALIGN="top"><CODE>admin</CODE></TD>
    <TD VALIGN="top">If a module requires a spot in the administrator section it should implement <CODE>module_admin</CODE>.  The engine will automatically add a link to the administration menus and will call <CODE>module_admin</CODE> when this link is followed.  In order to make virtually any module maintainer's life easier, you don't have to worry about access rights or permissions for that matter.  The engine will only allow priveleged users to call exported <CODE>admin</CODE> functions.</TD>
   </TR>
   <TR>
    <TD VALIGN="top"><CODE>export</CODE></TD>
    <TD VALIGN="top">... All you have to do is examine the string and figure out where you're at.</TD>
   </TR>
   <TR>
    <TD VALIGN="top"></TD>
    <TD VALIGN="top"></TD>
   </TR>
   <TR>
    <TD VALIGN="top"></TD>
    <TD VALIGN="top"></TD>
   </TR>
   <TR>
    <TD VALIGN="top"></TD>
    <TD VALIGN="top"></TD>
   </TR>
  </TABLE>

  <H3>Droplets</H3>

  <P>The site can be almost entirely configured through a web interface by using <I>droplets</I>.  Simply put, droplets are small bit of PHP code which will get plugged into the engine or modules powering the site.  Droplets are typically used to link modules with the mainstream engine or to customize various aspects of the engine itself.</P>
  <P>If you know how to script in PHP, droplets are pretty simple to create.  Don't get your panties in a knot if you are not confident with PHP: simply use the standard droplets (i.e. those available by default) as they are just fine or ask an expert dropletber to help you creating custom droplets that fit your need.</P>
  <P>Each droplet consists of a key of maximum 255 characters and an associated block of PHP code which can be as long as you want it to be.  You can use any piece of PHP code to make up a droplet.  A droplet's code is stored in the database and the engine or a particular module will use the key to find the associated piece of PHP code which will then be dynamically embedded in the engine or the module just-in-time for execution.</P>
  <P>There are however some factors to keep in mind when using and creating droplets: droplets can be extremly useful and flexible, yet be dangerous and insecure if not properly used.  If you are not confident with PHP, SQL or even with the site engine for that matter, avoid experimenting with droplets because you can - and you probably will - corrupt your database or even break your site!</P>
  <P>Remember that the code within each droplet must be valid PHP code, including things like terminating statements with a semicolon so the parser won't die.  Therefore, it is highly recommended to test your droplets seperatly using a simple test script on top of a test database before migrating to your production environment running your real database.</P>
  <P>Note that you can use any global variables, such as configuration parameters within the scope of a droplet and keep in mind that variables that have been given values in a droplet will retain these values in the engine or module afterwards.</P>
  <P>You may as well use the <CODE>return</CODE> statement to return a value back to the engine.</P>
  <P><U>A basic example:</U></P>
  <P>Given the droplet with key <CODE>sumbit_information</CODE>, used in <CODE>submit.php</CODE> to retrieve and display submission guidelines at the top of the story submission page.  A simple code block for this droplet could look like this:</P>
  <PRE>
   return "Welcome visitor, ... sumbission guidelines go here ...";
  </PRE>
  <P>If we are however dealing with a registered user, we can customize the message by using:
  <PRE>
   if ($user) {
     return "Welcome $user->userid, ... submission guidelines go here ...";
   }
   else {
     return "Welcome visitor, ... sumbission guidelines go here ...";
   }
  </PRE>
  <P>For more in depth example, we recommand you to check any of the available modules and to go from there.</P>
  <P>As said above, you can virtually use any piece of PHP code in a droplet: you can declare and use functions, consult the SQL database, access configuration settings and so on.</P>

  <H3>Database abstraction</H3>

  <P>Drop uses a database abstraction layer so I can easily run on top of different databases like MySQL, Oracle, Postgres and so on.  However, the only supported database is MySQL for the time being.  In fact, we haven't even bothered or tried to migrate to another database so our database abstraction layer might even contain undiscovered flaws.  Nevertless, moving to another database shouldn't be much of a problem.</P>
  <P>Take a look at <CODE>includes/database.inc</CODE> to see what database functions are supported.</P>
  
  <H3>Cron</H3>
 
  <P>Cron (wich stands for chronograph) is a periodic command scheduler: it executes commands at intervals specified in seconds.  It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period of n seconds).   Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution.</P>
  <P>Note that cron does not guarantee that the commands will be executed at the specified interval.  However, the engine will make sure that the commands are run at the specified intervals as closely as possible.</P>
  <P>Whenever <CODE>http://www.yourdomain.com/cron.php</CODE> is accessed, cron will run: it queries the database for the jobs cron controls, and their periods in seconds.  If a certain task wasn't executed in the last n seconds, where n is the period of that job, it will be executed.  It then records the date in the database so it can know when to run it again.  When all the executed commands terminate, cron is done.</P>
  <P>Cron is handy to run daily, weekly and monthly tasks that take care of various "housekeeping chores" such as database maintainance, recalculating settings, periodic mailings, scheduled backups and so on.</P>

  <P>The recommanded way to setup drop.org's cron system is to setup a  Unix/Linux <CODE>crontab</CODE> that frequently visits <CODE>http://www.yourdomain.com/cron.php</CODE>: the more you visit <CODE>cron.php</CODE>, the more accurate cron can and will be.  If your hosting company does not allow you to setup <CODE>crontabs</CODE>, you can always ask someone else to setup a <CODE>crontab</CODE> for you.  Afterall, virtually any host machine with access to the internet can setup a <CODE>crontab</CODE> to frequently visit <CODE>http://www.yourdomain.com/cron.php</CODE> for you.<P>
  <P>For the <CODE>crontab</CODE> itself, use a browser like <CODE>lynx</CODE> or <CODE>wget</CODE> but make sure the process terminates: either use <CODE>/usr/bin/lynx -source http://www.yourdomain.com/cron.php</CODE> or <CODE>/usr/bin/wget -O /dev/null http://www.yourdomain.com/cron.php</CODE>.  Take a look at the example scripts in the <CODE>scripts</CODE>-directory and make sure to adjust them to your needs.</P>
  <P>A good <CODE>crontab</CODE>-line to run the <CODE>cron</CODE>-script once every hour would be:</P>
  <PRE>
    00 * * * * /home/www/drop/scripts/cron-lynx
  </PRE>

 <?
 }
?>