<?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   # ||
|| ###################################################################### ||
\*========================================================================*/

/**
 * @package vBulletin
 */
class vBRelatedText_dB_MYSQL_QueryDefs extends vB_dB_MYSQL_QueryDefs
{
	/*Properties====================================================================*/

	//type-specific
	protected $db_type = 'MYSQL';

	protected $table_data = [
		'noderelated' => [
			'key' => 'nodeid',
			'structure' => [
				'keywords', 'nodeid',
			],
			'forcetext' => ['keywords'],
		],
	];

	/*
	 * This is the definition for queries.
	 */

	protected $query_data = [

	];

	public function getTopicBatch($params, $db, $check_only = false)
	{
		if ($check_only)
		{
			return true;
		}

		$params = vB::getCleaner()->cleanArray($params, [
			'startat' => vB_Cleaner::TYPE_UINT,
			'nextid' => vB_Cleaner::TYPE_UINT,
			'excludedtypes' => vB_Cleaner::TYPE_ARRAY_UINT,
		]);

		$where = [
			"`node`.`nodeid` >= " . $params['startat'] ,
			"`node`.`nodeid` < " . $params['nextid'],
		];

		$sql = $this->getTopicSql("`node`.`nodeid`, `node`.`title`", $params, [], $where, null, []);

		return $this->getResultSet($db, $sql, __FUNCTION__);
	}

	public function getIncrementalTopicBatch($params, $db, $check_only = false)
	{
		if ($check_only)
		{
			return true;
		}

		$params = vB::getCleaner()->cleanArray($params, [
			'startat' => vB_Cleaner::TYPE_UINT,
			'nextid' => vB_Cleaner::TYPE_UINT,
			'cutoff' => vB_Cleaner::TYPE_UINT,
			'excludedtypes' => vB_Cleaner::TYPE_ARRAY_UINT,
		]);

		$joins = [
			'noderelated' => "LEFT JOIN `" . TABLE_PREFIX . "noderelated` AS `noderelated` ON (`node`.`nodeid` = `noderelated`.`nodeid`)",
		];

		$where = [
			"`node`.`nodeid` >= " . $params['startat'] ,
			"`node`.`nodeid` < " . $params['nextid'],
			"`node`.`lastcontent` >= " . $params['cutoff'],
			"`noderelated`.`nodeid` IS NULL"
		];

		$sql = $this->getTopicSql("`node`.`nodeid`, `node`.`title`", $params, $joins, $where, null, []);
		return $this->getResultSet($db, $sql, __FUNCTION__);
	}

	public function getTextForTopic($params, $db, $check_only = false)
	{
		if ($check_only)
		{
			return true;
		}

		$params = vB::getCleaner()->cleanArray($params, [
			'nodeid' => vB_Cleaner::TYPE_UINT,
			'textcount' => vB_Cleaner::TYPE_UINT,
		]);

		$where = [
			"`node`.`starter` = " . $params['nodeid'] ,
			"`text`.`rawtext` != ''",

			// keep the filters for the text in sync with the topics so we don't pull text
			// for for nodes we aren't going to process.
			"`node`.`showpublished` = 1",
			"`node`.`showapproved` = 1",
		];

		$sql = "
			SELECT `text`.`rawtext`
			FROM `" . TABLE_PREFIX . "node` AS `node`
				JOIN `" . TABLE_PREFIX . "text` AS `text` ON `text`.`nodeid` = `node`.`nodeid`
			WHERE
				" . implode(" AND ", $where) . "
			ORDER BY `node`.`nodeid` ASC
			LIMIT " . $params['textcount'] . "
		";


		return $this->getResultSet($db, $sql, __FUNCTION__);
	}

	public function getTopicNextId($params, $db, $check_only = false)
	{
		if ($check_only)
		{
			return true;
		}

		$params = vB::getCleaner()->cleanArray($params, [
			'startat' => vB_Cleaner::TYPE_UINT,
			'batchsize' => vB_Cleaner::TYPE_UINT,
			'cutoff' => vB_Cleaner::TYPE_UINT,
			'excludedtypes' => vB_Cleaner::TYPE_ARRAY_UINT,
		]);

		$where = [
			"`node`.`nodeid` >= " . $params['startat'] ,
		];

		// If we have a cutoff, use it.  We won't try to do the join to exclude the already processed items
		// Chances are we won't have a lot of batches and the "not in table" logic isn't super efficient.
		if ($params['cutoff'])
		{
			$where[] = "`node`.`lastcontent` >= " . $params['cutoff'];
		}

		$sql = $this->getTopicSql("`node`.`nodeid`", $params, [], $where, $params['batchsize'], []);
		return $this->getResultSet($db, $sql, __FUNCTION__);
	}

	public function getTopicMaxId($params, $db, $check_only = false)
	{
		if ($check_only)
		{
			return true;
		}

		$params = vB::getCleaner()->cleanArray($params, [
			'excludedtypes' => vB_Cleaner::TYPE_ARRAY_UINT,
		]);

		$sql = $this->getTopicSql("MAX(`node`.`nodeid`) AS `max`", $params, [], [], null, ['node_showapproved', 'showpublished']);
		return $this->getResultSet($db, $sql, __FUNCTION__);
	}

	private function getTopicSql(string $select, array $params, array $joins, array $where, ?int $limit, array $excludeindex)
	{
		// add the stardard filters to the caller specific ones.
		$where[] = "`node`.`nodeid` = `node`.`starter`";
		$where[] = "`node`.`starter` != 0";
		$where[] = "`node`.`title` != ''";
		$where[] = "`node`.`showpublished` = 1";
		$where[] = "`node`.`showapproved` = 1";
		$where[] = "`node`.`contenttypeid` NOT IN (" . implode($params['excludedtypes']) . ")";

		$indexhint = '';
		if (count($excludeindex))
		{
			$indexhint = ' IGNORE INDEX (' . implode(', ', $excludeindex) . ')';
		}

		$sql = "
			SELECT " . $select . "
			FROM `" . TABLE_PREFIX . "node` AS `node`" . $indexhint . "
				" . implode ("\n", $joins) . "
			WHERE
				" . implode(" AND ", $where) . "
			ORDER BY `node`.`nodeid` ASC
		";

		if ($limit)
		{
			$sql .= "\nLIMIT " . $limit . ", 1";
		}

		return $sql;
	}

	public function updateKeywords($params, $db, $check_only = false)
	{
		if ($check_only)
		{
			return true;
		}

		$params = vB::getCleaner()->cleanArray($params, [
			'keywords' => vB_Cleaner::TYPE_NOCLEAN,
		]);

		// make sure we clean both the key and the value here.
		$values = [];
		foreach ($params['keywords'] AS $nodeid => $keywords)
		{
			$safekeywords = "'" . $db->escape_string($keywords) . "'";
			$values[] = '(' . intval($nodeid) . ', ' . $safekeywords . ')';
		}
		// we haven't cleaned this so make sure it doesn't get used downstream.
		unset($params['keywords']);

		$sql = "
			INSERT INTO `" . TABLE_PREFIX . "noderelated` (`nodeid`, `keywords`)
			VALUES " . implode(',', $values) .  "
			ON DUPLICATE KEY UPDATE `keywords` = VALUES(`keywords`)
		";

		return $this->executeWriteQuery($db, $sql, __FUNCTION__);
	}
}

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