Getting started with xPDO "A guide by an idiot, for others of a similar persuasion ..... " To set the scene, I use a Windows XP workstation and have a home server running SME Server 7.1 behind an IPCOP firewall connected to ADSL. The tools I use and recommend are noted at the end of this guide.
Having fallen in love with ModX, and having read up on the much anticipated new core coming in 0.9.7, I thought to myself, "i'd like to have a go at that", so I started to read up all I could find.
Disaster, I couldn't understand a word of it. Sorry Jason and Co. but you clever guys leave us mere mortals lagging far behind - especially this fat old fart in his late fifties whose last exposure to the world of programming involved COBOL.
So, having time on my hands after being made redundant (hooray!), I decided to see if I could delve into the mysterious box of tricks to see if I could produce a starters guide of such stunning simplicity even I could pretend to understand it. 99.9% of this content was originally created by Jason and others, all I have done is try to organise and present it in a simple manner.
So here goes :
1. Obtain a copy of xPDO from
www.xpdo.org - either the packaged version as a zip file or the latest SVN using the tool of your choice.
2. Create a folder called /xpdo at the same level as /assets and /manager in your modx installation.
3. Create a folder called /_model under /xpdo and give it write permissions (777 using chmod or WinSCP).
4. Obtain a copy of the current modx095 xml schema (attached at the end of this post), and upload it to /_model.
5. Create a folder called /modx095 under /om and give it write permissions (777 using chmod or WinSCP).
6. In the manager, create a snippet (I called mine 'xml2class', but you please yourselves) as below :
<?php
///
// To forward-engineer your database, just tailor the [reverse-engineered]
// xml file (the schema) then comment the reverse-engineering line and
// uncomment the forward-engineering line; that will generate the classes
// and maps of your object model and provide the basic scaffolding for
// working with those objects
//
$mtime= microtime();
$mtime= explode(' ', $mtime);
$mtime= $mtime[1] + $mtime[0];
$tstart= $mtime;
echo "</br>Execution started : </br>";
//
// set up and connect to the database
//
global $modx;
include_once ( $modx->config['base_path'] . 'xpdo/xpdo.class.php');
$xpdo= new xPDO('mysql:host=localhost;dbname=mdx', 'mdxAdmin', 'mdxAdminLouches', 'mdx_');
$xpdo->setPackage('modx095');
$xpdo->setDebug(true);
//
// initiate the manager
//
$manager= $xpdo->getManager();
$generator= $manager->getGenerator();
//
// reverse-engineer an existing database
//
//$xml= $generator->writeSchema(XPDO_CORE_PATH . '_model/mymodel.mysql.schema.xml', 'mymodel', 'xPDOObject', 'optional_tbl_prefix_');
//
// forward-engineer a model
//
$generator->parseSchema(XPDO_CORE_PATH . '_model/schema_modx095_mysql.xml');
$mtime= microtime();
$mtime= explode(" ", $mtime);
$mtime= $mtime[1] + $mtime[0];
$tend= $mtime;
$totalTime= ($tend - $tstart);
$totalTime= sprintf("%2.4f s", $totalTime);
echo "</br>Execution ended : </br>";
echo "Execution time: {$totalTime}</br>";
?>
Now we can start. As I understand it and in very simple terms, xPDO needs an XML schema describing the tables and relationships within the ModX (or other) database from which it can build the classes and maps that enable it to access the data. (I can hear all the techies sniggering..).
There is some good news, and some good and not so good news.
The first good news is that Jason has very kindly provided the full schema for ModX 0.9.5 that you should have downloaded above, from which we can generate the required classes and maps using the snippet described above.
The second good news is that the same snippet can be used to reverse engineer an XML schema from an existing database BUT this will not contain the relationship information which will have to be added manually. In my view, being that we have a wonderful starting point with the modx095 schema, it would be wise not to try to reverse engineer but to manally update the existing shema and always forward engineer the classes and maps.
7. Create a new document in the manager called xPDO Generator; access Site Admin only, not rich text, using template (blank); with one line in it :
[! xml2class? !]
8. Log yourself in the front end as the SiteAdmin web user and execute your page from the recent pages list. Alternatively call your page explicitly using the code below (nn = number of the document created above):
http://yourserver/modx/index.php?id=nn
***I'm sure there is an easier way to do this - but it works - even if a bit convoluted!***
9. Now check in /om/modx095/mysql, you should have lots of classes and maps !
Now let's see if it works ......10. In the manager, create a snippet (I called mine 'testPDO', but you please yourselves) as below :
<?php
//
// get start time
//
$mtime= microtime();
$mtime= explode(' ', $mtime);
$mtime= $mtime[1] + $mtime[0];
$tstart= $mtime;
echo "</br>Execution started: </br>";
//
// startup and connect to the database
//
global $modx;
define('XPDO_MODE', 2);
include_once ( $modx->config['base_path'] . 'xpdo/xpdo.class.php');
$xpdo= new xPDO('mysql:host=localhost;dbname=mdx', 'mdxAdmin', 'mdxAdminLouches', 'modx_');
$xpdo->setPackage('modx095');
$xpdo->setDebug(false);
//
// get the record of your choice, here its the default content thank-you page, no. 46
//
$id= 46;
$criteria= $xpdo->newQuery('modResource', $id);
$criteria->limit(1);
$docm= $xpdo->getObject('modResource', $criteria);
//
// get the column values that you want and display them
//
//$content= $docm->_fields['content']; ----- possible alternative get method
$content= $docm->get('content');
$pagetitle= $docm->get('pagetitle');
$longtitle= $docm->get('longtitle');
echo "</br>Content : {$content}";
echo "</br>PageTitle : {$pagetitle}</br>";
//
// update the longtitle by adding a string
//
$longtitle2= $longtitle . '.added this phrase.';
$docm->set('longtitle', $longtitle2);
$docm->save();
echo "</br>Updated longtitle from {$longtitle} to {$longtitle2}</br>";
echo "</br>Execution ended: </br>";
$mtime= microtime();
$mtime= explode(' ', $mtime);
$mtime= $mtime[1] + $mtime[0];
$tend= $mtime;
$totalTime= ($tend - $tstart);
$totalTime= sprintf("%2.4f s", $totalTime);
echo "</br>Execution time: {$totalTime}</br>";
?>
11. Create a new document in the manager called xPDO Test; access Site Admin only, not rich text, using template (blank); with one line in it :
[! testPDO? !]
12. Log yourself in the front end as the SiteAdmin web user and execute your page from the recent pages list, Alternatively call your page explicitly using the code below (nn = number of the document created above):
http://yourserver/modx/index.php?id=nn
... and that is the first step down the road... The tools I use :
IPCOP Firewall
http://www.ipcop.orgSME SERVER
http://www.smeserver.org or
http://www.contribs.orgWindows XP ... no further comment
WinSCP
http://www.winscp.netPutty
http://www.chiark.greenend.org.uk/~sgtatham/putty/RapidSVN
http://rapidsvn.tigris.org/