]> git.wh0rd.org Git - tt-rss.git/blob - opml.php
opml: some indenting stuff
[tt-rss.git] / opml.php
1 <?php
2         set_include_path(get_include_path() . PATH_SEPARATOR .
3                 dirname(__FILE__) . "/include");
4
5         require_once "functions.php";
6         require_once "sessions.php";
7         require_once "sanity_check.php";
8         require_once "config.php";
9         require_once "db.php";
10         require_once "db-prefs.php";
11
12         $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
13
14         if (!init_connection($link)) return;
15
16         function opml_import_feed($link, $doc, $node, $cat_id, $owner_uid) {
17                 $attrs = $node->attributes;
18
19                 $feed_title = db_escape_string($attrs->getNamedItem('text')->nodeValue);
20                 if (!$feed_title) $feed_title = db_escape_string($attrs->getNamedItem('title')->nodeValue);
21
22                 $feed_url = db_escape_string($attrs->getNamedItem('xmlUrl')->nodeValue);
23                 if (!$feed_url) $feed_url = db_escape_string($attrs->getNamedItem('xmlURL')->nodeValue);
24
25                 $site_url = db_escape_string($attrs->getNamedItem('htmlUrl')->nodeValue);
26
27                 if ($feed_url && $feed_title) {
28                         $result = db_query($link, "SELECT id FROM ttrss_feeds WHERE
29                                 feed_url = '$feed_url' AND owner_uid = '$owner_uid'");
30
31                         if (db_num_rows($result) == 0) {
32                                 #opml_notice("[FEED] [$feed_title/$feed_url] dst_CAT=$cat_id");
33                                 opml_notice(T_sprintf("Adding feed: %s", $feed_title));
34
35                                 $query = "INSERT INTO ttrss_feeds
36                                         (title, feed_url, owner_uid, cat_id, site_url, order_id) VALUES
37                                         ('$feed_title', '$feed_url', '$owner_uid',
38                                         '$cat_id', '$site_url', 0)";
39                                 db_query($link, $query);
40
41                         } else {
42                                 opml_notice(T_sprintf("Duplicate feed: %s", $feed_title));
43                         }
44                 }
45         }
46
47         function opml_import_label($link, $doc, $node, $owner_uid) {
48                 $attrs = $node->attributes;
49                 $label_name = db_escape_string($attrs->getNamedItem('label-name')->nodeValue);
50
51                 if ($label_name) {
52                         $fg_color = db_escape_string($attrs->getNamedItem('label-fg-color')->nodeValue);
53                         $bg_color = db_escape_string($attrs->getNamedItem('label-bg-color')->nodeValue);
54
55                         if (!label_find_id($link, $label_name, $_SESSION['uid'])) {
56                                 opml_notice(T_sprintf("Adding label %s", htmlspecialchars($label_name)));
57                                 label_create($link, $label_name, $fg_color, $bg_color);
58                         } else {
59                                 opml_notice(T_sprintf("Duplicate label: %s", htmlspecialchars($label_name)));
60                         }
61                 }
62         }
63
64         function opml_import_preference($link, $doc, $node, $owner_uid) {
65                 $attrs = $node->attributes;
66                 $pref_name = db_escape_string($attrs->getNamedItem('pref-name')->nodeValue);
67
68                 if ($pref_name) {
69                         $pref_value = db_escape_string($attrs->getNamedItem('value')->nodeValue);
70
71                         opml_notice(T_sprintf("Setting preference key %s to %s",
72                                 $pref_name, $pref_value));
73
74                         set_pref($link, $pref_name, $pref_value);
75                 }
76         }
77
78         function opml_import_filter($link, $doc, $node, $owner_uid) {
79                 $attrs = $node->attributes;
80
81                 $filter_name = db_escape_string($attrs->getNamedItem('filter-name')->nodeValue);
82
83                 if ($filter_name) {
84
85                 $filter = json_decode($node->nodeValue, true);
86
87                         if ($filter) {
88                                 $reg_exp = db_escape_string($filter['reg_exp']);
89                                 $filter_type = (int)$filter['filter_type'];
90                                 $action_id = (int)$filter['action_id'];
91
92                                 $result = db_query($link, "SELECT id FROM ttrss_filters WHERE
93                                         reg_exp = '$reg_exp' AND
94                                         filter_type = '$filter_type' AND
95                                         action_id = '$action_id' AND
96                                         owner_uid = " .$_SESSION['uid']);
97
98                                 if (db_num_rows($result) == 0) {
99                                         $enabled = bool_to_sql_bool($filter['enabled']);
100                                         $action_param = db_escape_string($filter['action_param']);
101                                         $inverse = bool_to_sql_bool($filter['inverse']);
102                                         $filter_param = db_escape_string($filter['filter_param']);
103                                         $cat_filter = bool_to_sql_bool($filter['cat_filter']);
104
105                                         $feed_url = db_escape_string($filter['feed_url']);
106                                         $cat_title = db_escape_string($filter['cat_title']);
107
108                                         $result = db_query($link, "SELECT id FROM ttrss_feeds WHERE
109                                                 feed_url = '$feed_url' AND owner_uid = ".$_SESSION['uid']);
110
111                                         if (db_num_rows($result) != 0) {
112                                                 $feed_id = db_fetch_result($result, 0, "id");
113                                         } else {
114                                                 $feed_id = "NULL";
115                                         }
116
117                                         $result = db_query($link, "SELECT id FROM ttrss_feed_categories WHERE
118                                                 title = '$cat_title' AND  owner_uid = ".$_SESSION['uid']);
119
120                                         if (db_num_rows($result) != 0) {
121                                                 $cat_id = db_fetch_result($result, 0, "id");
122                                         } else {
123                                                 $cat_id = "NULL";
124                                         }
125
126                                         opml_notice(T_sprintf("Adding filter %s", htmlspecialchars($reg_exp)));
127
128                                         $query = "INSERT INTO ttrss_filters (filter_type, action_id,
129                                                         enabled, inverse, action_param, filter_param,
130                                                         cat_filter, feed_id,
131                                                         cat_id, reg_exp,
132                                                         owner_uid)
133                                                 VALUES ($filter_type, $action_id,
134                                                         $enabled, $inverse, '$action_param', '$filter_param',
135                                                         $cat_filter, $feed_id,
136                                                         $cat_id, '$reg_exp', ".
137                                                         $_SESSION['uid'].")";
138
139                                         db_query($link, $query);
140
141                                 } else {
142                                         opml_notice(T_sprintf("Duplicate filter %s", htmlspecialchars($reg_exp)));
143                                 }
144                         }
145                 }
146         }
147
148         function opml_import_category($link, $doc, $root_node, $owner_uid, $parent_id) {
149                 $body = $doc->getElementsByTagName('body');
150
151                 $default_cat_id = (int) get_feed_category($link, 'Imported feeds', false);
152
153                 if ($root_node) {
154                         $cat_title = db_escape_string($root_node->attributes->getNamedItem('title')->nodeValue);
155
156                         if (!in_array($cat_title, array("tt-rss-filters", "tt-rss-labels", "tt-rss-prefs"))) {
157                                 $cat_id = get_feed_category($link, $cat_title, $parent_id);
158                                 db_query($link, "BEGIN");
159                                 if ($cat_id === false) {
160                                         add_feed_category($link, $cat_title, $parent_id);
161                                         $cat_id = get_feed_category($link, $cat_title, $parent_id);
162                                 }
163                                 db_query($link, "COMMIT");
164                         } else {
165                                 $cat_id = 0;
166                         }
167
168                         $outlines = $root_node->childNodes;
169
170                 } else {
171                         $xpath = new DOMXpath($doc);
172                         $outlines = $xpath->query("//opml/body/outline");
173
174                         $cat_id = 0;
175                 }
176
177                 #opml_notice("[CAT] $cat_title id: $cat_id P_id: $parent_id");
178                 opml_notice(T_sprintf("Processing category: %s", $cat_title ? $cat_title : __("Uncategorized")));
179
180                 foreach ($outlines as $node) {
181                         if ($node->hasAttributes() && strtolower($node->tagName) == "outline") {
182                                 $attrs = $node->attributes;
183                                 $node_cat_title = db_escape_string($attrs->getNamedItem('title')->nodeValue);
184
185                                 if ($node->hasChildNodes() && $node_cat_title) {
186                                         opml_import_category($link, $doc, $node, $owner_uid, $cat_id);
187                                 } else {
188
189                                         if (!$cat_id) {
190                                                 $dst_cat_id = $default_cat_id;
191                                         } else {
192                                                 $dst_cat_id = $cat_id;
193                                         }
194
195                                         switch ($cat_title) {
196                                         case "tt-rss-prefs":
197                                                 opml_import_preference($link, $doc, $node, $owner_uid);
198                                                 break;
199                                         case "tt-rss-labels":
200                                                 opml_import_label($link, $doc, $node, $owner_uid);
201                                                 break;
202                                         case "tt-rss-filters":
203                                                 opml_import_filter($link, $doc, $node, $owner_uid);
204                                                 break;
205                                         default:
206                                                 opml_import_feed($link, $doc, $node, $dst_cat_id, $owner_uid);
207                                         }
208                                 }
209                         }
210                 }
211         }
212
213         function opml_import_domdoc($link, $owner_uid) {
214
215                 $debug = isset($_REQUEST["debug"]);
216                 $doc = false;
217
218                 #if ($debug) $doc = DOMDocument::load("/tmp/test.opml");
219
220                 if (is_file($_FILES['opml_file']['tmp_name'])) {
221                         $doc = DOMDocument::load($_FILES['opml_file']['tmp_name']);
222                 } else if (!$doc) {
223                         print_error(__('Error: please upload OPML file.'));
224                         return;
225                 }
226
227                 if ($doc) {
228                         opml_import_category($link, $doc, false, $owner_uid);
229                 } else {
230                         print_error(__('Error while parsing document.'));
231                 }
232         }
233
234         function opml_export_category($link, $owner_uid, $cat_id, $hide_private_feeds=false) {
235
236                 if ($cat_id) {
237                         $cat_qpart = "parent_cat = '$cat_id'";
238                         $feed_cat_qpart = "cat_id = '$cat_id'";
239                 } else {
240                         $cat_qpart = "parent_cat IS NULL";
241                         $feed_cat_qpart = "cat_id IS NULL";
242                 }
243
244                 if ($hide_private_feeds)
245                         $hide_qpart = "(private IS false AND auth_login = '' AND auth_pass = '')";
246                 else
247                         $hide_qpart = "true";
248
249                 $out = "";
250
251                 if ($cat_id) {
252                         $result = db_query($link, "SELECT title FROM ttrss_feed_categories WHERE id = '$cat_id'
253                                 AND owner_uid = '$owner_uid'");
254                         $cat_title = db_fetch_result($result, 0, "title");
255                 }
256
257                 if ($cat_title) $out .= "<outline title=\"$cat_title\">\n";
258
259                 $result = db_query($link, "SELECT id,title
260                         FROM ttrss_feed_categories WHERE
261                         $cat_qpart AND owner_uid = '$owner_uid' ORDER BY order_id, title");
262
263                 while ($line = db_fetch_assoc($result)) {
264                         $title = htmlspecialchars($line["title"]);
265                         $out .= opml_export_category($link, $owner_uid, $line["id"], $hide_private_feeds);
266                 }
267
268                 $feeds_result = db_query($link, "select title, feed_url, site_url
269                                 from ttrss_feeds where $feed_cat_qpart AND owner_uid = '$owner_uid' AND $hide_qpart
270                                 order by order_id, title");
271
272                 while ($fline = db_fetch_assoc($feeds_result)) {
273                         $title = htmlspecialchars($fline["title"]);
274                         $url = htmlspecialchars($fline["feed_url"]);
275                         $site_url = htmlspecialchars($fline["site_url"]);
276
277                         if ($site_url) {
278                                 $html_url_qpart = "htmlUrl=\"$site_url\"";
279                         } else {
280                                 $html_url_qpart = "";
281                         }
282
283                         $out .= "<outline text=\"$title\" xmlUrl=\"$url\" $html_url_qpart/>\n";
284                 }
285
286                 if ($cat_title) $out .= "</outline>\n";
287
288                 return $out;
289         }
290
291         function opml_export($link, $name, $owner_uid, $hide_private_feeds=false, $include_settings=true) {
292                 if (!isset($_REQUEST["debug"])) {
293                         header("Content-type: application/xml+opml");
294                         header("Content-Disposition: attachment; filename=" . $name );
295                 } else {
296                         header("Content-type: text/xml");
297                 }
298
299                 $out = "<?xml version=\"1.0\" encoding=\"utf-8\"?".">";
300
301                 $out .= "<opml version=\"1.0\">";
302                 $out .= "<head>
303                         <dateCreated>" . date("r", time()) . "</dateCreated>
304                         <title>Tiny Tiny RSS Feed Export</title>
305                 </head>";
306                 $out .= "<body>";
307
308                 $out .= opml_export_category($link, $owner_uid, false, $hide_private_feeds);
309
310                 # export tt-rss settings
311
312                 if ($include_settings) {
313                         $out .= "<outline title=\"tt-rss-prefs\" schema-version=\"".SCHEMA_VERSION."\">";
314
315                         $result = db_query($link, "SELECT pref_name, value FROM ttrss_user_prefs WHERE
316                            profile IS NULL AND owner_uid = " . $_SESSION["uid"] . " ORDER BY pref_name");
317
318                         while ($line = db_fetch_assoc($result)) {
319                                 $name = $line["pref_name"];
320                                 $value = htmlspecialchars($line["value"]);
321
322                                 $out .= "<outline pref-name=\"$name\" value=\"$value\"/>";
323                         }
324
325                         $out .= "</outline>";
326
327                         $out .= "<outline title=\"tt-rss-labels\" schema-version=\"".SCHEMA_VERSION."\">";
328
329                         $result = db_query($link, "SELECT * FROM ttrss_labels2 WHERE
330                                 owner_uid = " . $_SESSION['uid']);
331
332                         while ($line = db_fetch_assoc($result)) {
333                                 $name = htmlspecialchars($line['caption']);
334                                 $fg_color = htmlspecialchars($line['fg_color']);
335                                 $bg_color = htmlspecialchars($line['bg_color']);
336
337                                 $out .= "<outline label-name=\"$name\" label-fg-color=\"$fg_color\" label-bg-color=\"$bg_color\"/>";
338
339                         }
340
341                         $out .= "</outline>";
342
343                         $out .= "<outline title=\"tt-rss-filters\" schema-version=\"".SCHEMA_VERSION."\">";
344
345                         $result = db_query($link, "SELECT filter_type,
346                                         reg_exp,
347                                         action_id,
348                                         enabled,
349                                         action_param,
350                                         inverse,
351                                         filter_param,
352                                         cat_filter,
353                                         ttrss_feeds.feed_url AS feed_url,
354                                         ttrss_feed_categories.title AS cat_title
355                                         FROM ttrss_filters
356                                                 LEFT JOIN ttrss_feeds ON (feed_id = ttrss_feeds.id)
357                                                 LEFT JOIN ttrss_feed_categories ON (ttrss_filters.cat_id = ttrss_feed_categories.id)
358                                         WHERE
359                                                 ttrss_filters.owner_uid = " . $_SESSION['uid']);
360
361                         while ($line = db_fetch_assoc($result)) {
362                                 $name = htmlspecialchars($line['reg_exp']);
363
364                                 foreach (array('enabled', 'inverse', 'cat_filter') as $b) {
365                                         $line[$b] = sql_bool_to_bool($line[$b]);
366                                 }
367
368                                 $filter = json_encode($line);
369
370                                 $out .= "<outline filter-name=\"$name\">$filter</outline>";
371
372                         }
373
374
375                         $out .= "</outline>";
376                 }
377
378                 $out .= "</body></opml>";
379
380                 // Format output.
381                 $doc = new DOMDocument();
382                 $doc->formatOutput = true;
383                 $doc->preserveWhiteSpace = false;
384                 $doc->loadXML($out);
385                 $res = $doc->saveXML();
386
387                 // saveXML uses a two-space indent.  Change to tabs.
388                 $res = preg_replace_callback('/^(?:  )+/mu',
389                         create_function(
390                                 '$matches',
391                                 'return str_repeat("\t", intval(strlen($matches[0])/2));'),
392                         $res);
393
394                 print $res;
395         }
396
397         // FIXME there are some brackets issues here
398
399         $op = $_REQUEST["op"];
400         if (!$op) $op = "Export";
401
402         $output_name = $_REQUEST["filename"];
403         if (!$output_name) $output_name = "TinyTinyRSS.opml";
404
405         $show_settings = $_REQUEST["settings"];
406
407         if ($op == "Export") {
408
409                 login_sequence($link);
410                 $owner_uid = $_SESSION["uid"];
411                 return opml_export($link, $output_name, $owner_uid, false, ($show_settings == 1));
412         }
413
414         if ($op == "publish"){
415                 $key = db_escape_string($_REQUEST["key"]);
416
417                 $result = db_query($link, "SELECT owner_uid
418                                 FROM ttrss_access_keys WHERE
419                                 access_key = '$key' AND feed_id = 'OPML:Publish'");
420
421                 if (db_num_rows($result) == 1) {
422                         $owner_uid = db_fetch_result($result, 0, "owner_uid");
423                         return opml_export($link, "", $owner_uid, true, false);
424                 } else {
425                         print "<error>User not found</error>";
426                 }
427         }
428
429         if ($op == "Import") {
430
431                 login_sequence($link);
432                 $owner_uid = $_SESSION["uid"];
433
434                 header('Content-Type: text/html; charset=utf-8');
435
436                 print "<html>
437                         <head>
438                                 <link rel=\"stylesheet\" href=\"utility.css\" type=\"text/css\">
439                                 <title>".__("OPML Utility")."</title>
440                                 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
441                         </head>
442                         <body>
443                         <div class=\"floatingLogo\"><img src=\"images/logo_wide.png\"></div>
444                         <h1>".__('OPML Utility')."</h1>";
445
446                 db_query($link, "BEGIN");
447
448                 /* create Imported feeds category just in case */
449
450                 $result = db_query($link, "SELECT id FROM
451                         ttrss_feed_categories WHERE title = 'Imported feeds' AND
452                         owner_uid = '$owner_uid' LIMIT 1");
453
454                 if (db_num_rows($result) == 0) {
455                                 db_query($link, "INSERT INTO ttrss_feed_categories
456                                         (title,owner_uid)
457                                                 VALUES ('Imported feeds', '$owner_uid')");
458                 }
459
460                 db_query($link, "COMMIT");
461
462                 opml_notice(__("Importing OPML..."));
463
464                 opml_import_domdoc($link, $owner_uid);
465
466                 print "<br><form method=\"GET\" action=\"prefs.php\">
467                         <input type=\"submit\" value=\"".__("Return to preferences")."\">
468                         </form>";
469
470                 print "</body></html>";
471
472         }
473
474 //      if ($link) db_close($link);
475
476         function opml_notice($msg) {
477                 print "$msg<br/>";
478         }
479
480 ?>