]> git.wh0rd.org - tt-rss.git/blob - plugins/af_readability/init.php
Fix accidental use of emtpy array: [E_WARNING (2) plugins/af_readability/init.php...
[tt-rss.git] / plugins / af_readability / init.php
1 <?php
2 class Af_Readability extends Plugin {
3
4 private $host;
5
6 function about() {
7 return array(1.0,
8 "Try to inline article content using Readability",
9 "fox");
10 }
11
12 function save() {
13 //
14 }
15
16 function init($host)
17 {
18 $this->host = $host;
19
20 $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
21 $host->add_hook($host::HOOK_PREFS_TAB, $this);
22 $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this);
23 $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this);
24
25 $host->add_filter_action($this, "action_inline", __("Inline content"));
26 }
27
28 function hook_prefs_tab($args) {
29 if ($args != "prefFeeds") return;
30
31 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('af_readability settings')."\">";
32
33 print_notice("Enable the plugin for specific feeds in the feed editor.");
34
35 $enabled_feeds = $this->host->get($this, "enabled_feeds");
36 if (!array($enabled_feeds)) {
37 $enabled_feeds = array();
38 } else {
39 $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds);
40 }
41 $this->host->set($this, "enabled_feeds", $enabled_feeds);
42
43 if (count($enabled_feeds) > 0) {
44 print "<h3>" . __("Currently enabled for (click to edit):") . "</h3>";
45
46 print "<ul class=\"browseFeedList\" style=\"border-width : 1px\">";
47 foreach ($enabled_feeds as $f) {
48 print "<li>" .
49 "<img src='images/pub_set.png'
50 style='vertical-align : middle'> <a href='#'
51 onclick='editFeed($f)'>".
52 getFeedTitle($f) . "</a></li>";
53 }
54 print "</ul>";
55 }
56
57 print "</div>";
58 }
59
60 function hook_prefs_edit_feed($feed_id) {
61 print "<div class=\"dlgSec\">".__("Readability")."</div>";
62 print "<div class=\"dlgSecCont\">";
63
64 $enabled_feeds = $this->host->get($this, "enabled_feeds");
65 if (!array($enabled_feeds)) $enabled_feeds = array();
66
67 $key = array_search($feed_id, $enabled_feeds);
68 $checked = $key !== FALSE ? "checked" : "";
69
70 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"af_readability_enabled\"
71 name=\"af_readability_enabled\"
72 $checked>&nbsp;<label for=\"af_readability_enabled\">".__('Inline article content')."</label>";
73
74 print "</div>";
75 }
76
77 function hook_prefs_save_feed($feed_id) {
78 $enabled_feeds = $this->host->get($this, "enabled_feeds");
79 if (!is_array($enabled_feeds)) $enabled_feeds = array();
80
81 $enable = checkbox_to_sql_bool($_POST["af_readability_enabled"]) == 'true';
82 $key = array_search($feed_id, $enabled_feeds);
83
84 if ($enable) {
85 if ($key === FALSE) {
86 array_push($enabled_feeds, $feed_id);
87 }
88 } else {
89 if ($key !== FALSE) {
90 unset($enabled_feeds[$key]);
91 }
92 }
93
94 $this->host->set($this, "enabled_feeds", $enabled_feeds);
95 }
96
97 function hook_article_filter_action($article, $action) {
98 return $this->process_article($article);
99 }
100
101 function process_article($article) {
102
103 if (!class_exists("Readability")) require_once(dirname(dirname(__DIR__)). "/lib/readability/Readability.php");
104
105 if (!defined('NO_CURL') && function_exists('curl_init') && !ini_get("open_basedir")) {
106
107 $ch = curl_init($article["link"]);
108
109 curl_setopt($ch, CURLOPT_TIMEOUT, 5);
110 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
111 curl_setopt($ch, CURLOPT_HEADER, true);
112 curl_setopt($ch, CURLOPT_NOBODY, true);
113 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
114 curl_setopt($ch, CURLOPT_USERAGENT, SELF_USER_AGENT);
115
116 @$result = curl_exec($ch);
117 $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
118
119 if (strpos($content_type, "text/html") === FALSE)
120 return $article;
121 }
122
123 $tmp = fetch_file_contents($article["link"]);
124
125 if ($tmp && mb_strlen($tmp) < 65535 * 4) {
126 $tmpdoc = new DOMDocument("1.0", "UTF-8");
127
128 if (!$tmpdoc->loadHTML($tmp))
129 return $article;
130
131 if (strtolower($tmpdoc->encoding) != 'utf-8') {
132 $tmpxpath = new DOMXPath($tmpdoc);
133
134 foreach ($tmpxpath->query("//meta") as $elem) {
135 $elem->parentNode->removeChild($elem);
136 }
137
138 $tmp = $tmpdoc->saveHTML();
139 }
140
141 $r = new Readability($tmp, $article["link"]);
142
143 if ($r->init()) {
144
145 $tmpxpath = new DOMXPath($r->dom);
146
147 $entries = $tmpxpath->query('(//a[@href]|//img[@src])');
148
149 foreach ($entries as $entry) {
150 if ($entry->hasAttribute("href")) {
151 $entry->setAttribute("href",
152 rewrite_relative_url($article["link"], $entry->getAttribute("href")));
153
154 }
155
156 if ($entry->hasAttribute("src")) {
157 $entry->setAttribute("src",
158 rewrite_relative_url($article["link"], $entry->getAttribute("src")));
159
160 }
161
162 }
163
164 $article["content"] = $r->articleContent->innerHTML;
165 }
166 }
167
168 return $article;
169 }
170
171 function hook_article_filter($article) {
172
173 $enabled_feeds = $this->host->get($this, "enabled_feeds");
174 $key = array_search($article["feed"]["id"], $enabled_feeds);
175 if ($key === FALSE) return $article;
176
177 return $this->process_article($article);
178
179 }
180
181 function api_version() {
182 return 2;
183 }
184
185 private function filter_unknown_feeds($enabled_feeds) {
186 $tmp = array();
187
188 if (!empty($enabled_feeds)) {
189 foreach ($enabled_feeds as $feed) {
190
191 $result = db_query("SELECT id FROM ttrss_feeds WHERE id = '$feed' AND owner_uid = " . $_SESSION["uid"]);
192
193 if (db_num_rows($result) != 0) {
194 array_push($tmp, $feed);
195 }
196 }
197 }
198
199 return $tmp;
200 }
201
202 }
203 ?>