Passed
Pull Request — master (#5)
by Cody
03:17
created

Af_Comics   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Importance

Changes 2
Bugs 2 Features 0
Metric Value
eloc 99
c 2
b 2
f 0
dl 0
loc 183
rs 9.76
wmc 33
1
<?php
2
class Af_Comics extends Plugin {
3
4
	private $host;
5
	private $filters = array();
6
7
	public function about() {
8
		return array(2.0,
9
			"Fixes RSS feeds of assorted comic strips",
10
			"fox");
11
	}
12
13
	public function init($host) {
14
		$this->host = $host;
15
16
		$host->add_hook($host::HOOK_FETCH_FEED, $this);
17
		$host->add_hook($host::HOOK_FEED_BASIC_INFO, $this);
18
		$host->add_hook($host::HOOK_SUBSCRIBE_FEED, $this);
19
		$host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
20
		$host->add_hook($host::HOOK_PREFS_TAB, $this);
21
22
		require_once __DIR__ . "/filter_base.php";
23
24
		$filters = array_merge(glob(__DIR__ . "/filters.local/*.php"), glob(__DIR__ . "/filters/*.php"));
25
		$names = [];
26
27
		foreach ($filters as $file) {
28
			$filter_name = preg_replace("/\..*$/", "", basename($file));
29
30
			if (array_search($filter_name, $names) === FALSE) {
31
				if (!class_exists($filter_name)) {
32
					require_once $file;
33
				}
34
35
				array_push($names, $filter_name);
36
37
				$filter = new $filter_name();
38
39
				if (is_subclass_of($filter, "Af_ComicFilter")) {
40
					array_push($this->filters, $filter);
41
					array_push($names, $filter_name);
42
				}
43
			}
44
		}
45
	}
46
47
	public function hook_prefs_tab($args) {
48
		if ($args != "prefFeeds") return;
49
50
		print "<div dojoType=\"dijit.layout.AccordionPane\"
51
			title=\"<i class='material-icons'>photo</i> ".__('Feeds supported by af_comics')."\">";
52
53
		print "<p>" . __("The following comics are currently supported:") . "</p>";
54
55
		$comics = array("GoComics");
56
57
		foreach ($this->filters as $f) {
58
			foreach ($f->supported() as $comic) {
59
				array_push($comics, $comic);
60
			}
61
		}
62
63
		asort($comics);
64
65
		print "<ul class='panel panel-scrollable list list-unstyled'>";
66
		foreach ($comics as $comic) {
67
			print "<li>$comic</li>";
68
		}
69
		print "</ul>";
70
71
		print "<p>".__("To subscribe to GoComics use the comic's regular web page as the feed URL (e.g. for the <em>Garfield</em> comic use <code>http://www.gocomics.com/garfield</code>).")."</p>";
72
73
		print "<p>".__('Drop any updated filters into <code>filters.local</code> in plugin directory.')."</p>";
74
75
		print "</div>";
76
	}
77
78
	public function hook_article_filter($article) {
79
		foreach ($this->filters as $f) {
80
			if ($f->process($article))
81
				break;
82
		}
83
84
		return $article;
85
	}
86
87
	// GoComics dropped feed support so it needs to be handled when fetching the feed.
88
	/**
89
	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
90
	 */
91
	public function hook_fetch_feed($feed_data, $fetch_url, $owner_uid, $feed, $last_article_timestamp, $auth_login, $auth_pass) {
92
		if ($auth_login || $auth_pass)
93
			return $feed_data;
94
95
		if (preg_match('#^https?://(?:feeds\.feedburner\.com/uclick|www\.gocomics\.com)/([-a-z0-9]+)$#i', $fetch_url, $comic)) {
96
			$site_url = 'https://www.gocomics.com/' . $comic[1];
97
98
			$article_link = $site_url . date('/Y/m/d');
99
100
			$body = fetch_file_contents(array('url' => $article_link, 'type' => 'text/html', 'followlocation' => false));
101
102
			require_once 'lib/MiniTemplator.class.php';
103
104
			$feed_title = htmlspecialchars($comic[1]);
105
			$site_url = htmlspecialchars($site_url);
106
			$article_link = htmlspecialchars($article_link);
107
108
			$tpl = new MiniTemplator();
109
110
			$tpl->readTemplateFromFile('templates/generated_feed.txt');
111
112
			$tpl->setVariable('FEED_TITLE', $feed_title, true);
113
			$tpl->setVariable('VERSION', get_version(), true);
114
			$tpl->setVariable('FEED_URL', htmlspecialchars($fetch_url), true);
115
			$tpl->setVariable('SELF_URL', $site_url, true);
116
117
			if ($body) {
118
				$doc = new DOMDocument();
119
120
				if (@$doc->loadHTML($body)) {
121
					$xpath = new DOMXPath($doc);
122
123
					$node = $xpath->query('//picture[contains(@class, "item-comic-image")]/img')->item(0);
124
125
					if ($node) {
126
						$title = $xpath->query('//h1')->item(0);
127
128
						if ($title) {
129
							$title = clean(trim($title->nodeValue));
130
						} else {
131
							$title = date('l, F d, Y');
132
						}
133
134
						foreach (['srcset', 'sizes', 'data-srcset', 'width'] as $attr ) {
135
							$node->removeAttribute($attr);
136
						}
137
138
						$tpl->setVariable('ARTICLE_ID', $article_link, true);
139
						$tpl->setVariable('ARTICLE_LINK', $article_link, true);
140
						$tpl->setVariable('ARTICLE_UPDATED_ATOM', date('c', mktime(11, 0, 0)), true);
141
						$tpl->setVariable('ARTICLE_TITLE', htmlspecialchars($title), true);
142
						$tpl->setVariable('ARTICLE_EXCERPT', '', true);
143
						$tpl->setVariable('ARTICLE_CONTENT', $doc->saveHTML($node), true);
144
145
						$tpl->setVariable('ARTICLE_AUTHOR', '', true);
146
						$tpl->setVariable('ARTICLE_SOURCE_LINK', $site_url, true);
147
						$tpl->setVariable('ARTICLE_SOURCE_TITLE', $feed_title, true);
148
149
						$tpl->addBlock('entry');
150
					}
151
				}
152
			}
153
154
			$tpl->addBlock('feed');
155
156
			if ($tpl->generateOutputToString($tmp_data))
157
				$feed_data = $tmp_data;
158
		}
159
160
		return $feed_data;
161
	}
162
163
	public function hook_subscribe_feed($contents, $url, $auth_login, $auth_pass) {
164
		if ($auth_login || $auth_pass)
165
			return $contents;
166
167
		if (preg_match('#^https?://www\.gocomics\.com/([-a-z0-9]+)$#i', $url))
168
			return '<?xml version="1.0" encoding="utf-8"?>'; // Get is_html() to return false.
169
170
		return $contents;
171
	}
172
173
	public function hook_feed_basic_info($basic_info, $fetch_url, $owner_uid, $feed, $auth_login, $auth_pass) {
174
		if ($auth_login || $auth_pass)
175
			return $basic_info;
176
177
		if (preg_match('#^https?://www\.gocomics\.com/([-a-z0-9]+)$#i', $fetch_url, $matches))
178
			$basic_info = array('title' => ucfirst($matches[1]), 'site_url' => $matches[0]);
179
180
		return $basic_info;
181
	}
182
183
	public function api_version() {
184
		return 2;
185
	}
186
187
}
188