onsdag 28 december 2011

Introducing Simplx Mirage Part II

Previous post showed the very minimum features to make Mirage useful. Now lets take a look at what else is in the box.


A word on Prototyping
Simplx Mirage implements a prototypical style of inheritance. This means that instead of deriving attributes and functions using extending of php classes, you simply build on an existing php object. Note that i wrote object, not class.

In prototypical inheritance you don't have the concept of classes. Objects, with state and all, are simply extended at runtime. Its generally done by setting a reference to a prototype, which is then used as a starting point for building the new entity.
A neat and handy feature in prototype orientation is the possibility to add properties and methods at any time during excecution. This is used heavily in the most famous prototype based language today, which is of course Javascript.

Simplx Mirage does prototyping in a very straight forward way. Much like Javascript, you extend the MODX core model by simply creating a new class and setting its _prototype property to an instance of a modResource class. You can then add and override the prototypes properties and public methods just as if they where extended in a normal inheritance style.

How stuff works - in short
Many things can be said about the highs and lows of php. One thing is clear though, its a darn flexible language! To make Mirage tick I have used many of php's pragmatic features such as Magic Methods, Introspection, Dynamic Class invocation and more.

The Mirage package consists of three Classes at the moment,
  1. Simplx_Mirage - a Factory/Repository style class with static utility properties and methods. This class also handles caching and overall settings management.
  2. Simplx_Mirage _Class - a class which encapsulates a modTemplate object using the Prototype concept mentioned previously. Its members gives a straight forward way access what Mirage sees as Class definition: the modTemplate and its modTemplateVar associations.
  3. Simplx_Mirage_Object - a class that encapsulates a modResource object and lets you override and extend it thanks to php goodies like Introspection and Magic Methods. Every Mirage Object gets a reference to its corresponding Simplx_Mirage_Class as it is created.
With these three classes we have everything we need to play dress-up with MODX.

Conventions to keep it simple
In MODX, as you might know, Template Variables have a one-to-many relationship with Templates. This is not a problem for Mirage really, but a one-to-one association is more in tune with the overall Class/Object metaphore we use. To get this working Mirage uses namespace prefixes by default. The default convention used here is to simply take the name of the class (modTemplate) as prefix. A Template Variable for the Product class could look like this:


Product_category
which would resolve to:
$myProduct->category

This general convention of using class name is used through out Mirage.
A really nice feature is the automagic matching of class/template matching using class name.

If you do the following:

class Product extends Simplx_Mirage_Object {}


Mirage very gracefully helps you at by assuming that the class 'Product' represents a modResource which uses a modTemplate named 'Product', and that its associated Template Variables are prefixed with 'Product_'.


Overriding and extending modResource
The possibilities to override properties and methods in the modResource class are not really obvious as our Mirage classes do not extend modResource but Simplx_Mirage_Object. Simplx_Mirage_Object in turn does not inherit from modResource either. So what is the secrete? Again, the Prototype concept in combination with php magic.

Let's revisit the Product class and add some new features.


class Product extends Simplx_Mirage_Object {
  // Set a custom default value to the modResource pagetitle property
  public $pagetitle = 'New Product';
  public function save(){
    // Do something customish
    parent::save();
  }  

}


Nothing out of the ordinary taking place above right? Well thanks, I'll take that as a compliment :) That was my grand plan actually, to hide all the details from you. What actually takes place is far from rocket science thankfully.

This is what happens in the Simplx_Mirage_Object class constructor:
  1. The name of the class which implements the Simplx_Mirage_Object class is noted using the php function get_class(). We now know that the class being constructed is of type Product.
  2. The Simplx_Mirage static method getClass()  using the class name as argument. A reference to a Simplx_Mirage_Class is returned, or, 'false' if no modTemplate named Product exists.
  3. If we got an 'id' argument in the constructor call we get the modResource using the good old MODX API. If we get a valid reference back we continue.
  4. Now we must check so that the modResource actually uses the Template wrapped in the Mirage class we checked previously. If it uses the Product class, we can continue.
  5. All the modResource properties are serialized to the internal _properties array.

This is what happens in the Simplx_Mirage_Object class __set, __get and __call:

Read up on php Magic Methods if your unfamiliar with them.
  1. A property or method on a Product object is called. If php can not find a match using its regular process of resolving implemented members, it defaults to its Magic Functions. This first step is where your implementations overrides modResource members.
  2. The method or property was not found in the Product class, or the Simplx_Mirage_Object class. Here is where a big part of the prototype coolness takes place.

    1. If a property was requested, the name is used to perform a lookup in the _property array. If the property is found its retrieved and returned. If the lookup returned false it is assumed that the property is a Template Variable and the MODX API is used to get or set the requested value.
    2. If a method call was made it is intercepted by the Magic  __call  function. This in turn uses php's Introspection features to lookup a matching method on the modResource prototype and simply pass the method call on, including any and all arguments. The resulting value, if any, is returned back.
Wrapping up
Thanks for taking the time to read! Hope you have found if interesting.
I will continue this tour shortly, I hope however that i have given you enough hints to get you started :)
Be good!
Lars

fredag 25 november 2011

Introducing Simplx Mirage

Yes. You are seeing things 

"In contrast to a hallucination, a mirage is a real optical phenomenon which can be captured on camera. ... What the image appears to represent, however, is determined by the interpretive faculties of the human mind." - Wikipedia

Simplx Mirage is a simple Class library that helps you see and handle your MODX Templates and Resources as PHP Classes and Objects. Mirage is my 'optical illusion' to help you build web applications using only the very basic features of MODX.

 Using the awesomeness of MODX 

Since day one with our dear CMS I have seen Templates as modx version of data types, or Classes.

This is not only a working Metaphore but pretty much a practical reality as Templates in MODX do represent a logical entity with named fields. When a Resource chooses a Template it inherits these fields, extending its own set of fields. The Resource ends up representing the Template in much the same manner as an Object represents an instance of a Class.

The MODX API twist

The MODX API is plenty great for dealing with all aspects of the framework. This goes for the modResource class as well. The problem for me however, with my line of thinking, has been that the Template Variables that extend the Templates (and thus also the Resources) are very generic and volatile in their nature. By this l refer to the fact that one TV can be assigned to multiple Templates, and can also be removed from a Template at any time.
The whole thing is made even more problematic by the fact that a Resource can change template at anytime and loose its set of attributes, and thus also its signature. Summing up, we have all the stuff in MODX to turn it in to the Rapid Application Studio for the web, but with a slightly incompatible model.

Now lets put on our 3D goggles and see how Mirage lets us fix this!

Conjuring up the illusion 

Ok. First of all I have made a Template which is to represent a product on my site. This Template has a bunch of Template Variables such as category, price and product image.

I have also made a container Resource called Product in the tree. This in turn is placed in a container called Objects. Like this,

Objects 
- Product 

Remember, when using Mirage, the Product Template with its Template Variables is considered to be a type declaration, or Class.

To create an Object of type Product, we now add a new Resource in our Product container and make sure to set the Template to Product. Lets say the new Resource is called 'Camera' gets the id 30.

Objects 
- Product 
-- Camera 

Create a Snippet (for testing purposes) .

Be sure to include the simplx.mirage.php file.
Declare a php class like this:

class Product extends Simplx_Mirage_Object {} 

We can now get the Product Object like this,

$camera = new Product(30); 

Easy right? You can now thanks to the inner workings of Mirage use this object in plain old php fashion:

$camera->price = 45; 
$camera->category = 'Cameras'; 
$camera->save(); 

And you can use the Simplx_Mirage class to do this:

$ProductClass = Simplx_Mirage::getClass('Product'); 
$cheapCameras = $ProductClass->getObjects(array( 'price:<'=>50, 'category:='=>'Cameras' )); 

Thats all for now kids! Ill continue this article in a day or two :)

Have fun,
Lars

onsdag 23 februari 2011

Adaptive System Principles: Mind set


1. Mind set

The bits and pieces of our ongoing existence, which our subconscious store for quick reference according to some still uncovered scheme, much define how we perceive our reality and the world around us.
One such defining fragment of my past was recorded for future use when I was eleven or twelve. My father had made the decision to spend a small fortune on a home computer, the Commdore 64.

One afternoon he brought with him from work a new tape, which me and my brother of course thought was filled with new 8 bit magic in the form of ground breaking graphics, music and game-play. After the usual eternity of loading my father announced that, after another eternity of waiting, the real magic, that of modern science, would reveal it self in this humble room in the back of our house.

What my father had brought with him from work was chaos. The computer was, with seemingly painstaking labour, building a wonderful and enigmatic weave of swirling colors; the algorithm of the Mandelbrot set was being unveiled pixel by pixel.

What I remember more than the complex patterns on the screen was the message from my father, or maybe creation itself, that the comprehension of something so intricate and mystic was within grasp even for my tiny little brain. What seemed vastly complicated from a distance could actually be built from parts that I might already be familiar with!
I am sure I never ran this program more than twice, but I remember being puzzled by the evidence of the ever repeating patterns; each new level of detail a true test in the virtue of patience, rewarding us with more and more conclusive proof of real magic.

I don't know if my brother remembers this, and I would be surprised if my father does. Moments in life are perceived and processed, indexed or discarded without much intervention from our consciousness. For some reason my brain did me (itself of course...) the favor to implant a resident childish sense, that I only need to look close enough at a problem to find it's solution. And, as always, find comfort in the fact that the solution was already at hand, just at another level of magnification.