All Roads Lead to index.php
In order for our bootstrap to work, and for the Front Controller to get all the information it needs, I first have to ensure that all the traffic to the application is routed through a single place: in this case, index.php. That "forced routing" is handled by the mod_rewrite extension to Apache. The mechanism I have chosen to handle this is to create httpd.conf files at the root level of each application folder.
Listing: httpd.conf
<Directory /Users/markf/Sites/dblog/>
RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
</Directory>
The redirect rule is a fairly simple one, and it essentially tells Apache to route every request for a file (that does not end in .js, .ico, etc.) to index.php. In order for this to work, Apache has to know about this file, so I reference this configuration file at the very end of Apache's main configuration file.
One way to more efficiently and securely manage a web application is to take advantage of the Front Controller design pattern. This pattern calls for a single object to route web traffic: for the developerBlog (and other applications I build with the IWFrameworks), this means there must be an entry point for the application (often termed the bootstrap) and the Front Controller object to which it defers control.
End of Listing: /usr/local/apache2/conf/httpd.conf
## Appendix: Directory-specific Directives Include /Users/markf/Sites/dblog/httpd.conf
Bootstrapping
The bootstrap for an IWFrameworks-based application consists of a few include files and instantiation of an ApplicationRunner object, which acts as the front controller.
Bootstrap Components:
- Application Constants:This file includes application database and filepath information.
- ApplicationDelegate: In addition to acting as an autoloader for application classes, this object also handles requests that apply to the entire web application.
- ApplicationRunner: This object identifies the page request and acts on it, with a little help from the ApplicationDelegate.
Listing: /index.php
<?php
require 'rsrc/conf/ApplicationConstants.php';
require 'rsrc/ApplicationDelegate.php';
ini_set('session.cookie_path', APPL_ROOT_DIR);
require FRAMEWORK_DIR . 'ApplicationRunner.php';
$app = new ApplicationRunner;
$app->go();
?>
Front Controller
ApplicationRunner uses the page information to deduce the module that should be displayed, and then instantiates the workflow that will manage the module. That workflow can be one of many different types (including unique ones defined in the application itself, if desired) and it acts as a mediator between the view and its associated model object.
With the developerBlog postrgesql database now restored to the active development server, the website application project can be created.
markf$ cd ~/Sites/fw/install markf$ ./app_install -n developerBlog -w /Users/markf/Sites -a dblog -d pgsql:dblog@localhost:markf:mypassword
Initializing Application... initialize() complete... setApplicationPath() complete... setApplicationName() complete... setFrameworkDirectory() complete... setDatabase() complete... Creating application directories... createDirectory() complete... Creating Apache configuration file... createApacheConfigurationFile() complete... Creating application constants file... createApplicationConstantsFile() complete... Creating front controller... createFrontController() complete... Creating ApplicationDelegate class... createApplicationDelegate() complete... Creating ApplicationSecurityDelegate class... createApplicationSecurityDelegate() complete... Creating Application home page... createApplicationHomePage() complete... Installation Successful!
markf$ ls -R ~/Sites/dblog
dblog
httpd.conf
img/
index.php
lib/
rsrc/
ApplicationDelegate.php
ApplicationSecurityDelegate.php
conf/
Home.php
page/
DefaultPage.php
html/
index.html
log/
All roads lead to index.php
httpd.conf takes advantage of mod_rewrite to redirect page requests to index.php, the application bootstrap that implements the Front Controller design pattern.
Listing: /dblog/httpd.conf
<Directory /Users/markf/Sites/dblog>
RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
</Directory>
The redirect rule is a fairly simple one: it tells Apache to route every request for a file (that does not end in .js, .ico, etc.) to index.php. In order for this developerBlog configuration to be active, the following directive needs to be added to /opt/local/apache2/conf/httpd.conf, the main Apache configuration file.
End of Listing: /opt/local/apache2/conf/httpd.conf
## Appendix: Directory-specific Directives Include /Users/markf/Sites/dblog/httpd.conf
Naturally, apache must be restarted for this change to take effect.
markf$ sudo /opt/local/apache/bin/apachectl restart
Obviously, in a different server environment, access to the main configuration file may not be possible. When I deploy the developerBlog, I will show the changes necessary to make it work in such circumstances.
Next up is the web server. Apache 2 comes pre-installed on Leopard systems, but I want all my open source projects to work alongside one another.
Apache 2 Install
One (perhaps unexpected) dependency for Apache 2 is SQLite 3. Though this normally makes no difference to MacPorts -- dependencies are installed as needed. However, if you simply attempt the Apache 2 installation, it fails (or, at least, I had fatal errors related to SQLite 3).
markf$ sudo port install sqlite3 markf$ sudo port install apache2 markf$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist
The last command ensures that Apache 2 will launch at startup.
Apache Configuration
With Apache 2 installed, my next task is to configure it. To create an initial configuration file, I copy a sample distributed with the MacPorts Apache 2 installation.
markf$ sudo cp /opt/local/apache2/conf/httpd.conf.sample
/opt/local/apache2/conf/httpd.conf
Since one version of Apache 2 already runs courtesy of Leopard, I need to make some modifications to the configuration file for the MacPorts installation. In particular, this version will operate on port 8080 instead of the standard port 80.
markf$ sudo vi /opt/local/apache2/conf/httpd.conf
I made the following changes to /opt/local/apache2/conf/httpd.conf.
Listen *:8080
NameVirtualHost *:8080
ServerAdmin markf@istarelworkshop.com
ServerName 127.0.0.1
<Directory "/Users/markf/Sites">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
# At very bottom of httpd.conf
Include /Users/markf/Sites/httpd.conf
DocumentRoot
I use the /Users/markf/Sites/httpd.conf configuration file to set the DocumentRoot and other key attributes.
Listing: /Users/markf/Sites/httpd.conf
<VirtualHost *:8080>
ServerName dev.minethlos.com
DocumentRoot /Users/markf/Sites/
AcceptPathInfo On
UseCanonicalName Off
DirectoryIndex index.php index.html
<Directory /Users/markf/Sites/>
Allow from All
</Directory>
</VirtualHost>
With Apache2 and PostgreSQL installed, I am now ready to complete the initial setup with PHP 5.
