Skip to content

Instantly share code, notes, and snippets.

@jakzal
Created May 26, 2011 19:39
Show Gist options
  • Save jakzal/993890 to your computer and use it in GitHub Desktop.
Save jakzal/993890 to your computer and use it in GitHub Desktop.
Tag Cloud in PHP
<?php
/*
* This file is part of the PSSBlogBundle package.
*
* (c) Jakub Zalas <jakub@zalas.pl>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PSS\Bundle\BlogBundle\Tag;
/**
* Class solves a problem of a tag size calculation.
*
* Example usage:
*
* <code>
* // List of tags with frequencies.
* $tags = array(array('php' => 1, 'symfony' => 4, 'tdd' => 2, 'Symfony2' => 7));
* // List of tag sizes ordered from smallest to the biggest
* $sizes = array('small', 'big', 'large');
*
* $tagCloud = new TagCloud($tags, $sizes);
* // Get size for frequency
* $size = $tagCloud->getSize(4);
* // Get size for tag
* $size = $tagCloud->getSizeByTag('symfony');
* </code>
*
* @author Jakub Zalas <jakub@zalas.pl>
*/
class TagCloud
{
/**
* @var array $tagFrequencies
*/
private $tagFrequencies = array();
/**
* @var array $sizes
*/
private $sizes = array();
/**
* @var integer $maxFrequency
*/
private $maxFrequency = 0;
/**
* @var integer $minFrequency
*/
private $minFrequency = 0;
/**
* @param array $tagFrequencies
* @param array $sizes
* @return null
*/
public function __construct(array $tagFrequencies, array $sizes)
{
if (count($sizes) == 0) {
throw new \InvalidArgumentException('You need to give a list of tag sizes');
}
$this->sizes = $sizes;
$this->tagFrequencies = $tagFrequencies;
$this->updateMinAndMaxFrequency();
}
/**
* @return null
*/
protected function updateMinAndMaxFrequency()
{
foreach ($this->tagFrequencies as $frequency) {
if ($this->minFrequency > $frequency || 0 == $this->minFrequency) {
$this->minFrequency = $frequency;
}
if ($this->maxFrequency < $frequency) {
$this->maxFrequency = $frequency;
}
}
}
/**
* @param integer $frequency
* @return string
*/
public function getSize($frequency)
{
if ($frequency <= $this->minFrequency) {
return $this->sizes[0];
}
$maxSize = count($this->sizes);
$size = ($maxSize * ($frequency - $this->minFrequency)) / ($this->maxFrequency - $this->minFrequency);
$sizeIndex = $size - 1;
return isset($this->sizes[$sizeIndex]) ? $this->sizes[$sizeIndex] : $this->sizes[$maxSize - 1];
}
/**
* @param string $tag
* @return string
*/
public function getSizeByTag($tag)
{
return isset($this->tagFrequencies[$tag]) ? $this->getSize($this->tagFrequencies[$tag]) : $this->sizes[0];
}
}
<?php
namespace PSS\Bundle\BlogBundle\Tests;
use PSS\Bundle\BlogBundle\Tag\TagCloud;
class TagCloudTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testThatAtLeastOneSizeIsRequired()
{
$tagCloud = new TagCloud(array('symfony' => 10), array());
}
public function testThatFrequencyOutOfRangeHasMaximumSize()
{
$tagCloud = new TagCloud(array('symfony' => 2, 'php' => 10), array('small', 'big', 'large'));
$this->assertEquals('large', $tagCloud->getSize(400));
}
public function testThatTooSmallFrequencyHasMinimumSize()
{
$tagCloud = new TagCloud(array('symfony' => 200, 'php' => 300), array('small', 'big', 'large'));
$this->assertEquals('small', $tagCloud->getSize(1));
}
public function testThatSizeCanBeRetrievedByTagName()
{
$tagCloud = new TagCloud(array('symfony' => 2, 'php' => 10), array('small', 'big', 'large'));
$this->assertEquals('small', $tagCloud->getSizeByTag('symfony'));
$this->assertEquals('large', $tagCloud->getSizeByTag('php'));
}
public function testThatSizeForTagOutsideOfCloudIsMinimal()
{
$tagCloud = new TagCloud(array('symfony' => 2, 'php' => 10), array('small', 'big', 'large'));
$this->assertEquals('small', $tagCloud->getSizeByTag('tdd'));
}
/**
* @dataProvider getTags
*/
public function testSizeDistribution($sizes, $tags, $expectedSizes)
{
$tagCloud = new TagCloud($tags, $sizes);
foreach ($expectedSizes as $tagSlug => $size) {
$this->assertEquals($size, $tagCloud->getSize($tags[$tagSlug]), sprintf('Tag "%s" is "%s"', $tagSlug, $size));
}
}
public static function getTags()
{
return array(
array(
array('small'),
array('symfony' => 1),
array('symfony' => 'small')
),
array(
array('small'),
array('symfony' => 1, 'Symfony2' => 2),
array('symfony' => 'small', 'Symfony2' => 'small')
),
array(
array('small'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small')
),
array(
array('small', 'big'),
array('symfony' => 1),
array('symfony' => 'small')
),
array(
array('small', 'big'),
array('symfony' => 1, 'Symfony2' => 2),
array('symfony' => 'small', 'Symfony2' => 'big')
),
array(
array('small', 'big'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'big')
),
array(
array('small', 'big'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small', 'tdd' => 'big')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1),
array('symfony' => 'small')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2),
array('symfony' => 'small', 'Symfony2' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'big', 'tdd' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4, 'bdd' => 5),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small', 'tdd' => 'big', 'bdd' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4, 'bdd' => 5, 'ui' => 6),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small', 'tdd' => 'small', 'bdd' => 'big', 'ui' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4, 'bdd' => 5, 'ui' => 6, 'phpunit' => 7),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small', 'tdd' => 'small', 'bdd' => 'big', 'ui' => 'big', 'phpunit' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4, 'bdd' => 5, 'ui' => 6, 'phpunit' => 7, 'lime' => 8),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small', 'tdd' => 'small', 'bdd' => 'small', 'ui' => 'big', 'phpunit' => 'big', 'lime' => 'large')
),
array(
array('small', 'big', 'large'),
array('symfony' => 1, 'Symfony2' => 2, 'php' => 3, 'tdd' => 4, 'bdd' => 5, 'ui' => 6, 'phpunit' => 7, 'lime' => 8, 'ddd' => 9),
array('symfony' => 'small', 'Symfony2' => 'small', 'php' => 'small', 'tdd' => 'small', 'bdd' => 'small', 'ui' => 'small', 'phpunit' => 'big', 'lime' => 'big', 'ddd' => 'large')
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment