Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Install/Upgrade/2010010-210a.php
<?php

namespace XF\Install\Upgrade;

use
XF\Db\Schema\Alter;
use
XF\Db\Schema\Create;

class
Version2010010 extends AbstractUpgrade
{
    public function
getVersionName()
    {
        return
'2.1.0 Alpha';
    }

    public function
step1()
    {
       
$this->createTable('xf_addon_install_batch', function (Create $table) {
           
$table->addColumn('batch_id', 'int')->autoIncrement();
           
$table->addColumn('start_date', 'int')->setDefault(0);
           
$table->addColumn('complete_date', 'int')->setDefault(0);
           
$table->addColumn('addon_ids', 'mediumblob');
           
$table->addColumn('results', 'blob');
        });

       
$this->createTable('xf_api_attachment_key', function (Create $table) {
           
$table->addColumn('attachment_key', 'varbinary', 32)->primaryKey();
           
$table->addColumn('create_date', 'int');
           
$table->addColumn('user_id', 'int');
           
$table->addColumn('temp_hash', 'varbinary', 32);
           
$table->addColumn('content_type', 'varbinary', 25);
           
$table->addColumn('context', 'blob');
           
$table->addKey('create_date');
        });

       
$this->createTable('xf_api_key', function (Create $table) {
           
$table->addColumn('api_key_id', 'int')->autoIncrement();
           
$table->addColumn('api_key', 'varbinary', 32);
           
$table->addColumn('api_key_hash', 'varbinary', 20);
           
$table->addColumn('title', 'varchar', 50)->setDefault('');
           
$table->addColumn('is_super_user', 'tinyint', 3);
           
$table->addColumn('user_id', 'int')->setDefault(0);
           
$table->addColumn('allow_all_scopes', 'tinyint', 3);
           
$table->addColumn('scopes', 'mediumblob');
           
$table->addColumn('active', 'tinyint', 3);
           
$table->addColumn('creation_user_id', 'int')->setDefault(0);
           
$table->addColumn('creation_date', 'int')->setDefault(0);
           
$table->addColumn('last_use_date', 'int')->setDefault(0);
           
$table->addUniqueKey('api_key_hash');
        });

       
$this->createTable('xf_api_key_scope', function (Create $table) {
           
$table->addColumn('api_key_id', 'int');
           
$table->addColumn('api_scope_id', 'varbinary', 50);
           
$table->addPrimaryKey(['api_key_id', 'api_scope_id']);
        });

       
$this->createTable('xf_api_scope', function (Create $table) {
           
$table->addColumn('api_scope_id', 'varbinary', 50);
           
$table->addColumn('addon_id', 'varbinary', 50)->setDefault('');
           
$table->addPrimaryKey('api_scope_id');
        });

       
$this->createTable('xf_bookmark_item', function (Create $table) {
           
$table->addColumn('bookmark_id', 'int')->autoIncrement();
           
$table->addColumn('user_id', 'int');
           
$table->addColumn('content_type', 'varbinary', 25);
           
$table->addColumn('content_id', 'int');
           
$table->addColumn('bookmark_date', 'int');
           
$table->addColumn('message', 'text');
           
$table->addColumn('labels', 'mediumblob');
           
$table->addKey(['content_type', 'content_id']);
           
$table->addUniqueKey(['user_id', 'content_type', 'content_id']);
        });

       
$this->createTable('xf_bookmark_label', function (Create $table) {
           
$table->addColumn('label_id', 'int')->autoIncrement();
           
$table->addColumn('label', 'varchar', 100);
           
$table->addColumn('label_url', 'varchar', 100);
           
$table->addColumn('user_id', 'int');
           
$table->addColumn('use_count', 'int')->setDefault(0);
           
$table->addColumn('last_use_date', 'int')->setDefault(0);
           
$table->addUniqueKey(['label', 'user_id']);
           
$table->addUniqueKey(['label_url', 'user_id']);
           
$table->addKey('use_count');
        });

       
$this->createTable('xf_bookmark_label_use', function (Create $table) {
           
$table->addColumn('label_id', 'int');
           
$table->addColumn('bookmark_id', 'int');
           
$table->addColumn('use_date', 'int')->setDefault(0);
           
$table->addPrimaryKey(['label_id', 'bookmark_id']);
        });

       
$this->createTable('xf_editor_dropdown', function (Create $table) {
           
$table->addColumn('cmd', 'varbinary', 50);
           
$table->addColumn('icon', 'varchar', 50)->setDefault('')->comment('Optional icon');
           
$table->addColumn('buttons', 'blob');
           
$table->addColumn('display_order', 'int')->setDefault(0);
           
$table->addColumn('active', 'tinyint')->setDefault(1);
           
$table->addPrimaryKey('cmd');
        });

       
// This table was actually added later in 2.1, but it's needed here for when people upgrade to 2.1
       
$this->createTable('xf_json_convert_error', function(Create $table)
        {
           
$table->addColumn('error_id', 'int')->autoIncrement();
           
$table->addColumn('table_name', 'varbinary', 100);
           
$table->addColumn('column_name', 'varbinary', 100);
           
$table->addColumn('pk_id', 'int');
           
$table->addColumn('original_value', 'mediumblob');
           
$table->addUniqueKey(['table_name', 'column_name', 'pk_id'], 'table_column_pk');
        });

       
$this->createTable('xf_reaction', function (Create $table) {
           
$table->addColumn('reaction_id', 'int')->autoIncrement();
           
$table->addColumn('title', 'varchar', 100);
           
$table->addColumn('text_color', 'varchar', 100);
           
$table->addColumn('image_url', 'varchar', 200);
           
$table->addColumn('image_url_2x', 'varchar', 200)->setDefault('');
           
$table->addColumn('sprite_mode', 'tinyint', 3)->setDefault(0);
           
$table->addColumn('sprite_params', 'blob');
           
$table->addColumn('reaction_score', 'int')->unsigned(false)->setDefault(1);
           
$table->addColumn('display_order', 'int')->setDefault(1);
           
$table->addColumn('active', 'tinyint', 3)->setDefault(1);
           
$table->addKey('display_order');
        });

       
$this->createTable('xf_unfurl_result', function (Create $table) {
           
$table->addColumn('result_id', 'int')->autoIncrement();
           
$table->addColumn('url', 'text');
           
$table->addColumn('url_hash', 'varbinary', 32);
           
$table->addColumn('title', 'text')->nullable();
           
$table->addColumn('description', 'text')->nullable();
           
$table->addColumn('image_url', 'text')->nullable();
           
$table->addColumn('favicon_url', 'text')->nullable();
           
$table->addColumn('last_request_date', 'int')->setDefault(0);
           
$table->addColumn('pending', 'tinyint')->setDefault(0);
           
$table->addColumn('error_count', 'int')->setDefault(0);
           
$table->addUniqueKey('url_hash');
           
$table->addKey('last_request_date');
        });

       
$this->createTable('xf_upgrade_check', function (Create $table) {
           
$table->addColumn('check_id', 'int')->autoIncrement();
           
$table->addColumn('error_code', 'varchar', 50)->nullable();
           
$table->addColumn('check_date', 'int')->nullable();
           
$table->addColumn('board_url_valid', 'tinyint')->nullable();
           
$table->addColumn('branding_valid', 'tinyint')->nullable();
           
$table->addColumn('license_expired', 'tinyint')->nullable();
           
$table->addColumn('invalid_add_ons', 'blob')->nullable();
           
$table->addColumn('available_updates', 'blob')->nullable();
           
$table->addKey('check_date');
        });

       
$this->createTable('xf_user_push_optout', function (Create $table) {
           
$table->addColumn('user_id', 'int');
           
$table->addColumn('push', 'varbinary', 50);
           
$table->addPrimaryKey(['user_id', 'push']);
        });

       
$this->createTable('xf_user_push_subscription', function (Create $table) {
           
$table->addColumn('endpoint_id', 'int')->autoIncrement();
           
$table->addColumn('endpoint_hash', 'varbinary', 32);
           
$table->addColumn('endpoint', 'text');
           
$table->addColumn('user_id', 'int');
           
$table->addColumn('data', 'mediumblob')->nullable();
           
$table->addColumn('last_seen', 'int');
           
$table->addUniqueKey('endpoint_hash');
           
$table->addKey('user_id');
        });
    }

    public function
step2()
    {
       
$this->alterTable('xf_option_group', function (Alter $table) {
           
$table->addColumn('icon', 'varchar', 50)
                ->
setDefault('')
                ->
comment('Optional icon')
                ->
after('group_id');
        });

       
$this->alterTable('xf_tfa_provider', function (Alter $table) {
           
$table->addColumn('options', 'blob')->nullable();
        });

       
$this->alterTable('xf_widget', function (Alter $table) {
           
$table->addColumn('display_condition', 'mediumtext');
           
$table->addColumn('condition_expression', 'mediumblob');
        });

       
$this->alterTable('xf_stats_daily', function (Alter $table) {
           
$table->changeColumn('stats_type')->length(50);
        });
    }

    public function
step3()
    {
       
$this->alterTable('xf_profile_post', function (Alter $table) {
           
$table->addColumn('embed_metadata', 'blob')->nullable();
        });
    }

    public function
step4()
    {
       
$this->alterTable('xf_profile_post_comment', function (Alter $table) {
           
$table->addColumn('embed_metadata', 'blob')->nullable();
        });
    }

    public function
step5()
    {
       
// Add 'last_thread_id' to the xf_forum table
        // and update it to the correct value based on last_post_id

       
$this->alterTable('xf_forum', function (Alter $table) {
           
$table
               
->addColumn('last_thread_id', 'int')
                ->
setDefault(0)
                ->
comment('Most recent thread_id')
                ->
after('last_post_username');
        });

       
$this->executeUpgradeQuery('
            UPDATE xf_forum
            INNER JOIN xf_post ON (xf_post.post_id = xf_forum.last_post_id)
            SET last_thread_id = IFNULL(xf_post.thread_id, 0)
        '
);

       
$this->alterTable('xf_node_type', function (Alter $table) {
           
$table->addColumn('handler_class', 'varchar', 100)->setDefault('');
        });

       
$db = $this->db();

       
$nodeTypeHandlerMap = [
           
'Category' => 'XF:Category',
           
'Forum' => 'XF:Forum',
           
'LinkForum' => 'XF:LinkForum',
           
'Page' => 'XF:Page',
        ];
        foreach (
$nodeTypeHandlerMap AS $nodeTypeId => $handlerClass)
        {
           
$db->update('xf_node_type', ['handler_class' => $handlerClass], 'node_type_id = ?', $nodeTypeId);
        }
    }

    public function
step6()
    {
       
$this->alterTable('xf_user_option', function (Alter $table) {
           
$table->addColumn('push_on_conversation', 'tinyint', 3)->setDefault(1)->after('email_on_conversation');
           
$table->addColumn('push_optout', 'text')->after('alert_optout')
                ->
comment('Comma-separated list of alerts from which the user has opted out for push notifications. Example: \'post_like,user_trophy\'');
        });

       
$this->executeUpgradeQuery("
            UPDATE xf_user_option
            SET push_optout = alert_optout
        "
);

       
$this->executeUpgradeQuery("
            INSERT IGNORE INTO xf_user_push_optout
                (user_id, push)
            SELECT user_id, alert
            FROM xf_user_alert_optout
        "
);

       
$this->executeUpgradeQuery("
            INSERT INTO `xf_tfa_provider`
                (`provider_id`, `provider_class`, `priority`, `active`)
            VALUES
                ('authy', 'XF:Authy', 5, 1)
        "
);

       
// we stopped using this type/action combo in XF 2.0 but only removed the template in XF 2.1.
       
$this->executeUpgradeQuery("
            UPDATE
                xf_user_alert
            SET
                content_type = 'trophy',
                action = 'award'
            WHERE
                content_type = 'user'
                AND action = 'trophy'
        "
);
    }

    public function
step7()
    {
       
// misc permission application

       
$this->applyGlobalPermission('general', 'usePush', 'general', 'view');
       
$this->applyGlobalPermission('bookmark', 'view', 'forum', 'postReply');
       
$this->applyGlobalPermission('bookmark', 'create', 'forum', 'postReply');

       
$this->applyContentPermission('forum', 'uploadVideo', 'forum', 'uploadAttachment');
       
$this->applyGlobalPermission('conversation', 'uploadVideo', 'conversation', 'uploadAttachment');

       
// setup the default editor button config
       
$defaultButtons = [
           
'clearFormatting',
           
'-vs',
           
'bold',
           
'italic',
           
'underline',
           
'strikeThrough',
           
'-vs',
           
'textColor',
           
'fontFamily',
           
'fontSize',
           
'-vs',
           
'insertLink',
           
'insertImage',
           
'insertVideo',
           
'xfSmilie',
           
'-vs',
           
'align',
           
'insertTable',
           
'-vs',
           
'undo',
           
'redo',
           
'-vs',
           
'xfDraft',
           
'xfBbCode'
       
];
       
$defaultButtonsXS = array_values(
            \
XF\Util\Arr::arrayDelete(['fontFamily', 'strikeThrough', 'xfDraft'], $defaultButtons)
        );

       
$this->executeUpgradeQuery("
            INSERT INTO xf_option
                (option_id, option_value, default_value, edit_format_params, sub_options, validation_class, validation_method)
            VALUES
                ('editorToolbarConfig', '', '', '', '', '', ''),
                ('editorDropdownConfig', '', '', '', '', '', '')
        "
);

       
$optionValue = [
           
'toolbarButtons' => $defaultButtons,
           
'toolbarButtonsMD' => $defaultButtons,
           
'toolbarButtonsSM' => $defaultButtons,
           
'toolbarButtonsXS' => $defaultButtonsXS
       
];

       
$this->executeUpgradeQuery("
            UPDATE xf_option
            SET option_value = ?
            WHERE option_id = 'editorToolbarConfig'
        "
, json_encode($optionValue));

       
$this->executeUpgradeQuery("
            UPDATE xf_option
            SET option_value = ?
            WHERE option_id = 'editorDropdownConfig'
        "
, json_encode([]));
    }

   
// ################################## SERIALIZED TO JSON STEPS ###########################################

   
public function step8()
    {
       
// Convert fields that contain Entity::SERIALIZED(_ARRAY) to Entity::JSON(_ARRAY).
        // Commented-out fields are handled in separate steps, and are retained here for reference only.

       
$serializedFields = [

           
// SERIALIZED_ARRAY
           
'XF:Admin' => ['permission_cache'],
           
'XF:CaptchaQuestion' => ['answers'],
//            'XF:ConversationMaster' => ['recipients'],
//            'XF:ConversationMessage' => ['like_users'],
           
'XF:CronEntry' => ['run_rules'],
//            'XF:Draft' => ['extra_data'],
//            'XF:ErrorLog' => ['request_state'],
           
'XF:Forum' => ['field_cache', 'prefix_cache'],
           
'XF:Language' => ['phrase_cache'],
//            'XF:NewsFeed' => ['extra_data'],
           
'XF:Node' => ['breadcrumb_data'],
           
'XF:Notice' => ['user_criteria', 'page_criteria'],
//            'XF:PermissionCacheContent' => ['cache_value'],
//            'XF:PermissionCombination' => ['cache_value'],
//            'XF:Poll' => ['responses'],
//            'XF:PollResponse' => ['voters'],
//            'XF:Post' => ['like_users'],
//            'XF:ProfilePost' => ['like_users', 'latest_comment_ids'],
//            'XF:ProfilePostComment' => ['like_users'],
//            'XF:Report' => ['content_info'],
           
'XF:Smilie' => ['sprite_params'],
//            'XF:SpamCleanerLog' => ['data'],
//            'XF:SpamTriggerLog' => ['details', 'request_state'],
           
'XF:Style' => ['properties'],
//            'XF:TagResultCache' => ['results'],
//            'XF:Thread' => ['custom_fields', 'tags'],
           
'XF:Trophy' => ['user_criteria'],
//            'XF:UserAlert' => ['extra_data'],
//            'XF:UserConnectedAccount' => ['extra_data'],
//            'XF:UserGroupPromotion' => ['user_criteria'],
//            'XF:UserProfile' => ['ignored', 'custom_fields', 'connected_accounts'],
//            'XF:UserTfa' => ['provider_data'],
//            'XF:UserUpgradeActive' => ['extra'],
//            'XF:UserUpgradeExpired' => ['extra']
       
];
       
// note: user auth is intentionally unchanged

        // add-ons, don't forget entities that extend AbstractCategoryTree

       
foreach ($serializedFields AS $entityName => $columns)
        {
           
$this->entityColumnsToJson($entityName, $columns, 0, [], true);
        }
    }

    public function
step9($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:ConversationMaster', ['recipients'], $position, $stepData);
    }

    public function
step10($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:ConversationMessage', ['like_users'], $position, $stepData);
    }

    public function
step11($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:Draft', ['extra_data'], $position, $stepData);
    }

    public function
step12($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:ErrorLog', ['request_state'], $position, $stepData, false, 300);
    }

    public function
step13($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:NewsFeed', ['extra_data'], $position, $stepData);
    }

    public function
step14($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:PermissionCacheContent', ['cache_value'], $position, $stepData);
    }

    public function
step15($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:PermissionCombination', ['cache_value'], $position, $stepData);
    }

    public function
step16($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:Poll', ['responses'], $position, $stepData);
    }

    public function
step17($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:PollResponse', ['voters'], $position, $stepData);
    }

   
// note: subsequent steps involving "like_users" are correct - the columns haven't been renamed at this point

   
public function step18($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:Post', ['like_users'], $position, $stepData);
    }

    public function
step19($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:ProfilePost', ['like_users', 'latest_comment_ids'], $position, $stepData);
    }

    public function
step20($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:ProfilePostComment', ['like_users'], $position, $stepData);
    }

    public function
step21($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:Report', ['content_info'], $position, $stepData);
    }

    public function
step22($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:SpamCleanerLog', ['data'], $position, $stepData);
    }

    public function
step23($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:SpamTriggerLog', ['details', 'request_state'], $position, $stepData);
    }

    public function
step24($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:TagResultCache', ['results'], $position, $stepData);
    }

    public function
step25($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:Thread', ['custom_fields', 'tags'], $position, $stepData);
    }

    public function
step26($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserAlert', ['extra_data'], $position, $stepData);
    }

    public function
step27($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserConnectedAccount', ['extra_data'], $position, $stepData);
    }

    public function
step28($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserGroupPromotion', ['user_criteria'], $position, $stepData);
    }

    public function
step29($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserProfile', ['ignored', 'custom_fields', 'connected_accounts'], $position, $stepData);
    }

    public function
step30($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserTfa', ['provider_data'], $position, $stepData);
    }

    public function
step31($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserUpgradeActive', ['extra'], $position, $stepData);
    }

    public function
step32($position, array $stepData)
    {
        return
$this->entityColumnsToJson('XF:UserUpgradeExpired', ['extra'], $position, $stepData);
    }

   
// ######################## REACTION MIGRATIONS ###################

   
public function step33()
    {
        if (!
$this->schemaManager()->tableExists('xf_liked_content'))
        {
           
// if this table doesn't exist, then this query has been run already, so we can skip it.
           
return;
        }

       
$this->alterTable('xf_liked_content', function(Alter $table)
        {
           
$table->renameTo('xf_reaction_content');
           
$table->renameColumn('like_id', 'reaction_content_id');
           
$table->addColumn('reaction_id', 'int')->setDefault(1)->after('reaction_content_id');
           
$table->renameColumn('like_user_id', 'reaction_user_id');
           
$table->renameColumn('like_date', 'reaction_date');

           
$table->dropIndexes([
               
'content_type_id_like_user_id',
               
'like_user_content_type_id',
               
'content_user_id_like_date',
               
'like_date'
           
]);

           
$table->addUniqueKey(['content_type', 'content_id', 'reaction_user_id'], 'content_type_id_user_id');
           
$table->addKey(['content_type', 'content_id', 'reaction_date'], 'content_type_id_reaction_date');
           
$table->addKey(['content_user_id', 'reaction_date']);
           
$table->addKey('reaction_date');
        });
    }

    public function
step34()
    {
       
$this->migrateTableToReactions('xf_post');
    }

    public function
step35()
    {
       
$this->migrateTableToReactions('xf_conversation_message');
    }

    public function
step36()
    {
       
$this->migrateTableToReactions('xf_profile_post');
    }

    public function
step37()
    {
       
$this->migrateTableToReactions('xf_profile_post_comment');
    }

    public function
step38()
    {
       
$this->renameLikeAlertOptionsToReactions(['post', 'profile_post', 'profile_post_comment', 'conversation_message']);
    }

    public function
step39()
    {
       
$this->renameLikeAlertsToReactions(['post', 'profile_post', 'profile_post_comment', 'conversation_message']);
    }

    public function
step40()
    {
       
// miscellaneous reaction migrations

       
$this->renameLikePermissionsToReactions([
           
'forum' => true, // global and content
           
'conversation' => false, // global only
           
'profilePost' => false // global only
       
]);

       
$this->renameLikeStatsToReactions(['post', 'profile_post', 'profile_post_comment']);

       
$this->renameLikeCriteriaToReactions('xf_notice', 'notice_id');
       
$this->renameLikeCriteriaToReactions('xf_trophy', 'trophy_id');
       
$this->renameLikeCriteriaToReactions('xf_user_group_promotion', 'promotion_id');

       
$this->executeUpgradeQuery("
            UPDATE xf_member_stat
            SET sort_order = 'reaction_score'
            WHERE sort_order = 'like_count'
        "
);

       
$this->applyAdminPermission('reaction', 'bbCodeSmilie');
    }

    public function
step41()
    {
        if (!
$this->schemaManager()->columnExists('xf_thread', 'first_post_likes'))
        {
           
// column is gone, so assume this has been run
           
return;
        }

       
$this->alterTable('xf_thread', function (Alter $table)
        {
           
$table->changeColumn('first_post_likes')->renameTo('first_post_reaction_score')->unsigned(false);
           
$table->addColumn('first_post_reactions', 'blob')->nullable()->after('first_post_reaction_score');
        });
    }

    public function
step42()
    {
       
$this->executeUpgradeQuery('UPDATE xf_thread SET first_post_reactions = CONCAT(\'{"1":\', first_post_reaction_score, \'}\') WHERE first_post_reaction_score > 0');
    }

    public function
step43()
    {
        if (!
$this->schemaManager()->columnExists('xf_user', 'like_count'))
        {
           
// column is gone, so assume this has been run
           
return;
        }

       
// extremely unlikely but prevent the upgrade being blocked
        // in the event of exceeding the signed int max.
       
$this->executeUpgradeQuery("
            UPDATE xf_user
            SET like_count = 2147483647
            WHERE like_count > 2147483647
        "
);

       
$this->alterTable('xf_user', function (Alter $table)
        {
           
$table->changeColumn('like_count')->renameTo('reaction_score')->unsigned(false);
           
$table->dropIndexes('like_count');
           
$table->addKey('reaction_score');
        });
    }

    public function
step44()
    {
       
$this->executeUpgradeQuery('
            INSERT INTO `xf_reaction`
                (`reaction_id`, `title`, `text_color`, `image_url`, `image_url_2x`, `sprite_mode`, `sprite_params`, `reaction_score`, `display_order`, `active`)
            VALUES
                (1, \'Like\', \'@xf-linkColor\', \'styles/default/xenforo/reactions/emojione/sprite_sheet_emojione.png\', \'\', 1, \'{\"w\":\"32\",\"h\":\"32\",\"x\":\"0\",\"y\":\"0\",\"bs\":\"100%\"}\', 1, 100, 1),
                (2, \'Love\', \'#E81C27\', \'styles/default/xenforo/reactions/emojione/sprite_sheet_emojione.png\', \'\', 1, \'{\"w\":\"32\",\"h\":\"32\",\"x\":\"0\",\"y\":\"-32\",\"bs\":\"100%\"}\', 1, 200, 1),
                (3, \'Haha\', \'#FDCA47\', \'styles/default/xenforo/reactions/emojione/sprite_sheet_emojione.png\', \'\', 1, \'{\"w\":\"32\",\"h\":\"32\",\"x\":\"0\",\"y\":\"-64\",\"bs\":\"100%\"}\', 1, 300, 1),
                (4, \'Wow\', \'#FDCA47\', \'styles/default/xenforo/reactions/emojione/sprite_sheet_emojione.png\', \'\', 1, \'{\"w\":\"32\",\"h\":\"32\",\"x\":\"0\",\"y\":\"-96\",\"bs\":\"100%\"}\', 0, 400, 1),
                (5, \'Sad\', \'#FDCA47\', \'styles/default/xenforo/reactions/emojione/sprite_sheet_emojione.png\', \'\', 1, \'{\"w\":\"32\",\"h\":\"32\",\"x\":\"0\",\"y\":\"-128\",\"bs\":\"100%\"}\', 0, 500, 1),
                (6, \'Angry\', \'#FF4D4D\', \'styles/default/xenforo/reactions/emojione/sprite_sheet_emojione.png\', \'\', 1, \'{\"w\":\"32\",\"h\":\"32\",\"x\":\"0\",\"y\":\"-160\",\"bs\":\"100%\"}\', 0, 600, 1);
        '
);

       
$db = $this->db();

       
$spamUserCriteria = $db->fetchOne('SELECT option_value FROM xf_option WHERE option_id = \'spamUserCriteria\'');
       
$spamUserCriteria = json_decode($spamUserCriteria, true);
        if (
$spamUserCriteria && isset($spamUserCriteria['like_count']))
        {
           
$spamUserCriteria['reaction_score'] = $spamUserCriteria['like_count'];
            unset(
$spamUserCriteria['like_count']);

           
$this->executeUpgradeQuery('UPDATE xf_option SET option_value = ? WHERE option_id = \'spamUserCriteria\'', json_encode($spamUserCriteria));
        }

       
$userTitleLadderField = $db->fetchOne('SELECT option_value FROM xf_option WHERE option_id = \'userTitleLadderField\'');
        if (
$userTitleLadderField && $userTitleLadderField == 'like_count')
        {
           
$userTitleLadderField = 'reaction_score';
           
$this->executeUpgradeQuery('UPDATE xf_option SET option_value = ? WHERE option_id = \'userTitleLadderField\'', $userTitleLadderField);
        }

       
$messageUserElements = $db->fetchAllColumn('SELECT property_id, property_value FROM xf_style_property WHERE property_name = \'messageUserElements\'');
        foreach (
$messageUserElements AS $propertyId => $value)
        {
           
$elements = json_decode($value, true);
            if (
$elements && isset($elements['like_count']))
            {
               
$elements['reaction_score'] = $elements['like_count'];
                unset(
$elements['like_count']);

               
$this->executeUpgradeQuery('UPDATE xf_style_property SET property_value = ? WHERE property_id = ?', [json_encode($elements, $propertyId)]);
            }
        }
    }

   
// final misc additions

   
public function step45()
    {
       
$this->alterTable('xf_phrase_map', function (Alter $table)
        {
           
$table->addKey('title');
        });
    }

    public function
step46()
    {
       
$this->alterTable('xf_template_map', function (Alter $table)
        {
           
$table->addKey(['type', 'title']);
        });
    }

    public function
step47()
    {
       
$this->alterTable('xf_mail_queue', function (Alter $table) {
           
$table->addColumn('send_date', 'int')->setDefault(0);
           
$table->addColumn('fail_date', 'int')->nullable()->setDefault(null);
           
$table->addColumn('fail_count', 'int')->setDefault(0);
           
$table->dropIndexes('queue_date');
           
$table->addKey(['send_date', 'queue_date']);
        });
    }

    public function
step48()
    {
       
$this->executeUpgradeQuery("
            REPLACE INTO xf_phrase
                (language_id, title, phrase_text)
            VALUES
                (0, 'trophy_description.5', 'Somebody out there reacted positively to one of your messages. Keep posting like that for more!'),
                (0, 'trophy_description.6', 'Your messages have been positively reacted to 25 times.'),
                (0, 'trophy_description.7', 'Content you have posted has attracted a positive reaction score of 100.'),
                (0, 'trophy_description.8', 'Your content has been positively reacted to 250 times.'),
                (0, 'trophy_description.9', 'Content you have posted has attracted 500 positive reactions.')
        "
);
    }
}