Archive for the ‘PEAR’ category

A New PEAR Channel Frontend

December 21st, 2009

It seems like PEAR2 has been brewing forever. I mean, we’ve been talking about PEAR2, namespace usage, and a brand new installer for a long time. But, now that PHP 5.3.0 is a reality and 5.3.1 is so close out the door – things are actually taking shape and getting to the point where not only can we show you what we’ve been working on, but you can actually try things out for yourself.

What I’ve been working on the past couple of days months is a new PEAR channel frontend; the basis for the PEAR2 website. I wanted a simple PEAR channel frontend, that just looks at the local filesystem for all the channel info, and would display the basics: what packages are available, categories, releases etc. Basically, just a simple web view that would not need a database backend, or any complex installation.

It would be simple to create a standalone library that just parsed xml files and read out the data, but having each underlying piece a reusable component would be very beneficial.

  • a simpler XML library for parsing files
  • an HTTP request library
  • a library to talk to PEAR channels
  • a simple templating system with php as the template language
  • html/css templates to present the content in

So when you consider the all the pieces that are required, this is quite an undertaking.

Implementation:

Ordinarily the pear installer, or pyrus, communicates to a PEAR channel through the xml files that describe the packages available. What we’ve done, is used the installer as the backbone for channel discovery and information retrieval, and we’ve told it to look at the local filesystem instead of at a remote channel. This is done using a “filesystem” adapter for the PEAR2_HTTP_Request package, which turns your local filesystem into a fake Internet. This is a fairly simple concept, that makes for a very simple PEAR channel frontend.

So, if you couple that model for data retrieval with a completely new PHP 5.3+ template system with roots in Savant, we’ve got a really nifty base for building pear channel websites.

So! The package is in the pear2 sandbox and is titled PEAR2_SimpleChannelFrontend as a companion to the PEAR2_SimpleChannelServer which makes channel creation (with categories!) a breeze.

I’ve added it to my local PEAR channel by simply dropping the .phar file in the web root as index.php, add a small .htaccess file and that’s all that is needed. Check it out at http://pear.saltybeagle.com/

As of tonight you can try it out for yourself by grabbing the PEAR2_SimpleChannelFrontend-0.1.0.phar off of the PEAR2 website and saving it along side your channel.xml and browsing to the phar file. I named it index.php for simplicity, and placed the following .htaccess file in place:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>

Also, my thanks to Amir for the coding help with SimpleChannelFrontend, and the pear2 site. Things are moving along quite nicely.

PHP Template Wars – A New Hope

November 6th, 2009

Templating has been a recent issue up for debate in the PHP community, which is why I think it’s time to share what we’ve been up to with PEAR2 and Savant.

Savant is the foundation of the top PHP-based templating systems. In particular Solar View and Zend Framework’s View have roots in Savant and the great work of Paul M. Jones. Each of these are very successful templating systems, and they make for a proven foundation for templating and ease of use. So now that PEAR2 is gathering energy, and needs a strong templating system, Savant makes a good fit. But, with PEAR2, we have a lot of new features available with PHP 5.3, which means we can re-think some aspects of templating.

First, I want to talk about template/view annoyances, then about how Savant has solved these issues in PEAR2_Templates_Savant.

Annoyances:

1.) assigning data to the view

This is a problematic issue. Either you manually assign all of the data to the view, or choose individual pieces of data. Assigning individual pieces takes too much time and can lead to missing data in the view if new fields are added to a model and not assigned, or mismatched variable names. Data assignment is also difficult when the model uses magic methods or iterators for data retrieval.

2.) view selection

If you’re a sane person you probably have a pretty strong map between your models and views. Meaning, for the BaseballPlayer model, you’re probably going to be using a BaseballPlayer[.tpl.php|.phtml] file. This model to view mapping should be logical and happen automatically.

3.) isolation/sandboxing view data and template system

The data used within the view should be isolated from the templating system. The contextual data should not interfere with the templating system and vice-versa. Protected/private methods in the template system should not be callable within the template.

4.) view system setup

You should only have to set up your view system once per application, not per template.

5.) controller and flow logic in templates

It’s easier to maintain one template file for the site rather than separate sandwich templates pieces for the header and footer. The sandwich template method can lead to out of sync HTML tags, but it is difficult to use one template for the site without introducing controller logic into this view.

6.) data escaping

Sometimes this is necessary, sometimes it isn’t. Should the developer handle this or the designer? Does it matter? Flexibility should be allowed for either, and if we want data to be escaped it should happen automatically while still allowing access to un-escaped data if I know what I’m doing.

PEAR2_Templates_Savant – A New Hope

First, I want to talk about the concept of partial templates. If you’ve used the partial helper within Zend View or Solar View, you know how beneficial this can be. Partials are a simple way to break up large templates into smaller templates. This makes for a very object-oriented template usage, which matches many MVC applications, and also aids in data isolation and limiting variable scope. This is the default method of rendering in PEAR2_Templates_Savant.

Now the pitch.

How PEAR2_Templates_Savant fixes the annoyances above

1.) assigning data to the view

Because partials are the default method of rendering, there is no more assignment of data to the view. The data is made available to the template as the $context variable. This means instead of $view->name = $baseballplayer->name; or using $view->assign($baseballplayer);, you’ll simply use $view->render($baseballplayer, [tpl]);

This means that there is never any confusion about what data was assigned, or how to access the data from within the template. It also means that views have access to the public methods of the object rendered, which helps for objects which use getters and setters, or magic methods for data retrieval.

For those of you used to the old way, you can still pass a stdClass object with your own custom assignments.

2.) view selection

The render method accepts two parameters, contextual data and the template you wish to use. BOTH are optional arguments, but the magic happens when the template name is null.

Back to our ’sane’ developers who know that a BaseballPlayer object should always be rendered using the BaseballPlayer.tpl.php template. They have taken the time to build a good structure for the models in their applications, and by doing so, their life is made easier by eliminating what template to select. PEAR2_Templates_Savant uses a mapper which will map objects to templates (configurable of course). The default mapper simply maps class names to template files.

BaseballPlayer => BaseballPlayer.tpl.php
BaseballCoach => BaseballCoach.tpl.php
BaseballTeam_Phillies => BaseballTeam/Phillies.tpl.php
BaseballTeam\Phillies => BaseballTeam/Phillies.tpl.php

You can assign simple replacements to apply to the class name and the file extension is also customizable for the .phtml fans out there. Of course you can provide your own template mapper which implements the MapperInterface.

ClassToTemplateMapper.php

3.) isolation/sandboxing view data and template system

This is where PHP 5.3 shines. Closures allow us to create little sandboxes for data to play in. Feel free to pass in a __config value to the view, knowing that the data won’t interfere with the view object (who would do this?) – without using nasty global variables. Also, your template system can have private/protected methods which aren’t available inside the view which makes the class easy to extend if you need to customize. Side effect, we don’t use $this-> to get to the data, we use the $context to access data given to the view, and $savant to render further partial templates. Win for data and template separation!

4.) view system setup

Because partials are used as the default rendering, the view setup happens once and is used through the entire application.

5.) controller and flow logic in templates

When used in an application which maps objects to templates, this makes it very easy to pass off data to other templates without knowing the type of data. This means there’s no more controller-ish logic within a template such as:

<html>

<body>
<?php
if ($this->mydata instanceof BaseballPlayer) echo $this->partial('baseballplayer.tpl.php', array('name', $this->mydata->name));
elseif ($this->mydata instanceof BaseballTeam) echo $this->partial('baseballteam.tpl.php', array('name', $this->mydata->name));
?>
</body>
</html>

Now, you can create one outer page template, and hand off data to another template without having to know what type of data is:

<html>

<body>
<?php echo $savant->render($context->mydata); ?>
</body>
</html>

Objects are mapped to templates, arrays are looped over, strings, ints, doubles etc are returned after they’ve passed through any escape methods you’ve assigned.

6.) data escaping

If the developer assigns methods to escape data, this happens automatically. This is handled through an ObjectProxy which handles all requests to the inner object. If you need direct/raw access to unescaped data, you can use $context->__raw(’fieldName’);

This makes escaping easy, automatic, and avoidable if you know what you’re doing.

Teh End.

There are a few other nuances that I can share in another post, but those are the basics. Also, I want to really thank Greg Beaver who contributed many of the ideas for the latest version of Savant – including the title of this post, so thanks Greg!

So feel free to try it out and give some feedback. And so far things are shaping up nicely in the PEAR2 universe – definitely something to keep an eye on in my biased opinion.

A full example is available in the repository.

The development version of PEAR2_Templates_Savant is available through the svn repository, or installable with pyrus.

SVN:
svn checkout http://svn.php.net/repository/pear2/Templates_Savant/trunk

Browse online:
http://svn.php.net/viewvc/pear2/Templates_Savant/trunk/src/Templates/Savant/

On the (under construction) PEAR2 website:
PEAR2_Templates_Savant

Install with pyrus
php pyrus.phar /putithere install PEAR2_Templates_Savant-0.1.0

Autoloader That Installs PEAR Packages

November 4th, 2009

I had a thought the other night about an autoloader that could install pear packages automatically for you.

Security concerns aside, I thought this would be a fun/juvenile coding experiment, and something that could showcase how easy the pyrus api is for installing PEAR packages. So here it is, pushed out on github – http://github.com/saltybeagle/AutoloadPackage/blob/master/AutoloadPackage.php

Only 56 lines of code to have an autoloader that will install a PEAR2 package. Now if that’s not fun, I don’t know what is.

:-)

Oh, and you should really check out Pyrus, the new PEAR installer. Get it over at the pear2 website (under construction).

Remote PEAR Package Releases

June 17th, 2009

Sune Jensen sent me a note about a couple minor additions to the remote PEAR package releaser script, which would allow it to automatically create the package and maintainers if it did not exist on the PEAR channel managed with Chiara_PEAR_Server. This is now possible since Christian Weiske added the options to the Chiara_PEAR_Server admin interface a while ago.

I’ve added in the patch from Sune, and released it as Salty_PEAR_Server_RemoteReleaseDeployer-0.1.0.

You can grab the release here, or install it with

pear channel-discover pear.saltybeagle.com
pear install salty/Salty_PEAR_Server_RemoteReleaseDeployer-0.1.0

Thanks Sune!

Using SimpleChannelServer to manage a PEAR channel on Google Code

December 8th, 2008

I needed to build a quick pear channel for a library I had built – here’s all it takes:

For this example, we’ll assume your Google project is named: myproject

First, we need to check out the root of your Google Code project, so we can place the channel files here, away from your source code files.

svn checkout https://myproject.googlecode.com/svn/ myproject --username mygoogleusername

Now that we have a checkout, let’s build the channel:

cd myproject

Download the SimpleChannelServer phar file from here:

wget "http://svn.php.net/viewvc/pear2/sandbox/SimpleChannelServer/trunk/pearscs.phar?view=co" -O pearscs.phar

Using a recent version of PHP 5.3, let’s execute the pearscs.phar file, and create the channel for the project:

php pearscs.phar create myproject.googlecode.com/svn myproject

Now commit the files to your repository, and let’s try discovering your pear channel.

pear channel-discover myproject.googlecode.com/svn/

You should see the following message, telling you that the channel was added successfully:

Adding Channel "myproject.googlecode.com/svn" succeeded
Discovery of channel "myproject.googlecode.com/svn/" succeeded

Now let’s create our pear package. PEAR has many tools available to aid in package creation. To get up and running quickly, we’ll start from an example and modify it for our own needs.
Download http://simplecas.googlecode.com/svn/trunk/makepackage.php and save it to your local project as trunk/makepackage.php

Modify this file to use your channel name, package name, release information and maintainer info.
Now let’s create the package:

php makepackage.php
pear package

Now you should have a file myproject-0.1.0.tgz

Let’s release the package to the world, substitute the lead name with your handle:

php pearscs.phar release trunk/myproject-0.1.0.tgz leadhandle

This will add the distribution files to the /get/ directory, and update the channel xml files. There’s a small issue with using Google code to host the xml files, and that’s that the content-type needs to be sent as application/xml or text/xml for the channel files to be read correctly, so set the mime-type property for the xml files.

find . -name '*.xml' | xargs svn propset svn:mime-type application/xml

Now commit these files to your repository, and let’s try installing the package!

pear install myproject/myproject-0.1.0

If everything went correctly, pear should have installed the package. Now when you create a new release, just run the release command, update the mime-type on the xml files and commit your changes.

FYI – the package I needed a channel for is SimpleCAS a PHP5 library for authenticating users against a JA-SIG Central Authentication Service.

Updates

There are a couple gotchas for phar packaging. Here’s some info that might ease some problems with creating or opening phars or PEAR packages:
* Make sure you have zlib! ./configure –with-zlib
* php.ini settings

[phar]
phar.readonly = 0
phar.require_hash = 0

Getting started with Pyrus, the new PEAR compatible package installer

April 30th, 2008

There are quite a few reasons to start playing with the new PEAR package manager – named Pyrus. The first of which is that it is filled with PHP 5 goodness, utilizing many features of the SPL. And secondly, PEAR2 is just around the corner and these are exciting times for PHP development.

Prerequisites:

  • PHP >= 5.3 (I believe you need libxml > 2.6.16, but could use some help verifying this)
  • SQLite Extension, should be included by default (sudo apt-get install php5-sqlite)

The first thing we need to do, is create a temporary directory to checkout the PEAR2 files from the repository:
Note: In case you haven’t heard, PEAR2 source files are in subversion at http://svn.pear.php.net/PEAR2


mkdir ~/PEAR2_SVN
cd ~/PEAR2_SVN/
svn co http://svn.pear.php.net/PEAR2


Great, now you have a copy of the latest files for Pyrus and PEAR2. (r 314 when this was written).
The following packages are the backbone of the new package manager:
PEAR2_Autoload
PEAR2_Exception
PEAR2_Pyrus
PEAR2_HTTP_Request
PEAR2_Developer (if you’d like to build some PEAR2/Pyrus installable packages)
The PEAR2 channel is not available yet, but we can install the individual packages in Pyrus by using their respective package.xml files within the svn checkout.
Before we install the new packages, let’s create a directory to place our Pyrus installation. Previously, users would create a system PEAR install in /usr/share/pear or similar, or a local PEAR install in ~/pear/. And at this point, you would have to make a decision you might have to live with for the rest of the installed packages’ lives. But, don’t worry! With PEAR2 we can move this Pyrus managed installation later if needed.

mkdir ~/pyrus
cd ~/pyrus/

Note: it is important to change the directory to where you wish to install the packages as the current directory will be used as the default install location for pyrus commands.
Now let’s install some packages

php ~/PEAR2_SVN/PEAR2/Pyrus/trunk/pyrus.phar install ~/PEAR2_SVN/PEAR2/Autoload/trunk/package.xml
php ~/PEAR2_SVN/PEAR2/Pyrus/trunk/pyrus.phar install ~/PEAR2_SVN/PEAR2/Exception/trunk/package.xml
php ~/PEAR2_SVN/PEAR2/Pyrus/trunk/pyrus.phar install ~/PEAR2_SVN/PEAR2/HTTP_Request/trunk/package.xml
php ~/PEAR2_SVN/PEAR2/Pyrus/trunk/pyrus.phar install ~/PEAR2_SVN/PEAR2/Pyrus/trunk/package.xml
php ~/PEAR2_SVN/PEAR2/Pyrus/trunk/pyrus.phar install ~/PEAR2_SVN/PEAR2/Pyrus_Developer/package.xml

Now you have Pyrus and all the necessary dependencies installed!
To get started, you can create your PHP files which reference the PEAR2 autoloader by using:

<?php

require
'pyrus/src/PEAR2/Autoload.php';

How to create a PEAR2 package

The easiest way to create a Pyrus installable package is to set up a standard filesystem layout, and auto-generate the package.xml manifest for installation.
The source layout is as follows:
PackageName/src/      [role="php"]
PackageName/examples/ [role="doc"]
PackageName/doc/      [role="doc"]
PackageName/data/     [role="data"]
PackageName/tests/    [role="test"]
PackageName/www/      [role="www"]

In the root of your package directory create the following files:
CREDITS (this file contains the project lead info) example

; maintainers of PackageName

Brett Bieber [saltybeagle] <brett.bieber@gmail.com> (lead)

README (this file contains the summary and description for the package) example
This package is for use with blah


With this package you can do blah, blah, blah blah. My extended
description goes here.
RELEASE-0.1.0 (This file contains the release notes) example
This is the first alpha release.
You can create your PEAR2 installable package by using the Pyrus_Developer package and using a file like this:

makepackage.php
<?php

error_reporting
(E_ALL);

ini_set('display_errors',true);

require
'pyrus/src/PEAR2/Autoload.php';



$a = new PEAR2_Pyrus_Developer_PackageFile_PEAR2SVN(dirname(__FILE__), 'PEAR2_MyNewPackage');






Then run the file to generate the package.xml and install your package:
php makepackage.php

cd ~/pyrus

php ~/PEAR2_SVN/PEAR2/Pyrus/trunk/pyrus.phar install PackageName/package.xml



Hopefully this gives you all a quick understanding of how to get started, and some idea of where things are headed.

Note: The latest copy of this document is available at http://docs.google.com/Doc?id=dgtbrg66_50d5c68d

Upgrading Ancient PEAR Versions

January 11th, 2008

If your PEAR installer is acting funky, returning 404’s, remote packages not found etc you may have an ancient version in need of upgrading. As announced almost a year ago, XML RPC would be disabled on Jan 1st, 2008.

Here’s a typical error:

# pear list-upgrades
HTTP error, got response: HTTP/1.1 404 Not Found
Didn't receive 200 OK from remote server. (HTTP/1.1 404 Not Found)

Read this message on the PEAR website for how to fix it.

New Release of Services_W3C_HTMLValidator

July 31st, 2007

I recently released a new version of the PEAR Services_W3C_HTMLValidator package which supports the latest features of the HTML Validator.

With release 0.8.0 the W3C Validator has a shiny new interface and speed improvements to boot. In addition, the web services and SOAP output supports additional features which make the web service just as good as the web interface at http://validator.w3.org/.

The additions to the SOAP output format give developers the ability to re-create the validator’s interface in any template they choose, or just programmatically validate HTML documents.
As a quick example, I’ve built a simple validation interface within the UNL web templates.

Screenshot-UNL | Document Template - Mozilla Firefox

Big thanks to Olivier for all his work, and getting my patches in to production.

Grab the latest release and build your own interface at http://pear.php.net/package/Services_W3C_HTMLValidator/

Commenting Re-enabled / Salty_Services_Akismet

March 26th, 2007

Commenting on the blog has been re-enabled now that I’ve had time to code in Akismet spam checking.

The process was fairly simple, I utilized existing code from Alex Potsides @ http://www.achingbrain.net/, and pearified the code into a package Salty_Services_Akismet which is now a dependency on the saltybeagle.com code.

Hooray for PEAR packages.

I’m gonna check with Alex and see if he’s considering adding his package to PEAR under Services_Akismet… there would only be minor coding standards changes, a look into how he uses the sockets to connect to akismet, and a re-license from GPL. (A bit of work :-) )

I’ll also note that Tobias Schlitt has Akismet trackback checking already built in to Services_Trackback, but as of yet I don’t think there’s an Akismet comment spam checker inside PEAR.

Custom PhpDocumentor Templates

January 30th, 2007

PhpDocumentor is an essential tool all serious PHP developers should know about.
By parsing the phpdoc blocks within the source of your files phpDocumentor can generate API documentation for your entire project/application.

I recently had the need to build a custom output template for the HTML converter, and decided to distribute it using a PEAR installable package so other PHP developers at the University could generate documentation for their code.

The process is fairly straightforward – I copied the frames template and created my own named ‘UNL.’ This template yields .php pages in the UNL Templates so that the API documentation matches the rest of the www.unl.edu website.

Tricks with creating an installable PEAR package were to mark all the files .tpl, .inc, etc as ‘php’ and to use ‘/’ as the baseinstalldir. This will make sure the template files get installed into the correct location.

Other UNL PHP developers can run:

pear install pear.unl.edu/UNL_PhpDocumentor_UNLHTMLTemplate-alpha

And then set phpDocumentor loose on your files like so:

phpdoc -po UNL_DWT -o HTML:UNL:UNL -d UNL_DWT -t /Library/WebServer/pear.unl.edu/docs/UNL_DWT/

which will generate API documentation within the UNL templates and it will look like this.