-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRelatedPostsGenerator.php
99 lines (81 loc) · 2.69 KB
/
RelatedPostsGenerator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
namespace Tsphethean\Sculpin\Bundle\RelatedPostsBundle;
use Sculpin\Core\Sculpin;
use Sculpin\Core\Event\SourceSetEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Sculpin\Core\Permalink\SourcePermalinkFactory;
/**
* Related Posts Generator.
*
* @author Tom Phethean <www.tsphethean.co.uk>
*/
class RelatedPostsGenerator implements EventSubscriberInterface {
/**
* Permalink factory
*
* @var SourcePermalinkFactory
*/
protected $permalinkFactory;
public function __construct(SourcePermalinkFactory $permalinkFactory) {
$this->permalinkFactory = $permalinkFactory;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return array(
Sculpin::EVENT_BEFORE_RUN => array('beforeRun', 100),
);
}
public function beforeRun(SourceSetEvent $sourceSetEvent) {
$sourceSet = $sourceSetEvent->sourceSet();
$updatedSources = $sourceSet->updatedSources();
$allSources = $sourceSet->allSources();
$tagsMap = array();
// Build a map of all the tags on each source
foreach ($updatedSources as $source) {
// Get the tags of this source.
if ($sourceTags = $source->data()->get('tags')) {
foreach ($sourceTags as $tag) {
$tagsMap[$tag][] = $source->sourceId();
}
}
if ($source->isGenerated()) {
// Skip generated sources.
continue;
}
}
// Re-run through each source, identifying sources with matching tags.
foreach ($updatedSources as $source) {
$tagMatch = array();
if ($sourceTags = $source->data()->get('tags')) {
// for each tag that this post has...
foreach ($sourceTags as $tag) {
// get the mapped sources for this tag
$tagMatch = array_merge($tagMatch, $tagsMap[$tag]);
}
$tagMatchCount = array_count_values($tagMatch);
// remove self from list of related sources
unset($tagMatchCount[$source->sourceid()]);
asort($tagMatchCount);
// Get information about the matching tags
$relatedSources = array();
foreach ($tagMatchCount as $match => $count) {
// @TODO - make limit configurable
if (count($relatedSources) == 5) {
break;
}
$relatedSource = $allSources[$match];
if (!$relatedSource->data()->get('draft')) {
$relatedSources[] = array(
// @TODO - figure out why the title won't come through in the source.
'title' => $relatedSource->data()->get('title'),
'source' => $relatedSource,
);
}
}
$source->data()->set('related', $relatedSources);
}
}
}
}