Page 1 of 1

Content Management System Design / Plugin Implementation

Posted: Wed Oct 01, 2003 10:48 pm
by laterus
I would like to write a simple, clean and object oriented content management system that will make use of a plug-in system. In the past I had written applications in PHP with a terrible implementation of object oriented design. Instead of treating certain entities as objects I would just gather related functions within classes. I used this poor design in a c.m.s. I wrote several years back, times have changed.

Since I have spent much time studying and applying object oriented methodology and would like to make another attempt. I have browsed and reviewed the Movable Type source and find its object oriented base extraordinarily inspirational. The application itself is based on a low-level object, MT. MT's subclass, App, handles most of the user authentication, browser-related details and other important functionality. CMS, the final subclass of MT and App provides the final link to the user containing functions related to the backend itself and other important features.

The data storage device is also similar. Each Entry, Comment and Trackback is a subclass of Object which makes use of specific Drivers objects. The Drivers are written to handle the data storage. The developer could program drivers for MySQL, DBM, XML or just flat-files while the application just implements a standard API. The Object subclasses are able to load themselves, save themselves and do other important storage functions.

The last aspect of Movable Type which I love is the manner in which plugging are used. Developers could write this plug-ins, following certain rules and API's, and place them in a directory that the application browses. Upon the realization of a plug-in it is loaded into the application and hooked into the templating system. It's a well thought out design.

Now, the problem is how could I implement a design like this in a c.m.s. written in PHP? The object oriented design itself isn't too hard to implement. However, the plug-in system is somewhat more difficult to implement. How could the application incorporate this plug-ins into its own code base? Where could I hook this plug-ins into the code of the application? I would love to create plug-ins that has tremendous power and solid access to the application. It would be ideal to be able to write an XML-RPC plug-in that provides a remote interface for external clients.

I need some ideas, comments, code examples. I haven't written a PHP application in some time. In the recent months I have been concentrating on OS X development with Cocoa and Objective-C. I had come up with the idea for plug-ins after working with Objective-C and Cocoa for some time and would like to make use of this practice with a PHP application. I would like to thank those who took the time to read this.

Interesting

Posted: Thu Oct 02, 2003 1:44 pm
by NoReason
It sounds interesting, could you elaborate on this anymore so that I may get a better understanding of the proposed methodology?
Perhaps a few code proposed code snipets..

I noticed in your forum title;
Content Management System
I am trying to design one my self, with grainular security for the various modules and elements that the applicaiton serves.

My current design is .. scetchy.. at best even in my mind. But its the best ive been able to come up with, based on my current knowledge. so having said that, I am always interested in learning somthing new, or finding a differant way to solve a problem.

cheers

Posted: Thu Oct 02, 2003 6:58 pm
by laterus
I'll attempt to summarize what I have come up with. The best way to understanding the design is in terms of objects and their references and relations to one another. In the following lines I will outline each of the proposed objects, parent/children relations as well as other references, here we go.

The application has three main objects that are each responsible for a specific aspect of the entire project: CMS, Template and Object. CMS provides functionality at the lowest level of the application, such as extracting arguments from the URI, authentication and other important low-level tasks. Application, a child or subclass of CMS, extends from this base. It is responsible for providing the administrative backend to the entire project. Application will also be the location where the PluginManager hooks into the application. PluginManager is responsible for authorizing plugins and adding the plugin into the plugin queue as well as adding other plugin information into the system (this system must be considered further and would require the space of a multi-document paper).

Template is the object that the HTML compiler is based on. This object is used by the Application object to create HTML for the application's administrative backend, which is completely dynamic. Compiler, a subclass of Template, is used to compile the static HTML for the target web site. The Definitions object contains a list of handles that refer to template tags and references to their respective functions. These tags are searched for and replaced with the output of their functions during compile time. I haven't found a place to tie this object into the template system, but I suppose the best place is the parent of Template. Definitions is also responsible for loading and incorporating external definitions, either created by myself (the developer) or third-parties. These external definitions would be added to the main list of other definitions via a special method provided by Definitions. It would be possible to write a plugin and definition that could be used together. If more are interested I could spend some time writing about definitions and plugins in a later post.

Object is an object (obviously) that represents data in the application, albeit an entry, comment, trackback, etc. Object contains functions which allow the data to be written to disk. However, the magic behind this implementation is abstraction. The developer, or an able third-party, could write small objects called drivers which handle the data and write them to a secondary storage device (for those not into computer science, hard disk, etc). These drivers could store the data in a database, flat-file or an XML document depending on their needs. The magic is that the application doesn't need to know how the storage is implemented just which methods to call. DriverManager is the object responsible for authorizing these drivers (making sure it conforms to the established protocol or interface) and loading the driver into the application.

The last object I would like to discuss is the Console. This object is utilized as a service within all objects, it logs all user activity for use in debugging and security. It runs on multiple levels, from debugging that records everything from method calls to authentication to database requests to simple security logging. These logs and records can either be saved to a database, xml document or flat-file depending on which driver is being utilized. It would be a superb means in recording and reporting application errors, a big help.

It's a somewhat complicated design, but the room for expansion is huge and allows the application to be easily maintained. I would love to get this project started within the next few weeks, and if there are people interested in understanding this design further please don't hesitate to contact me.

Posted: Thu Oct 02, 2003 9:31 pm
by McGruff
First step is to work out what is common to all modules, and abstract that out in a useful way.

I'd suggest starting with a single module (one of the more complex examples like a discussion forum - I assume that's the kind of thing you mean by module plug-ins?). Working out the module API is much easier with only one module to edit - get it as fully developed as you can before rolling out to other modules.

Enabling an admin interface to automatically detect modules is as simple as putting each one in its own folder inside a "modules" folder and telling your main admin page to go and look there.

Posted: Sun Oct 05, 2003 11:55 pm
by NoReason
Well .. In my case, the problem with authentication/security in modules is that I require a grainular type of security, where I can explicitly deny or allow a service, element, or function to a user account.

My modules are being authorized/loaded based on the security privalages of that perticular account. This is tracked in a database using a self refrencing table that is used to create an Access Control List, its grainular in that I can create groups of ACL and assign it to an account, or add a specific element/function/service which is loaded in at time of authentication. Removal of a privalage while logged in will remove the ability to finalize the action even if they had access at time of login... ITs a great little system in my opinion. One problem though .. the ID's of the ACL are hardcoded into the buisness rules.. No way around that that I am aware of so far.

But a big one for me has always been a navigation system.. Currently I am doing everything in post vars, not get vars.. This removes the god awfull mess that can clutter the uri, and provides a bit of security( though obscruity) as well. Navigation posts to a page that takes in the post variable from teh submitting nav element and determains what module and document that will be include() as the main content. Simple and effective, however most peeps think its .. "wacked out" but its how ive always done it.. and it works..

Most actions that require access to the userClass or documentClass of my app all post to a new doc for proccessing and security.. Unless these actions are coded in as a java script that is just modifing or checking form entries etc..

Anyway, I see that my app is not far from grace when read about peeps projects.. One big diff though is that i am working on a iis/php/mssql platform, and work mostly in tracking systems for company resources.
Always looking for a better way to do it.. but so far i have had 3 changes the the system and each time I am having always break some element in the framework that drives me nuts...

l8s