Ok, one of the final delays in getting 0.9.7 ready for preview is having at least the basic add-ons that have been included in our core distributions to-date, migrated to the new API’s and packaged for distribution as official MODx transport packages. It’s now time for component developers to step-up to help migrate and package their components for 0.9.7.
As part of this effort, I want to encourage a little more formality in maintaining the components considered critical to the project. To get us started, I have created a new SVN repository (see
http://svn.modxcms.com:8000/svn/modx-components) that contains a directory for each component that is to be packaged individually, and within each of those is the standard branches/tags/trunk structure. But the structure in trunk is equally as important, especially the _build/ directory and the structure for the rest of the component source, which I will try to explain, as they relate to the build scripts; here’s an example:
<?php
$mtime = microtime();
$mtime = explode(" ", $mtime);
$mtime = $mtime[1] + $mtime[0];
$tstart = $mtime;
// get rid of time limit
set_time_limit(0);
// create this file and override with your own defines here (see build.config.sample.php)
require_once ('build.config.php');
require_once (MODX_CORE_PATH . 'model/modx/modx.class.php');
$modx= new modX();
$modx->initialize('mgr');
//$modx->setDebug(true);
$modx->loadClass('transport.xPDOTransport', XPDO_CORE_PATH, true, true);
if (!$workspace= $modx->getObject('modWorkspace', array('active' => 1))) {
echo "\nYou must have a valid core installation with an active workspace to run the build.\n";
exit();
}
$packageDirectory= $workspace->get('path') . 'packages/';
$packageSignature= array (
'name' => 'tinymce',
'version' => '2.0.9',
'release' => 'rc2',
);
$signature= implode('-', $packageSignature);
$packageFilename= $signature . '.transport.zip';
if (file_exists($packageDirectory . $packageFilename)) {
unlink($packageDirectory . $packageFilename);
}
if (file_exists($packageDirectory . $signature) && is_dir($packageDirectory . $signature)) {
$cacheManager= $modx->getCacheManager();
$cacheManager->deleteTree($packageDirectory . $signature);
}
$package= new xPDOTransport($modx, $signature, $packageDirectory);
$sources= array (
'assets' => dirname(dirname(__FILE__)) . '/assets/'
);
// get the source from the actual snippet in your database (make sure it is correct in db)
// [alternative] you could also manually create the object, grabbing the source from a file
// or you can manually set the properties of the object before putting it in the package
$c= $modx->getObject('modPlugin', array ('name' => 'TinyMCE'));
$c->set('category', 0);
// use resolve attributes of type 'php' to add scripts that run after the object record is
// saved to the appropriate database table when the package is installed
$attributes['resolve'][]= array (
'type' => 'php',
'source' => dirname(__FILE__) . '/scripts/add_plugin_events.php',
);
// use resolve attributes of type 'file' to add physical file resources to the file system
// when the package is installed; target is evaluated on the deployment it is being
// installed at, so no matter where users have configured the location of various
// directories, you can install the files in the appropriate place
$attributes['resolve'][]= array (
'type' => 'file',
'source' => $sources['assets'] . 'plugins/tinymce',
'target' => "return MODX_ASSETS_PATH . 'plugins/';",
);
// this package attribute indicates that the name field must be unique on install
$attributes['unique_key']= 'name';
// this puts the object into the package
$package->put($c, $attributes);
// this compresses the package into a zip file
$package->pack();
$mtime= microtime();
$mtime= explode(" ", $mtime);
$mtime= $mtime[1] + $mtime[0];
$tend= $mtime;
$totalTime= ($tend - $tstart);
$totalTime= sprintf("%2.4f s", $totalTime);
echo "\nExecution time: {$totalTime}\n";
exit ();
?>
Now you can simply run this script to build a package from your sources. The tricky part of course will be testing the components within a deployment, but I have yet to find a simple way to manage this. I imagine as more people get involved and start building packages, we’ll find better solutions to this. But for now you’ll just have to make sure you copy changes to your file dependencies when developing/testing in a deployment back to the appropriate source locations in the component’s SVN repository for check-in and package building.
This is more work than most of you are used to when developing a component, but I think the benefits of packaging and consistency in development structure will help strengthen the incentives for more serious development of MODx add-ons and extensions.
I am in the process of setting up a temporary download repository where packages can be retrieved, as well as the infrastructure for providing trusted downloads of the packages via web services, directly to a MODx deployment. These services will be deployed in conjunction with a new, refactored version of the MODx add-on repository. More on this soon, but until this is ready, we can simply communicate when new components are ready to be posted and I’ll build the packages and place them in the download area.
Please don’t hesitate to ask questions or make suggestions if you have them.
NOTE: You must upgrade to the latest SVN version of 0.9.7 for these new build scripts to work, as they require the presence of a new core class called modWorkspace (table = workspaces), and two additional classes called transport.modTransportPackage and transport.modTransportProvider in order to actually perform installations from the packages you build.