/[drupal]/contributions/modules/zend_feed/zend_feed.module
ViewVC logotype

Contents of /contributions/modules/zend_feed/zend_feed.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.10 - (show annotations) (download) (as text)
Mon Sep 28 21:05:08 2009 UTC (8 weeks, 4 days ago) by mustafau
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +5 -5 lines
File MIME type: text/x-php
"files[]" array in info file.
Use "Implement ..." instead of "Implementation of ..."
1 <?php
2 // $Id: zend_feed.module,v 1.9 2009/09/28 19:22:24 mustafau Exp $
3
4 /**
5 * @file
6 *
7 * @see http://framework.zend.com/
8 */
9
10 /**
11 * Indicates that autodiscovery is enabled.
12 */
13 define('ZEND_FEED_AUTODISCOVERY_NORMAL', 1);
14
15 /**
16 * Indicates that autodiscovery is disabled.
17 */
18 define('ZEND_FEED_AUTODISCOVERY_DISABLED', 0);
19
20 /**
21 * Minimum cache lifetime.
22 */
23 define('ZEND_FEED_CACHE_LIFETIME', 3600);
24
25 /**
26 * Implement hook_help().
27 */
28 function zend_feed_help($path, $arg) {
29 switch ($path) {
30 case 'admin/help#zend_feed':
31 return '<p>'. t("Uses the Zend Framework's Zend_Feed to download and parse feeds.") .'</p>';
32 case 'admin/settings/zend/zend_feed':
33 return '<p>'. t('Zend_Feed provides functionality for consuming RSS and Atom feeds.') .'</p>';
34 }
35 }
36
37 /**
38 * Implement hook_menu().
39 */
40 function zend_feed_menu() {
41 $items['admin/settings/zend/zend_feed'] = array(
42 'title' => 'Zend_Feed',
43 'description' => 'Control how Zend_Feed works.',
44 'page callback' => 'drupal_get_form',
45 'page arguments' => array('zend_feed_admin_settings'),
46 'access arguments' => array('administer site configuration'),
47 'type' => MENU_LOCAL_TASK,
48 );
49
50 return $items;
51 }
52
53 function zend_feed_admin_settings() {
54 $form['zend_feed_autodiscovery'] = array(
55 '#type' => 'radios',
56 '#title' => t('Disable/Enable autodiscovery'),
57 '#default_value' => variable_get('zend_feed_autodiscovery', ZEND_FEED_AUTODISCOVERY_DISABLED),
58 '#options' => array(
59 ZEND_FEED_AUTODISCOVERY_DISABLED => t('Disabled'),
60 ZEND_FEED_AUTODISCOVERY_NORMAL => t('Enabled')
61 ),
62 '#description' => t('Web pages often contain <link> tags that refer to feeds with content relevant to the particular page. Zend_Feed enables you to retrieve first feed referenced by a web page.'),
63 );
64
65 return system_settings_form($form);
66 }
67
68 /**
69 * Implement hook_cron().
70 *
71 * Expire outdated cache entries.
72 */
73 function zend_feed_cron() {
74 cache_clear_all(NULL, 'cache_zend_feed');
75 }
76
77 /**
78 * Implement hook_simpletest().
79 */
80 function zend_feed_simpletest() {
81 $tests = file_scan_directory(drupal_get_path('module', 'zend_feed') .'/tests', '\.test');
82 return array_keys($tests);
83 }
84
85 /**
86 * Write a record to the database.
87 *
88 * @param unknown_type $url
89 * @param unknown_type $etag
90 * @param unknown_type $modified
91 * @param unknown_type $alternate
92 * @return unknown
93 */
94 function zend_feed_write_record($url, $etag = '', $modified = 0, $alternate = '') {
95 // Update.
96 db_query("UPDATE {zend_feed} SET etag = '%s', modified = %d, alternate = '%s' WHERE url = '%s'", $etag, $modified, $alternate, $url);
97 if (!db_affected_rows()) {
98 // Insert.
99 @db_query("INSERT INTO {zend_feed} (url, etag, modified, alternate) VALUES ('%s', '%s', %d, '%s')", $url, $etag, $modified, $alternate);
100 }
101 }
102
103 /**
104 * Read a record from the database.
105 *
106 * @param int $nid
107 * @return unknown
108 */
109 function zend_feed_read_record($url, $reset = FALSE) {
110 static $records;
111
112 if ($reset || !isset($records[$url])) {
113 $result = db_query("SELECT * FROM {zend_feed} WHERE url = '%s'", $url);
114 while ($row = db_fetch_array($result)) {
115 $records[$url] = $row;
116 // return $row;
117 }
118 }
119
120 return isset($records[$url]) ? $records[$url] : FALSE;
121 }
122
123 function zend_feed_get_alternate($url) {
124 if ($record = zend_feed_read_record($url)) {
125 return $record['alternate'];
126 }
127
128 return FALSE;
129 }
130
131 /**
132 * Enter description here...
133 *
134 * @param string $url
135 * @return unknown
136 */
137 function zend_feed_http_request($url) {
138 $request_url = $url;
139
140 // Generate conditional GET headers.
141 $headers = array();
142 $db_result = zend_feed_read_record($url);
143 if ($db_result !== FALSE) {
144 $headers['If-None-Match'] = $db_result['etag'];
145 $headers['If-Modified-Since'] = gmdate('D, d M Y H:i:s', $db_result['modified']) .' GMT';
146 if (valid_url($db_result['alternate'], TRUE)) {
147 $request_url = (string) $db_result['alternate'];
148 }
149 }
150
151 // Request feed.
152 $result = drupal_http_request($request_url, $headers);
153
154 // Process HTTP response code.
155 switch ($result->code) {
156 case 304: // Not modified.
157 return $result;
158 case 200: // OK
159 case 301: // Moved permanently.
160 case 302: // Moved temporarily.
161 case 307: // Moved temporarily.
162 $etag = empty($result->headers['ETag']) ? '' : $result->headers['ETag'];
163 $modified = empty($result->headers['Last-Modified']) ? 0 : strtotime($result->headers['Last-Modified']);
164
165 // if ($modified != $db_result['modified']) {
166 // Update conditional GET headers data.
167 zend_feed_write_record($url, $etag, $modified);
168 // }
169
170 return $result;
171
172 default:
173 if (($result->code > 99) && ($result->code < 1000)) {
174 // @todo Output should be more user friendly.
175 watchdog('zend_feed', 'Feed %url: HTTP code: %code, error: %error', array('%url' => $url, '%code' => $result->code, '%error' => $result->error), WATCHDOG_WARNING);
176 }
177 }
178
179 return FALSE;
180 }
181
182 /**
183 * Import feed from URL. Supports autodiscovery.
184 *
185 * @param string $url
186 * @return Zend_Feed_Abstract
187 */
188 function zend_feed_import($url, $retry = 1) {
189 // Ensure that the URL is valid.
190 if (!valid_url($url, TRUE)) {
191 return FALSE;
192 }
193
194 $hash = md5($url);
195
196 /**
197 * Download.
198 */
199 if ($cache = cache_get('zend_feed:'. $hash, 'cache_zend_feed') && !empty($cache->data)) {
200 $result = $cache->data;
201 }
202 else {
203 // Request.
204 $result = zend_feed_http_request($url);
205 }
206
207 // Process HTTP response data.
208 if ($result && !empty($result->data)) {
209 zend_require('Zend/Feed.php');
210
211 try {
212 $zend_feed = Zend_Feed::importString($result->data);
213 if ($cache == 0) {
214 cache_set('zend_feed:'. $hash, $result, 'cache_zend_feed', time() + ZEND_FEED_CACHE_LIFETIME);
215 }
216 return $zend_feed;
217 }
218 catch (Exception $e) {
219 // Feed import failed. Continue execution.
220 }
221
222 /**
223 * Autodiscovery.
224 */
225
226 if ($retry <= 0) {
227 return FALSE;
228 }
229
230 // Parse the contents for appropriate <link ... /> tags.
231 $pattern = '~(<link[^>]+)/?>~i';
232 $preg_result = @preg_match_all($pattern, $result->data, $matches);
233 if ($preg_result === FALSE) {
234 return FALSE;
235 }
236
237 // Try to fetch a feed from first link tag that appears to refer to a feed.
238 if (isset($matches[1]) && count($matches[1]) > 0) {
239 foreach ($matches[1] as $link) {
240 // Force string to be an utf-8 one.
241 if (!mb_check_encoding($link, 'UTF-8')) {
242 $link = mb_convert_encoding($link, 'UTF-8');
243 }
244 $xml = @simplexml_load_string(rtrim($link, ' /') .' />');
245 if ($xml === FALSE) {
246 continue;
247 }
248 $attributes = $xml->attributes();
249 if (!isset($attributes['rel']) || !@preg_match('~^(?:alternate|service\.feed)~i', $attributes['rel'])) {
250 continue;
251 }
252 if (!isset($attributes['type']) || !@preg_match('~^application/(?:atom|rss)\+xml~', $attributes['type'])) {
253 continue;
254 }
255 if (!isset($attributes['href'])) {
256 continue;
257 }
258
259 $alt_url = (string) $attributes['href'];
260 if (!valid_url($alt_url, TRUE)) {
261 $uri = parse_url($url);
262 // Canonize the url.
263 if (substr($alt_url, 0, 1) != '/') {
264 // Add the current root path to this one.
265 $alt_url = rtrim($uri['path'], '/') .'/'. $alt_url;
266 }
267 $alt_url = $uri['scheme'] .'://'. $uri['host'] .'/'. $alt_url;
268 }
269
270 $zend_feed = zend_feed_import($alt_url, --$retry);
271 if ($zend_feed !== FALSE) {
272 // cache_set('zend_feed:'. md5($alt_url), 'cache_zend_feed', serialize($result), time() + ZEND_FEED_CACHE_LIFETIME);
273 db_query("UPDATE {zend_feed} SET alternate = '%s' WHERE url = '%s'", $alt_url, $url);
274 return $zend_feed;
275 }
276 }
277 }
278 }
279
280 return FALSE;
281 }

  ViewVC Help
Powered by ViewVC 1.1.2