<?php
namespace XF\Install\Upgrade;
use XF\Db\Schema\Alter;
use XF\Db\Schema\Create;
class Version2020010 extends AbstractUpgrade
{
public function getVersionName()
{
return '2.2.0 Alpha';
}
public function step1()
{
$this->createTable('xf_activity_summary_definition', function (Create $table)
{
$table->addColumn('definition_id', 'varbinary', 50);
$table->addColumn('definition_class', 'varchar', 100);
$table->addColumn('addon_id', 'varbinary', 50)->setDefault('');
$table->addPrimaryKey('definition_id');
});
$this->createTable('xf_activity_summary_section', function (Create $table)
{
$table->addColumn('section_id', 'int')->autoIncrement();
$table->addColumn('definition_id', 'varbinary', 50);
$table->addColumn('display_order', 'int')->setDefault(0);
$table->addColumn('show_value', 'tinyint', 3)->setDefault(1);
$table->addColumn('options', 'blob');
$table->addColumn('active', 'tinyint', 3)->setDefault(1);
});
$this->createTable('xf_api_login_token', function (Create $table)
{
$table->addColumn('login_token_id', 'int')->autoIncrement();
$table->addColumn('login_token', 'varbinary', 32);
$table->addColumn('user_id', 'int');
$table->addColumn('expiry_date', 'int');
$table->addColumn('limit_ip', 'varbinary', 16)->nullable();
$table->addPrimaryKey('login_token_id');
$table->addUniqueKey('login_token');
$table->addKey('expiry_date');
});
$this->createTable('xf_content_vote', function (Create $table)
{
$table->addColumn('vote_id', 'int')->autoIncrement();
$table->addColumn('content_type', 'varbinary', 25);
$table->addColumn('content_id', 'int');
$table->addColumn('vote_user_id', 'int');
$table->addColumn('content_user_id', 'int');
$table->addColumn('is_content_user_counted', 'tinyint', 3)->setDefault(1);
$table->addColumn('score', 'int')->unsigned(false);
$table->addColumn('vote_date', 'int');
$table->addUniqueKey(['content_type', 'content_id', 'vote_user_id'], 'content_type_id_user');
$table->addKey('vote_user_id');
$table->addKey('content_user_id');
});
$this->createTable('xf_forum_type', function(Create $table)
{
$table->addColumn('forum_type_id', 'varbinary', 50);
$table->addColumn('handler_class', 'varchar', 100);
$table->addColumn('addon_id', 'varbinary', 50)->setDefault('');
$table->addPrimaryKey('forum_type_id');
});
$this->createTable('xf_pre_reg_action', function (Create $table)
{
$table->addColumn('action_id', 'int')->autoIncrement();
$table->addColumn('guest_key', 'varbinary', 75)->nullable();
$table->addColumn('user_id', 'int')->nullable();
$table->addColumn('content_id', 'int');
$table->addColumn('ip_address', 'varbinary', 16)->setDefault('');
$table->addColumn('last_update', 'int');
$table->addColumn('action_class', 'varchar', 100);
$table->addColumn('action_data', 'mediumblob');
$table->addUniqueKey('guest_key');
$table->addUniqueKey('user_id');
$table->addKey('last_update');
});
$this->createTable('xf_search_forum', function (Create $table)
{
$table->addColumn('node_id', 'int');
$table->addColumn('search_criteria', 'mediumblob');
$table->addColumn('sort_order', 'varchar', 25)->setDefault('last_post_date');
$table->addColumn('sort_direction', 'varchar', 5)->setDefault('desc');
$table->addColumn('max_results', 'smallint', 5)->setDefault(200);
$table->addColumn('cache_ttl', 'int')->setDefault(10);
$table->addColumn('discussion_count', 'int')->setDefault(0);
$table->addColumn('message_count', 'int')->setDefault(0);
$table->addColumn('last_post_id', 'int')->setDefault(0);
$table->addColumn('last_post_date', 'int')->setDefault(0);
$table->addColumn('last_post_user_id', 'int')->setDefault(0);
$table->addColumn('last_post_username', 'varchar', 50)->setDefault('');
$table->addColumn('last_thread_id', 'int')->setDefault(0);
$table->addColumn('last_thread_title', 'varchar', 150)->setDefault('');
$table->addColumn('last_thread_prefix_id', 'int')->setDefault(0);
$table->addPrimaryKey('node_id');
});
$this->createTable('xf_search_forum_cache', function (Create $table)
{
$table->addColumn('node_id', 'int');
$table->addColumn('results', 'mediumblob');
$table->addColumn('cache_date', 'int');
$table->addPrimaryKey('node_id');
});
$this->createTable('xf_search_forum_cache_user', function (Create $table)
{
$table->addColumn('node_id', 'int');
$table->addColumn('user_id', 'int');
$table->addColumn('results', 'mediumblob');
$table->addColumn('cache_date', 'int');
$table->addPrimaryKey(['node_id', 'user_id']);
});
$this->createTable('xf_thread_question', function (Create $table)
{
$table->addColumn('thread_id', 'int');
$table->addColumn('solution_post_id', 'int')->setDefault(0);
$table->addColumn('solution_user_id', 'int')->setDefault(0);
$table->addPrimaryKey('thread_id');
});
$this->createTable('xf_thread_type', function(Create $table)
{
$table->addColumn('thread_type_id', 'varbinary', 50);
$table->addColumn('handler_class', 'varchar', 100);
$table->addColumn('addon_id', 'varbinary', 50)->setDefault('');
$table->addPrimaryKey('thread_type_id');
});
$this->createTable('xf_username_change', function (Create $table)
{
$table->addColumn('change_id', 'int')->autoIncrement();
$table->addColumn('user_id', 'int');
$table->addColumn('old_username', 'varchar', 50);
$table->addColumn('new_username', 'varchar', 50);
$table->addColumn('change_reason', 'varchar', 200)->setDefault('');
$table->addColumn('change_state', 'enum')->values(['moderated', 'approved', 'rejected'])->setDefault('approved');
$table->addColumn('change_user_id', 'int');
$table->addColumn('change_date', 'int');
$table->addColumn('moderator_user_id', 'int')->setDefault(0);
$table->addColumn('reject_reason', 'varchar', 200)->setDefault('');
$table->addColumn('visible', 'tinyint')->setDefault(1);
$table->addKey('change_date');
$table->addKey(['old_username', 'change_state', 'change_date'], 'old_username_state_date');
$table->addKey(['new_username', 'change_state'], 'new_username_state');
$table->addKey(['user_id', 'change_state', 'change_date'], 'user_id_state_date');
});
}
public function step2()
{
$this->alterTable('xf_admin', function (Alter $table)
{
$table->addColumn('advanced', 'tinyint', 3)->setDefault(0)->after('admin_language_id');
});
$this->alterTable('xf_forum', function (Alter $table)
{
$table->addColumn('allow_index', 'enum')->values(['allow', 'deny', 'criteria'])->setDefault('allow')->after('find_new');
$table->addColumn('index_criteria', 'blob')->after('allow_index');
$table->addColumn('forum_type_id', 'varbinary', 50)->setDefault('discussion');
$table->addColumn('type_config', 'mediumblob');
});
$this->alterTable('xf_language', function (Alter $table)
{
$table->addColumn('user_selectable', 'bool')->setDefault(1);
});
$this->alterTable('xf_member_stat', function (Alter $table)
{
$table->addColumn('visibility_class', 'varchar', 100)->setDefault('')->after('callback_method');
$table->addColumn('visibility_method', 'varchar', 75)->setDefault('')->after('visibility_class');
});
$this->alterTable('xf_upgrade_check', function (Alter $table)
{
$table->addColumn('installable_add_ons', 'blob')->nullable()->after('invalid_add_ons');
});
}
public function step3()
{
$this->alterTable('xf_option', function (Alter $table)
{
$table->addColumn('advanced', 'tinyint', 3)
->setDefault(0)
->after('validation_method');
});
$this->alterTable('xf_option_group', function (Alter $table)
{
$table->addColumn('advanced', 'tinyint', 3)
->setDefault(0)
->after('debug_only');
});
$this->alterTable('xf_style', function (Alter $table)
{
$table->addColumn('assets', 'mediumblob')->after('properties');
$table->addColumn('effective_assets', 'mediumblob')->after('assets');
});
$this->alterTable('xf_thread_field', function (Alter $table)
{
$table->addColumn('wrapper_template', 'text')->after('display_template');
});
$this->alterTable('xf_user_field', function (Alter $table)
{
$table->addColumn('wrapper_template', 'text')->after('display_template');
});
}
public function step4()
{
$this->alterTable('xf_attachment_data', function (Alter $table)
{
$table->changeColumn('file_size', 'bigint');
});
}
public function step5()
{
$this->alterTable('xf_attachment', function(Alter $table)
{
$table->addKey('data_id');
});
}
public function step6()
{
$this->alterTable('xf_conversation_master', function (Alter $table)
{
$table->addKey('last_message_user_id');
});
}
public function step7()
{
$this->alterTable('xf_conversation_user', function (Alter $table)
{
$table->addKey('last_message_user_id');
});
}
public function step8()
{
$this->alterTable('xf_image_proxy', function (Alter $table)
{
$table->changeColumn('file_size', 'bigint');
});
}
public function step9()
{
$this->alterTable('xf_moderator_log', function (Alter $table)
{
$table->addKey('content_user_id');
});
}
public function step10()
{
$this->alterTable('xf_post', function (Alter $table)
{
$table->addColumn('type_data', 'mediumblob')->after('position');
$table->addColumn('vote_score', 'int')->unsigned(false);
$table->addColumn('vote_count', 'int')->setDefault(0);
$table->addKey(
['thread_id', ['vote_score', 'descending' => true], 'post_date'],
'thread_id_score_date'
);
});
}
public function step11()
{
$this->alterTable('xf_reaction_content', function (Alter $table)
{
$table->addKey(['content_user_id', 'is_counted', 'reaction_id', 'reaction_date']);
$table->addKey('reaction_user_id');
});
}
public function step12()
{
$this->alterTable('xf_report', function (Alter $table)
{
$table->addKey('last_modified_user_id');
});
}
public function step13()
{
$this->alterTable('xf_thread', function (Alter $table)
{
$table->addColumn('vote_score', 'int')->unsigned(false);
$table->addColumn('vote_count', 'int')->setDefault(0);
$table->addColumn('type_data', 'mediumblob');
$table->addKey(['node_id', 'sticky', 'discussion_state', 'vote_score'], 'node_id_sticky_state_vote_score');
$table->addKey('last_post_user_id');
});
}
public function step14()
{
$this->alterTable('xf_user', function (Alter $table)
{
$table->addColumn('username_date', 'int')->setDefault(0)->after('username');
$table->addColumn('username_date_visible', 'int')->setDefault(0)->after('username_date');
$table->addColumn('security_lock', 'enum')->values(['', 'change', 'reset'])->setDefault('')->after('user_state');
$table->addColumn('vote_score', 'int')->unsigned(false)->setDefault(0);
$table->addColumn('last_summary_email_date', 'int')->nullable()->after('last_activity');
$table->addColumn('question_solution_count', 'int')->setDefault(0)->after('message_count');
$table->addColumn('alerts_unviewed', 'smallint', 5)->setDefault(0)->after('trophy_points');
$table->addKey('vote_score');
$table->addKey('last_summary_email_date');
$table->addKey('permission_combination_id');
$table->addKey('question_solution_count');
});
}
public function step15()
{
$this->alterTable('xf_user_alert', function (Alter $table)
{
$table->addColumn('read_date', 'int')->setDefault(0)->after('view_date');
$table->addColumn('auto_read', 'tinyint')->setDefault(1)->after('read_date');
// index is superseded
$table->dropIndexes('contentType_contentId');
// for basic content type lookups
$table->addKey(['content_type', 'content_id', 'user_id']);
// primarily for looking up active alerts for a user from a set of content -- content_id will generally
// be a multiple element list, so further columns aren't particularly helpful
$table->addKey(['alerted_user_id', 'content_type', 'content_id']);
// for unviewed calculations
$table->addKey(['alerted_user_id', 'view_date']);
// for unread calculations
$table->addKey(['alerted_user_id', 'read_date']);
});
}
public function step16()
{
$this->alterTable('xf_user_profile', function (Alter $table)
{
$table->addColumn('banner_date', 'int')->setDefault(0)->after('avatar_crop_y');
$table->addColumn('banner_position_y', 'tinyint')->nullable()->after('banner_date');
});
}
public function step17()
{
$this->alterTable('xf_profile_post_comment', function (Alter $table)
{
$table->addColumn('attach_count', 'smallint', 5)->setDefault(0)->after('message_state');
});
}
// Convert username changes to the new log
public function step18($position, array $stepData)
{
$perPage = 1000;
$db = $this->db();
if (!isset($stepData['max']))
{
$stepData['max'] = $db->fetchOne("SELECT MAX(content_id) FROM xf_change_log WHERE content_type = 'user' AND field = 'username'");
}
$userIds = $db->fetchAllColumn($db->limit("
SELECT DISTINCT(content_id)
FROM xf_change_log
WHERE content_id > ? AND content_type = 'user' AND field = 'username'
ORDER BY content_id
", $perPage), $position);
if (!$userIds)
{
return true;
}
$em = $this->app->em();
$db->beginTransaction();
$next = 0;
foreach ($userIds AS $userId)
{
$next = $userId;
$changes = $db->fetchAll("
SELECT
content_id AS user_id,
old_value AS old_username,
new_value AS new_username,
'approved' AS change_state,
edit_user_id AS change_user_id,
edit_date AS change_date,
0 AS moderator_user_id,
'' AS reject_reason,
0 AS visible
FROM xf_change_log
WHERE content_id = ? AND content_type = 'user' AND field = 'username'
ORDER BY change_date
", $userId);
if (!$changes)
{
continue;
}
$inserts = [];
foreach ($changes AS $change)
{
// we don't have any unique constraints but this ensures dupes aren't introduced
// in the event that this upgrade step is somehow run multiple times
$exists = $em->findOne('XF:UsernameChange', $change);
if ($exists)
{
continue;
}
$inserts[] = $change;
}
if ($inserts)
{
$db->insertBulk('xf_username_change', $inserts);
$dates = array_column($inserts, 'change_date');
$db->update('xf_user', ['username_date' => end($dates)], 'user_id = ?', $userId);
}
}
$db->commit();
return [
$next,
"$next / $stepData[max]",
$stepData
];
}
public function step19()
{
$this->executeUpgradeQuery("
UPDATE xf_user_privacy
SET allow_post_profile = 'members'
WHERE allow_post_profile = 'everyone'
");
$this->executeUpgradeQuery("
UPDATE xf_user_privacy
SET allow_send_personal_conversation = 'members'
WHERE allow_send_personal_conversation = 'everyone'
");
}
public function step20()
{
// note this is intentionally separate from other alters as the updates are needed first
$this->alterTable('xf_user_privacy', function (Alter $table)
{
$table->changeColumn('allow_post_profile')
->removeValues('everyone')
->setDefault('members');
$table->changeColumn('allow_send_personal_conversation')
->removeValues('everyone')
->setDefault('members');
});
}
public function step21()
{
// if opted-in to admin emails also opt-in to activity summary
// emails but in a paused state (0) to avoid excessive emails
$this->executeUpgradeQuery("
UPDATE xf_user AS u
INNER JOIN xf_user_option AS uo ON
(u.user_id = uo.user_id)
SET u.last_summary_email_date = 0
WHERE uo.receive_admin_email = 1
");
}
public function step22()
{
if (!$this->columnExists('xf_forum', 'allow_poll'))
{
return;
}
$this->executeUpgradeQuery("
UPDATE xf_forum
SET type_config = IF(allow_poll = 1,
'{\"allowed_thread_types\":[\"poll\"]}',
'{\"allowed_thread_types\":[]}'
)
");
$this->alterTable('xf_forum', function(Alter $table)
{
$table->dropColumns('allow_poll');
});
}
public function step23()
{
$this->db()->update(
'xf_thread',
['discussion_type' => 'discussion'],
"discussion_type = ''"
);
}
protected function getEditorButtonDefault(): array
{
return [
'toolbarButtons' => [
'moreText' => [
'buttons' => [
'clearFormatting',
'bold',
'italic',
'fontSize',
'textColor',
'fontFamily',
'strikeThrough',
'underline',
'xfInlineCode',
'xfInlineSpoiler',
],
'buttonsVisible' => '5',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreParagraph' => [
'buttons' => [
'xfList',
'align',
'paragraphFormat',
],
'buttonsVisible' => '3',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreRich' => [
'buttons' => [
'insertLink',
'insertImage',
'xfSmilie',
'xfMedia',
'xfQuote',
'insertTable',
'insertHR',
'insertVideo',
'xfSpoiler',
'xfCode',
],
'buttonsVisible' => '6',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreMisc' => [
'buttons' => [
'undo',
'redo',
'xfBbCode',
'xfDraft',
],
'buttonsVisible' => '4',
'align' => 'right',
'icon' => '',
],
],
'toolbarButtonsMD' => [
'moreText' => [
'buttons' => [
'bold',
'italic',
'fontSize',
'textColor',
'fontFamily',
'strikeThrough',
'underline',
'xfInlineCode',
'xfInlineSpoiler',
],
'buttonsVisible' => '3',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreParagraph' => [
'buttons' => [
'xfList',
'align',
'paragraphFormat',
],
'buttonsVisible' => '3',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreRich' => [
'buttons' => [
'insertLink',
'insertImage',
'xfSmilie',
'insertVideo',
'xfMedia',
'xfQuote',
'insertTable',
'insertHR',
'xfSpoiler',
'xfCode',
],
'buttonsVisible' => '2',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreMisc' => [
'buttons' => [
'undo',
'redo',
'clearFormatting',
'xfBbCode',
'xfDraft',
],
'buttonsVisible' => '1',
'align' => 'right',
'icon' => '',
],
],
'toolbarButtonsSM' => [
'moreText' => [
'buttons' => [
'bold',
'italic',
'fontSize',
'textColor',
'fontFamily',
'strikeThrough',
'underline',
'xfInlineCode',
'xfInlineSpoiler',
],
'buttonsVisible' => '2',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreParagraph' => [
'buttons' => [
'xfList',
'align',
'paragraphFormat'
],
'buttonsVisible' => '1',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreRich' => [
'buttons' => [
'insertLink',
'insertImage',
'xfSmilie',
'xfQuote',
'insertVideo',
'xfMedia',
'insertTable',
'insertHR',
'xfSpoiler',
'xfCode',
],
'buttonsVisible' => '3',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreMisc' => [
'buttons' => [
'undo',
'redo',
'xfBbCode',
'clearFormatting',
'xfDraft',
],
'buttonsVisible' => '1',
'align' => 'right',
'icon' => '',
],
],
'toolbarButtonsXS' => [
'moreText' => [
'buttons' => [
'bold',
'italic',
'fontSize',
'textColor',
'fontFamily',
'xfList',
'align',
'paragraphFormat',
'strikeThrough',
'underline',
'xfInlineSpoiler',
'xfInlineCode',
],
'buttonsVisible' => '2',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreParagraph' => [
'buttons' => [],
'buttonsVisible' => '0',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreRich' => [
'buttons' => [
'insertLink',
'insertImage',
'xfSmilie',
'xfQuote',
'insertVideo',
'xfMedia',
'insertTable',
'insertHR',
'xfSpoiler',
'xfCode',
],
'buttonsVisible' => '2',
'align' => 'left',
'icon' => 'fa-ellipsis-v',
],
'moreMisc' => [
'buttons' => [
'undo',
'redo',
'xfBbCode',
'clearFormatting',
'xfDraft',
],
'buttonsVisible' => '1',
'align' => 'right',
'icon' => '',
],
],
];
}
public function step24()
{
$db = $this->db();
$newToolbars = $this->getEditorButtonDefault();
$customInsertGroup = 'moreRich';
$standardButtons = [
"-hs",
"-vs",
"align",
"bold",
"clearFormatting",
"color",
"fontFamily",
"fontSize",
"formatOL",
"formatUL",
"indent",
"insertImage",
"insertLink",
"insertTable",
"insertVideo",
"italic",
"outdent",
"redo",
"strikeThrough",
"textColor", // probably won't be there -- this is Froala 3
"underline",
"undo",
"xfBbCode",
"xfCode",
"xfDraft",
"xfInlineCode",
"xfInlineSpoiler",
"xfList",
"xfMedia",
"xfQuote",
"xfSmilie",
"xfSpoiler",
];
$dropdowns = json_decode($db->fetchOne("
SELECT option_value
FROM xf_option
WHERE option_id = 'editorDropdownConfig'
"), true);
$existingToolbarConfig = json_decode($db->fetchOne("
SELECT option_value
FROM xf_option
WHERE option_id = 'editorToolbarConfig'
"), true);
if (isset($existingToolbarConfig['toolbarButtons']['moreRich']))
{
// already been converted
return;
}
$db->beginTransaction();
foreach ($dropdowns AS $dropdownId => &$dropdown)
{
if ($dropdownId === 'xfList')
{
// we want to keep this by default
continue;
}
$buttonsChanged = false;
foreach ($dropdown['buttons'] AS $i => $button)
{
if (in_array($button, $standardButtons))
{
unset($dropdown['buttons'][$i]);
$buttonsChanged = true;
}
}
if (!$dropdown['buttons'])
{
// Dropdown is empty, so remove or disable. Consider it to be a "standard" button and it won't
// be moved into the new layout.
$standardButtons[] = $dropdownId;
switch ($dropdownId)
{
case 'xfInsert':
// these are default dropdowns from before so just get rid of them
$db->delete('xf_editor_dropdown', 'cmd = ?', $dropdownId);
$db->delete('xf_phrase', 'title = ? AND language_id = 0', "editor_dropdown.{$dropdownId}");
break;
default:
// these are custom dropdowns so disable them
$db->update('xf_editor_dropdown', ['active' => 0], 'cmd = ? ', $dropdownId);
}
unset($dropdowns[$dropdownId]);
}
else if ($buttonsChanged)
{
// we still have buttons but they're different, so update the dropdown
$db->update(
'xf_editor_dropdown',
['buttons' => json_encode($dropdown['buttons'])],
'cmd = ?',
$dropdownId
);
}
}
foreach ($existingToolbarConfig AS $toolbarType => $buttons)
{
foreach ($buttons AS $button)
{
if (!in_array($button, $standardButtons))
{
$newToolbars[$toolbarType][$customInsertGroup]['buttons'][] = $button;
}
}
}
$db->update(
'xf_option',
['option_value' => json_encode($dropdowns)],
"option_id = 'editorDropdownConfig'"
);
$db->update(
'xf_option',
['option_value' => json_encode($newToolbars)],
"option_id = 'editorToolbarConfig'"
);
$db->commit();
}
public function step25()
{
$this->executeUpgradeQuery("
UPDATE xf_user_alert
SET read_date = view_date
");
}
public function step26()
{
$this->executeUpgradeQuery("
UPDATE xf_user
SET alerts_unviewed = alerts_unread
");
}
public function step27()
{
$this->addThreadPrefixDescHelpPhrases();
$this->db()->query("
INSERT IGNORE INTO xf_phrase
(language_id, title, phrase_text, global_cache, addon_id)
VALUES
(0, 'activity_summary_section.1', '', 0, ''),
(0, 'activity_summary_section.2', '', 0, '')
");
$this->db()->query("
INSERT IGNORE INTO `xf_activity_summary_section`
(`section_id`, `definition_id`, `display_order`, `options`)
VALUES
(1, 'latest_threads', 100, '[]'),
(2, 'latest_posts', 200, '[]')
");
$this->db()->insert(
'xf_node_type',
[
'node_type_id' => 'SearchForum',
'entity_identifier' => 'XF:SearchForum',
'permission_group_id' => 'searchForum',
'admin_route' => 'search-forums',
'public_route' => 'search-forums',
'handler_class' => 'XF:SearchForum'
],
true
);
$this->db()->emptyTable('xf_mail_queue');
}
public function addThreadPrefixDescHelpPhrases()
{
$inserts = [];
$prefixIds = $this->db()->fetchAllColumn("SELECT prefix_id FROM `xf_thread_prefix`");
$contentType = 'thread';
foreach ($prefixIds AS $prefixId)
{
$inserts[] = sprintf("(0, '%s_prefix_%s.%d', '')", $contentType, 'desc', $prefixId);
$inserts[] = sprintf("(0, '%s_prefix_%s.%d', '')", $contentType, 'help', $prefixId);
}
if ($inserts)
{
$this->executeUpgradeQuery("
INSERT IGNORE INTO xf_phrase
(language_id, title, phrase_text)
VALUES
" . implode(",\n", $inserts)
);
}
}
public function step28()
{
// don't trigger rebuilds here as it's possible the code will fail -- it's triggered by the core cache rebuild
$this->insertForumType('article', 'XF:Article', 'XF', false);
$this->insertForumType('discussion', 'XF:Discussion', 'XF', false);
$this->insertForumType('question', 'XF:Question', 'XF', false);
$this->insertForumType('suggestion', 'XF:Suggestion', 'XF', false);
$this->insertThreadType('article', 'XF:Article', 'XF', false);
$this->insertThreadType('discussion', 'XF:Discussion', 'XF', false);
$this->insertThreadType('poll', 'XF:Poll', 'XF', false);
$this->insertThreadType('question', 'XF:Question', 'XF', false);
$this->insertThreadType('redirect', 'XF:Redirect', 'XF', false);
$this->insertThreadType('suggestion', 'XF:Suggestion', 'XF', false);
}
public function step29()
{
$this->applyGlobalPermission('profileBanner', 'allowed', 'avatar', 'allowed');
$this->applyGlobalPermission('general', 'changeUsername', 'general', 'editProfile');
$this->applyGlobalPermission('general', 'approveUsernameChange', 'general', 'approveRejectUser');
$this->applyGlobalPermission('general', 'bypassNofollowLinks', 'general', 'viewIps');
// Don't give this to the unconfirmed group as it may not be obvious.
// If it's desired, it can be explicitly added.
$this->executeUpgradeQuery("
DELETE FROM xf_permission_entry
WHERE user_group_id = 1
AND user_id = 0
AND permission_group_id = 'general'
AND permission_id = 'changeUsername'
");
$this->applyGlobalPermission('forum', 'contentVote', 'forum', 'react');
$this->applyContentPermission('forum', 'contentVote', 'forum', 'react');
$this->applyGlobalPermission('forum', 'markSolution', 'forum', 'postThread');
$this->applyContentPermission('forum', 'markSolution', 'forum', 'postThread');
$this->applyGlobalPermission('forum', 'markSolutionAnyThread', 'forum', 'manageAnyThread');
$this->applyContentPermission('forum', 'markSolutionAnyThread', 'forum', 'manageAnyThread');
// profile post / comment attachment permissions
$this->applyGlobalPermission('profilePost', 'viewAttachment', 'forum', 'viewAttachment');
$this->applyGlobalPermission('profilePost', 'uploadAttachment', 'conversation', 'uploadAttachment');
$this->applyGlobalPermission('profilePost', 'uploadVideo', 'conversation', 'uploadVideo');
}
}