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