The Problem
In the latest version of MyComponent, I faced a problem I'd never seen before. In most of my projects, I had been moving whole directories in the transport package. If you've created any extras, you've probably seen code like the following:
$vehicle->resolve('file', array(
'source' => $sources['source_core'],
'target' => "return MODX_CORE_PATH . 'components/';",
));
The code above, packages the entire core directory of the project and moves it to the core/components/componentName/ directory of the site where it's being installed. A similar bit of code moves the assets directory to the assets/component/componentName/ directory.
In my case, I needed to move the Example project's config file to the installation site as well. That file is in the _build/config/ directory at my local site. Moving the entire _build/config/ directory to the installation site would be ludicrous, because it contains all the config files for all my extras. Nobody wants forty-plus extra config files installed at their site along with MyComponent. I just wanted to package the Example config file in addition to the current package's config file.
In working it out, I made a couple of stupid errors, so I thought I'd confess to them here, so you could avoid them if you ever need to move a single file in a transport package.
The Wrong Solution
The first thing I tried was to put the full path to that file in a file resolver's target field, like this:
$vehicle->resolve('file', array(
'source' => $sources['root'] . '/_build/config/example.config.php',
'target' => "return MODX_CORE_PATH .
'components/mycomponent/_build/config/example.config.php';",
));
When I installed MyComponent, I discovered that the file was there, but with this directory structure:
core
components
mycomponent
_build
config
example.config.php
example.config.php
The file was transferred, but MODX put it in an odd place. It should be under the config/ directory. Notice the two instance of example.config.php/. The first one is a directory, the second one is the file I wanted to transport. For obvious reasons, my program couldn't find the file, since it was looking for it in the _build/config directory.
Why did the file end up where it did? Because when MODX creates a file resolver, it treats the source field as a full path to a file, but the target field holds the directory where you want that file. Once I figured this out, the solution seemed simple.
Another Wrong Solution
My next try was this code:
$vehicle->resolve('file', array(
'source' => $sources['root'] . '/_build/config/example.config.php',
'target' => "return MODX_CORE_PATH .
'components/mycomponent/_build/config';",
));
This code looks good and works perfectly, but it's not right. It installs the file in the right place, the program finds it, and it everything works — until you uninstall it. When you do that, the console shows an error like this:
Could not find file to remove: configexample.config.php.
You've probably already guessed what the problem is, and how to solve it.
The Correct Solution
$vehicle->resolve('file', array(
'source' => $sources['root'] . '/_build/config/example.config.php',
'target' => "return MODX_CORE_PATH .
'components/mycomponent/_build/config/';",
));
As with most MODX paths and URLs, the target directory needs to end with a slash. Without it, the file is installed correctly, but when MODX goes to remove it, it just tacks the filename onto the end of the directory name. Without the slash at the end of the directory, it can't find the file.
Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.