lime icon

Phosphorus and Lime

A Developer's Broadsheet

This blog has been deprecated. Please visit my new blog at klenwell.com/press.
Deep Web
My curiosity about IPv6 led me to meander from its Wikipedia entry over to this entry on the Dark Web:

http://en.wikipedia.org/wiki/Deep_web

This was something of more practical interest to me back in graduate school, where I would often search in vain for more or less obscure academic articles online in the hope I could save myself a trip to the library. There were a few closed databases like JSTOR that I gravitated towards as a student in the humanities.

Now, outside the academy, I still long at times for the unfettered access to such databases enrollment at a major university with a well-funded, major research library provided.

The wikipedia article mentions a few services which claim to index the dark web. Tried goshme.com. Looks potentially useful, or at least novel. I'll have to try it again when I have something darker to look for.
Project: The Law Offices of Nigel Burns
Did the following site as a favor to my sister for one of her friends:

http://burnsattorneys.com/

I warned her to warn her friends that I had to keep it simple. Some of the reference law office sites were rather bloated. (I told my sister to check out Prada's website before looking at my design.)

I was pleased with the result (it was a little bit more work than it might look at first glance.) More surprisingly, so were they.
PHP: Page Framework
Since shortly after I started seriously scripting in PHP -- nearly 18 months ago now -- I began to put together my own framework. It started rather unsystematically as a function of necessity but soon became more formalized and structure. It had three main goals:

1. Be reusable
2. Be portable
3. Be versatile but not too bloated

A fourth goal might be: be as intuitive and as neatly formatted as possible.

The biggest challenge was figuring out how to automatically set root paths so that changing the level of the root project directory between servers would not break assocations with include files.

About 3 months ago, I arrived at something that I feel meets the goals above. It's a continual work in project, but it's stable (I can make changes and additions without having to refactor major parts of my library) and it works. It's still a bit idiosyncratic, but more intuitive I suspect than a lot of the more complex frameworks out there, and I continue to work at making it more elegant.

The one glaring problem I still face, however, is developing a clean, logical framework for individual pages. The ideal framework, I suppose, would load template from one master controller index.php file. I don't want that. But I want to organize my scripted web page files around a limited number of functions: most fundamentally, input pages (forms) and output pages (views -- like a search results page.)

I've been giving a lot of thought to the issue of page frameworks recently and I finally came up with something this week that satisfies the goals above and I hope won't need to be significantly revised in the future. It's designed to work with my more general site/project framework, but the underlying concept I believe is broadly applicable.

Here are the major components -- they could also be called modules, or simply sections -- of my framework. These are fundamental things that I figure every dynamic web page requires:


// *** File Overview (Documentation)

// *** Driver (Core Path Declaration and Includes)

// *** Variable Declarations
/* PHP is loose with this but I try to be as exact as possible) */

// *** Access Module
/* What data must be provided (e.g. authentication data) for page to be processed */

// *** Event Module
/* This consists of two parts -- a controller section and a case section. The controller section set boolean trigger variables ($_TRIGGER['event'] = TRUE;) based on the data submitted to the page (by say a user form or a referring page). The case section is then a series of short routines or includes that are wrapped in IF statements conditioned by whether the trigger is TRUE or FALSE. These IF blocks will generally flip another boolean flag -- a show flag ($_SHOW['panel'] = TRUE;) that dictates in the next section what heredocs get displayed in the page. */

// *** Output Module
/* A series of heredocs -- really subtemplates -- that get set according to their show flag. They're termed panels and make up an array: $_PANEL['heredoc'] = <<<HEREDOC... These should all be declared as empty strings above. */

// *** Template
/* The basic page template. Where the heredocs are echoed. */

// *** Postscript
/* Where other scripts (like a database update or an email dispatch) can be run in the background after the (buffered) template has been flushed. */


I'll post my actual template sometime in the future after doing a little more real-world refinement on it.
PEAR: templates and renderers
PEAR Flexy documentation

Trying to figure out how to use renderer with PEAR QuickForm class. Hard to believe that this is supposed to make development simpler or more efficient than patching together your own pages just using PHP and HTML. But I figure it's a lesson in PHP classes if nothing else.

Focusing on Flexy, which is described as follows

the long term aim of Flexy is to provide a universal Template Base API for Compiling and native PHP type templates


Basic routine

# create template (separate file)

# include class (e.g. HTML/QuickForm/Renderer/Object.php)

# instantiate renderer class
$Renderer =& new HTML_QuickForm_Renderer_Object(TRUE);

# assign classes to elements
$_CSS['CLASS'] = array
(
'text' => 'text',
'textarea' => 'textarea',
);

$Renderer->setElementStyle($_CSS['CLASS']);

# give renderer to form class
$Qform->accept($Renderer);

# instantiate template class

# configure options (as static)
$TPL_OPTIONS = &PEAR::getStaticProperty('HTML_Template_Flexy','TPL_OPTIONS');
$TPL_OPTIONS = array
(
'templateDir' => './templates',
'compileDir' => './templates/build',
'debug' => 0
);

# instantiate class
$Template =& new HTML_Template_Flexy($TPL_OPTIONS);

# instantiate "Convenience class for the form object passed to outputObject()" (demo comments)
# I don't fully comprehend the function of this step yet
$View = new StdClass; # generic class
$View->form = $Renderer->toObject(); # returns convenience class as object

# compile
$Template ->compile('flexy-dynamic.html');

# display
$Template ->outputObject($View);


As noted in comments above, I still don't fully understand the logic of the generic $View class. I can follow the processing but don't see why, after compiling the template, you wouldn't use some method like $Template->outputHTML() to display the template. Also, I'm a little confused as to why the entire object $View is passed to outputObject() and not $View->form, the variable to which the result of $Renderer->toObject() was assigned.

I did find this page with a little more info on Renderers. It notes:

Renderers are plugins that can transform the form that you have defined into any format supported.


So to conclude, this examples involves three different objects:

1. Renderer (accepted by QuickForm object $Qform)
$Renderer =& new HTML_QuickForm_Renderer_Object(TRUE);

2. Template (which compiles template and outputs outputs form)
$Template =& new HTML_Template_Flexy($TPL_OPTIONS);

3. Viewer (which represents Renderer as object)
$View = new StdClass;
$View->form = $Renderer->toObject();

I've not gotten into the template itself yet ('flexy-dynamic.html'). Tomorrow perhaps.
PEAR: QuickForm
PEAR documentation

I have a form system that works pretty well. Once I refactored it, it would be quite cogent. But if I'm going to master PEAR, I figure I better learn QuickForm. And it should help me refactor my form system.

Setting up QuickForm is not too complicated -- it's rendering it that gets messy. More on that later.

Basic routine for using QuickForm

# set form field default values

# instantiate class (create form)

# set defaults

# add elements

# add submit button

# add rules

# add filters

# validate and freeze


Example

# set form field default values
$QFORM['defaults'] = array
(
'textfield' => 'default value',
'textarea' => 'default text',
);

# instantiate class
$OBJ['QFORM'] = new HTML_QuickForm('form_name', 'post');

# set defaults
$OBJ['QFORM']->setDefaults(QFORM['defaults']);

# add elements
$OBJ['QFORM']->addElement('text', 'textfield', 'Textfield Label');
$OBJ['QFORM']->addElement('textarea', 'textarea', 'Textarea Label');

# add submit button
$OBJ['QFORM']->addElement('submit', 'submit_post', 'post label');

# add rules
$OBJ['QFORM']->addRule('text', 'rule failed prompt', 'required');

# add filters
$OBJ['QFORM']->addFilter('text', 'trim');

# validate the form
if ($OBJ['QFORM']->validate())
{
$OBJ['QFORM']->freeze();
}


That's the gist. Now how to display?
PHP Objects
One of my new year's resolutions is to stop reinventing wheels and start using PEAR. PEAR of course requires some familiarity classes. I did a little work with object-oriented programming when I was playing with Java a few years ago but haven't done much with it since then. That was enough to finally get my mind wrapped around the concept.

What I've been looking for to get started is simply a crib sheet for PHP object syntax. Finally found it here:

Classes and Objects (PHP 5) : The Basics
(php.net)

This animated gif (linked in the comments) is really helpful in comprehending the difference between instances, variables, and references:

http://www.prism.gatech.edu/~gtg624r/Code_Explenation.gif
source: http://www.prism.gatech.edu/~gtg624r/Code_Explenation.gif
PHP: MySQL statements in heredocs
Detailed my problem on Usenet/Google Groups/GUBA:

http://groups.google.com/group/comp.lang.php...


The only response I got wasn't much help so I went out and found the answer myself.

It's right here:

http://www.php.net/manual/en/function.mysql-query.php#37870

The problem: like me, the PHP mysql_query() function can only handle 1 statement at a time. The manual isn't quite explicit on the point, but does note:

The query string should not end with a semicolon.


Kudos to Predrag Supurovic. I cleaned up his batch function slightly:

/* fx mysql_query_batch
source: http://www.php.net/manual/en/function.mysql-query.php#31381
*************************************************/
function mysql_query_batch($query, $as_transaction=TRUE)
{
// *** DATA

# internal
$_SPLIT = array();

# return
$query_result = 0;


// *** MANIPULATE

# transaction-safe query
if ( $as_transaction )
{
$query = 'START TRANSACTION;' . $query . '; COMMIT;';
}

# split query
$_SPLIT = preg_split("/[;]+/", $query);

# process statements one-by-one
foreach ( $_SPLIT as $_statement )
{
$_statement = trim($_statement);

if ( !empty($_statement) )
{
# try query
$query_result = mysql_query($_statement);

# catch
if ( !$query_result )
{
trigger_error('MySQL error number '.mysql_errno().': '.mysql_error());
break;
}
}
}


// *** RETURN

return $query_result;

} # end Fx
/*______________________________________________*/


Plugged it in. So far, so good.

keywords: PHP, MySQL, heredoc, sql, multiple statements, batch, syntax, error
PHP: function template
Somewhat obvious but very useful. I call it the DMR model. Nothing complicated but it's helped organize my coding quite a bit. I re-use this template a lot so I'm putting it up here for easier access:

/* fx
*************************************************/
function NAME()
{
// *** DATA

// *** MANIPULATE

// *** RETURN

} # end Fx
/*______________________________________________*/


keywords: PHP, function, template, DMR
PHP: extension_loaded()
Just discovered this function:

// check for ssl
if ( extension_loaded("openssl") )
{
# do something (e.g. PEAR HTTP)
}
else
{
# issue notice or something
}


Simple, obvious, useful
HTTP: Deconstructing Xanga Posts
Anatomy of a Xanga Post:

__EVENTTARGET=
&__EVENTARGUMENT=
&__VIEWSTATE=dDw...
&txtTitle=Title+Goes+Here
&xformatblock=removeFormat
&xfontsize=removeFormat
&txtProfImageName=
&proftitle1=
&proftitle2=
&proftitle3=
&xztitle1=
&xztitle2=
&xzasin1=
&radAccess=1
&chkComments=on
&btnSubmit=Submit
&txtUserId=12345678
&xbgcolor=
&txtAcc=0
&xbordercolor=
&xcontent=The+body+goes+here.%3Cbr%3E
&xcopypost=0
&xmsgs=-1


"txtTitle=Title+Goes+Here"
should be of interest to the developers of crosspost.
OSS: dyne:bolic
Came across a link to this morning in an article from The Independent linked on Slashdot. It sounds like another Linux live CD with emphasis on multimedia software. If so, it appears the developers are downplaying the Linux aspect of it and offering it rather as a multimedia suite. Or am I missing something?
Definitive Book of Color Tags
An x16 tag:
x16 #1e2c6a
(quartertilmidnightblue)
Linux: Ubuntu Arrives
Finally! I'd complain that it took too long, but then I see it was sent from the Isle of Man! In the process of loading it on an old machine. Trying to partition the hard-drive, but I confess I didn't do much research about it. We'll see how it turns out.

In any event, a good idea well executed.

ubuntu linux website
PHP: alphanum regex
This should be instinct by now:

$_REGEX['alphanum'] = '%[^A-Za-z0-9]*%';


As used to remove all non-alphanumeric characters:

$_STRING['alphanum_only'] = preg_match($_REGEX['alphanum'], '', $string);


keywords: PHP, regex, alphanumeric, alphanum
The Definitive Book of Colors
Just finished the banner for the DBC, for which I'm an editor:



The blog actually inspired by a collection of poetry I've been sitting on for a few years now. But Iris has an interesting idea with which to conflate it. We'll be announcing details soon.

The artwork in the banner is a detail from a painting by Matisse, Le bonheur de vivre. A copy of the full painting can be found at the Web Museum.
OSS: Icons
I've been looking for a reliable set of open source icons for a while now. I suppose I could pull some from an open source project, but I'd prefer to just find a set that was explicitly designed for widespread reuse.

I just discovered this site:

http://www.kde-look.org/

A portal that seems to include a lot of open source icons.
Arbitrary Rule for Development of GUIs for Web-Based Applications #1
Include a notice/prompt field somewhere on every page, even if it is empty and currently has no use.