/** * Constructor * @since Verison 3.9.1 */ public function __construct($api_key = 0, $api_secret = 0) { parent::__construct(); $api_key = (bool) $api_key; $api_secret = (bool) $api_secret; if ($api_key) { $this->api_key = $api_key; } if ($api_secret) { $this->api_secret = $api_secret; } if (!$api_key && defined("SMUGMUG_API_KEY")) { $this->api_key = SMUGMUG_API_KEY; } if (!$api_secret && defined("SMUGMUG_API_SECRET")) { $this->api_secret = SMUGMUG_API_SECRET; } if (!$api_secret && ($Config = AppCore::getConfig())) { $this->api_key = $Config->SmugMug->APIKey; } $this->Client = new Client(); }
/** * Is this user an administrator of the Flickr group * @since Version 3.9.1 * @return boolean */ private function isGroupAdmin() { $Config = AppCore::getConfig(); $params = ["group_id" => $Config->Flickr->GroupID, "membertypes" => "3,4", "per_page" => 100, "page" => 1]; $members = $this->execute("flickr.groups.members.getList", $params); if (!$members) { throw new Exception(sprintf("Could not fetch members of Flickr group %s: %s (%d)", $params[0], $this->getErrorMessage(), $this->getErrorCode())); } foreach ($members['members']['member'] as $row) { if ($row['nsid'] == $this->User->flickr_nsid) { return true; } } return false; }
/** * Validate user avatar * @since Version 3.9.1 * @return \Railpage\Users\User * * @param boolean $force */ public function validateAvatar($force = false) { if (!empty($this->avatar)) { if ($force || (empty($this->avatar_width) || empty($this->avatar_height) || $this->avatar_width == 0 || $this->avatar_height == 0)) { if ($size = @getimagesize($this->avatar)) { $Config = AppCore::getConfig(); if ($size[0] >= $Config->AvatarMaxWidth || $size[1] >= $Config->AvatarMaxHeight) { $this->avatar = sprintf("https://static.railpage.com.au/image_resize.php?w=%d&h=%d&image=%s", $Config->AvatarMaxWidth, $Config->AvatarMaxHeight, urlencode($this->avatar)); $this->avatar_filename = $this->avatar; $this->avatar_width = $size[0]; $this->avatar_height = $size[1]; } else { $this->avatar_width = $size[0]; $this->avatar_height = $size[1]; $this->avatar_filename = $this->avatar; } $this->commit(true); return $this; } } } $this->avatar = function_exists("format_avatar") ? format_avatar("http://static.railpage.com.au/modules/Forums/images/avatars/gallery/blank.png", 120, 120) : "http://static.railpage.com.au/modules/Forums/images/avatars/gallery/blank.png"; $this->avatar_filename = function_exists("format_avatar") ? format_avatar("http://static.railpage.com.au/modules/Forums/images/avatars/gallery/blank.png", 120, 120) : "http://static.railpage.com.au/modules/Forums/images/avatars/gallery/blank.png"; $this->avatar_width = 120; $this->avatar_height = 120; return $this; }
/** * Get WoE data for a latitude/longitude lookup * @since Version 3.9.1 * @param float $lat * @param float $lon * @return array */ public static function LatLonWoELookup($lat, $lon, $force = false) { if (is_null($lon) && strpos($lat, ",") !== false) { $tmp = explode(",", $lat); $lat = $tmp[0]; $lon = $tmp[1]; } $Config = AppCore::getConfig(); $Redis = AppCore::getRedis(); $placetypes = array(7, 8, 9, 10, 22, 24); $mckey = sprintf("railpage:woe=%s,%s;types=", $lat, $lon, implode(",", $placetypes)); if ($force || !($return = $Redis->fetch($mckey))) { $url = sprintf("http://where.yahooapis.com/v1/places\$and(.q('%s,%s'),.type(%s))?lang=en&appid=%s&format=json", $lat, $lon, implode(",", $placetypes), $Config->Yahoo->ApplicationID); $dbresult = self::getWoeFromCache($lat, $lon); if (is_array($dbresult)) { return $dbresult; } /** * Try and fetch using GuzzleHTTP from the web service */ try { $GuzzleClient = new Client(); $response = $GuzzleClient->get($url); } catch (RequestException $e) { switch ($e->getResponse()->getStatusCode()) { case 503: throw new Exception("Your call to Yahoo Web Services failed and returned an HTTP status of 503. That means: Service unavailable. An internal problem prevented us from returning data to you."); break; case 403: throw new Exception("Your call to Yahoo Web Services failed and returned an HTTP status of 403. That means: Forbidden. You do not have permission to access this resource, or are over your rate limit."); break; case 400: if (!($return = self::getViaCurl($url))) { throw new Exception(sprintf("Your call to Yahoo Web Services failed (zomg) and returned an HTTP status of 400. That means: Bad request. The parameters passed to the service did not match as expected. The exact error is returned in the XML/JSON response. The URL sent was: %s\n\n%s", $url, json_decode($e->getResponse()->getBody()))); } break; default: throw new Exception("Your call to Yahoo Web Services returned an unexpected HTTP status of: " . $response->getStatusCode()); } } if (!$return && isset($response) && $response->getStatusCode() == 200) { $return = json_decode($response->getBody(), true); } /** * Save it in the database */ if (!empty($lat) && !empty($lon)) { $Database = (new AppCore())->getDatabaseConnection(); // Stop ZF1 with MySQLi adapter from bitching about "invalid parameter: 3". F***s sake. Sort your shit out. unset($return['places']['start']); unset($return['places']['count']); unset($return['places']['total']); $query = "INSERT INTO woecache (\r\n lat, lon, response, stored, address\r\n ) VALUES (\r\n %s, %s, %s, NOW(), NULL\r\n ) ON DUPLICATE KEY UPDATE\r\n response = VALUES(response),\r\n stored = NOW()"; $query = sprintf($query, $Database->quote($lat), $Database->quote($lon), $Database->quote(json_encode($return))); try { $rs = $Database->query($query); } catch (Exception $e) { // throw it away } } $return['url'] = $url; if ($return !== false) { $Redis->save($mckey, $return, 0); } } return $return; }
/** * @depends test_newUser */ public function test_validateAvatar($User) { $User->avatar = "http://doge2048.com/meta/doge-600.png"; $User->validateAvatar(); $Config = AppCore::getConfig(); $Config->AvatarMaxWidth = 100; $Config->AvatarMaxHeight = 100; $User->avatar = "http://doge2048.com/meta/doge-600.png"; $User->validateAvatar(); $User->validateAvatar(true); $Config->AvatarMaxWidth = 1000; $Config->AvatarMaxHeight = 1000; $User->avatar = "http://doge2048.com/meta/doge-600.png"; $User->validateAvatar(); $User->validateAvatar(true); $User->avatar = "http://not-an-image.com/noimage.jpgzor"; $User->validateAvatar(); $User->validateAvatar(true); }
/** * Constructor * @since Version 3.8.7 * @return void */ public function __construct() { $this->Memcached = new Memcached(); if (!defined("RP_SITE_DOMAIN")) { define("RP_SITE_DOMAIN", "railpage.com.au"); } /** * Get memcached host configuration. If it's empty for whatever reason, fall back to hardcoded host(s) */ $Config = AppCore::getConfig(); $host['primary']['addr'] = isset($Config->Memcached->host) && !empty($Config->Memcached->host) ? $Config->Memcached->host : "cache.railpage.com.au"; $host['primary']['port'] = isset($Config->Memcached->port) && !empty($Config->Memcached->port) ? $Config->Memcached->host : "11211"; $handlername = isset($Config->SessionHandler) && !empty($Config->SessionHandler) ? $Config->SessionHandler : "MemcachedSessionHandler"; $handlername = sprintf("\\Railpage\\SessionHandler\\%s", $handlername); #$handlername = "Redis"; /** * Create a new \Memcached (aka PHPMemcached) object, connect our hosts to it */ if (strpos($handlername, "Memcached") !== false) { $Memcached = new PHPMemcached(); foreach ($host as $row) { $Memcached->addServer($row['addr'], $row['port']); } $Memcached->setOption(PHPMemcached::OPT_DISTRIBUTION, PHPMemcached::DISTRIBUTION_CONSISTENT); $Memcached->setOption(PHPMemcached::OPT_CONNECT_TIMEOUT, 150); $Memcached->setOption(PHPMemcached::OPT_RETRY_TIMEOUT, 0); $Memcached->setOption(PHPMemcached::OPT_HASH, PHPMemcached::HASH_MD5); /** * Create our MemcachedSessionHandler instance and instruct PHP to use that for session storage */ $options = array("prefix" => "memc.sess.key.", "expiretime" => self::DEFAULT_SESSION_LENGTH); $SessionHandler = new $handlername($Memcached, $options); session_set_save_handler($SessionHandler, true); } if (strpos($handlername, "Redis") !== false) { session_save_path(sprintf("tcp://%s:6379?weight=1", $host['primary']['addr'])); } /** * Cross-subdomain cookies n shiz */ if (!isset($_SERVER['HTTP_REFERER']) || !strpos($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_ADDR'])) { session_set_cookie_params(0, "/", sprintf(".%s", RP_SITE_DOMAIN)); } /** * ZOMG ACTUALLY START THE EFFING SESSION */ session_start(); /** * Force a session length - from http://stackoverflow.com/a/1270960/319922 */ ini_set("session.gc_maxlifetime", self::DEFAULT_SESSION_LENGTH); /* if (empty($_POST) && isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > self::DEFAULT_SESSION_LENGTH)) { // last request was more than 60 minutes ago session_unset(); // unset $_SESSION variable for the run-time session_destroy(); // destroy session data in storage } */ $_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp /** * Re-generate the session ID to avoid session attacks - from http://stackoverflow.com/a/1270960/319922 */ /* if (!isset($_SESSION['CREATED'])) { $_SESSION['CREATED'] = time(); } elseif (time() - $_SESSION['CREATED'] > self::DEFAULT_SESSION_LENGTH) { // session started more than 30 minutes ago session_regenerate_id(true); // change session ID for the current session and invalidate old session ID $_SESSION['CREATED'] = time(); // update creation time } */ $this->id = $this->getSessionId(); $_SESSION['session_id'] = $this->id; }
/** * Get WOE (Where On Earth) data from Yahoo's GeoPlanet API * * Ported from [master]/includes/functions.php * @since Version 3.8.7 * @param string $lookup * @param array $types Yahoo Woe types to lookup * @return array */ public static function getWOEData($lookup = false, $types = false) { if ($lookup === false) { return false; } $return = array(); $expiry = strtotime("+1 year"); $mckey = "railpage:woe=" . $lookup; if ($types) { $mckey .= ";types=" . implode(",", $types); } $Cache = AppCore::getRedis(); $Cache = AppCore::getMemcached(); /** * Try and get the WoE data from Memcached or Redis */ if ($return = $Cache->fetch($mckey)) { /** * Convert JSON back to an array if required */ if (!is_array($return) && is_string($return)) { $return = json_decode($return, true); } return $return; } /** * Try and get the WoE data from the database */ $Database = (new AppCore())->getDatabaseConnection(); $query = "SELECT response FROM cache_woe WHERE hash = ?"; if ($return = $Database->fetchOne($query, md5($mckey))) { $return = json_decode($return, true); $Cache->save($mckey, $return, $expiry); return $return; } /** * Nothing found in our cache - look it up */ $Config = AppCore::getConfig(); $latlng = $lookup; if (preg_match("@[a-zA-Z]+@", $lookup) || strpos($lookup, ",")) { $lookup = sprintf("places.q('%s')", $lookup); } else { $lookup = sprintf("place/%s", $lookup); } if ($types === false) { $url = sprintf("http://where.yahooapis.com/v1/%s?lang=en&appid=%s&format=json", $lookup, $Config->Yahoo->ApplicationID); } else { $url = sprintf("http://where.yahooapis.com/v1/places\$and(.q('%s'),.type(%s))?lang=en&appid=%s&format=json", $latlng, implode(",", $types), $Config->Yahoo->ApplicationID); } /** * Attempt to fetch the WoE data from our local cache */ if (strpos($lookup, ",") !== false) { $tmp = str_replace("places.q('", "", str_replace("')", "", $lookup)); $tmp = explode(",", $tmp); $return = PlaceUtility::LatLonWoELookup($tmp[0], $tmp[1]); $Cache->save($mckey, $return, strtotime("+1 hour")); return $return; } /** * Try and fetch using GuzzleHTTP from the web service */ try { $GuzzleClient = new Client(); $response = $GuzzleClient->get($url); } catch (RequestException $e) { switch ($e->getResponse()->getStatusCode()) { case 503: throw new Exception("Your call to Yahoo Web Services failed and returned an HTTP status of 503. That means: Service unavailable. An internal problem prevented us from returning data to you."); break; case 403: throw new Exception("Your call to Yahoo Web Services failed and returned an HTTP status of 403. That means: Forbidden. You do not have permission to access this resource, or are over your rate limit."); break; case 400: if (!($return = PlaceUtility::getViaCurl($url))) { throw new Exception(sprintf("Your call to Yahoo Web Services failed and returned an HTTP status of 400. That means: Bad request. The parameters passed to the service did not match as expected. The exact error is returned in the XML/JSON response. The URL sent was: %s\n\n%s", $url, json_decode($e->getResponse()->getBody()))); } break; default: throw new Exception("Your call to Yahoo Web Services returned an unexpected HTTP status of: " . $e->getResponse()->getStatusCode()); } } if (!$return && isset($response) && $response->getStatusCode() == 200) { $return = json_decode($response->getBody(), true); } $return['url'] = $url; /** * Attempt to cache this data */ if ($return !== false) { /** * Save it in MariaDB */ $data = ["hash" => md5($mckey), "response" => json_encode($return), "expiry" => date("Y-m-d H:i:s", $expiry)]; $Database->insert("cache_woe", $data); $rs = $Cache->save($mckey, $return, $expiry); /** * Verify that it actually saved in the cache handler. It's being a turd lately */ if (!$rs || json_encode($return) != json_encode($Cache->fetch($mckey))) { $Cache->save($mckey, json_encode($return), $expiry); } } return $return; }