After working with Spring and Grails recently, I became very comfortable with their method of dependency injection. Based on my experiences, I went and wrote a simple injector that will automatically wire dependencies by name. At first it might seem to have quite an overhead, but in profiling with 40 or so objects being injected in a single request, its footprint was quite light.
Download the injector
Examples in the testing as a basic unit test, or click on for more
(more…)
This isn’t a comparison of the two, which I may one day get to having worked extensively with both and having had good and bad experiences with both. Instead, due to the release of a PHP5 version of MySource Matrix recently, I had a few hours in which I quickly created a bridge to pull content from Alfresco into Matrix.
While not completely functional, here’s a quick screenshot because that’s what screenshots are for right? Code to come at a later point in time, but the goal is to be able to perform CRUD operations against an Alfresco repository from within the Matrix backend, and from within a Matrix powered website.

“But why, when Alfresco has its own WCM?” you ask? A story for another time I’m sure…
Alfresco’s 1.4 version of the PHP library has been around as a technical preview, but doesn’t seem to have progressed much further. Regardless, it’s still quite functional, and allows you to do most things in a more sane way than the previous releases of it. Over the next couple of weeks I’ll be playing around with some of the functionality available, and given that some people are still a bit unsure of how everything works in the new version, hopefully I can help shed some light on things. First up; browsing spaces.
Everything in the PHP API requires the use of the Session object, either directly or indirectly. Connecting to the repository must be done before anything else, and is quite simple; provide the username, password, and URL of where the repository is located (remember that api bit!).
Code (php)
-
-
$session = Session::create("admin", "admin", "http://localhost:8080/alfresco/api");
-
$spacesStore = new SpacesStore($session);
Next, I’m going to get the selected node; note that if I haven’t specified one on the request, I’ll just get the company home.
Code (php)
-
-
$selected =
isset($_GET[‘id’]) ?
$_GET[‘id’] :
null;
-
$root = null;
-
if (!$selected) {
-
$root = $spacesStore->getCompanyHome();
-
} else {
-
$root = getNode($session, $spacesStore, $selected);
-
}
-
-
function getNode($session, $store, $id)
-
{
-
$nodes = $session->query($store, ‘@sys:node-uuid:"’.$id.‘"’);
-
return isset($nodes[0]) ?
$nodes[0] :
null;
-
}
With the node in hand, I can now iterate over its children and list out a browseable listing.
Code (php)
-
-
$children = $root->getChildren();
-
-
foreach ($children as $childAssociation) {
-
/* @var $childAssociation ChildAssociation */
-
-
$child = $childAssociation->getChild();
-
/* @var $child Node */
-
-
-
-
-
-
echo ‘<a href="?id=’.
$child->
getId().
‘">’.
$childAssociation->
getChild()->
cm_name.
"</a><br/>";
-
-
-
}
-
Looking at the few tutorials available off zftutorials, there’s not much in the way of a proper “here’s a usable search engine based on Zend_Search_Lucene”. So while building one, I came across the problem of updating existing documents, which Lucene handles by deleting then re-adding the document. Which is fine, you just need to have a way of uniquely identifying the document in the index. So, something like a DB’s unique ID, stored as a particular field like ‘id’ in the index maybe? Well, I thought so, till I realised that I wasn’t removing anything… turns out that the default Lucene analyzer will treat numbers as whitespace characters, so that doesn’t work too well. One option that I’ve briefly implemented (depending on speed, and whether I need proper number indexing) is to just convert each digit of the ID into a lower case character. The other is to get into a custom analyzer which will treat numbers with the respect they deserve.
Extending Search Analysis
One thing I like about Grails (being based on rails, I assume it stems from there…) is that it allows quite easy definition of constraints that the model classes should adhere to. Taking that idea, consider the following;
Code (php)
-
-
class SampleModel{
-
public $variable;
-
public $othervariable;
-
public $integer;
-
public $constraints =
array(
-
‘variable’ => ‘Zend_Validate_Alnum’,
-
‘othervariable’ => ‘Zend_Validate_EmailAddress’,
-
);
-
-
public function __construct()
-
{
-
$this->constraints[‘integer’] = new Zend_Validate_Between(4, 8);
-
}
-
}
The idea is that you can define simple validators by supplying the class name, or more complex validators by declaring them in the constructor. This allows for custom validator declarations, or chained validators using Zend_Validate.
The next part to this is actually doing something with the constraints, and here’s where mixins would be ultra handy. The current implementations of mixins don’t really float my boat, so instead I’ll use a separate validator;
Code (php)
-
-
class ModelValidator implements Zend_Validate_Interface
-
{
-
/**
-
* Array of validation failure messages
-
*
-
* @var array
-
*/
-
private $messages =
array();
-
/**
-
* Is the model valid?
-
* @return boolean
-
*/
-
public function isValid($model)
-
{
-
// see if the user has defined any constraints at all
-
if (!
isset($model->
constraints)) {
-
return true;
-
}
-
$isValid = true;
-
$this->
messages =
array();
-
// Process the constraints otherwise
-
foreach ($model->constraints as $property => $constraint) {
-
// If the constraint is a string, we create an instance
-
// of the class it describes. If it’s an object, we
-
// use that instead
-
-
$constraint = new $constraint;
-
}
-
if (!$constraint->isValid($model->$property)) {
-
$this->messages[$property] = $constraint->getMessages();
-
$isValid = false;
-
}
-
}
-
return $isValid;
-
}
-
-
/**
-
* Get validation erro messages
-
*
-
* @return array
-
*/
-
public function getMessages()
-
{
-
return $this->messages;
-
}
-
}
So that will run through all the defined constraints and let us know if we’re valid or not. Also, being an implementor of Zend_Validator_Interface, it can be chained along with other validator calls. Useful… for me anyway.