From 5c110b68994b90a75362de00828aef5cef9bc867 Mon Sep 17 00:00:00 2001 From: Klaus Weidenbach Date: Sat, 14 Jul 2012 20:30:12 +0200 Subject: [PATCH] Updated Services_Libravatar 0.2.1 Updated external class Services_Libravatar to version 0.2.1 and replaced deprecated functions. This class is under MIT License. Included libravatar.tgz --- libravatar.tgz | Bin 0 -> 7970 bytes libravatar/Services/Libravatar.php | 631 +++++++++++++++++++++-------- libravatar/libravatar.php | 17 +- 3 files changed, 472 insertions(+), 176 deletions(-) create mode 100644 libravatar.tgz diff --git a/libravatar.tgz b/libravatar.tgz new file mode 100644 index 0000000000000000000000000000000000000000..0405af9bd532c8ec17112fcbbd3b92d65f07ead8 GIT binary patch literal 7970 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 Y6e&`qNRc8%iu4rpFSfFU?f{?w01Q=L!vFvP literal 0 HcmV?d00001 diff --git a/libravatar/Services/Libravatar.php b/libravatar/Services/Libravatar.php index d3024408..1b6d022e 100644 --- a/libravatar/Services/Libravatar.php +++ b/libravatar/Services/Libravatar.php @@ -1,7 +1,5 @@ * @copyright 2011 Services_Libravatar committers. * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version SVN: * @link http://pear.php.net/package/Services_Libravatar * @since File available since Release 0.1.0 */ @@ -43,240 +40,364 @@ * PHP support for the Libravatar.org service. * * Using this class is easy. After including or requiring - * PEAR/libravatar.php simply do: - * - * $libravatar = new Services_Libravatar(); - * $url = $libravatar->url('melissa@meldraweb.com'); - * + * Services/Libravatar.php simply do: + * + * $libravatar = new Services_Libravatar(); + * $url = $libravatar->getUrl('melissa@meldraweb.com'); + * * - * This would populate $url with the string: - * http://cdn.libravatar.org/avatar/4db84629c121f2d443d33bdb9fd149bc + * This would populate $url with the string: + * + * http://cdn.libravatar.org/avatar/4db84629c121f2d443d33bdb9fd149bc + * * * A complicated lookup using all the options is: - * - * $libravatar = new Services_Libravatar(); - * $options = array(); - * $options['s'] = '40'; - * $options['algorithm'] = 'sha256'; - * $options['https'] = true; - * $options['d'] = 'http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png'; - * $url = $libravatar->url('melissa@meldraweb.com', $options); - * + * + * $libravatar = new Services_Libravatar(); + * $libravatar->setSize(40); + * $libravatar->setAlgorithm('sha256'); + * $libravatar->setHttps(true); + * $libravatar->setDefault( + * 'http://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png' + * ); + * $url = $libravatar->getUrl('melissa@meldraweb.com'); + * * * @category Services * @package Services_Libravatar * @author Melissa Draper * @copyright 2011 Services_Libravatar committers. * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version Release: + * @version Release: 0.2.1 * @link http://pear.php.net/package/Services_Libravatar * @since Class available since Release 0.1.0 */ class Services_Libravatar { + /** + * Hashing algorithm to use + * + * @var string + * @see processAlgorithm() + * @see setAlgorithm() + */ + protected $algorithm = 'md5'; /** - * Composes a URL for the identifier and options passed in + * Default image URL to use * - * Compose a full URL as specified by the Libravatar API, based on the - * email address or openid URL passed in, and the options specified. + * @var string + * @see processDefault() + * @see setDefault() + */ + protected $default; + + /** + * If HTTPS URLs should be used * - * @param string $identifier a string of either an email address - * or an openid url - * @param array $options an array of (bool) https, (string) algorithm - * (string) s or size, (string) d or default + * @var boolean + * @see detectHttps() + * @see setHttps() + */ + protected $https; + + /** + * Image size in pixels * - * @return string A string of a full URL for an avatar image + * @var integer + * @see processSize() + * @see setSize() + */ + protected $size; + + + /** + * Composes a URL for the identifier and options passed in * - * @since Method available since Release 0.1.0 + * Compose a full URL as specified by the Libravatar API, based on the + * email address or openid URL passed in, and the options specified. + * + * @param string $identifier a string of either an email address + * or an openid url + * @param array $options an array of (bool) https, (string) algorithm + * (string) size, (string) default. + * See the set* methods. + * + * @return string A string of a full URL for an avatar image + * + * @since Method available since Release 0.2.0 + * @deprecated Use getUrl() instead */ public function url($identifier, $options = array()) { + return $this->getUrl($identifier, $options); + } + /** + * Composes a URL for the identifier and options passed in + * + * Compose a full URL as specified by the Libravatar API, based on the + * email address or openid URL passed in, and the options specified. + * + * @param string $identifier a string of either an email address + * or an openid url + * @param array $options an array of (bool) https, (string) algorithm + * (string) size, (string) default. + * See the set* methods. + * + * @return string A string of a full URL for an avatar image + * + * @since Method available since Release 0.2.0 + * @throws InvalidArgumentException When an invalid option is passed + */ + public function getUrl($identifier, $options = array()) + { // If no identifier has been passed, set it to a null. // This way, there'll always be something returned. if (!$identifier) { $identifier = null; - } - - $https = null; - if (isset($options['https']) && $options['https'] === true) { - $https = true; - } - - // If the algorithm has been passed in $options, send it on. - // This will only affect email functionality. - if (isset($options['algorithm']) && is_string($options['algorithm'])) { - $identiferHash = $this->identiferHash( - $identifier, - $https, - $options['algorithm'] - ); } else { - $identiferHash = $this->identiferHash($identifier, $https); + $identifier = $this->normalizeIdentifier($identifier); } + // Load all options + $options = $this->checkOptionsArray($options); + $https = $this->https; + if (isset($options['https'])) { + $https = (bool)$options['https']; + } + + $algorithm = $this->algorithm; + if (isset($options['algorithm'])) { + $algorithm = $this->processAlgorithm($options['algorithm']); + } + + $default = $this->default; + if (isset($options['default'])) { + $default = $this->processDefault($options['default']); + } + $size = $this->size; + if (isset($options['size'])) { + $size = $this->processSize($options['size']); + } + + + $identifierHash = $this->identifierHash($identifier, $algorithm); + // Get the domain so we can determine the SRV stuff for federation - $domain = $this->domainGet($identifier, $https); + $domain = $this->domainGet($identifier); // If https has been specified in $options, make sure we make the // correct SRV lookup - if (isset($options['https']) && $options['https'] === true) { - $service = $this->srvGet($domain, true); - $protocol = 'https'; - } else { - $service = $this->srvGet($domain); - $protocol = 'http'; + $service = $this->srvGet($domain, $https); + $protocol = $https ? 'https' : 'http'; + + $params = array(); + if ($size !== null) { + $params['size'] = $size; } - - // We no longer need these, and they will pollute our query string - unset($options['algorithm']); - unset($options['https']); - - // If there are any $options left, we want to make those into a query - $params = null; - if (count($options) > 0) { - $params = '?' . http_build_query($options); + if ($default !== null) { + $params['default'] = $default; + } + $paramString = ''; + if (count($params) > 0) { + $paramString = '?' . http_build_query($params); } // Compose the URL from the pieces we generated - $url = $protocol . '://' . $service . '/avatar/' . $identiferHash . $params; + $url = $protocol . '://' . $service . '/avatar/' . $identifierHash + . $paramString; // Return the URL string return $url; - } /** - * Create a hash of the identifier. + * Checks the options array and verify that only allowed options are in it. * - * Create a hash of the email address or openid passed in. Algorithm - * used for email address ONLY can be varied. Either md5 or sha256 - * are supported by the Libravatar API. Will be ignored for openid. + * @param array $options Array of options for getUrl() * - * @param string $identifier A string of the email address or openid URL - * @param boolean $https If this is https, true. - * @param string $hash A string of the hash algorithm type to make - * - * @return string A string hash of the identifier. - * - * @since Method available since Release 0.1.0 + * @return void + * @throws Exception When an invalid option is used */ - protected function identiferHash($identifier, $https = false, $hash = 'md5') + protected function checkOptionsArray($options) { + //this short options are deprecated! + if (isset($options['s'])) { + $options['size'] = $options['s']; + unset($options['s']); + } + if (isset($options['d'])) { + $options['default'] = $options['d']; + unset($options['d']); + } + $allowedOptions = array( + 'algorithm' => true, + 'default' => true, + 'https' => true, + 'size' => true, + ); + foreach ($options as $key => $value) { + if (!isset($allowedOptions[$key])) { + throw new InvalidArgumentException( + 'Invalid option in array: ' . $key + ); + } + } + + return $options; + } + + /** + * Normalizes the identifier (E-mail address or OpenID) + * + * @param string $identifier E-Mail address or OpenID + * + * @return string Normalized identifier + */ + protected function normalizeIdentifier($identifier) + { if (filter_var($identifier, FILTER_VALIDATE_EMAIL)) { - // If email, we can select our algorithm. Default to md5 for - // gravatar fallback. - return hash($hash, $identifier); + return strtolower($identifier); } else { - - // The protocol is important. If we're lacking it this will not be - // filtered. Add it per our preference in the options. - if (stripos($identifier, 'http') !== 0) { - if ($https === true) { - $protocol = 'https://'; - } else { - $protocol = 'http://'; - } - $identifier = $protocol . $identifier; - } - - // Is this an email address or an OpenID account - $filter = filter_var( - $identifier, - FILTER_VALIDATE_URL, - FILTER_FLAG_PATH_REQUIRED - ); - - if ($filter) { - // If this is an OpenID, split the string and make sure the - // formatting is correct. See the Libravatar API for more info. - // http://wiki.libravatar.org/api/ - $url = parse_url($identifier); - $hashurl = strtolower($url['scheme']) . '://' . - strtolower($url['host']); - if (isset($url['port']) && $url['scheme'] === 'http' - && $url['port'] != 80 - || isset($url['port']) && $url['scheme'] === 'https' - && $url['port'] != 443 - ) { - $hashurl .= ':' . $url['port']; - } - $hashurl .= $url['path']; - return hash('sha256', $hashurl); - } + return self::normalizeOpenId($identifier); } } /** - * Grab the domain from the identifier. + * Create a hash of the identifier. * - * Extract the domain from the Email or OpenID. + * Create a hash of the email address or openid passed in. Algorithm + * used for email address ONLY can be varied. Either md5 or sha256 + * are supported by the Libravatar API. Will be ignored for openid. * - * @param string $identifier A string of the email address or openid URL - * @param boolean $https If this is https, true. + * @param string $identifier A string of the email address or openid URL + * @param string $hash A string of the hash algorithm type to make + * Uses the php implementation of hash() + * MD5 preferred for Gravatar fallback * - * @return string A string of the domain to use + * @return string A string hash of the identifier. * - * @since Method available since Release 0.1.0 + * @since Method available since Release 0.1.0 */ - protected function domainGet($identifier, $https = false) + protected function identifierHash($identifier, $hash = 'md5') { + if (filter_var($identifier, FILTER_VALIDATE_EMAIL) || $identifier === null) { + // If email, we can select our algorithm. Default to md5 for + // gravatar fallback. + return hash($hash, $identifier); + } + + //no email, so the identifier has to be an OpenID + return hash('sha256', $identifier); + } + + /** + * Normalizes an identifier (URI or XRI) + * + * @param mixed $identifier URI or XRI to be normalized + * + * @return string Normalized Identifier. + * Empty string when the OpenID is invalid. + * + * @internal Adapted from OpenID::normalizeIdentifier() + */ + public static function normalizeOpenId($identifier) + { + // XRI + if (preg_match('@^xri://@i', $identifier)) { + return preg_replace('@^xri://@i', '', $identifier); + } + + if (in_array($identifier[0], array('=', '@', '+', '$', '!'))) { + return $identifier; + } + + // URL + if (!preg_match('@^http[s]?://@i', $identifier)) { + $identifier = 'http://' . $identifier; + } + if (strpos($identifier, '/', 8) === false) { + $identifier .= '/'; + } + if (!filter_var($identifier, FILTER_VALIDATE_URL)) { + return ''; + } + + $parts = parse_url($identifier); + $parts['scheme'] = strtolower($parts['scheme']); + $parts['host'] = strtolower($parts['host']); + + //http://openid.net/specs/openid-authentication-2_0.html#normalization + return $parts['scheme'] . '://' + . (isset($parts['user']) ? $parts['user'] : '') + . (isset($parts['pass']) ? ':' . $parts['pass'] : '') + . (isset($parts['user']) || isset($parts['pass']) ? '@' : '') + . $parts['host'] + . ( + (isset($parts['port']) + && $parts['scheme'] === 'http' && $parts['port'] != 80) + || (isset($parts['port']) + && $parts['scheme'] === 'https' && $parts['port'] != 443) + ? ':' . $parts['port'] : '' + ) + . $parts['path'] + . (isset($parts['query']) ? '?' . $parts['query'] : ''); + //leave out fragment as requested by the spec + } + + /** + * Grab the domain from the identifier. + * + * Extract the domain from the Email or OpenID. + * + * @param string $identifier A string of the email address or openid URL + * + * @return string A string of the domain to use + * + * @since Method available since Release 0.1.0 + */ + protected function domainGet($identifier) + { + if ($identifier === null) { + return null; + } // What are we, email or openid? Split ourself up and get the // important bit out. if (filter_var($identifier, FILTER_VALIDATE_EMAIL)) { $email = explode('@', $identifier); return $email[1]; - } else { - - // The protocol is important. If we're lacking it this will not be - // filtered. Add it per our preference in the options. - if ( ! strpos($identifier, 'http')) { - if ($https === true) { - $protocol = 'https://'; - } else { - $protocol = 'http://'; - } - $identifier = $protocol . $identifier; - } - - $filter = filter_var( - $identifier, - FILTER_VALIDATE_URL, - FILTER_FLAG_PATH_REQUIRED - ); - - if ($filter) { - $url = parse_url($identifier); - $domain = $url['host']; - if (isset($url['port']) && $url['scheme'] === 'http' - && $url['port'] != 80 - || isset($url['port']) && $url['scheme'] === 'https' - && $url['port'] != 443 - ) { - $domain .= ':' . $url['port']; - } - - return $domain; - } } + + //OpenID + $url = parse_url($identifier); + $domain = $url['host']; + if (isset($url['port']) && $url['scheme'] === 'http' + && $url['port'] != 80 + || isset($url['port']) && $url['scheme'] === 'https' + && $url['port'] != 443 + ) { + $domain .= ':' . $url['port']; + } + + return $domain; } /** - * Get the target to use. + * Get the target to use. * - * Get the SRV record, filtered by priority and weight. If our domain - * has no SRV records, fall back to Libravatar.org + * Get the SRV record, filtered by priority and weight. If our domain + * has no SRV records, fall back to Libravatar.org * - * @param string $domain A string of the domain we extracted from the - * provided identifer with domainGet() - * @param boolean $https Whether or not to look for https records + * @param string $domain A string of the domain we extracted from the + * provided identifier with domainGet() + * @param boolean $https Whether or not to look for https records * - * @return string The target URL. + * @return string The target URL. * - * @since Method available since Release 0.1.0 + * @since Method available since Release 0.1.0 */ protected function srvGet($domain, $https = false) { @@ -344,20 +465,197 @@ class Services_Libravatar } /** - * Sorting function for record priorities. + * Sorting function for record priorities. * - * @param mixed $a A mixed value passed by usort() - * @param mixed $b A mixed value passed by usort() + * @param mixed $a A mixed value passed by usort() + * @param mixed $b A mixed value passed by usort() * - * @return mixed The result of the comparison + * @return mixed The result of the comparison * - * @since Method available since Release 0.1.0 + * @since Method available since Release 0.1.0 */ protected function comparePriority($a, $b) { return $a['pri'] - $b['pri']; } + /** + * Automatically set the https option depending on the current connection + * value. + * + * If the current connection is HTTPS, the https options is activated. + * If it is not HTTPS, the https option is deactivated. + * + * @return self + */ + public function detectHttps() + { + $this->setHttps( + isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] + ); + + return $this; + } + + /** + * Verify and cast the email address hashing algorithm to use. + * + * @param string $algorithm Algorithm to use, "sha256" or "md5". + * + * @return string Algorithm + * + * @throws InvalidArgumentException When an unsupported algorithm is given + */ + protected function processAlgorithm($algorithm) + { + $algorithm = (string)$algorithm; + if ($algorithm !== 'md5' && $algorithm !== 'sha256') { + throw new InvalidArgumentException( + 'Only md5 and sha256 hashing supported' + ); + } + + return $algorithm; + } + + /** + * Verify and cast the default URL to use when no avatar image can be found. + * If none is set, the libravatar logo is returned. + * + * @param string $url Full URL to use OR one of the following: + * - "404" - give a "404 File not found" instead of an image + * - "mm" + * - "identicon" + * - "monsterid" + * - "wavatar" + * - "retro" + * + * @return string Default URL + * + * @throws InvalidArgumentException When an invalid URL is given + */ + protected function processDefault($url) + { + if ($url === null) { + return $url; + } + + $url = (string)$url; + + switch ($url) { + case '404': + case 'mm': + case 'identicon': + case 'monsterid': + case 'wavatar': + case 'retro': + break; + default: + $valid = filter_var($url, FILTER_VALIDATE_URL); + if (!$valid) { + throw new InvalidArgumentException('Invalid default avatar URL'); + } + break; + } + + return $url; + } + + /** + * Verify and cast the required size of the images. + * + * @param integer $size Size (width and height in pixels) of the image. + * NULL for the default width. + * + * @return integer Size + * + * @throws InvalidArgumentException When a size <= 0 is given + */ + protected function processSize($size) + { + if ($size === null) { + return $size; + } + + $size = (int)$size; + if ($size <= 0) { + throw new InvalidArgumentException('Size has to be larger than 0'); + } + + return (int)$size; + } + + + /** + * Set the email address hashing algorithm to use. + * To keep gravatar compatibility, use "md5". + * + * @param string $algorithm Algorithm to use, "sha256" or "md5". + * + * @return self + * @throws InvalidArgumentException When an unsupported algorithm is given + */ + public function setAlgorithm($algorithm) + { + $this->algorithm = $this->processAlgorithm($algorithm); + + return $this; + } + + /** + * Set the default URL to use when no avatar image can be found. + * If none is set, the gravatar logo is returned. + * + * @param string $url Full URL to use OR one of the following: + * - "404" - give a "404 File not found" instead of an image + * - "mm" + * - "identicon" + * - "monsterid" + * - "wavatar" + * - "retro" + * + * @return self + * @throws InvalidArgumentException When an invalid URL is given + */ + public function setDefault($url) + { + $this->default = $this->processDefault($url); + + return $this; + } + + /** + * Set if HTTPS URLs shall be returned. + * + * @param boolean $useHttps If HTTPS url shall be returned + * + * @return self + * + * @see detectHttps() + */ + public function setHttps($useHttps) + { + $this->https = (bool)$useHttps; + + return $this; + } + + /** + * Set the required size of the images. + * Every avatar image is square sized, which means you need to set only number. + * + * @param integer $size Size (width and height) of the image + * + * @return self + * @throws InvalidArgumentException When a size <= 0 is given + */ + public function setSize($size) + { + $this->size = $this->processSize($size); + + return $this; + } + } /* @@ -369,4 +667,3 @@ class Services_Libravatar */ ?> - diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index 1705a9c1..08ed6d00 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -2,7 +2,7 @@ /** * Name: Libravatar Support * Description: If there is no avatar image for a new user or contact this plugin will look for one at Libravatar. Please disable Gravatar addon if you use this one. (requires PHP >= 5.3) - * Version: 1.0 + * Version: 1.1 * Author: Klaus Weidenbach */ @@ -26,7 +26,7 @@ function libravatar_install() { function libravatar_uninstall() { unregister_hook('avatar_lookup', 'addon/libravatar/libravatar.php', 'libravatar_lookup'); - logger("uninstalled libravatar"); + logger("unregistered libravatar in avatar_lookup hook"); } /** @@ -48,10 +48,9 @@ function libravatar_lookup($a, &$b) { require_once 'Services/Libravatar.php'; $libravatar = new Services_Libravatar(); - $options = array(); - $options['s'] = $b['size']; - $options['d'] = $default_avatar; - $avatar_url = $libravatar->url($b['email'], $options); + $libravatar->setSize($b['size']); + $libravatar->setDefault($default_avatar); + $avatar_url = $libravatar->getUrl($b['email']); $b['url'] = $avatar_url; $b['success'] = true; @@ -81,8 +80,8 @@ function libravatar_plugin_admin (&$a, &$o) { // Show warning if PHP version is too old if (! version_compare(PHP_VERSION, '5.3.0', '>=')) { $o = '
' .t('Warning') .'

'; - $o .= sprintf(t('Your PHP version %s is lower than the required PHP 5.3.'), PHP_VERSION); - $o .= '
' .t('This addon is not functional on you server.') .'


'; + $o .= sprintf(t('Your PHP version %s is lower than the required PHP >= 5.3.'), PHP_VERSION); + $o .= '
' .t('This addon is not functional on your server.') .'


'; return; } @@ -91,7 +90,7 @@ function libravatar_plugin_admin (&$a, &$o) { dbesc('gravatar') ); if (count($r)) { - $o = '

' .t('Information') .'

' .t('Gravatar addon is installed. Please disable the gravatar addon.
The Libravatar addon will fall back to gravatar if nothing was found at libravatar.') .'



'; + $o = '
' .t('Information') .'

' .t('Gravatar addon is installed. Please disable the Gravatar addon.
The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar.') .'



'; } // output Libravatar settings