load feed entry urls and extract linked URLs from there
[stapibas.git] / src / stapibas / Feed / UpdateFeeds.php
1 <?php
2 namespace stapibas;
3
4 /**
5  * Fetches feeds that need an update and updates their feedentries.
6  */
7 class Feed_UpdateFeeds
8 {
9     public $db;
10     public $log;
11
12     public function updateAll()
13     {
14         $this->log->info('Updating feeds..');
15         $res = $this->db->query(
16             'SELECT * FROM feeds'
17             . ' WHERE f_needs_update = 1 OR f_updated = "0000-00-00 00:00:00"'
18         );
19         while ($feedRow = $res->fetch(\PDO::FETCH_OBJ)) {
20             $this->log->info(
21                 sprintf('Updating feed #%d: %s', $feedRow->f_id, $feedRow->f_url)
22             );
23             $this->updateFeed($feedRow);
24         }
25         $this->log->info('Finished updating feeds.');
26     }
27
28     protected function updateFeed($feedRow)
29     {
30         $req = new \HTTP_Request2($feedRow->f_url);
31         $req->setHeader('User-Agent', 'stapibas');
32
33         if ($feedRow->f_updated != '0000-00-00 00:00:00') {
34             $req->setHeader(
35                 'If-Modified-Since',
36                 gmdate('r', strtotime($feedRow->f_updated))
37             );
38         }
39
40         $res = $req->send();
41         if ($res->getStatus() == 304) {
42             //not modified
43             $this->setNoUpdate($feedRow);
44             $this->log->info('Not modified');
45             return;
46         }
47
48         if (intval($res->getStatus() / 100) != 2) {
49             //no 2xx is an error for us
50             $this->log->err('Error fetching feed');
51             return;
52         }
53
54         $this->updateEntries($feedRow, $res);
55     }
56
57     protected function updateEntries($feedRow, \HTTP_Request2_Response $res)
58     {
59         require_once $GLOBALS['stapibas_libdir'] . '/simplepie/autoloader.php';
60         $sp = new \SimplePie();
61         $sp->set_raw_data($res->getBody());
62         $sp->init();
63
64         $new = $updated = $items = 0;
65         foreach ($sp->get_items() as $item) {
66             ++$items;
67             $url = $item->get_permalink();
68             $entryRow = $this->db->query(
69                 'SELECT fe_id, fe_updated, fe_needs_update FROM feedentries'
70                 . ' WHERE fe_url = ' . $this->db->quote($url)
71                 . ' AND fe_f_id = ' . $this->db->quote($feedRow->f_id)
72             )->fetch(\PDO::FETCH_OBJ);
73
74             if ($entryRow === false) {
75                 //new item!
76                 $this->db->exec(
77                     'INSERT INTO feedentries SET'
78                     . '  fe_f_id = ' . $this->db->quote($feedRow->f_id)
79                     . ', fe_url = ' . $this->db->quote($url)
80                     . ', fe_needs_update = 1'
81                 );
82                 ++$new;
83                 continue;
84             }
85             if ($entryRow->fe_needs_update == 0
86                 && $item->get_updated_gmdate('U') > strtotime($entryRow->fe_updated)
87             ) {
88                 //updated
89                 $this->db->exec(
90                     'UPDATE feedentries SET'
91                     . '  fe_url = ' . $this->db->quote($url)
92                     . ', fe_needs_update = 1'
93                     . ' WHERE fe_id = ' . $this->db->quote($entryRow->fe_id)
94                 );
95                 ++$updated;
96                 continue;
97             }
98         }
99         $this->log->info(
100             sprintf(
101                 'Feed #%d: %d new, %d updated of %d entries',
102                 $feedRow->f_id, $new, $updated, $items
103             )
104         );
105         $this->setUpdated($feedRow, $res);
106     }
107
108     protected function setNoUpdate($feedRow)
109     {
110         $this->db->exec(
111             'UPDATE feeds SET f_needs_update = 0'
112             . ' WHERE f_id = ' . $this->db->quote($feedRow->f_id)
113         );
114     }
115
116     protected function setUpdated($feedRow, \HTTP_Request2_Response $res)
117     {
118         $this->db->exec(
119             'UPDATE feeds'
120             . ' SET f_needs_update = 0'
121             . ', f_updated = ' . $this->db->quote(
122                 gmdate('Y-m-d H:i:s', strtotime($res->getHeader('last-modified')))
123             )
124             . ' WHERE f_id = ' . $this->db->quote($feedRow->f_id)
125         );
126     }
127
128 }
129
130 ?>