PHP Content Repository - the other part of CMS decoupling

A while back I wrote about decoupling content management. The post generated lots of good reactions, and since then our VIE library has been adopted by multiple CMSs to achieve decoupling on the UI level.

Now it is time to focus on the other side of decoupling - the relation between a web framework and a content repository. I've written multiple times about the benefits of using a content repository, but JCR spec lead David Nuescheler sums them well:

  • Functional Definition of a “Content Repository”
  • Common Vocabulary!
  • No longer learn (dozens of) (ugly) proprietary APIs
  • Write (mostly) portable code, for Document Management, Web Content Management, Source Code Control
  • Compare Repository Functionality
  • No more information silos and vendor Lock-in Content-Centric Infrastructure

The Midgard Project has provided a generic content repository for PHP a long time now, but our APIs have been our own, which is probably too much vendor lock-in for many PHP CMSs. Because of this, I was very happy to see the PHPCR project start to provide a PHP port of the Java Content Repository interfaces. This is the way to achieve truly a vendor-independent content repository API.

What is PHPCR, then? It is a set of PHP interfaces that define how to deal with a content repository. Instead of thinking about particular databases or file formats, you get a standard way to deal with content using a tree-based metaphor and query APIs. On top of this, *CR provides standard ways to handle access control, versioning, content creation and many other things depending on what the particular repository supports. The repositories provide ways for applications to check their capabilities and content model, so an application can adapt to various repositories used.

TYPO3 and Symfony are already pushing strongly towards PHPCR, using Apache Jackrabbit via a PHP bridge as the reference implementation. Jackrabbit is great because it provides support for all *CR features, but obviously at the cost of a Java dependency. For those that want to keep their content in a RDBMS, and not run Java processes, we're now working on making a Midgard2-based PHPCR provider. The project is still in quite initial stage, but some of the APIs work:

use Midgard2CR as CR;

// Set up credentials, in this case the default account
$credentials = new \PHPCR\SimpleCredentials('admin', 'password');
// Get a Midgard configuration
$factory = new CR\RepositoryFactory();
$repo = $factory->getRepository();
// Connect to Midgard repository with the credentials
$session = $repo->login($credentials);
// Get the root node matching our workspace
echo "\ngetRootNode\n";
$root = $session->getRootNode();
$title = $root->getProperty('mgd:title');
var_dump($root->getIdentifier(), $root->getName());
var_dump($title->getName(), $title->getString(), $root->getPropertyValue('mgd:title'));

// Iterate child nodes
echo "\ngetNodes\n";
foreach ($root->getNodes() as $node)
// Get a property with absolute path
echo "\nsession->getProperty\n";

Feel free to follow the effort on GitHub, and also to participate :-) I also recommend reading at least parts of the JCR 2.0 spec. It is quite enlightening on where content management will go in the future.

Read more Midgard posts.