1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Upgrading an Existing Add-on

Discussion in 'XenForo Development Discussions' started by AndyB, Dec 7, 2013.

  1. AndyB

    AndyB Well-Known Member

    I would like some clarification on Upgrading an Existing Add-on.

    My add-on "Flag Thread" uses the Installation Code and Uninstallation Code fields to alter the xf_thread table during installation and uninstallation.

    My question is, what happens if the Upgrade Add-on button is used to upgrade the add-on? Will the Installation Code run? I assumed it would not, but it appears that it does.
     
  2. Brogan

    Brogan XenForo Moderator Staff Member

    Are you concerned about the query used to add the table/field being run again?
    If so, use if not exists or try/catch.
     
  3. AndyB

    AndyB Well-Known Member

    Hi Paul,

    Yes that is the problem, the alter table command cannot be run on a table that already has the column added from a previous install.

    I looked at the MySQL command IF NOT EXISTS which appears to only be used for CREATE TABLE command. In my case I'm not creating a table but alerting it.

    Here's my code:

    PHP:
    <?php

    class Andy_FlagThread_Install
    {
        public static function 
    install()
        {
            
    $db XenForo_Application::get('db');      
            
    $db->query("
                ALTER TABLE xf_thread
                    ADD flag TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT 0
            "
    );
        }
    }

    ?>
    I suppose I could simply state in my add-on instructions to NOT upgrade, but to uninstall the add-on and then install the newer version.
     
  4. Brogan

    Brogan XenForo Moderator Staff Member

    Use try/catch for adding a field to an existing table.

    PHP:
    try
        {
            
    $db->query("
                ALTER TABLE xf_thread
                    ADD flag TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT 0
            "
    );
        }
    catch (
    Zend_Db_Exception $e) {}
     
    Chris D likes this.
  5. AndyB

    AndyB Well-Known Member

    Thank you, Paul. That is exactly the information I needed. Works perfect.

    PHP:
    <?php

    class Andy_FlagThread_Install
    {
        public static function 
    install()
        {
            
    $db XenForo_Application::get('db');        
            
            try
            {    
                
    $db->query("
                    ALTER TABLE xf_thread
                        ADD flag TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT 0
                "
    );
            }
            catch (
    Zend_Db_Exception $e)
            {
                return 
    false;
            }
        }
    }

    ?>
     
  6. Brogan

    Brogan XenForo Moderator Staff Member

    You don't need the return.
     
  7. AndyB

    AndyB Well-Known Member

    Thank you.

    PHP:
    <?php

    class Andy_FlagThread_Install
    {
        public static function 
    install()
        {
            
    $db XenForo_Application::get('db');        
            
            try
            {    
                
    $db->query("
                    ALTER TABLE xf_thread
                        ADD flag TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT 0
                "
    );
            }
            catch (
    Zend_Db_Exception $e) {}
        }
    }

    ?>
     
  8. AndyB

    AndyB Well-Known Member

    I assume it's good practice to use the try/catch code on the Uninstall.php as well?

    PHP:
    <?php

    class Andy_FlagThread_Uninstall
    {
        public static function 
    uninstall()
        {
            
    $db XenForo_Application::get('db');
            
            try
            {        
                
    $db->query("
                    ALTER TABLE xf_thread
                        DROP flag
                "
    );
            }
            catch (
    Zend_Db_Exception $e) {}
        }
    }

    ?>
     
  9. Chris D

    Chris D XenForo Developer Staff Member

    Yeah good practice to use try/catch there too.

    Speaking of good practice.

    You should also be looking to prefix your custom columns and custom database tables with some sort of prefix unique to your add-on. Reason being, if XenForo were ever to update XenForo in future with a column called "flag" in the xf_thread table, it would no doubt cause all sorts of problems during upgrade for people who have your add-on installed.

    Something like andyb_flag would work well.
     
    AndyB likes this.
  10. AndyB

    AndyB Well-Known Member

    Thank you, Chris. That is excellent advice.
     
  11. TheJP

    TheJP Member

    Isn't there an easy way to detect which version of the addon is currently installed? That would allow to write much cleaner upgrade code.
    (Using try/catch avoid unhandled exceptions is good practice. But to rely on them, when the exception itself could be avoided isn't.)

    Edit: I found this: http://xenforo.com/community/threads/suggestion-is-addon-installed.43221/#post-570401
    I will try this out in the installation script as indication which version is installed.
     
    Last edited: Feb 6, 2014
  12. Brogan

    Brogan XenForo Moderator Staff Member

    You simply use this in your installer:
    PHP:
    public static function install($installedAddon)
    {
        
    $version is_array($installedAddon) ? $installedAddon['version_id'] : 0;

        if (
    $version 1050010)
        {
    Where 1050010 is the version ID.
     
    Aayush likes this.
  13. TheJP

    TheJP Member

    Thank you. This approach is even easier.
     
  14. AndyB

    AndyB Well-Known Member

    Where does $installedAddon variable get defined?

    PHP:
    public static function install($installedAddon)
     
  15. Chris D

    Chris D XenForo Developer Staff Member

    It gets passed to the function automatically when the installation callback gets called.
     
    AndyB likes this.

Share This Page