<?php
/*========================================================================*\
|| ###################################################################### ||
|| # vBulletin 6.2.3 - Licence Number L3138846
|| # ------------------------------------------------------------------ # ||
|| # Copyright 2000-2026 MH Sub I, LLC dba vBulletin. All Rights Reserved.  # ||
|| # This file may not be redistributed in whole or significant part.   # ||
|| # ----------------- VBULLETIN IS NOT FREE SOFTWARE ----------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html   # ||
|| ###################################################################### ||
\*========================================================================*/

// ##################### DEFINE IMPORTANT CONSTANTS #######################
define('CVS_REVISION', '$RCSfile$ - $Revision: 122851 $');

// #################### PRE-CACHE TEMPLATES AND DATA ######################
global $phrasegroups, $specialtemplates, $vbphrase, $vbulletin, $imodcache;;
$phrasegroups = ['forum', 'cpuser', 'forumdisplay', 'prefix'];
$specialtemplates = [];

// ########################## REQUIRE BACK-END ############################
require_once(dirname(__FILE__) . '/global.php');
require_once(DIR . '/includes/adminfunctions_template.php');
require_once(DIR . '/includes/adminfunctions_prefix.php');

//It's not really clear why we disable the time limit in this file.
//None of the operations seem to be sufficiently long to warrant it.
vB_Utility_Functions::setPhpTimeout(0);

// ######################## CHECK ADMIN PERMISSIONS #######################
if (!can_administer('canadminforums'))
{
	print_cp_no_permission();
}

// ############################# LOG ACTION ###############################


$vbulletin->input->clean_array_gpc('r', [
	'moderatorid' 	=> vB_Cleaner::TYPE_UINT,
	'nodeid'		=> vB_Cleaner::TYPE_UINT
]);

$message = '';
if ($vbulletin->GPC['moderatorid'] != 0)
{
	$message = 'moderator id = ' . $vbulletin->GPC['moderatorid'];
}
else if ($vbulletin->GPC['nodeid'] != 0)
{
	$message = 'node id = ' . $vbulletin->GPC['nodeid'];
}

log_admin_action($message);
unset($message);

// ########################################################################
// ######################### START MAIN SCRIPT ############################
// ########################################################################

print_cp_header($vbphrase['channel_manager_gforum'], [
	get_admincp_script_tag('vbulletin_channel.js'),
]);

if (empty($_REQUEST['do']))
{
	$_REQUEST['do'] = 'modify';
}

// Legacy Hook 'channeladmin_start' Removed //

// ###################### Start add #######################
if ($_REQUEST['do'] == 'add' OR $_REQUEST['do'] == 'edit')
{
	$vbulletin->input->clean_array_gpc('r', [
		'nodeid'			=> vB_Cleaner::TYPE_UINT,
		'parentid'			=> vB_Cleaner::TYPE_UINT
	]);

	$channelApi = vB_Api::instanceInternal('Content_Channel');
	$rootChannelid = $channelApi->fetchChannelIdByGUID(vB_Channel::MAIN_CHANNEL);
	$forumChannelid = $channelApi->fetchChannelIdByGUID(vB_Channel::MAIN_FORUM);

	if ($_REQUEST['do'] == 'add')
	{
		if ($vbulletin->GPC['parentid'] == $rootChannelid)
		{
			print_stop_message('cant_add_channel_to_root');
		}

		// Set Defaults;
		$channel = [
			'nodeid' => 0,
			'title' => '',
			'description' => '',
			'displayorder' => 1,
			'parentid' => $vbulletin->GPC['parentid'],
			'styleid' => '',
			'styleoverride' => 0,
			'cancontainthreads' => 1,
			'postsperperiod' => 0,
			'postperiodlength' => 0,
			'options' => [
				'allowbbcode' => 1,
				'allowsmilies' => 1,
				'styleoverride' => 0,
				'prefixrequired' => 0,
				'moderatepublish' => 0,
				'collapsedbydefault' => 0,
			],
			'category' => 0,
			'filedataid' => null,
		];

		print_form_header2('admincp/forum', 'update', [], ['enctype' => 'multipart/form-data']);
		print_table_start2();
		print_table_header($vbphrase['add_new_forum_gforum']);
	}
	else
	{
		$channel = vB_Library::instance('Content_Channel')->getContent($vbulletin->GPC['nodeid']);
		$channel = reset($channel);

		print_form_header2('admincp/forum', 'update', [], ['enctype' => 'multipart/form-data']);
		print_table_start2();
		print_table_header(construct_phrase($vbphrase['x_y_id_z'], $vbphrase['channel'], vB_String::htmlSpecialCharsUni($channel['title']), $channel['nodeid']));
		construct_hidden_code('nodeid', $vbulletin->GPC['nodeid']);
	}

	$channel['title'] = str_replace('&amp;', '&', $channel['title']);
	$channel['description'] = str_replace('&amp;', '&', $channel['description'] ?? '');

	print_input_row($vbphrase['title'], 'channel[title]', $channel['title']);
	print_textarea_row($vbphrase['description_gcpglobal'], 'channel[description]', $channel['description']);

	// icon
	// This check may not be accurate as the parent may not be accurate/known (e.g. adding a new channel)
	$iconChannelId = $channel['parentid'];
	if (empty($iconChannelId))
	{
		$iconChannelId = $forumChannelid;
	}

	if (!empty($channel['nodeid']))
	{
		// If this is a channel in itself, use its own channel permissions
		$iconChannelId = $channel['nodeid'];
	}

	$userContext = vB::getUserContext();
	$canUploadChannelIcon = $userContext->getChannelPermission('forumpermissions', 'canuploadchannelicon', $iconChannelId);
	if ($canUploadChannelIcon)
	{
		print_channel_icon_upload_row(
			$vbphrase['channel_icon_admincp_label'],
			'channel_icon',
			null,
			$channel['filedataid'],
			'channel[filedataid]'
		);
	}
	else if (!empty($channel['filedataid']))
	{
		print_channel_icon_preview_row($vbphrase['channel_icon_admincp_label'], $channel['filedataid']);
	}

	print_input_row(get_text_with_description($vbphrase['display_order'], $vbphrase['zero_equals_no_display']), 'channel[displayorder]', $channel['displayorder']);
	if ($vbulletin->GPC['nodeid'] != -1)
	{
		$topLevelChannels = vB_Api::instance('content_channel')->fetchTopLevelChannelIds();
		if (!isset($channel['guid']) OR ($channel['guid'] != vB_Channel::MAIN_CHANNEL AND !in_array($channel['nodeid'], $topLevelChannels)))
		{
			$showParents = true;
			if (!empty($channel['nodeid']))
			{
				// Do not allow editing any "Special" sub-channel's ancestry, because doing so will break things badly.
				// ATM this is only needed to prevent moving the "Albums" channel.
				$specialDescendant = vB::getDbAssertor()->getRow('vBForum:closure',	[
					'parent' => $topLevelChannels['special'],
					'child' => $channel['nodeid'],
				]);

				$showParents = empty($specialDescendant);
			}
			if ($showParents)
			{
				print_channel_chooser($vbphrase['parent_forum'], 'channel[parentid]', $channel['parentid'], false, false, false, null, true);
			}
		}
	}
	else
	{
		construct_hidden_code('parentid', 0);
	}

	print_yes_no_row($vbphrase['category_collapsed_by_default'], 'channel[options][collapsedbydefault]', $channel['options']['collapsedbydefault']);
	print_input_row($vbphrase['maxpostsperperiod'], 'channel[postsperperiod]', $channel['postsperperiod']);
	print_input_row($vbphrase['postperiodlength'], 'channel[postperiodlength]', $channel['postperiodlength']);

	print_table_header($vbphrase['style_options']);

	if ($channel['styleid'] == 0)
	{
		$channel['styleid'] = -1; // to get the "use default style" option selected
	}
	print_style_chooser_row('channel[styleid]', $channel['styleid'], $vbphrase['use_default_style_gforum'], $vbphrase['custom_forum_style'], 1);
	print_yes_no_row($vbphrase['override_style_choice'], 'channel[options][styleoverride]', $channel['options']['styleoverride']);

	$mainChannel = vB_Library::instance('content_channel')->getMainChannel();
	if ($mainChannel['nodeid'] != $channel['nodeid'])
	{
		print_table_header($vbphrase['posting_options']);
		// For the main channel, changing "cancontainthreads" to Yes can severely break the site.
		// Disable that option for nodeid=1.
		// Edit: On second though, decided to hide the whole "posting options" block for nodeid=1 as
		// these options seem irrelevant for a category (no threads) channel, but leaving this block
		// in case we change our mind and want to be more selective.
		$extraattributes = [];
		if ($mainChannel['nodeid'] == $channel['nodeid'])
		{
			$extraattributes['title'] = $vbphrase['cannot_modify_system_channel'];
			$extraattributes['disabled'] = null;
		}

		print_yes_no_row($vbphrase['act_as_forum'], 'channel[options][cancontainthreads]', ($channel['category'] ? 0 : 1), $extraattributes);
		print_yes_no_row($vbphrase['allow_bbcode'], 'channel[options][allowbbcode]', $channel['options']['allowbbcode']);
		print_yes_no_row($vbphrase['allow_smilies'], 'channel[options][allowsmilies]', $channel['options']['allowsmilies']);
		print_yes_no_row($vbphrase['require_topics_have_prefix'], 'channel[options][prefixrequired]', $channel['options']['prefixrequired']);
		print_yes_no_row($vbphrase['moderatepublish'], 'channel[options][moderatepublish]', $channel['options']['moderatepublish']);
	}

	print_table_default_footer($vbphrase['save']);
}

// ###################### Start update #######################
if ($_POST['do'] == 'update')
{
	$vbulletin->input->clean_array_gpc('p', [
		'nodeid' => vB_Cleaner::TYPE_UINT,
		'channel' => vB_Cleaner::TYPE_ARRAY,
	]);

	$channelid = $vbulletin->GPC['nodeid'];

	// Keeping this separate from 'channel' array for isolated cleaning & handling
	$vbulletin->input->clean_array_gpc('f', [
		'channel_icon' => vB_Cleaner::TYPE_FILE
	]);
	scanVbulletinGPCFile('channel_icon');

	$channelAPI = vB_Api::instance('Content_Channel');
	$data = [];
	$data = $vbulletin->GPC['channel'];

	// Try uploading the channel icon first. If there was an error with the upload
	// (which may cause tmp_name to be empty), pass that along and let the API
	// functions map the error code to an error phrase. However ignore the error
	// if it's a NO_FILE error (that just means no icon was uploaded)
	$hasUpload = (
		!empty($vbulletin->GPC['channel_icon']['tmp_name']) OR
		!empty($vbulletin->GPC['channel_icon']['error']) AND
		$vbulletin->GPC['channel_icon']['error'] !== UPLOAD_ERR_NO_FILE
	);

	if ($hasUpload)
	{
		// If this channel already exists (i.e. this is an update), use itself for
		// channel permission lookups, otherwise try its specified parent channel
		if ($channelid)
		{
			$iconChannelId = $channelid;
		}
		else if (!empty($data['parentid']))
		{
			$iconChannelId = intval($data['parentid']);
		}

		if (!empty($iconChannelId))
		{
			$vbulletin->GPC['channel_icon']['parentid'] = $iconChannelId;
			$vbulletin->GPC['channel_icon']['uploadFrom'] = 'channelicon';

			$attachAPI = vB_Api::instance('content_attach');
			$result = $attachAPI->upload($vbulletin->GPC['channel_icon']);
			print_stop_message_on_api_error($result);

			if (!empty($result['filedataid']))
			{
				$data['filedataid'] = $result['filedataid'];
			}
		}
	}

	// There are smilie options in both the channel options and the node options
	// this duplication needs to be removed but that's going to require some additional
	// work.  For now try to keep them in sync.
	$data['disablesmilies'] = ($data['options']['allowsmilies'] ? 0 : 1);

	$isCategory = !$data['options']['cancontainthreads'];
	if ($channelid)
	{
		$response = $channelAPI->switchForumCategory($isCategory, $channelid);
		print_stop_message_on_api_error($response);

		$prior = vB::getDbAssertor()->getRow('vBForum:node', ['nodeid' => $channelid]);
		$response = $channelAPI->update($channelid, $data);
		print_stop_message_on_api_error($response);

		if (isset($data['parentid']) AND ($prior['parentid'] != $data['parentid']))
		{
			$response = vB_Api::instance('node')->moveNodes($channelid, $data['parentid']);
			print_stop_message_on_api_error($response);
		}
	}
	else
	{
		$data['category'] = ($isCategory ? 1 : 0);
		// Allow IMG BB Code
		$data['options']['allowimages'] = 1;
		// Allow HTML (but control it with channel permissions instead)
		$data['options']['allowhtml'] = 1;

		// article channels require different routes & pagetemplates to be set.
		if (isset($data['parentid']))
		{
			$parentid = $data['parentid'];
			$parentFullContent = vB_Library::instance('node')->getNodeFullContent($parentid);
			$parentFullContent = $parentFullContent[$parentid];
			if (!empty($parentFullContent['channeltype']) AND ($parentFullContent['channeltype'] == 'article'))
			{
				$data['templates']['vB5_Route_Channel'] = $channelPgTemplateId;
				$data['templates']['vB5_Route_Article'] = $channelConvTemplateid;
				$data['childroute'] = 'vB5_Route_Article';
				unset($data['category']);
			}
		}

		$channelid = $channelAPI->add($data);
		print_stop_message_on_api_error($channelid);
	}

	$url = get_admincp_url('forum', ['do'=>'modify', 'n'=> $channelid], 'channel' . $channelid);
	print_stop_message(['saved_channel_x_successfully',  $vbulletin->GPC['channel']['title']], $url);
}
// ###################### Start Remove #######################

if ($_REQUEST['do'] == 'remove')
{
	$vbulletin->input->clean_array_gpc('r', [
		'nodeid' => vB_Cleaner::TYPE_UINT
	]);

	$channel = vB_Library::instance('Content_Channel')->getContent($vbulletin->GPC['nodeid']);
	$channel = reset($channel);

	$description = construct_phrase(
		$vbphrase['are_you_sure_want_to_delete_channel_x'],
		$channel['title'],
		'nodeid',
		$channel['nodeid'],
	 	$vbphrase['are_you_sure_you_want_to_delete_this_channel'] . '<br /><br />'
	);

	$header = construct_phrase($vbphrase['confirm_deletion_x'], htmlspecialchars_uni($channel['title']));
	$hidden = ['nodeid' => $channel['nodeid']];
	print_confirmation($vbphrase, 'forum', 'kill', $description, $hidden, $header);
}

// ###################### Start Kill #######################

if ($_POST['do'] == 'kill')
{
	$vbulletin->input->clean_array_gpc('p', [
		'nodeid' => vB_Cleaner::TYPE_UINT
	]);

	vB_Api::instanceInternal('content_channel')->delete($vbulletin->GPC['nodeid']);
	print_stop_message('deleted_channel_successfully', get_admincp_url('forum', []));
}

// ###################### Start do order #######################
if ($_POST['do'] == 'doorder')
{
	$vbulletin->input->clean_array_gpc('p', [
		'order' => vB_Cleaner::TYPE_ARRAY
	]);
	$channelorder = $vbulletin->GPC['order'];

	$channelApi = vB_Api::instanceInternal('content_channel');

	$channels = vB_Api::instanceInternal('search')->getChannels(true);
	foreach ($channels AS $channel)
	{
		if (!isset($channelorder[$channel['nodeid']]))
		{
			continue;
		}

		$displayorder = intval($channelorder[$channel['nodeid']]);
		if ($channel['displayorder'] != $displayorder)
		{
			$channelApi->update($channel['nodeid'], ['displayorder' => $displayorder]);
		}
	}

	print_stop_message('saved_display_order_successfully', get_admincp_url('forum', ['do'=>'modify']));
}

function get_channel_actions($vbphrase, $modcount = null)
{
	$channeloptions = [
		''        => $vbphrase['choose_action'],
		'edit'    => $vbphrase['edit_forum'],
		'view'    => $vbphrase['view_forum'],
		'remove'  => $vbphrase['delete_forum'],
		'add'     => $vbphrase['add_child_forum'],
		'addmod'  => $vbphrase['add_moderator_gforum'],
		'listmod' => $vbphrase['list_moderators'],
		'perms'   => $vbphrase['view_permissions_gforum'],
	];

	if (is_int($modcount))
	{
		if ($modcount > 0)
		{
			$channeloptions['listmod'] = $vbphrase['list_moderators'] . " ($modcount)";
		}
		else
		{
			unset($channeloptions['listmod']);
		}
	}

	return $channeloptions;
}

function print_channel_rows($vbphrase, $imodcache, $cp_collapse_forums, $channels, $expanded_parents)
{
	foreach ($channels AS $nodeid => $channel)
	{
		$expandthis = ($expanded_parents === true OR in_array($nodeid, $expanded_parents));

		$modlist = $imodcache[$nodeid] ?? [];

		$modcount = sizeof($modlist);
		$mainoptions = get_channel_actions($vbphrase, $modcount);
		$cells = [];

		//Channel column
		$collapseprefix = '';
		if ($cp_collapse_forums)
		{
			if ($expandthis OR empty($channel['channels']))
			{
				$collapseprefix = '[-] ';
			}
			else
			{
				$collapseprefix = construct_link_code2('+', get_admincp_url('forum', ['do' => 'modify', 'expandid' => $nodeid]));
			}
		}

		$spacer = str_repeat('- - ', $channel['depth']);
		$url = get_admincp_url('forum', ['do' => 'edit', 'n' => $nodeid]);
		$cells[] = $collapseprefix . $spacer . '<a id="forum' . $nodeid . '" href="' . $url . '">' . $channel['htmltitle'] . '</a> (' . $vbphrase['node_id'] . ': ' . $nodeid . ')';

		//Controls column
		$attributes = ['class' => 'js-channeljump-select', 'data-channel' => $nodeid, 'data-collapse' => $cp_collapse_forums];
		$select  = construct_select('n' . $nodeid, $mainoptions, '', $attributes);

		$cells[] = "\n\t" . $select . "\n\t";

		//Display Order colunn
		$cells[] = construct_displayorder_control('order[' . $nodeid . ']', $channel['displayorder'], $vbphrase['edit_display_order']);

		//Last Update
		//unfortantely the dateformat options gets updated in the legacy registry is ways
		//that skip the datastore so use the legacy.  This follows the front end formatting logic which
		//is less than perfect.
		$cells[] = vbdate($GLOBALS['vbulletin']->options['dateformat'], $channel['lastcontent']) . ', ' .
			vbdate($GLOBALS['vbulletin']->options['timeformat'], $channel['lastcontent']);


		//Moderators Column
		$mods = [
			'' => $vbphrase['moderators'] . ' (' . $modcount . ')',
		];
		foreach ($modlist AS $moderator)
		{
			// deferred until needed/requested.
			//$displayname = getAdminCPUsernameAndDisplayname($moderator['username'], $moderator['displayname'], ['nospan']);
			$displayname = $moderator['username'];
			$mods[$moderator['moderatorid']] = '&nbsp;&nbsp;&nbsp;&nbsp;' . $displayname;
		}

		if ($modcount > 0)
		{
			$mods['show'] = $vbphrase['list_moderators'];
		}

		$mods['add'] = $vbphrase['add_moderator_gforum'];

		$select  = construct_select('m' . $nodeid, $mods, '', ['class' => 'js-modjump-select', 'data-channel' => $nodeid]);
		$cells[] = "\n\t" . $select . "\n\t";
		print_cells_row2($cells);

		if (!empty($channel['channels']) AND (!$cp_collapse_forums OR $expandthis))
		{
			print_channel_rows($vbphrase, $imodcache, $cp_collapse_forums, $channel['channels'], $expanded_parents);
		}
	}
}

// ###################### Start modify #######################
if ($_REQUEST['do'] == 'modify')
{
	$vbulletin->input->clean_array_gpc('r', [
		'nodeid' 	=> vB_Cleaner::TYPE_UINT,
		'expandid'	=> vB_Cleaner::TYPE_INT,
	]);

	if (!$vbulletin->GPC['expandid'])
	{
		$vbulletin->GPC['expandid'] = -1;
	}

	register_js_phrase([
		'please_select_forum',
	]);

	$channeloptions = get_channel_actions($vbphrase);
	$cp_collapse_forums = vB::getDatastore()->getOption('cp_collapse_forums');
	if ($cp_collapse_forums != 2)
	{
		$headers = [
			$vbphrase['channel'],
			$vbphrase['controls'],
			$vbphrase['display_order'],
			$vbphrase['last_updated'],
			$vbphrase['moderators']
		];
		$headercount = count($headers);

		print_form_header2('admincp/forum', 'doorder');
		print_table_start2();

		print_table_header($vbphrase['channel_manager_gforum'], $headercount);
		print_description_row($vbphrase['if_you_change_display_order'], 0, $headercount);
		fetch_row_bgclass(); // restart alternating row classes

		//this is primarily for print_channel_rows below but it sets a magic global $imodcache so
		//changing it's position could affect things unexpectedly.
		$modcache = cache_moderators();

		if ($vbulletin->GPC['expandid'] == -2)
		{
			$expanded_parents = true;
		}
		else
		{
			$expanded_parents = [];
			if (!empty($vbulletin->GPC['expandid']))
			{
				$expanded_parents = vB::getDbAssertor()->getColumn('vBForum:closure', 'parent', ['child' => $vbulletin->GPC['expandid']], 'depth');
			}
		}

		print_cells_row2($headers, 'thead');

		// Hide protected channels. A bug in search API was already hiding them, and per VBV-14764 we'll continue to hide them unless
		// customer feedback overwhelmingly indicate they want to be able to edit the special/protected channels.
		$channels = vB_Api::instanceInternal('search')->getChannels(false, ['include_protected' => 0]);
		print_channel_rows($vbphrase, $modcache, $cp_collapse_forums, $channels, $expanded_parents);

		$buttons = [
			['submit', $vbphrase['save_display_order']],
			construct_link_button($vbphrase['add_new_forum_gforum'] , get_admincp_url('forum', ['do' => 'add'])),
		];
		print_table_button_footer($buttons, $headercount);

		if ($cp_collapse_forums)
		{
			echo '<p class="smallfont" align="center">' . construct_link_code2($vbphrase['expand_all'], get_admincp_url('forum', ['do' => 'modify', 'expandid' => -2])) . '</p>';
		}
	}
	else
	{
		$headers = [
			$vbphrase['channel'],
			$vbphrase['controls'],
		];
		$headercount = count($headers);

		print_form_header2('admincp/forum', '');
		print_table_start2();

		print_table_header($vbphrase['channel_manager_gforum'], $headercount);

		print_cells_row2([$vbphrase['channel'], $vbphrase['controls']], 'thead');
		$cells = [];

		//the construct_select isn't compatible with construct_channel_chooser, should figure out how to bring this together.
		$attributes = construct_control_attributes('nodeid', ['id' => 'sel_foruid']);
		$cells[] = '<select ' . $attributes . '>' . construct_channel_chooser($vbulletin->GPC['nodeid'], true) . '</select>';

		$attributes = ['class' => 'js-channeljump-select', 'data-collapse' => $vbulletin->options['cp_collapse_forums']];
		$select  = construct_select('controls', $channeloptions, '', $attributes);

		$cells[] = "\n\t" . $select . "\n\t";

		print_cells_row2($cells);

		$buttons = [
			construct_link_button($vbphrase['add_new_forum_gforum'] , get_admincp_url('forum', ['do' => 'add'])),
		];
		print_table_button_footer($buttons, $headercount);
	}
}

// ###################### Start update #######################
if ($_REQUEST['do'] == 'view')
{
	$vbulletin->input->clean_array_gpc('r', [
		'nodeid' => vB_Cleaner::TYPE_UINT,
	]);

	$channel = vB_Api::instanceInternal('node')->getNode($vbulletin->GPC['nodeid']);
	$path = vB_Api::instanceInternal('route')->getUrl($channel['routeid'], [], []);
	print_cp_redirect($path);
}

if ($_REQUEST['do'] == 'listtasks')
{
	$assertor = vB::getDbAssertor();

	$nodeApi = vB_Api::instanceInternal('node');
	$channelLib = vB_Library::instance('content_channel');

	$tasks = $channelLib->getChannelTasks();

	$head = [];
	$head[] = $vbphrase['channel'];
	$head[] = $vbphrase['task'];
	$head[] = $vbphrase['when'];
	$head[] = $vbphrase['controls'];

	$colspan = count($head);
	print_form_header2('', '');
	print_table_start();

	print_table_header($vbphrase['channel_tasks'], $colspan);
	print_description_row($vbphrase['channel_tasks_description'], false, $colspan);

	if (!$tasks)
	{
		print_description_row($vbphrase['no_channel_tasks'], false, $colspan, '', 'center');
	}
	else
	{
		$channelids = [];
		foreach ($tasks AS $task)
		{
			$channelids[] = $task->nodeid;
		}
		$channels = $nodeApi->getNodes($channelids);

		print_cells_row2($head, 'thead');

		//currently these all match but I'm not sure that will continue to be the case.
		$taskPhrases = [
			'delete' => 'delete',
			'close' => 'close'
		];


		// display existing sets
		// Current phrases:
		// x_days_after_topic_activity
		// x_days_after_topic_created
		foreach ($tasks AS $task)
		{
			$cells = [];
			$cells[] = $channels[$task->nodeid]['title'];
			$cells[] = $vbphrase[$task->task];
			$cells[] = construct_phrase($vbphrase['x_days_after_topic_' . $task->maxagefrom], $task->maxagedays);
			$cells[] = '<div class="smallfont">' .
				construct_link_code2($vbphrase['edit'], get_admincp_url('forum', ['do' => 'edittask', 'channeltaskid' => $task->channeltaskid])) .
				construct_link_code2($vbphrase['delete'], get_admincp_url('forum', ['do' => 'deletetask', 'channeltaskid' => $task->channeltaskid])) .
			'</div>';

			print_cells_row2($cells);
		}
	}

	$buttons = [
		construct_link_button($vbphrase['add_task'] , get_admincp_url('forum', ['do' => 'addtask'])),
	];

	print_table_button_footer($buttons, $colspan);
}

if ($_REQUEST['do'] == 'addtask' OR $_REQUEST['do'] == 'edittask')
{
	$vbulletin->input->clean_array_gpc('r', [
		'channeltaskid' => vB_Cleaner::TYPE_UINT,
	]);

	$channelLib = vB_Library::instance('content_channel');

	print_form_header2('admincp/forum', 'savetask');
	print_table_start2();

	if ($vbulletin->GPC['channeltaskid'])
	{
		$task = $channelLib->getChannelTask($vbulletin->GPC['channeltaskid']);

		print_table_header($vbphrase['edit_channel_task']);
		construct_hidden_code('channeltaskid', $task->channeltaskid);
	}
	else
	{
		$task = vB_Entity_Channeltask::createDefault();
		print_table_header($vbphrase['add_task']);
	}

	//currently these all match but I'm not sure that will continue to be the case.
	$taskPhrases = [
		'delete' => 'delete',
		'close' => 'close'
	];

	// Current phrases
	// days_after_topic_activity
	// days_after_topic_created
	$fromPhrases = [];
	foreach ($task->getValidMaxAgeFrom() AS $from)
	{
		$fromPhrases[$from] =  'days_after_topic_' . $from;
	}

	$phraselookup = function($key) use($vbphrase) {return $vbphrase[$key] ?? $key;};

	print_channel_chooser($vbphrase['channel'], 'nodeid', $task->nodeid);
	print_select_row($vbphrase['task'], 'task', array_map($phraselookup, $taskPhrases), $task->task);
	print_select_row($vbphrase['channel_task_trigger'], 'maxagefrom', array_map($phraselookup, $fromPhrases), $task->maxagefrom);
	print_input_row($vbphrase['days'], 'maxagedays', $task->maxagedays);
	print_table_default_footer($vbphrase['save']);
}

if ($_POST['do'] == 'savetask')
{
	$vbulletin->input->clean_array_gpc('p', [
		'channeltaskid' => vB_Cleaner::TYPE_UINT,
		'nodeid' => vB_Cleaner::TYPE_UINT,
		'task' => vB_Cleaner::TYPE_STR,
		'maxagefrom' => vB_Cleaner::TYPE_STR,
		'maxagedays' => vB_Cleaner::TYPE_NUM,
	]);

	$data = [
		'nodeid' => $vbulletin->GPC['nodeid'],
		'task' => $vbulletin->GPC['task'],
		'maxagefrom' => $vbulletin->GPC['maxagefrom'],
		'maxageseconds' => $vbulletin->GPC['maxagedays'] * 86400,
	];

	if ($vbulletin->GPC['channeltaskid'])
	{
		$data['channeltaskid'] = $vbulletin->GPC['channeltaskid'];
	}

	$channelLib = vB_Library::instance('content_channel');
	$result = $channelLib->saveChannelTask($data);

	print_stop_message('channel_task_saved', get_admincp_url('forum', ['do' => 'listtasks']));
}

if ($_REQUEST['do'] == 'deletetask')
{
	$vbulletin->input->clean_array_gpc('r', [
		'channeltaskid' => vB_Cleaner::TYPE_UINT
	]);

	$channelLib = vB_Library::instance('content_channel');
	$channeltask = $channelLib->getChannelTask($vbulletin->GPC['channeltaskid']);

	$channel = $channelLib->getContent($channeltask->nodeid);
	$channel = reset($channel);

	$description = construct_phrase(
		$vbphrase['are_you_sure_want_to_delete_channeltask_x'],
		$channeltask->task,
		'channeltaskid',
		$channeltask->channeltaskid,
		$channel['title'],
	);

	$header = construct_phrase($vbphrase['confirm_deletion_x'], htmlspecialchars_uni($channel['title']));
	$hidden = ['channeltaskid' => $channeltask->channeltaskid];
	print_confirmation($vbphrase, 'forum', 'killtask', $description, $hidden, $header);
}

if ($_POST['do'] == 'killtask')
{
	$vbulletin->input->clean_array_gpc('p', [
		'channeltaskid' => vB_Cleaner::TYPE_UINT
	]);

	vB_Library::instance('content_channel')->deleteChannelTask($vbulletin->GPC['channeltaskid']);
	print_stop_message('deleted_channeltask_successfully', get_admincp_url('forum', ['do' => 'listtasks']));
}

print_cp_footer();

/*=========================================================================*\
|| #######################################################################
|| # Downloaded: 13:27, Sun Aug 30th 2026
|| # CVS: $RCSfile$ - $Revision: 122851 $
|| #######################################################################
\*=========================================================================*/
