Show:

File: platform/plugins/Places/classes/Places/Interest.php

<?php
	
class Places_Interest
{
	/**
	 * Fetch (and create, if necessary) category streams for things happening
	 * around the given location, during a particular hour.
	 * @method streams
	 * @static
	 * @param {string} $publisherId The publisherId of the category streams
	 * @param {double} $latitude The latitude of the coordinates near which to relate
	 * @param {double} $longitude The longitude of the coordinates near which to relate
	 * @param {string} $title The title of the interest, which will be normalized
	 * @param {array} $options The options to pass to the Streams::relate and Streams::create functions. Also can contain the following options:
	 * @param {string} [$experienceId="main"]
	 *   The id of a community experience, the last part of its stream name
	 * @param {array} [$options.meters] Override the default set of distances found in the config under Places/nearby/meters
	 * @param {callable} [$options.create] If set, this callback will be used to create streams when they don't already exist. It receives the $options array and should return a Streams_Stream object. If this option is set to null, new streams won't be created.
	 * @param {callable} [$options.transform="array_keys"] Can be used to override the function which takes the output of Places_Nearby::forPublishers, and this $options array, and returns the array of ($originalStreamName => $newStreamName) pairs.
	 * @param {array} [$streamNames=null] Optional reference to fill with the stream names
	 * @return {array} Returns the array of category streams
	 */
	static function streams(
		$publisherId,
		$latitude, 
		$longitude, 
		$title,
		$options = array(),
		&$streamNames = array())
	{
		$options = array_merge(array(
			'transform' => array('Places_Interest', '_transform'),
			'create' => array('Places_Interest', '_create'),
			'title' => $title
		), $options);
		return Places_Nearby::streams(
			$publisherId,
			$latitude,
			$longitude,
			$options,
			$streamNames
		);
	}
	
	/**
	 * Get all the relations to various Places/interest streams, sorted by ascending weight.
	 * Note that some of these streams may be slightly out of range
	 * and you may want to perform additional filtering using Places::distance().
	 * The "latitude", "longitude" and "meters" options can be used to override
	 * those found in Places_Nearby::defaults(). If after this, any one of
	 * "latitude", "longitude" or "meters" is still not set, then the
	 * "Streams/experience/$experienceId" stream is used instead of Places_Nearby streams.
	 * @method related
	 * @static
	 * @param {string} $publisherId The publisher of the category streams
	 * @param {string} $relationType The type of the relation
	 * @param {string|array|Db_Range} $titles
	 *    The titles of the interests, which will be normalized
	 * @param {string} [$experienceId="main"]
	 *    The id of a community experience, the last part of its stream name
	 * @return {array} Returns an array of Streams_RelatedTo objects
	 */
	static function related(
		$publisherId,
		$relationType,
		$titles,
		$experienceId = 'main')
	{
		if (is_string($titles)) {
			$titles = array($titles);
		}
		list($latitude, $longitude, $meters) = Places_Nearby::defaults();
		$categories = array('Places_Interest', '_categories');
		$options = compact('categories', 'experienceId', 'titles');
		return Places_Nearby::related(
			$publisherId, $relationType, $latitude, $longitude, $meters, $options
		);
	}
	
	/**
	 * Get streams related to Places/interest streams, which are found from the
	 * following parameters. Note that some of these streams may be slightly out of range
	 * and you may want to perform additional filtering using Places::distance().
	 * The "latitude", "longitude" and "meters" options can be used to override
	 * those found in Places_Nearby::defaults(). If after this, any one of
	 * "latitude", "longitude" or "meters" is still not set, then the
	 * "Streams/experience/$experienceId" stream is used instead of Places_Nearby streams.
	 * @method byTime
	 * @static
	 * @param {string} $publisherId The publisher of the category streams
	 * @param {string} $relationType The type of the relation
	 * @param {string|array|Db_Range} $titles 
	 *   The titles of the interests, which will be normalized
	 * @param {integer} $fromTime A unix timestamp, in either seconds or milliseconds
	 * @param {integer} $toTime A unix timestamp, in either seconds or milliseconds
	 * @param {string} [$experienceId="main"]
	 *   The id of a community experience, the last part of its stream name
	 * @param {array} [$options]
	 * @param {double} [$options.latitude] The latitude of the point to search around
	 * @param {double} [$options.longitude] The longitude of the point to search around
	 * @param {double} [$options.meters=null] One of the values in Places/nearby/meters config array,
	 *  used to find the right Places/nearby stream.
	 * @param {string} [$options.asUserId] Override the default user id to fetch streams as.
	 *  Not used for now, since this function always fetches the relations only.
	 * @return {array} Returns an array of Streams_RelatedTo objects
	 */
	static function byTime(
		$publisherId, 
		$relationType,
		$titles,
		$fromTime, 
		$toTime, 
		$experienceId = 'main',
		$options = array())
	{
		$fromTime = Q_Utils::timestamp($fromTime);
		$toTime = Q_Utils::timestamp($toTime);
		list($latitude, $longitude, $meters) = Places_Nearby::defaults();
		$weight = new Db_Range($fromTime, true, false, $toTime);
		if (is_string($titles)) {
			$titles = array($titles);
		}
		extract(Q::take($options, array('latitude', 'longitude', 'meters')), EXTR_IF_EXISTS);
		$categories = array('Places_Interest', '_categories');
		$o = compact(
			'categories', 'experienceId', 'titles',
			'fromTime', 'toTime', 'weight'
		);
		if (isset($latitude) and isset($longitude) and isset($meters)) {
			return Places_Nearby::related(
				$publisherId, $relationType, $latitude, $longitude, $meters, $o
			);
		}
		$o['relationType'] = $relationType;
		$prefix = "Streams/interest/$experienceId/";
		if ($titles instanceof Db_Range) {
			$streamNames = new Db_Range(
				$prefix . $titles->min,
				$titles->includeMin,
				$titles->includeMax,
				$prefix . $titles->max
			);
		} else {
			$streamNames = array();
			foreach ($titles as $title) {
				$t[] = $prefix . Q_Utils::normalize($title);
			}
		}
		return Streams_RelatedTo::fetchAll(
			$publisherId, $streamNames, $relationType, $o
		);
	}
	
	static function _transform($nearby, $options)
	{
		$title = Q_Utils::normalize($options['title']);
		$experienceId = Q::ifset($options, 'experienceId', 'main');
		$result = array();
		foreach ($nearby as $k => $info) {
			$result[$k] = "Places/interest/$experienceId/$info[geohash]/$info[meters]/$title";
		}
		return $result;
	}
	
	static function _categories($nearby, $options)
	{
		$experienceId = Q::ifset($options, 'experienceId', 'main');
		$result = array();
		$titles = $options['titles'];
		foreach ($nearby as $k => $info) {
			$prefix = "Places/interest/$experienceId/$info[geohash]/$info[meters]/";
			if ($titles instanceof Db_Range) {
				$t = new Db_Range(
					$prefix . $titles->min,
					$titles->includeMin,
					$titles->includeMax,
					$prefix . $titles->max
				);
			} else {
				$t = array();
				foreach ($titles as $title) {
					$t[] = $prefix . Q_Utils::normalize($title);
				}
			}
			$result[$k] = $t;
		}
		return $result;
	}
	
	static function _create($params, $options)
	{
		$options['name'] = $params['name'];
		return Streams::create(null, $params['publisherId'], 'Places/interest', $options);
	}
	
}