<commit_before><?php

/*
 * PorPOISe
 * Copyright 2009 SURFnet BV
 * Released under a permissive license (see LICENSE)
 *
 * Acknowledgments:
 * <NAME> for the "Increase range" error message
 */

/**
 * POI Server for Layar
 *
 * The server consists of a server class whose objects serve Layar responses when
 * properly configured and a factory class that helps you create a properly
 * configured server.
 *
 * @package PorPOISe
 */

/** requires most of PorPOISe base files */
require_once("porpoise.inc.php");

/**
 * Server class that serves up POIs for Layar
 *
 * @package PorPOISe
 */
class LayarPOIServer {
	/** Default error code */
	const ERROR_CODE_DEFAULT = 20;
	/** Request has no POIs in result */
	const ERROR_CODE_NO_POIS = 21;

	/** @var string[] Error messages stored in an array because class constants cannot be arrays */
	protected static $ERROR_MESSAGES = array(
		self::ERROR_CODE_DEFAULT => "An error occurred"
		, self::ERROR_CODE_NO_POIS => "No POIs found. Increase range or adjust filters to see POIs"
	);

	// layers in this server
	protected $layers = array();

	protected $requiredRequestFields = array("userId", "layerName", "lat", "lon");
	protected $optionalRequestFields = array("accuracy", "timestamp", "RADIOLIST", "SEARCHBOX_1", "SEARCHBOX_2", "SEARCHBOX_3", "CUSTOM_SLIDER_1", "CUSTOM_SLIDER_2", "CUSTOM_SLIDER_3", "pageKey", "oath_consumer_key", "oauth_signature_method", "oauth_timestamp", "oauth_nonce", "oauth_version", "oauth_signature", "radius", "alt");
	protected $optionalPOIFieldsDefaults = array(
		"inFocus" => FALSE,
		"alt" => NULL,
		"relativeAlt" => NULL,
		"timestamp" => NULL,
		"doNotIndex" => FALSE,
		"showSmallBiw" => TRUE,
		"showBiwOnClick" => TRUE
	);
	protected $optionalResponseFieldsDefaults = array(
		"refreshInterval" => 300,
		"refreshDistance" => 100,
		"fullRefresh" => TRUE,
		"actions" => array(),
		"showMessage" => NULL,
		"deletedHotspots" => array()
	);
	protected $optionalActionFieldsDefaults = array(
		"autoTriggerRange" => NULL,
		"autoTriggerOnly" => NULL,
		"contentType" => NULL,
		"method" => "GET",
		"activityType" => NULL,
		"params" => array(),
		"closeBiw" => FALSE,
		"showActivity" => TRUE,
		"activityMessage" => NULL
	);
	protected $optionalAnimationFieldsDefaults = array(
		"delay" => NULL,
		"interpolation" => NULL,
		"interpolationParam" => NULL,
		"persist" => FALSE,
		"repeat" => FALSE,
		"from" => NULL,
		"to" => NULL,
		"axis" => array("x" => NULL, "y" => NULL, "z" => NULL)
	);


	/**
	 * Add a layer to the server
	 *
	 * @param Layer $layer
	 *
	 * @return void
	 */
	public function addLayer(Layer $layer) {
		$this->layers[$layer->layerName] = $layer;
	}

	/**
	 * Handle a request
	 *
	 * Request variables are expected to live in the $_REQUEST superglobal
	 *
	 * @return void
	 */
	public function handleRequest(LayarLogger $loghandler = null) {
		$filter = $this->buildFilter();
		try {
			$this->validateRequest();
			
			$layer = $this->layers[$filter->layerName];
			$layer->determineNearbyPOIs($filter);
			
			$response = $layer->getLayarResponse();
			$response->layer = $filter->layerName;
			$numPois = count($response->hotspots);
			if ($loghandler) {
				$loghandler->log($filter, array('numpois' => $numPois));
			}
	
			$this->sendLayarResponse($response);
		} catch (Exception $e) {
			if ($loghandler) {
				$loghandler->log($filter, array('errorMessage' => $e->getMessage()));
			}
	
			$this->sendErrorResponse(self::ERROR_CODE_DEFAULT, $e->getMessage());
		}
	}

	/**
	 * Send a Layar response to a client
	 *
	 * @param array $pois An array of POIs that match the client's request
	 * @param bool $morePages Pass TRUE if there are more pages beyond this set of POIs
	 * @param string $nextPageKey Pass a valid key if $morePages is TRUE
	 *
	 * @return void
	 */
	protected function sendLayarResponse(LayarResponse $response) {
		if (count($response->hotspots) == 0) {
			$response->errorCode = self::ERROR_CODE_NO_POIS;
			$response->errorString = self::$ERROR_MESSAGES[$response->errorCode];
		}
		$aResponse = array();
		foreach ($response as $name => $value) {
			switch($name) {
			case "layer":
			case "nextPageKey":
			case "errorString":
				$aResponse[$name] = (string)$value;
				break;
			case "morePages":
				$aResponse[$name] = (bool)$response->$name;
				break;
			case "errorCode":
				$aResponse[$name] = (int)$response->$name;
				break;
			case "radius":
				$aResponse[$name] = intval(1.25 * $response->$name); // extend radius with 25% to avoid far away POI's dropping off when location changes
				break;
			case "hotspots":
				foreach ($value as $poi) {
					// test if current POI was requested and should be in focus
					if ($poi->id == @$this->filter->requestedPoiId) {
						$poi->inFocus = true;
					}
					
					$aPoi = $poi->toArray();
					// strip out optional fields to cut on bandwidth
					foreach ($this->optionalPOIFieldsDefaults as $field => $defaultValue) {
						// strip param from reponse if equal to default
						//
						// A note on the @ operator here:
						// there is a slight difference in PHP between an undefined variable
						// and one that has been defined and set to NULL. There is NO clean way
						// right now to distinguish between the two as isset() returns FALSE
						// on both cases, empty() returns TRUE on both cases and no other
						// function will take an undefined variable without raising a warning
						if (@$aPoi[$field] == $defaultValue) {
							unset($aPoi[$field]);
						}
					}
					foreach($aPoi["actions"] as &$action) {
						foreach($this->optionalActionFieldsDefaults as $field => $defaultValue) {
							if (@$action[$field] == $defaultValue) {
								unset($action[$field]);
							}
						}
					}
					foreach ($aPoi["animations"] as $event => &$animations) {
						foreach ($animations as &$animation) {
							foreach ($this->optionalAnimationFieldsDefaults as $field => $defaultValue) {
								if (@$animation[$field] == $defaultValue) {
									unset($animation[$field]);
								}
							}
						}
					}
					// upscale coordinate values and truncate to int because of inconsistencies in Layar API
					// (requests use floats, responses use integers?)
					$aPoi["lat"] = (int)($aPoi["lat"] * 1000000);
					$aPoi["lon"] = (int)($aPoi["lon"] * 1000000);
					// fix some types that are not strings
					$aPoi["type"] = (int)$aPoi["type"];
					$aPoi["distance"] = (float)$aPoi["distance"];
					
					$aResponse["hotspots"][] = $aPoi;
				}
				break;
			default:
				$aResponse[$name] = $value;
				break;
			}
		}

		// strip out optional global parameters
		foreach ($aResponse["actions"] as &$action) {
			foreach ($this->optionalActionFieldsDefaults as $field => $defaultValue) {
				if (@$action->field == $defaultValue) {
					unset($action->field);
				}
			}
		}
		foreach ($aResponse["animations"] as $event => &$animations) {
			foreach ($animations as &$animation) {
				foreach ($this->optionalAnimationFieldsDefaults as $field => $defaultValue) {
					if (@$animation->$field == $defaultValue) {
						unset($animation->$field);
					}
				}
			}
		}
		foreach ($this->optionalResponseFieldsDefaults as $field => $defaultValue) {
			if (@$aResponse[$field] == $defaultValue) {
				unset($aResponse[$field]);
			}
		}

		/* Set the proper content type */
		header("Content-Type: application/json;charset=utf-8");

		printf("%s", json_encode($aResponse));<commit_msg>Sparse Animations lists: remove all empty components<commit_after><?php

/*
 * PorPOISe
 * Copyright 2009 SURFnet BV
 * Released under a permissive license (see LICENSE)
 *
 * Acknowledgments:
 * <NAME> for the "Increase range" error message
 */

/**
 * POI Server for Layar
 *
 * The server consists of a server class whose objects serve Layar responses when
 * properly configured and a factory class that helps you create a properly
 * configured server.
 *
 * @package PorPOISe
 */

/** requires most of PorPOISe base files */
require_once("porpoise.inc.php");

/**
 * Server class that serves up POIs for Layar
 *
 * @package PorPOISe
 */
class LayarPOIServer {
	/** Default error code */
	const ERROR_CODE_DEFAULT = 20;
	/** Request has no POIs in result */
	const ERROR_CODE_NO_POIS = 21;

	/** @var string[] Error messages stored in an array because class constants cannot be arrays */
	protected static $ERROR_MESSAGES = array(
		self::ERROR_CODE_DEFAULT => "An error occurred"
		, self::ERROR_CODE_NO_POIS => "No POIs found. Increase range or adjust filters to see POIs"
	);

	// layers in this server
	protected $layers = array();

	protected $requiredRequestFields = array("userId", "layerName", "lat", "lon");
	protected $optionalRequestFields = array("accuracy", "timestamp", "RADIOLIST", "SEARCHBOX_1", "SEARCHBOX_2", "SEARCHBOX_3", "CUSTOM_SLIDER_1", "CUSTOM_SLIDER_2", "CUSTOM_SLIDER_3", "pageKey", "oath_consumer_key", "oauth_signature_method", "oauth_timestamp", "oauth_nonce", "oauth_version", "oauth_signature", "radius", "alt");
	protected $optionalPOIFieldsDefaults = array(
		"inFocus" => FALSE,
		"alt" => NULL,
		"relativeAlt" => NULL,
		"timestamp" => NULL,
		"doNotIndex" => FALSE,
		"showSmallBiw" => TRUE,
		"showBiwOnClick" => TRUE
	);
	protected $optionalResponseFieldsDefaults = array(
		"refreshInterval" => 300,
		"refreshDistance" => 100,
		"fullRefresh" => TRUE,
		"actions" => array(),
		"showMessage" => NULL,
		"deletedHotspots" => array()
	);
	protected $optionalActionFieldsDefaults = array(
		"autoTriggerRange" => NULL,
		"autoTriggerOnly" => NULL,
		"contentType" => NULL,
		"method" => "GET",
		"activityType" => NULL,
		"params" => array(),
		"closeBiw" => FALSE,
		"showActivity" => TRUE,
		"activityMessage" => NULL
	);
	protected $optionalAnimationFieldsDefaults = array(
		"delay" => NULL,
		"interpolation" => NULL,
		"interpolationParam" => NULL,
		"persist" => FALSE,
		"repeat" => FALSE,
		"from" => NULL,
		"to" => NULL,
		"axis" => array("x" => NULL, "y" => NULL, "z" => NULL)
	);


	/**
	 * Add a layer to the server
	 *
	 * @param Layer $layer
	 *
	 * @return void
	 */
	public function addLayer(Layer $layer) {
		$this->layers[$layer->layerName] = $layer;
	}

	/**
	 * Handle a request
	 *
	 * Request variables are expected to live in the $_REQUEST superglobal
	 *
	 * @return void
	 */
	public function handleRequest(LayarLogger $loghandler = null) {
		$filter = $this->buildFilter();
		try {
			$this->validateRequest();
			
			$layer = $this->layers[$filter->layerName];
			$layer->determineNearbyPOIs($filter);
			
			$response = $layer->getLayarResponse();
			$response->layer = $filter->layerName;
			$numPois = count($response->hotspots);
			if ($loghandler) {
				$loghandler->log($filter, array('numpois' => $numPois));
			}
	
			$this->sendLayarResponse($response);
		} catch (Exception $e) {
			if ($loghandler) {
				$loghandler->log($filter, array('errorMessage' => $e->getMessage()));
			}
	
			$this->sendErrorResponse(self::ERROR_CODE_DEFAULT, $e->getMessage());
		}
	}

	/**
	 * Send a Layar response to a client
	 *
	 * @param array $pois An array of POIs that match the client's request
	 * @param bool $morePages Pass TRUE if there are more pages beyond this set of POIs
	 * @param string $nextPageKey Pass a valid key if $morePages is TRUE
	 *
	 * @return void
	 */
	protected function sendLayarResponse(LayarResponse $response) {
		if (count($response->hotspots) == 0) {
			$response->errorCode = self::ERROR_CODE_NO_POIS;
			$response->errorString = self::$ERROR_MESSAGES[$response->errorCode];
		}
		$aResponse = array();
		foreach ($response as $name => $value) {
			switch($name) {
			case "layer":
			case "nextPageKey":
			case "errorString":
				$aResponse[$name] = (string)$value;
				break;
			case "morePages":
				$aResponse[$name] = (bool)$response->$name;
				break;
			case "errorCode":
				$aResponse[$name] = (int)$response->$name;
				break;
			case "radius":
				$aResponse[$name] = intval(1.25 * $response->$name); // extend radius with 25% to avoid far away POI's dropping off when location changes
				break;
			case "hotspots":
				foreach ($value as $poi) {
					// test if current POI was requested and should be in focus
					if ($poi->id == @$this->filter->requestedPoiId) {
						$poi->inFocus = true;
					}
					
					$aPoi = $poi->toArray();
					// strip out optional fields to cut on bandwidth
					foreach ($this->optionalPOIFieldsDefaults as $field => $defaultValue) {
						// strip param from reponse if equal to default
						//
						// A note on the @ operator here:
						// there is a slight difference in PHP between an undefined variable
						// and one that has been defined and set to NULL. There is NO clean way
						// right now to distinguish between the two as isset() returns FALSE
						// on both cases, empty() returns TRUE on both cases and no other
						// function will take an undefined variable without raising a warning
						if (@$aPoi[$field] == $defaultValue) {
							unset($aPoi[$field]);
						}
					}
					foreach($aPoi["actions"] as &$action) {
						foreach($this->optionalActionFieldsDefaults as $field => $defaultValue) {
							if (@$action[$field] == $defaultValue) {
								unset($action[$field]);
							}
						}
					}
					foreach ($aPoi["animations"] as $event => &$animations) {
						foreach ($animations as $k => &$animation) {
							foreach ($this->optionalAnimationFieldsDefaults as $field => $defaultValue) {
								if (@$animation[$field] == $defaultValue) {
									unset($animation[$field]);
								}
							}
							if (!count($animations[$k])) {
								unset($animations[$k]);
							}							
						}
						if (!count($aPoi["animations"][$event])) {
							unset($aPoi["animations"][$event]);
						}
					}
					if (!count($aPoi["animations"])) {
						unset($aPoi["animations"]);
					}
					// upscale coordinate values and truncate to int because of inconsistencies in Layar API
					// (requests use floats, responses use integers?)
					$aPoi["lat"] = (int)($aPoi["lat"] * 1000000);
					$aPoi["lon"] = (int)($aPoi["lon"] * 1000000);
					// fix some types that are not strings
					$aPoi["type"] = (int)$aPoi["type"];
					$aPoi["distance"] = (float)$aPoi["distance"];
					
					$aResponse["hotspots"][] = $aPoi;
				}
				break;
			default:
				$aResponse[$name] = $value;
				break;
			}
		}

		// strip out optional global parameters
		foreach ($aResponse["actions"] as &$action) {
			foreach ($this->optionalActionFieldsDefaults as $field => $defaultValue) {
				if (@$action->field == $defaultValue) {
					unset($action->field);
				}
			}
		}
		foreach ($aResponse["animations"] as $event => &$animations) {
			foreach ($animations as $k => &$animation) {
				foreach ($this->optionalAnimationFieldsDefaults as $field => $defaultValue) {
					if (@$animation[$field] == $defaultValue) {
						unset($animation[$field]);
					}
				}
				if (!count($animations[$k])) {
					unset($animations[$k]);
				}							
			}
			if (!count($aResponse["animations"][$event])) {
				unset($aResponse["animations"][$event]);
			}
		}
		if (!count($aResponse["animations"])) {
			unset($aResponse["animations"]);
		}
		foreach ($this->optionalResponseFieldsDefaults as $field => $defaultValue) {
			if (@$aResponse[$field] == $defaultValue) {
				unset($aResponse[$field]);
			}
		}

		/* Set the proper content type */
		header("Content-Type: application/json;charset=utf-8");

		printf("%s", json_encode($aResponse));
{'fraction_non_alphanumeric': 0.15385114107883818, 'fraction_numerical': 0.005316390041493776, 'mean_word_length': 3.5023350846468184, 'pattern_counts': {'":': 14, '<': 7, '<?xml version=': 0, '>': 175, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7444448', 'n_tokens_mistral': 5922, 'n_tokens_neox': 4825, 'n_words': 1313}