Ejemplo n.º 1
0
	private function fetch_tagcloud($type = 'usage')
	{
		$vbulletin = &$this->registry;

		$tags = array();

		if ($vbulletin->options['tagcloud_usergroup'] > 0 AND !isset($vbulletin->usergroupcache[$vbulletin->options['tagcloud_usergroup']]))
		{
			// handle a usergroup being deleted: default to live permission checking
			$vbulletin->options['tagcloud_usergroup'] = -1;
		}

		require_once(DIR . '/includes/class_taggablecontent.php');
		$collection = new vB_Collection_ContentType();
		$collection->filterTaggable(true);

		//create dummy content item objects.  We use these to call a couple of (what? - Darren)
		$type_objects = array();
		foreach ($collection AS $contenttype)
		{
			$type_objects[$contenttype->getID()] = vB_Taggable_Content_Item::create($vbulletin, $contenttype->getID(), null);
		}
		unset($collection, $contenttype);

		$cacheable = true;
		foreach ($type_objects AS $content)
		{
			if (!$content->is_cloud_cachable())
			{
				$cacheable = false;
				break;
			}
		}

		if (!$cacheable)
		{
			$cloud = null;
		}
		else
		{
			switch ($type)
			{
				case 'search':
					if (isset($vbulletin->searchcloud)) {
						$cloud = $vbulletin->searchcloud;
					}
					break;

				case 'usage':
				default:
					$cloud = $vbulletin->tagcloud;
					break;
			}
		}

		$cloud = null;
		if (!is_array($cloud) OR $cloud['dateline'] < (TIMENOW - (60 * $vbulletin->options['tagcloud_cachetime'])))
		{
			if ($type == 'search')
			{
				$tags_result = $vbulletin->db->query_read_slave("
					SELECT tagsearch.tagid, tag.tagtext, COUNT(*) AS searchcount
					FROM " . TABLE_PREFIX . "tagsearch AS tagsearch
					INNER JOIN " . TABLE_PREFIX . "tag AS tag ON (tagsearch.tagid = tag.tagid)
					" . ($vbulletin->options['tagcloud_searchhistory'] ?
						"WHERE tagsearch.dateline > " . (TIMENOW - (60 * 60 * 24 * $vbulletin->options['tagcloud_searchhistory'])) :
						'') . "
					GROUP BY tagsearch.tagid, tag.tagtext
					ORDER BY searchcount DESC
					LIMIT " . $vbulletin->options['tagcloud_tags']
				);
			}
			else
			{
				//get the query bits from the type objects.  If two objects return the same exact join/where information
				//we can collapse the subqueries.  This is particularly useful for the cms content types which are
				//largely the same under the hood.
				$bit_ids = array();
				$bit_values = array();
				foreach ($type_objects AS $type => $content)
				{
					$contenttypeid = vB_Types::instance()->getContentTypeID($type);
					$bits = $content->fetch_tag_cloud_query_bits();
					if ($bits)
					{
						$pos = array_search($bits, $bit_values);
						if ($pos === false)
						{
							$bit_ids[] = array($contenttypeid);
							$bit_values[] = $bits;
						}
						else
						{
							$bit_ids[$pos][] = $contenttypeid;
						}
					}
				}

				//build the subqueries from the bits.
				$subqueries = array();
				foreach ($bit_values AS $key => $bits)
				{
					$timelimit = (TIMENOW - (60 * 60 * 24 * $vbulletin->options['tagcloud_usagehistory']));
					$query = 	"
						SELECT tagcontent.tagid, tag.tagtext, COUNT(*) AS searchcount
						FROM " . TABLE_PREFIX . "tagcontent AS tagcontent
						INNER JOIN " . TABLE_PREFIX . "tag AS tag ON (tagcontent.tagid = tag.tagid) " .
						implode("\n", $bits['join']) . "
						WHERE tagcontent.contenttypeid IN (" . implode(",", $bit_ids[$key]) . ") AND
							tagcontent.dateline > $timelimit AND " .
							implode(" AND ", $bits['where']) . "
						GROUP BY tagcontent.tagid, tag.tagtext
					";
					$subqueries[] = $query;
				}

				if (count($subqueries))
				{
					$query = "
						SELECT data.tagid, data.tagtext, SUM(data.searchcount) AS searchcount
						FROM
							(" . implode(" UNION ALL ", $subqueries) . ") AS data
						GROUP BY data.tagid, data.tagtext
						ORDER BY searchcount DESC
						LIMIT " . $vbulletin->options['tagcloud_tags'];

					$tags_result = $vbulletin->db->query_read_slave($query);
					while ($currenttag = $vbulletin->db->fetch_array($tags_result))
					{
						$tags["$currenttag[tagtext]"] = $currenttag;
						$totals[$currenttag['tagid']] = $currenttag['searchcount'];
					}
				}
			}

			while ($currenttag = $vbulletin->db->fetch_array($tags_result))
			{
				$tags["$currenttag[tagtext]"] = $currenttag;
				$totals[$currenttag['tagid']] = $currenttag['searchcount'];
			}

			// fetch the stddev levels
			$levels = fetch_standard_deviated_levels($totals, $vbulletin->options['tagcloud_levels']);

			// assign the levels back to the tags
			foreach ($tags AS $tagtext => $tag)
			{
				$tags[$tagtext]['level'] = $levels[$tag['tagid']];
				$tags[$tagtext]['tagtext_url'] = urlencode(unhtmlspecialchars($tag['tagtext']));
			}

			// sort the categories by title
			uksort($tags, 'strnatcasecmp');

			$cloud = array(
				'tags' => $tags,
				'count' => sizeof($tags),
				'dateline' => TIMENOW
			);

			if ($cacheable)
			{
				if ($type == 'search' OR $type == 'selectlist')
				{
					$vbulletin->searchcloud = $cloud;
				}
				else
				{
					$vbulletin->tagcloud = $cloud;
				}
			}
		}

		if (empty($cloud['tags']))
		{
			return '';
		}

		$cloud['links'] = '';


		return $cloud;
	}