We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 10378
    • 375 Posts
    Probably a silly question, but how do I rename an existing field/column of an object container while updating a MODX package?

    Is the alterField method

    alterField( string $class, string $name, array $options = array )


    I found in xpdomanager.class.php what I need?
    How do I use this method to rename a field? Where do I put the new field name?

    $manager->alterField('TableName', 'oldfiledName', array());


    Any kind of help is highly appreciated!
    Thanks, Martin
      Freelancer @bitego http://www.bitego.com
      ---
      GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
      More infos here: http://www.bitego.com/extras/goodnews/
      • 53462
      • 3 Posts
      Ooh, I have the same problem. Any help guys?
        • 10378
        • 375 Posts
        As there is no easy method for renaming fields in xPDO, I solved it this way:

        First new field is created and then the content of the old field is copied over (in this sample the field content is also converted from ISO Date to UNIX timestamp).
        This sample also holds goodies like preventing nasty errors in install log.

        -> content of file: resolve.dbchanges.php

        <?php
        /**
         * Resolve changes to db model on install and upgrade.
         *
         * @package goodnews
         * @subpackage build
         */
        
        /**
         * Checks if a field in a specified database table exist
         * 
         * @param mixed &$modx A reference to the MODX object
         * @param string $xpdoTableClass xPDO schema class name for the database table
         * @param string $field Name of the field to check
         * @return boolean
         */
        if (!function_exists('existsField')) {
            function existsField(&$modx, $xpdoTableClass, $field) {
        
                $existsField = true;
                
                $table = $modx->getTableName($xpdoTableClass);
                $sql = "SHOW COLUMNS FROM {$table} LIKE '".$field."'";
                $stmt = $modx->prepare($sql);
                $stmt->execute();
                $count = $stmt->rowCount();
                $stmt->closeCursor();
                
                if ($count < 1) {
                    $existsField = false;
                }
                return $existsField;
            }
        }
        
        /**
         * Checks if a field in a specified database table exist and creates it if not.
         * (this prevents the annoying erro messages in MODX install log)
         * 
         * @param mixed &$modx A reference to the MODX object
         * @param mixed &$manager A reference to the Manager object
         * @param string $xpdoTableClass xPDO schema class name for the database table
         * @param string $field Name of the field to create
         * @param string $after Name of the field after which the new field should be placed (Optional)
         * @return void
         */
        if (!function_exists('checkAddField')) {
            function checkAddField(&$modx, &$manager, $xpdoTableClass, $field, $after = '') {
        
                if (existsField($modx, $xpdoTableClass, $field)) { return; }
        
                $options = array();
                if (!empty($after)) $options['after'] = $after;
                $manager->addField($xpdoTableClass, $field, $options);
            }
        }
        
        
        if ($object->xpdo) {
            $modx = &$object->xpdo;
            
            switch ($options[xPDOTransport::PACKAGE_ACTION]) {
                case xPDOTransport::ACTION_INSTALL:
                    break;
                    
                case xPDOTransport::ACTION_UPGRADE:
        
                    $modx->log(modX::LOG_LEVEL_INFO, 'Database Changes Resolver - updating required database tables/fields...');
        
                    // Add package
                    $modelPath = $modx->getOption('goodnews.core_path', null, $modx->getOption('core_path').'components/goodnews/').'model/';
                    $modx->addPackage('goodnews', $modelPath);
                    $manager = $modx->getManager();
        
                    // Set log-level to ERROR
                    $oldLogLevel = $modx->getLogLevel();
                    $modx->setLogLevel(xPDO::LOG_LEVEL_ERROR);
        
                    // We need to change the field name of GoodNewsSubscriberMeta.createdon to GoodNewsSubscriberMeta.subscribedon
                    // and change the field type from date to int (phptype="timestamp")
                    
                    // First add the new field
                    checkAddField($modx, $manager, 'GoodNewsSubscriberMeta', 'subscribedon', 'sid');
                    
                    // Now convert all ISO Dates from old createdon field to unix timestamp and move to new subscribedon field
                    if (existsField($modx, 'GoodNewsSubscriberMeta', 'createdon')) {
                        
                        $tblSubscriberMeta = $modx->getTableName('GoodNewsSubscriberMeta');
                        $sql = "UPDATE {$tblSubscriberMeta} SET subscribedon = UNIX_TIMESTAMP(createdon)";
                
                        $updResult = $modx->exec($sql); // returns count of affected rows
                        if ($updResult) {
                            // If conversion was successfull, remove old createdon field
                            $manager->removeField('GoodNewsSubscriberMeta', 'createdon');
                        }
                    }
                    
                    // Set bakck log-level to previous level
                    $modx->setLogLevel($oldLogLevel);
                    break;
        
                case xPDOTransport::ACTION_UNINSTALL:
                    break;
            }
        }
        unset($manager, $oldLogLevel);
        return true;
        
        
          Freelancer @bitego http://www.bitego.com
          ---
          GoodNews - one of the most advanced and integrated Group Mailer premium add-ons for MODX Revolution!
          More infos here: http://www.bitego.com/extras/goodnews/