mirror of
https://github.com/silverstripe/silverstripe-blog
synced 2024-10-22 11:05:58 +02:00
ef4d84290d
BUG: Fixes [Notice] Undefined variable: popularity.
156 lines
3.9 KiB
PHP
156 lines
3.9 KiB
PHP
<?php
|
|
|
|
if(class_exists('Widget')) {
|
|
|
|
/**
|
|
* A list of tags associated with blog posts
|
|
*
|
|
* @package blog
|
|
*/
|
|
class TagCloudWidget extends Widget {
|
|
|
|
private static $db = array(
|
|
"Title" => "Varchar",
|
|
"Limit" => "Int",
|
|
"Sortby" => "Varchar"
|
|
);
|
|
|
|
private static $defaults = array(
|
|
"Title" => "Tag Cloud",
|
|
"Limit" => "0",
|
|
"Sortby" => "alphabet"
|
|
);
|
|
|
|
private static $cmsTitle = "Tag Cloud";
|
|
|
|
private static $description = "Shows a tag cloud of tags on your blog.";
|
|
|
|
/**
|
|
* List of popularity classes in order of least to most popular
|
|
*
|
|
* @config
|
|
* @var array
|
|
*/
|
|
private static $popularities = array(
|
|
'not-popular',
|
|
'not-very-popular',
|
|
'somewhat-popular',
|
|
'popular',
|
|
'very-popular',
|
|
'ultra-popular'
|
|
);
|
|
|
|
public function getCMSFields() {
|
|
|
|
$this->beforeUpdateCMSFields(function($fields) {
|
|
$fields->merge(
|
|
new FieldList(
|
|
new TextField("Title", _t("TagCloudWidget.TILE", "Title")),
|
|
new TextField("Limit", _t("TagCloudWidget.LIMIT", "Limit number of tags")),
|
|
new OptionsetField(
|
|
"Sortby",
|
|
_t("TagCloudWidget.SORTBY", "Sort by"),
|
|
array(
|
|
"alphabet" => _t("TagCloudWidget.SBAL", "alphabet"),
|
|
"frequency" => _t("TagCloudWidget.SBFREQ", "frequency")
|
|
)
|
|
)
|
|
)
|
|
);
|
|
});
|
|
|
|
return parent::getCMSFields();
|
|
}
|
|
|
|
function Title() {
|
|
return $this->Title ? $this->Title : _t('TagCloudWidget.DEFAULTTITLE', 'Tag Cloud');
|
|
}
|
|
|
|
/**
|
|
* Current BlogTree used as the container for this tagcloud.
|
|
* Used by {@link TagCloudWidgetTest} for testing
|
|
*
|
|
* @var BlogTree
|
|
*/
|
|
public static $container = null;
|
|
|
|
/**
|
|
* Return all sorted tags in the system
|
|
*
|
|
* @return ArrayList
|
|
*/
|
|
function getTagsCollection() {
|
|
Requirements::themedCSS("tagcloud");
|
|
|
|
// Ensure there is a valid BlogTree with entries
|
|
$container = BlogTree::current(self::$container);
|
|
if( !$container
|
|
|| !($entries = $container->Entries())
|
|
|| $entries->count() == 0
|
|
) return null;
|
|
|
|
// Extract all tags from each entry
|
|
$tagCounts = array(); // Mapping of tag => frequency
|
|
$tagLabels = array(); // Mapping of tag => label
|
|
foreach($entries as $entry) {
|
|
$theseTags = $entry->TagNames();
|
|
foreach($theseTags as $tag => $tagLabel) {
|
|
$tagLabels[$tag] = $tagLabel;
|
|
//getting the count into key => value map
|
|
$tagCounts[$tag] = isset($tagCounts[$tag]) ? $tagCounts[$tag] + 1 : 1;
|
|
}
|
|
}
|
|
if(empty($tagCounts)) return null;
|
|
$minCount = min($tagCounts);
|
|
$maxCount = max($tagCounts);
|
|
|
|
// Apply sorting mechanism
|
|
if($this->Sortby == "alphabet") {
|
|
// Sort by name
|
|
ksort($tagCounts);
|
|
} else {
|
|
// Sort by frequency
|
|
uasort($tagCounts, function($a, $b) {
|
|
return $b - $a;
|
|
});
|
|
}
|
|
|
|
// Apply limiting
|
|
if($this->Limit > 0) $tagCounts = array_slice($tagCounts, 0, $this->Limit, true);
|
|
|
|
// Calculate buckets of popularities
|
|
$numsizes = count(array_unique($tagCounts)); //Work out the number of different sizes
|
|
$popularities = self::config()->popularities;
|
|
$buckets = count($popularities);
|
|
|
|
// If there are more frequencies than buckets, divide frequencies into buckets
|
|
if ($numsizes > $buckets) $numsizes = $buckets;
|
|
|
|
// Adjust offset to use central buckets (if using a subset of available buckets)
|
|
$offset = round(($buckets - $numsizes)/2);
|
|
|
|
$output = new ArrayList();
|
|
foreach($tagCounts as $tag => $count) {
|
|
|
|
// Find position of $count in the selected range, adjusted for bucket range used
|
|
if($maxCount == $minCount) {
|
|
$popularity = $offset;
|
|
} else {
|
|
$popularity = round(
|
|
($count-$minCount) / ($maxCount-$minCount) * ($numsizes-1)
|
|
) + $offset;
|
|
}
|
|
$class = $popularities[$popularity];
|
|
|
|
$output->push(new ArrayData(array(
|
|
"Tag" => $tagLabels[$tag],
|
|
"Count" => $count,
|
|
"Class" => $class,
|
|
"Link" => Controller::join_links($container->Link('tag'), urlencode($tag))
|
|
)));
|
|
}
|
|
return $output;
|
|
}
|
|
}
|
|
}
|