We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 3749
    • 24,544 Posts
    I can probably figure it out from the source code, but is there a guide somewhere for creating Transport Packages?

    If there’s no objection, I’d like to create one for SPForm and perhaps EZFaq to go in the add-ons section.

    If it’s premature to do this or if they don’t belong in that section, let me know.

    Bob

      Did I help you? Buy me a beer
      Get my Book: MODX:The Official Guide
      MODX info for everyone: http://bobsguides.com/modx.html
      My MODX Extras
      Bob's Guides is now hosted at A2 MODX Hosting
      • 22303 MODX Staff
      • 10,725 Posts
      BobRay, I’m working on a MODx 0.9.7 Developer’s Guide and companion Migration Guide as quickly as I can. In the meantime, let me see if I can get you started with an example from the modx-components subversion repository:

      I generally create a project folder and create a transport build script in a _build subfolder, that looks something like this:
      <?php
      define(MODX_CORE_PATH, '/path/to/a/valid/core/');
      define(MODX_CONFIG_KEY, 'config');
      require_once (MODX_CORE_PATH . 'model/modx/modx.class.php');
      $modx= new modX();
      $modx->initialize('mgr');
      
      // set debugging on so you can see what's happening
      $modx->setDebug(true);
      
      // setup some variables to use
      $name = 'filedownload';
      $version = '2.5.97';
      $release = 'beta-1';
      
      // load the modPackageBuilder class and get an instance
      $modx->loadClass('transport.modPackageBuilder','',false, true);
      $builder = new modPackageBuilder($modx);
      
      // create a new package
      $builder->create($name, $version, $release);
      
      // define some locations for file resources
      $sources= array (
          'root' => dirname(dirname(__FILE__)) . '/',
          'assets' => dirname(dirname(__FILE__)) . '/assets/'
      );
      
      // get the source from the actual snippet in your database
      //$c= $modx->getObject('modSnippet', array('name', 'FileDownload'));
      
      // OR
      
      // manually create the object, grabbing the source from a file
      $c= $modx->newObject('modSnippet');
      $c->set('name', 'FileDownload');
      $c->set('description', '<strong>' . $version . ' ' . $release . '</strong> FileDownload for MODx 0.9.7');
      $c->set('snippet', file_get_contents($sources['root'] . 'snippet.filedownload.php'));
      
      // set up some attributes that define install behavior
      $attributes= array(
          XPDO_TRANSPORT_UNIQUE_KEY => 'name',
          XPDO_TRANSPORT_PRESERVE_KEYS => true,
          XPDO_TRANSPORT_UPDATE_OBJECT => true,
      );
      
      // create a transport vehicle for the data object
      $vehicle = $builder->createVehicle($c, $attributes);
      $vehicle->resolve('file',array(
          'source' => $sources['assets'] . 'snippets/filedownload',
          'target' => "return MODX_ASSETS_PATH . 'snippets/';",
      ));
      
      // put the vehicle into the package
      $builder->putVehicle($vehicle);
      
      // zip up the package
      $builder->pack();
      
      ?>

      You can see other examples throughout the modx-components repository.

      The ultimate goal is to create a UI for building these packages, but for now, you’ll have to create them like this using the modPackageBuilder API.
        • 3749
        • 24,544 Posts
        Thanks. That should get me started.
          Did I help you? Buy me a beer
          Get my Book: MODX:The Official Guide
          MODX info for everyone: http://bobsguides.com/modx.html
          My MODX Extras
          Bob's Guides is now hosted at A2 MODX Hosting
          • 3749
          • 24,544 Posts
          I think I’m pretty close. The program runs and produces the files in the package directory. I haven’t tried to install the package yet but I did get these errors and warnings so I thought I’d ask if they mean anything went wrong:

          [2008-05-03 14:30:02] (DEBUG @ /file:/C:/xampp/htdocs/MODx097/_build/mytransport.php)
          No primary key value found for pk definition: id
          
          [2008-05-03 14:30:02] (ERROR @ C:\xampp\htdocs\MODx097\core\xpdo\cache\xpdocachemanager.class.php : 132)
          PHP warning: mkdir() [function.mkdir]: No such file or directory
          
          [2008-05-03 14:30:02] (ERROR @ C:\xampp\htdocs\MODx097\core\xpdo\cache\xpdocachemanager.class.php : 132)
          PHP warning: mkdir() [function.mkdir]: No such file or directory
          
          ...
          
          [2008-05-03 14:30:02] (DEBUG @ /file:/C:/xampp/htdocs/MODx097/_build/mytransport.php)
          Error fetching result set from statement: SELECT `modSession`.`id` AS `modSession_id`, `modSession`.`access` AS `modSession_access`, `modSession`.`data` AS `modSession_data` FROM `modx_session` AS `modSession` WHERE `modSession`.`id` = ?  with bindings: Array
          (
              [0] => Array
                  (
                      [value] => 0ea2dd75cbe4db2caaf382f48f74e748
                      [type] => 2
                      [length] => 0
                  )
          
          )
          
          [2008-05-03 14:30:02] (WARN @ /file:/C:/xampp/htdocs/MODx097/_build/mytransport.php)
          Error fetching result set from query: SELECT `modSession`.`id` AS `modSession_id`, `modSession`.`access` AS `modSession_access`, `modSession`.`data` AS `modSession_data` FROM `modx_session` AS `modSession` WHERE `modSession`.`id` = ? Array
          (
              [0] => 00000
          )
          
           ...
          
          2008-05-03 14:30:02] (DEBUG @ /file:/C:/xampp/htdocs/MODx097/_build/mytransport.php)
          Returning validation rules: Array
          (
          )
          
          [2008-05-03 14:30:02] (INFO @ /file:/C:/xampp/htdocs/MODx097/_build/mytransport.php)
          Validation called but no rules were found.
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 3749
            • 24,544 Posts
            Errors aside, the EZFaq package installed the first time and appears to work fine. Man, what a cool system. grin grin grin

            I would have done SPForm first, but it’s going to be trickier since it’s actually three snippets rather than one. I’m still not sure how to handle that (or if it’s even possible in a single package).
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
              • 22303 MODX Staff
              • 10,725 Posts
              If you run it from the web, it’ll work fine. For the time being, I do not have a proper handler for using the CLI interface with the modX class where sessions are not allowed, but the errors in this regard are ignorable. As are the ones related to validation. If you comment out the $modx->setDebug(true) line, you won’t see any of these messages except the actual ERROR level message:

              [2008-05-03 14:30:02] (ERROR @ C:\xampp\htdocs\MODx097\core\xpdo\cache\xpdocachemanager.class.php : 132)
              PHP warning: mkdir() [function.mkdir]: No such file or directory


              This makes me think there may be an issue with the permissions on your /core/cache or core/packages/ directory? Not sure on this one.

              As for multiple vehicles per package, absolutely. A package can contain a single vehicle or collection of vehicles, so just repeat the vehicle creation process and put each into the package before pack()’ing it. Just keep in mind the order in which you add the vehicles is the order they are placed in the package manifest and this defines the order they are installed.

              In the works:

              • xPDOEmptyVehicle - to allow installation of physical resources or the execution of upgrade, uninstall, or other scripts (collectively known as vehicle validators and resolvers) without having an actual database row to represent in the vehicle.
              • An extensible manager UI - to allow creation of packages from within the manager by selecting xPDO objects from the database and/or files/folders from the file system.
                • 3749
                • 24,544 Posts
                Quote from: OpenGeek at May 03, 2008, 05:30 PM

                If you run it from the web, it’ll work fine. For the time being, I do not have a proper handler for using the CLI interface with the modX class where sessions are not allowed, but the errors in this regard are ignorable. As are the ones related to validation. If you comment out the $modx->setDebug(true) line, you won’t see any of these messages except the actual ERROR level message:

                [2008-05-03 14:30:02] (ERROR @ C:\xampp\htdocs\MODx097\core\xpdo\cache\xpdocachemanager.class.php : 132)
                PHP warning: mkdir() [function.mkdir]: No such file or directory


                This makes me think there may be an issue with the permissions on your /core/cache or core/packages/ directory? Not sure on this one.

                Seems unlikely since it’s Windows localhost, although with Vista, anything’s possible. Is the code maybe using a _SERVER variable to specify the dir? I ran it from within my editor which, I think, has its own version of PHP to execute.

                The referenced line is in the writeTree() function.

                It’s weird because the line in question should short-circuit when the first part of the OR is true, and even if it doesn’t, the @ should suppress the error message.

                    function writeTree($dirname, $mode= 0777) {
                        $written= false;
                        if (!empty ($dirname)) {
                            $dirname= strtr(trim($dirname), '\\', '/');
                            if ($dirname{strlen($dirname) - 1} == '/') $dirname = substr($dirname, 0, strlen($dirname) - 1);
                  -->>>  [color=red] if (is_dir($dirname) || @mkdir($dirname, $mode)) {[/color]
                                $written= true;
                            } elseif (!$this->writeTree(dirname($dirname), $mode)) {
                                $written= false;
                            } else {
                                $written= @ mkdir($dirname, $mode);
                            }
                            if ($written && !is_writable($dirname)) {
                                @ chmod($dirname, $mode);
                            }
                        }
                        if (!$written) {
                            $this->xpdo->_log(XPDO_LOG_LEVEL_ERROR, "Could not create directory {$dirname}");
                        }
                        return $written;
                    }


                Edit: Got it to work in the debugger. I’ll mess around some more and see if I can catch it failing.


                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 3749
                  • 24,544 Posts
                  After stepping through it a bunch of times, I think I see what’s happening.

                  The first directory checked is "../core/cache" -- no problem.

                  The next one, though, is:

                  "core/packages/EZFaq/modsnippet/12e3459f872398..." // mkdir() tries to create 3 directories at once - error

                  Then it tries "core/packages/EZFaq/modsnippet" // which also fails - error

                  Then "core/packages/EZFaq" // which succeeds

                  I’ve looked but I can’t really tell if this is by design or a bug. A breakpoint on the recursive call in writeTree() doesn’t ever trip and I can’t find any code that calls writeTree in a loop that walks back through the directories it’s trying to create.

                  At any rate, it appears that all the requisite files and directories are created.



                    Did I help you? Buy me a beer
                    Get my Book: MODX:The Official Guide
                    MODX info for everyone: http://bobsguides.com/modx.html
                    My MODX Extras
                    Bob's Guides is now hosted at A2 MODX Hosting
                    • 22303 MODX Staff
                    • 10,725 Posts
                    Ah, yes that is by design; I believe the modErrorHandler class just needs to be adjusted to not log the suppressed errors unless an option is set.
                      • 3749
                      • 24,544 Posts
                      Quote from: OpenGeek at May 04, 2008, 11:58 AM

                      Ah, yes that is by design; I believe the modErrorHandler class just needs to be adjusted to not log the suppressed errors unless an option is set.

                      As far as the error handling is concerned, it’s a warning not an error (E_WARN). The trouble with suppressing it, though, is that I think permission problems could generate the exact same error on certain iterations and it would be a real error.

                      Could we assume that the core directory will always be called "core" and start performing the mkdir() commands in order following the "core" dir from left to right rather than the other way around? That would eliminate the false errors.
                        Did I help you? Buy me a beer
                        Get my Book: MODX:The Official Guide
                        MODX info for everyone: http://bobsguides.com/modx.html
                        My MODX Extras
                        Bob's Guides is now hosted at A2 MODX Hosting