Browse Source

Add gravatar

euromark 11 years ago
parent
commit
a273aa0246
2 changed files with 415 additions and 0 deletions
  1. 184 0
      src/View/Helper/GravatarHelper.php
  2. 231 0
      tests/TestCase/View/Helper/GravatarHelperTest.php

+ 184 - 0
src/View/Helper/GravatarHelper.php

@@ -0,0 +1,184 @@
+<?php
+namespace Tools\View\Helper;
+
+use Cake\View\Helper;
+use Cake\View\View;
+use Cake\Validation\Validation;
+
+/**
+ * CakePHP Gravatar Helper
+ *
+ * A CakePHP View Helper for the display of Gravatar images (http://www.gravatar.com)
+ *
+ * @copyright Copyright 2009-2010, Graham Weldon (http://grahamweldon.com)
+ * @license http://opensource.org/licenses/mit-license.php MIT
+ * @author Mark Scherer
+ */
+class GravatarHelper extends Helper {
+
+	/**
+	 * Gravatar avatar image base URL
+	 *
+	 * @var string
+	 */
+	protected $_url = array(
+		'http' => 'http://www.gravatar.com/avatar/',
+		'https' => 'https://secure.gravatar.com/avatar/'
+	);
+
+	/**
+	 * Collection of allowed ratings
+	 *
+	 * @var array
+	 */
+	protected $_allowedRatings = array(
+		'g', 'pg', 'r', 'x');
+
+	/**
+	 * Default Icon sets
+	 *
+	 * @var array
+	 */
+	protected $_defaultIcons = array(
+		'none', 'mm', 'identicon', 'monsterid', 'retro', 'wavatar', '404');
+
+	/**
+	 * Default settings
+	 *
+	 * @var array
+	 */
+	protected $_defaultConfig = array(
+		'default' => null,
+		'size' => null,
+		'rating' => null,
+		'ext' => false);
+
+	/**
+	 * Helpers used by this helper
+	 *
+	 * @var array
+	 */
+	public $helpers = array('Html');
+
+	/**
+	 * Constructor
+	 *
+	 */
+	public function __construct($View = null, $config = array()) {
+		// Default the secure option to match the current URL.
+		$this->_defaultConfig['secure'] = (bool)env('HTTPS');
+
+		parent::__construct($View, $config);
+	}
+
+	/**
+	 * Show gravatar for the supplied email address
+	 *
+	 * @param string $email Email address
+	 * @param array $options Array of options, keyed from default settings
+	 * @return string Gravatar image string
+	 */
+	public function image($email, $options = array()) {
+		$imageUrl = $this->url($email, $options);
+		unset($options['default'], $options['size'], $options['rating'], $options['ext']);
+		return $this->Html->image($imageUrl, $options);
+	}
+
+	/**
+	 * Generate image URL
+	 * TODO: rename to avoid E_STRICT errors here
+	 *
+	 * @param string $email Email address
+	 * @param string $options Array of options, keyed from default settings
+	 * @return string Gravatar Image URL
+	 */
+	public function url($email, $options = array()) {
+		$options = $this->_cleanOptions($options + $this->_config);
+		$ext = $options['ext'];
+		$secure = $options['secure'];
+		unset($options['ext'], $options['secure']);
+		$protocol = $secure === true ? 'https' : 'http';
+
+		$imageUrl = $this->_url[$protocol] . md5($email);
+		if ($ext === true) {
+			// If 'ext' option is supplied and true, append an extension to the generated image URL.
+			// This helps systems that don't display images unless they have a specific image extension on the URL.
+			$imageUrl .= '.jpg';
+		}
+		$imageUrl .= $this->_buildOptions($options);
+		return $imageUrl;
+	}
+
+	/**
+	 * Generate an array of default images for preview purposes
+	 *
+	 * @param array $options Array of options, keyed from default settings
+	 * @return array Default images array
+	 */
+	public function defaultImages($options = array()) {
+		$options = $this->_cleanOptions($options + $this->_config);
+		$images = array();
+		foreach ($this->_defaultIcons as $defaultIcon) {
+			$options['default'] = $defaultIcon;
+			$images[$defaultIcon] = $this->image(null, $options);
+		}
+		return $images;
+	}
+
+	/**
+	 * Sanitize the options array
+	 *
+	 * @param array $options Array of options, keyed from default settings
+	 * @return array Clean options array
+	 */
+	protected function _cleanOptions($options) {
+		if (!isset($options['size']) || empty($options['size']) || !is_numeric($options['size'])) {
+			unset($options['size']);
+		} else {
+			$options['size'] = min(max($options['size'], 1), 512);
+		}
+
+		if (!$options['rating'] || !in_array(mb_strtolower($options['rating']), $this->_allowedRatings)) {
+			unset($options['rating']);
+		}
+
+		if (!$options['default']) {
+			unset($options['default']);
+		} else {
+			if (!in_array($options['default'], $this->_defaultIcons) && !Validation::url($options['default'])) {
+				unset($options['default']);
+			}
+		}
+		return $options;
+	}
+
+	/**
+	 * Generate email address hash
+	 *
+	 * @param string $email Email address
+	 * @param string $type Hash type to employ
+	 * @return string Email address hash
+	 */
+	protected function _emailHash($email, $type) {
+		return md5(mb_strtolower($email), $type);
+	}
+
+	/**
+	 * Build Options URL string
+	 *
+	 * @param array $options Array of options, keyed from default settings
+	 * @return string URL string of options
+	 */
+	protected function _buildOptions($options = array()) {
+		$gravatarOptions = array_intersect(array_keys($options), array_keys($this->_defaultConfig));
+		if (!empty($gravatarOptions)) {
+			$optionArray = array();
+			foreach ($gravatarOptions as $key) {
+				$value = $options[$key];
+				$optionArray[] = $key . '=' . mb_strtolower($value);
+			}
+			return '?' . implode('&amp;', $optionArray);
+		}
+		return '';
+	}
+}

+ 231 - 0
tests/TestCase/View/Helper/GravatarHelperTest.php

@@ -0,0 +1,231 @@
+<?php
+namespace Tools\TestCase\View\Helper;
+
+use Tools\View\Helper\GravatarHelper;
+use Tools\TestSuite\TestCase;
+use Cake\View\View;
+use Cake\Core\Configure;
+
+/**
+ * Gravatar Test Case
+ *
+ */
+class GravatarHelperTest extends TestCase {
+
+	/**
+	 * SetUp method
+	 */
+	public function setUp() {
+		parent::setUp();
+
+		$this->testEmail = 'graham@grahamweldon.com'; // For testing normal behavior
+		$this->garageEmail = 'test@test.de'; // For testing default image behavior
+
+		$this->Gravatar = new GravatarHelper(new View(null));
+	}
+
+	/**
+	 * TearDown method
+	 */
+	public function tearDown() {
+		parent::tearDown();
+
+		unset($this->Gravatar);
+	}
+
+	/**
+	 * @return void
+	 */
+	public function testDefaultImages() {
+		$is = $this->Gravatar->defaultImages();
+		$expectedCount = 7;
+
+		foreach ($is as $image) {
+			//$this->out($image . ' ');
+		}
+		$this->assertTrue(is_array($is) && (count($is) === $expectedCount));
+	}
+
+	/**
+	 * @return void
+	 */
+	public function testImages() {
+		$is = $this->Gravatar->image($this->garageEmail);
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image(Configure::read('Config.adminEmail'));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->testEmail);
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->testEmail, array('size' => '200'));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->testEmail, array('size' => '20'));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->testEmail, array('rating' => 'X')); # note the capit. x
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->testEmail, array('ext' => true));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->testEmail, array('default' => 'none'));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->garageEmail, array('default' => 'none'));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+
+		$is = $this->Gravatar->image($this->garageEmail, array('default' => 'http://2.gravatar.com/avatar/8379aabc84ecee06f48d8ca48e09eef4?d=identicon'));
+		//$this->out($is);
+		$this->assertTrue(!empty($is));
+	}
+
+/** BASE TEST CASES **/
+
+	/**
+	 * TestBaseUrlGeneration
+	 *
+	 * @return void
+	 */
+	public function testBaseUrlGeneration() {
+		$expected = 'http://www.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'default' => 'wavatar'));
+		list($url, $params) = explode('?', $result);
+		$this->assertEquals($expected, $url);
+	}
+
+	/**
+	 * TestExtensions
+	 *
+	 * @return void
+	 */
+	public function testExtensions() {
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => true, 'default' => 'wavatar'));
+		$this->assertRegExp('/\.jpg(?:$|\?)/', $result);
+	}
+
+	/**
+	 * TestRating
+	 *
+	 * @return void
+	 */
+	public function testRating() {
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => true, 'default' => 'wavatar'));
+		$this->assertRegExp('/\.jpg(?:$|\?)/', $result);
+	}
+
+	/**
+	 * TestAlternateDefaultIcon
+	 *
+	 * @return void
+	 */
+	public function testAlternateDefaultIcon() {
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'default' => 'wavatar'));
+		list($url, $params) = explode('?', $result);
+		$this->assertRegExp('/default=wavatar/', $params);
+	}
+
+	/**
+	 * TestAlternateDefaultIconCorrection
+	 *
+	 * @return void
+	 */
+	public function testAlternateDefaultIconCorrection() {
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'default' => '12345'));
+		$this->assertRegExp('/[^\?]+/', $result);
+	}
+
+	/**
+	 * TestSize
+	 *
+	 * @return void
+	 */
+	public function testSize() {
+		$result = $this->Gravatar->url('example@gravatar.com', array('size' => '120'));
+		list($url, $params) = explode('?', $result);
+		$this->assertRegExp('/size=120/', $params);
+	}
+
+	/**
+	 * TestImageTag
+	 *
+	 * @return void
+	 */
+	public function testImageTag() {
+		$expected = '<img src="http://www.gravatar.com/avatar/' . md5('example@gravatar.com') . '" alt=""/>';
+		$result = $this->Gravatar->image('example@gravatar.com', array('ext' => false));
+		$this->assertEquals($expected, $result);
+
+		$expected = '<img src="http://www.gravatar.com/avatar/' . md5('example@gravatar.com') . '" alt="Gravatar"/>';
+		$result = $this->Gravatar->image('example@gravatar.com', array('ext' => false, 'alt' => 'Gravatar'));
+		$this->assertEquals($expected, $result);
+	}
+
+	/**
+	 * TestDefaulting
+	 *
+	 * @return void
+	 */
+	public function testDefaulting() {
+		$result = $this->Gravatar->url('example@gravatar.com', array('default' => 'wavatar', 'size' => 'default'));
+		list($url, $params) = explode('?', $result);
+		$this->assertEquals($params, 'default=wavatar');
+	}
+
+	/**
+	 * TestNonSecureUrl
+	 *
+	 * @return void
+	 */
+	public function testNonSecureUrl() {
+		$_SERVER['HTTPS'] = false;
+
+		$expected = 'http://www.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false));
+		$this->assertEquals($expected, $result);
+
+		$expected = 'http://www.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'secure' => false));
+		$this->assertEquals($expected, $result);
+
+		$_SERVER['HTTPS'] = true;
+		$expected = 'http://www.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'secure' => false));
+		$this->assertEquals($expected, $result);
+	}
+
+	/**
+	 * TestSecureUrl
+	 *
+	 * @return void
+	 */
+	public function testSecureUrl() {
+		$expected = 'https://secure.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'secure' => true));
+		$this->assertEquals($expected, $result);
+
+		$_SERVER['HTTPS'] = true;
+
+		$this->Gravatar = new GravatarHelper(new View(null));
+
+		$expected = 'https://secure.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false));
+		$this->assertEquals($expected, $result);
+
+		$expected = 'https://secure.gravatar.com/avatar/' . md5('example@gravatar.com');
+		$result = $this->Gravatar->url('example@gravatar.com', array('ext' => false, 'secure' => true));
+		$this->assertEquals($expected, $result);
+	}
+
+}