Paul M. Jones

Don't listen to the crowd, they say "jump."

Savant2 version 2.4.1

This is a minor bugfix release (I was using func_get_args() as a function parameter in one place). Also, I've added a new method "eprint()" as an alternative to "_()" for escaping and printing. You can see the change notes and the download and installation pages for more information.


Interview Errata

I wrote previously that Marcus Whitney had interviewed me for Pro-PHP podcast; well, it is online at last! :-) Thanks again, Marcus, for the opportunity, and don't worry about that high-pitched whine -- I guess that from me talking so fast the whole time (I had no idea I did so). It was a great experience for me. :-)

I misspoke a couple of times, and I want to correct those statements here, as well as provide links to some people, projects, and sources I mentioned.

Regarding the PEAR proposal for Savant, I said it ended up at -3; in fact, it ended at +2 (but needed a +5). You can read many of the comments here, but there are a lot more in the PEAR-DEV mailing list archives in several different threads.

I mentioned Matthew Weier O'Phinney near the end, around the discussion of Solar collaboration; he runs the PHP-based Cgiapp project. Also regarding Solar, I failed to mention Clay Loveless, who has provided hosting, services, and moral support for Solar.

I think that's it; if anyone else notices inaccuracies, or just has questions in general, leave them in the comments here or at Pro-PHP and I'll do my best to answer them. :-)



Solar 0.7.0-devel released

After too-long a hiatus, I've released Solar 0.7.0; you can get it from our PEAR channel server here. (Solar is a simple object library and application repository for PHP5; it is similar to PEAR and Horde, and might be described as a library-like framework for MVC development.)

The interim was filled with lots of improvements, not the least of which are some new classes and fixes from Matthew Weier O'Phinney. His work on the forms portions has been helpful and enlightening; I think we may now have a true MVC contender against HTML_QuickForm when combined with the improved form plugin for Savant3.

The change notes are quite long; you can read them below.

* WARNING: This is a public development release, and is not yet stable.

* Added new class, Solar_Filter, to filter data.  This is a companion to
Solar_Valid and is currently used mostly for prefiltering submitted form
values.  Thanks, Matthew Weier O'Phinney.

* Added new class, Solar_Form_Loader, to allow loading of form elements
from external sources.  Currently has only one method, fromXml(), to load
elements from a SimpleXML file.  Thanks, Matthew Weier O'Phinney.

* Solar:

  * New protected method environment() performs some standardized
  environment setup at Solar::start() time.  Solar now
  automatically...

    * Unsets all registered global variables if 'register_globals'
    is on.

    * Unsets $_REQUEST (you should use Solar::get(), ::post(), and
    ::cookie() for security reasons).

    * Dispels magic quotes from get/post/cookie/files/server
    superglobals if 'magic_quotes_gpc' is on; handles Sybase quotes
    as well as slashed quotes.

    * Turns off 'magic_quotes_runtime' and 'magic_quotes_sybase' so
    that SQL sources do not quote values on retrieval.

  * Solar::start() no longer sets error_reporting and display_errors.
   Per note from Matthew Weier O'Phinney.

  * Fixed bug where start() was calling __solar('start') instead of
  solar('start') on shared objects (the latter is correct).

  * Added locale strings for 'VALID_*' keys to support default
  validation messages in Solar_Sql and Solar_Form.

  * You can now specify an alternate config sources as the only
  parameter to calling Solar::start().  Pass an array to populate
  $config directly, an object to populate from the object properties,
  or a string to indicate an arbitrary path to a config file.  The
  default remains to load $config from the file defined by the
  SOLAR_CONFIG_PATH constant.  Per discussion with Matthew Weier
  O'Phinney.

* Solar_App_*:

  * View scripts now use the new Savant3 auto-escaping function
  and the new Solar_Template plugin locale() for localized strings.

* Solar_Base:

  * Constructor now allows passing of a string as the $config value,
  which is subsequently treated as a path to a php-array config file
  (this means you can have a config file specifically for a class
  instead of having to pass an array).

* Solar_Filter:

  * The alphanumeric() method is deprecated; use alnum() instead, it's
  easier to type. The alphanumeric() method will be removed after the
  0.7.0 release.

* Solar_Form:

  * BC BREAK:  Made $config protected like every other Solar class.
  Config values are now populated through to the new $attribs
  property, which stores attributes for the form tag itself.  If you
  were using $config to retrive form-tag attributes, you should now
  use $attribs instead.  Updated Solar_App_* views to reflect this
  change.

  * Added prefiltering of submitted values; use addFilter() method, or
  add a 'filter' key to the element array when using setElement().
  Thanks, Matthew Weier O'Phinney.

  * The populate() and validate() methods now take an optional
  paramter; if that param is an array, it is used for the $submitted
  property.  This allows you to pick the value population source
  instead of having to choose only from $_GET and $_POST.  Thanks,
  Matthew Weier O'Phinney.

  * Added reset() method to restore form to its originally-configured
  state.

  * Added load() method to load attributes and elements (with filters

  and validations) from an external source.  Per discussions with
  Matthew Weier O'Phinney.

  * When no message is given for validation, attempt to get a default
  validation message from Solar/Locale/en_US.php based on the method
  used for validation (c.f. the new VALID_* translation keys).

* Solar_Sql:

  * In quote(), changed is_double() to is_float() to match with column
  pseudo-type name.

* Solar_Super:

  * No longer uses the magicStripSlashes() filter when values are
  fetched, because the Solar environment setup now takes care of
  slashes at start() time.

* Solar_Template:

  * Updated to Savant3 alpha2 and converted all Solar_App_* view
  scripts to use its new auto-escaping functions. See change notes at
  http://phpsavant.com/yawiki/index.php?area=Savant3.  Of note, the
  'form' plugin will change in the next release, and the 'scrub'
  plugin will disappear in the next release.

  * Added new 'Plugin/' directory with new 'locale' plugin to help
  with locale transalations (you can now use $this->locale('KEY')
  instead of Solar::locale('Solar', 'KEY')).  All Solar_App_* view
  scripts now use this plugin.

  * Adds the 'Solar/Template/Plugin/' directory to the top of the
  configured resource_path automatically.

* Solar_Valid:

  * The alphanumeric() method is deprecated; use alnum() instead, it's
  easier to type. The alphanumeric() method will be removed after the
  0.7.0 release.

Harry Potter III: The Prisoner of Azkaban

What a wonderful series. I've said it before, but I'll say it again: if this is what kids are clamoring to read, then I have hope for the future. Not only are the morals good, but the storylines are preparing the readers for other literary works, including not only Greek and Roman mythology, but also such things as C. S. Lewis' "Narnia" and Tolkien's "Lord of the Rings."

Near the end of the third Potter book, Dumbledore (so much more than just an "old-man-as-mentor" archetype described by Jospeh Campbell) counsels Harry after Harry has mercifully spared a traitorous informer against the Potter family: "This is magic at its deepest, its most impenetrable, Harry. But trust me ... the time may come when you will be very glad you saved [his] life." Anyone who reads that, who has also read the Lord of the Rings, will recognize immediately the similarities to the conversation between Gandalf and Frodo at the door to Moria about Gollum. Kids who read Harry Potter are thus ready to be introduced to Lord of the Rings, and will recognize the motif in the same way.

The Potter books are simply stunning; I can't believe I waited this long to read them. The movies don't do them justice by half.

Incidentally, I have a guess about the Harry/Hermione relationship; I think it will mirror the Luke/Leia relationship. But who knows? ;-)


Savant3 alpha2 Released

Savant3 is a PHP5 E_STRICT compliant template system; it is non-compiling by default, which means it uses plain PHP for its template language. It supports object-oriented plugins and output filters, supports multiple paths for template sources so you can "theme" or "skin" your application, has built-in support for streams as template sources, and has an automated hook for custom user-defined compilers.

The change notes for this release (3.0.0alpha2) are:

  • This is an ALPHA release; while mostly stable, future releases may break backwards comptability.
  • Added methods for escaping output (and for printing of escaped output). As a result, the 'scrub' plugin is deprecated and will be removed from future versions of Savant. Use $this->escape() instead of $this->scrub(), and "$this->_()" instead of "echo $this->scrub()".
  • Added new plugin 'html_attribs' to standardize how HTML attributes are added to a tag.
  • Added a whole series of 'form_*' plugins, one for each element type (button, checkbox, radio, select, text, and so on). These plugins generate only the related element with no layout, and have a standard argument order (name, value, attribs). In addition, they are Solar_Form friendly; if the first argument is an array instead of a string, that array is assumed to be a Solar_Form element array with 'name', 'value', 'attribs', etc. keys. Having them as separate plugins will make it easier to add new form elements, e.g. 'form_date' and 'form_time' pseudo-elements, a la HTML_QuickForm.
  • Added new 'form2' plugin that uses the 'form_*' plugins instead of embedded methods for generating elements. It mimics the current Savant2-derived 'form' plugin and is almost identical in function.
  • With respect to the new 'form_*' and 'form2' plugins, this will be the last release with the current Savant2-derived form plugin. The new 'form2' plugin, and the 'form_*' plugins, will be separated into their own Savant3_Plugin_Form package so they can be upgraded and maintained separately from the core Savant3 distribution.

YaWiki 0.22 released

YaWiki is "yet another wiki" for PHP. While YaWiki was originally designed for collaborative documentation efforts, it also serves nicely as site framework and content management system; sites such as Yawp and Solar use YaWiki and a custom theme.

The change notes for this release of YaWiki are:

  • Schema Change: Added a column to the "yacs" table ("yet another comment system" ;-). Run the "docs/MIGRATE_021_022" SQL code against your database, otherwise comments won't post properly.
  • Now requires Savant 2.4.0, as the default theme templates make extensive use of Savant2::_() to help automate output escaping.
  • Fixed bug in search template noted by David Coallier and reported by Davey Shafik. Thanks, guys.
  • Comment submission now redirects to the same page as the comment was posted on; previously, overzealous application of htmlspecialchars() interfered with proper redirection, sending the commenter to the HomePage for the area.
  • Comment submission now captures the commenter's IP number.
  • Comments are now deletable by the page administrator, not just the area administrator.

When Marcus Whitney interviewed me last week for Pro-PHP (hey Marcus, when's that one coming online?) he asked about some YaWiki technical highlights. I gave perhaps too quick an answer; here's a more-full one from the YaWiki site itself:

  • Uses the Yawp foundation for PHP applications.
  • Built from PEAR and PEAR-compliant objects such as...
  • Database abstracted with DB_Table; works on most anything from MySQL to Oracle, and self-installs the database tables
  • RSS feeds for page content changes (all pages in all areas, all pages in one area, or one page in one area)
  • Has a special AreaMap page that lets you define a page hierarchy for navigation elements
  • Supports separate name spaces (called "areas") in one installation
  • Supports anonymous users and user authentication
  • An access control list that lets the wiki administrator control who can edit and view individual pages in each area
  • A comment system for users who are not allowed to edit pages directly
  • Theme-aware (build your own look and feel) using the Savant template system

Interviewed for Pro-PHP

I can't claim that I'm starting a new series like Chris Shiflett, but Marcus did honor me by asking if I'd give an interview for Pro-PHP. Of course I accepted. :-) We had attempted it two previous times (once by Skype and once in-person) over the past few weeks, but due to technical difficulties they both fell through. Third time's the charm, though, and the interview itself went off without a hitch yesterday (by Skype on a much-improved connection).

We talked about everything from Savant (including comparisons to Smarty, and the failed PEAR proposal) to YaWiki, Yawp, and Solar, as well as some of my ideas about how to write code. I felt like I was rambling on at least half the time, and although I had the presence of mind to mention names where I could, I'm certain to have left out important folks. When I listen to the interview in its edited state (which I guess will be when everyone else does ;-) I'll make a list of everyone I failed to recall and post them here, or perhaps as a comment to the Pro-PHP blog entry.

And of course I can almost guarantee that it'll generate a(nother) spate of offended sensibilities; I seem to do that even when I edit my own written comments, I can only imagine how bad it'll be when I'm speaking without benefit of rephrase. :-)

Update: I just posted a followup to the interview here to proved errata and links.


Harry Potter and the Sorcerer's Stone

The reputation of the Harry Potter series is well deserved. I picked up the first one yesterday and finished it today; the style is easy to follow, and the story engaging. But above all, it has positive things to say about good character. One of my favorite bits comes right at the end; Dumbledore, the head-master of Hogwart's school of magic, has this to say after 11-year-old Harry perseveres in the face of terrible odds and manages temporarily to defeat an inexorable foe:

"Nevertheless, Harry, while you may only have delayed his return to power, it will merely take someone else who is prepared to fight what seems a losing battle next time -- and if he is delayed again, and again, why, he may never return to power."

If that's not both a description of adult life, as well a moral call to fight evil when it appears, and keep fighting even though victory cannot be guaranteed, then I don't know what is. If this is what kids are reading these days, then I think we will be all the better for it.

I can't wait to get started on the next one. :-)


Savant 2.4.0 Released

FYI: David Mytton of Olate Ltd has written a great introduction to and review of Savant over at SitePoint. Thanks, David! :-)

And now, back to our regularly-scheduled blog entry:

After a bit of kerfluffle over cross-site scripting attacks, and working to sanitize some template output, I realized it how useful it would be for Savant to help automate escaping of values for output. After a few days of mailing-list discussion about how such functionality should work, I've released Savant 2.4.0 with a handful of new methods built-in:

  • setEscape() and addEscape() to define what callbacks to use when escaping output
  • getEscape() to retrieve the array of escaping callbacks
  • $this->escape() to escape-and-return a value
  • $this->_() to escape-and-echo a value

The default escaping callback is htmlspecialchars(), but you can add any number of your own. For example, after instantiating Savant, you can do something like this:

$savant =& new Savant2();
$savant->setEscape(
    'strip_tags',
    'htmlspecialchars',
    array('StaticClass', 'method'),
    array($objectInstance, $objectMethod)
);

Each of the parameters is callback suitable for call_user_func(), and you can use an arbitrary number of parameters.

These callbacks are applied, in order, whenever you use the $this->_() or $this->escape() methods in your Savant templates (which are, of course, just PHP scripts dedicated to presentation logic). For example, instead of echo htmlspecialchars($this->value), you would call $this->_($this->value) (and the default htmlspecialchars escaping will be applied).

In addition, you can override the default escaping. You may optionally pass an arbitrary number of added parameters to escape() or _(), and these will be treated as callbacks to apply to the value instead of the default escaping callbacks. For example, $this->_($this->value, 'strip_tags', 'my_escape_function', array('StaticClass', 'method')) will override the default escaping with the callbacks listed as the added parameters.

Update: The documentation on the Savant site has been updated: all examples using "echo" have been changed to "$this->_()", and the escaping methods themselves have also been documented.