1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
44:
45:
46: $plugin_is_filter = 900 | FEATURE_PLUGIN | ADMIN_PLUGIN;
47: $plugin_description = gettext('The Zenphoto <em>externalFeed</em> handler.');
48:
49: $plugin_author = "Stephen Billard (sbillard)";
50:
51: $option_interface = 'externalFeed_options';
52:
53: class externalFeed_options {
54:
55: function __construct() {
56: if (OFFSET_PATH == 2) {
57: setOptionDefault('externalFeed_truncate_length', '100');
58: setOptionDefault('externalFeed_zenpage_items', '10');
59: setOptionDefault('externalFeed_items', 10);
60: setOptionDefault('externalFeed_imagesize', 240);
61: setOptionDefault('externalFeed_sortorder', 'latest');
62: setOptionDefault('externalFeed_sortorder_albums', 'latest');
63: }
64: }
65:
66: function getOptionsSupported() {
67: $options = array(gettext('externalFeed feeds enabled:') => array('key' => 'externalFeed_feed_list', 'type' => OPTION_TYPE_CHECKBOX_ARRAY,
68: 'order' => 0,
69: 'checkboxes' => array(gettext('Gallery') => 'externalFeed_album_image',
70: gettext('Gallery Comments') => 'externalFeed_comments',
71: gettext('News') => 'externalFeed_articles',
72: gettext('Pages') => 'externalFeed_pages',
73: gettext('News/Page Comments') => 'externalFeed_article_comments'
74: ),
75: 'desc' => gettext('Check each feeds you wish to activate.')),
76: gettext('Image feed items:') => array('key' => 'externalFeed_items', 'type' => OPTION_TYPE_TEXTBOX,
77: 'order' => 1,
78: 'desc' => gettext("The number of new images and comments you want to appear in your site’s feed")),
79: gettext('Image size') => array('key' => 'externalFeed_imagesize', 'type' => OPTION_TYPE_TEXTBOX,
80: 'order' => 3,
81: 'desc' => gettext('Size of image feed images:')),
82: gettext('Image feed sort order:') => array('key' => 'externalFeed_sortorder', 'type' => OPTION_TYPE_SELECTOR,
83: 'order' => 7,
84: 'selections' => array(gettext('latest by id') => 'latest',
85: gettext('latest by date') => 'latest-date',
86: gettext('latest by mtime') => 'latest-mtime',
87: gettext('latest by publishdate') => 'latest-publishdate'
88: ),
89: 'desc' => gettext("Choose between latest by id for the latest uploaded, latest by date for the latest uploaded fetched by date, or latest by mtime for the latest uploaded fetched by the file’s last change timestamp.")),
90: gettext('Album feed sort order:') => array('key' => 'externalFeed_sortorder_albums', 'type' => OPTION_TYPE_SELECTOR,
91: 'selections' => array(gettext('latest by id') => 'latest',
92: gettext('latest by date') => 'latest-date',
93: gettext('latest by mtime') => 'latest-mtime',
94: gettext('latest by publishdate') => 'latest-publishdate',
95: gettext('latest updated') => 'latestupdated'
96: ),
97: 'order' => 8,
98: 'desc' => gettext('In addition to the above you may select latest updated.')),
99: gettext('New requestor:') => array('key' => 'externalFeed_site', 'type' => OPTION_TYPE_TEXTBOX,
100: 'order' => 9,
101: 'desc' => gettext("Supply a site name to add a new using site.")),
102: gettext('Registered sites:') => array('key' => 'externalFeed_sitelist', 'type' => OPTION_TYPE_CUSTOM,
103: 'order' => 9,
104: 'desc' => gettext("Check the box to remove a site."))
105: );
106: if (extensionEnabled('zenpage')) {
107: $options[gettext('Feed text length')] = array('key' => 'externalFeed_truncate_length', 'type' => OPTION_TYPE_TEXTBOX,
108: 'order' => 6,
109: 'desc' => gettext("The text length of the Zenpage feed items. No value for full length."));
110: $options[gettext('News feed items')] = array('key' => 'externalFeed_zenpage_items', 'type' => OPTION_TYPE_TEXTBOX,
111: 'order' => 5,
112: 'desc' => gettext("The number of news articles you want to appear in your site’s News feed."));
113: }
114:
115: return $options;
116: }
117:
118: function handleOption($option, $currentValue) {
119: $count = 0;
120: $result = query('SELECT * FROM ' . prefix('plugin_storage') . ' WHERE `type`="externalFeed" ORDER BY `aux`');
121: if ($result) {
122: $list = array();
123: while ($row = db_fetch_assoc($result)) {
124: $count++;
125: $key = $row['data'];
126: $site = $row['aux'];
127: ?>
128: <div>
129: <label><?php printf(gettext('<em><strong>%1$s</strong></em> key=%2$s'), $site, $key); ?> <input type="checkbox" name="externalFeed_delete_<?php echo $site; ?>" /></label>
130: </div>
131: <?php
132: }
133: }
134: if (!$count)
135: echo gettext('No sites registered');
136: }
137:
138: function handleOptionSave($themename, $themealbum) {
139: if ($site = getOption('externalFeed_site')) {
140: purgeOption('externalFeed_site');
141: $key = md5($site . serialize($_SERVER));
142: query('INSERT INTO ' . prefix('plugin_storage') . ' (`type`, `aux`,`data`) VALUES ("externalFeed",' . db_quote($site) . ',' . db_quote($key) . ') ON DUPLICATE KEY UPDATE `data`=' . db_quote($key));
143: }
144: foreach ($_POST as $option => $value) {
145: if (strpos($option, 'externalFeed_delete_') !== false) {
146: $site = str_replace('externalFeed_delete_', '', $option);
147: query('DELETE FROM ' . prefix('plugin_storage') . ' WHERE `type`="externalFeed" AND `aux`=' . db_quote($site));
148: }
149: }
150: return false;
151: }
152:
153: }
154:
155: require_once(SERVERPATH . '/' . ZENFOLDER . '/class-feed.php');
156: require_once(SERVERPATH . '/' . ZENFOLDER . '/lib-MimeTypes.php');
157:
158: class ExternalFeed extends feed {
159:
160: protected $feed = 'externalFeed';
161: protected $key;
162:
163: 164: 165: 166:
167: function __construct($options = NULL) {
168: global $_zp_gallery, $_zp_current_admin_obj, $_zp_loggedin;
169: if (empty($options))
170: self::feed404();
171:
172: $this->feedtype = $options['external'];
173: $this->key = @$options['accesskey'];
174: parent::__construct($options);
175:
176:
177: if ($this->key) {
178: $result = query_single_row('SELECT * FROM ' . prefix('plugin_storage') . ' WHERE `type`="externalFeed" AND `data`=' . db_quote($this->key));
179: if (!$result) {
180: $this->key = NULL;
181: }
182: }
183: if (!$this->key && $this->feedtype != 'site_closed')
184: self::feed404();
185:
186: $channeltitlemode = getOption('externalFeed_title');
187: $this->host = html_encode($_SERVER["HTTP_HOST"]);
188:
189:
190: switch ($channeltitlemode) {
191: case 'gallery':
192: $this->channel_title = $_zp_gallery->getBareTitle($this->locale);
193: break;
194: case 'website':
195: $this->channel_title = getBare($_zp_gallery->getWebsiteTitle($this->locale));
196: break;
197: case 'both':
198: $website_title = $_zp_gallery->getWebsiteTitle($this->locale);
199: $this->channel_title = $_zp_gallery->getBareTitle($this->locale);
200: if (!empty($website_title)) {
201: $this->channel_title = $website_title . ' - ' . $this->channel_title;
202: }
203: break;
204: }
205:
206:
207: switch ($this->feedtype) {
208:
209: case 'gallery':
210: if (!getOption('externalFeed_album_image')) {
211: self::feed404();
212: }
213:
214: $albumname = $this->getChannelTitleExtra();
215: if ($this->albumfolder) {
216: $alb = newAlbum($this->albumfolder, true, true);
217: if ($alb->exists) {
218: $albumtitle = $alb->getTitle();
219: if ($this->mode == 'albums' || $this->collection) {
220: $albumname = ' - ' . html_encode($albumtitle) . $this->getChannelTitleExtra();
221: }
222: } else {
223: self::feed404();
224: }
225: } else {
226: $albumtitle = '';
227: }
228: $albumname = $this->getChannelTitleExtra();
229:
230: $this->channel_title = html_encode($this->channel_title . ' ' . getBare($albumname));
231: $this->imagesize = $this->getImageSize();
232: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/image_album_statistics.php');
233: break;
234:
235: case 'news':
236: if (!getOption('externalFeed_articles')) {
237: self::feed404();
238: }
239: $titleappendix = gettext(' (Latest news)');
240:
241: switch ($this->sortorder) {
242: case 'popular':
243: $titleappendix = gettext(' (Most popular news)');
244: break;
245: case 'mostrated':
246: $titleappendix = gettext(' (Most rated news)');
247: break;
248: case 'toprated':
249: $titleappendix = gettext(' (Top rated news)');
250: break;
251: case 'random':
252: $titleappendix = gettext(' (Random news)');
253: break;
254: }
255: $this->channel_title = html_encode($this->channel_title . $this->cattitle . $titleappendix);
256: $this->imagesize = $this->getImageSize();
257: $this->itemnumber = getOption("externalFeed_zenpage_items");
258: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/image_album_statistics.php');
259: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/zenpage/zenpage-template-functions.php');
260:
261: break;
262: case 'pages':
263: if (!getOption('externalFeed_pages')) {
264: self::feed404();
265: }
266: switch ($this->sortorder) {
267: case 'popular':
268: $titleappendix = gettext(' (Most popular pages)');
269: break;
270: case 'mostrated':
271: $titleappendix = gettext(' (Most rated pages)');
272: break;
273: case 'toprated':
274: $titleappendix = gettext(' (Top rated pages)');
275: break;
276: case 'random':
277: $titleappendix = gettext(' (Random pages)');
278: break;
279: default:
280: $titleappendix = gettext(' (Latest pages)');
281: break;
282: }
283: $this->channel_title = html_encode($this->channel_title . $titleappendix);
284: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/zenpage/zenpage-template-functions.php');
285: break;
286:
287: case 'comments':
288: if (!getOption('externalFeed_comments')) {
289: self::feed404();
290: }
291: if ($this->id) {
292: switch ($this->commentfeedtype) {
293: case 'album':
294: $table = 'albums';
295: break;
296: case 'image':
297: $table = 'images';
298: break;
299: case 'news':
300: $table = 'news';
301: break;
302: case 'page':
303: $table = 'pages';
304: break;
305: default:
306: self::feed404();
307: break;
308: }
309: $this->itemobj = getItemByID($table, $this->id);
310: if ($this->itemobj) {
311: $title = ' - ' . $this->itemobj->getTitle();
312: } else {
313: self::feed404();
314: }
315: } else {
316: $this->itemobj = NULL;
317: $title = NULL;
318: }
319: $this->channel_title = html_encode($this->channel_title . $title . gettext(' (latest comments)'));
320: if (extensionEnabled('zenpage')) {
321: require_once(SERVERPATH . '/' . ZENFOLDER . '/' . PLUGIN_FOLDER . '/zenpage/zenpage-template-functions.php');
322: }
323: break;
324: case 'null':
325: return;
326: }
327: $this->feeditems = $this->getitems();
328: }
329:
330: 331: 332: 333: 334: 335:
336: protected function getItemGallery($item) {
337: if ($this->mode == "albums") {
338: $albumobj = $item;
339: $totalimages = $albumobj->getNumImages();
340: $itemlink = $this->host . $albumobj->getLink();
341: $thumb = $albumobj->getAlbumThumbImage();
342: $title = $albumobj->getTitle($this->locale);
343:
344: $filechangedate = filectime(ALBUM_FOLDER_SERVERPATH . internalToFilesystem($albumobj->name));
345: $latestimage = query_single_row("SELECT mtime FROM " . prefix('images') . " WHERE albumid = " . $albumobj->getID() . " AND `show` = 1 ORDER BY id DESC");
346: if ($latestimage && $this->sortorder == 'latestupdated') {
347: $count = db_count('images', "WHERE albumid = " . $albumobj->getID() . " AND mtime = " . $latestimage['mtime']);
348: } else {
349: $count = $totalimages;
350: }
351: if ($count != 0) {
352: $imagenumber = sprintf(ngettext('%s (%u image)', '%s (%u images)', $count), $title, $count);
353: } else {
354: $imagenumber = $title;
355: }
356: $feeditem['desc'] = $albumobj->getDesc($this->locale);
357:
358: $feeditem['title'] = $imagenumber;
359: $feeditem['pubdate'] = date("r", strtotime($albumobj->getDateTime()));
360: } else {
361: if (isAlbumClass($item)) {
362: $albumobj = $item;
363: $thumb = $albumobj->getAlbumThumbImage();
364: } else {
365: $albumobj = $item->getAlbum();
366: $thumb = $item;
367: }
368: $itemlink = $this->host . $item->getLink();
369: $title = $item->getTitle($this->locale);
370:
371: $feeditem['desc'] = $item->getDesc($this->locale);
372: $feeditem['title'] = sprintf('%1$s (%2$s)', $item->getTitle($this->locale), $albumobj->getTitle($this->locale));
373: $feeditem['pubdate'] = date("r", strtotime($item->getDateTime()));
374: }
375:
376:
377: $feeditem['link'] = $itemlink;
378:
379:
380: $feeditem['category'] = html_encode($albumobj->getTitle($this->locale));
381:
382:
383:
384: $feeditem['media_content'] = '<image url="' . PROTOCOL . '://' . html_encode($thumb->getCustomImage($this->imagesize, NULL, NULL, NULL, NULL, NULL, NULL, TRUE)) . '" />';
385: $feeditem['media_thumbnail'] = '<thumbnail url="' . PROTOCOL . '://' . html_encode($thumb->getThumb()) . '" />';
386:
387: return $feeditem;
388: }
389:
390: 391: 392: 393: 394: 395:
396: protected function getItemNews($item) {
397: $categories = '';
398: $feeditem['enclosure'] = '';
399: $obj = new ZenpageNews($item['titlelink']);
400: $title = $feeditem['title'] = get_language_string($obj->getTitle('all'), $this->locale);
401: $link = $obj->getLink();
402: $count2 = 0;
403: $plaincategories = $obj->getCategories();
404: $categories = '';
405: foreach ($plaincategories as $cat) {
406: $catobj = new ZenpageCategory($cat['titlelink']);
407: $categories .= get_language_string($catobj->getTitle('all'), $this->locale) . ', ';
408: }
409: $categories = rtrim($categories, ', ');
410: $desc = $obj->getContent($this->locale);
411: $desc = str_replace('//<![CDATA[', '', $desc);
412: $desc = str_replace('//]]>', '', $desc);
413: $feeditem['desc'] = shortenContent($desc, getOption('externalFeed_truncate_length'), '...');
414: if (!empty($categories)) {
415: $feeditem['category'] = html_encode($categories);
416: $feeditem['title'] = $title . ' (' . $categories . ')';
417: }
418: $feeditem['link'] = $link;
419: $feeditem['media_content'] = '';
420: $feeditem['media_thumbnail'] = '';
421: $feeditem['pubdate'] = date("r", strtotime($obj->getDateTime()));
422:
423: return $feeditem;
424: }
425:
426: public function getitems() {
427: $items = array();
428: if (($album = @$this->options['album'])) {
429: if ($image = @$this->options['image']) {
430: if (!is_array($image)) {
431: $image = array($image);
432: }
433: foreach ($image as $filename) {
434: $obj = newImage(NULL, array('folder' => $album, 'filename' => $filename), true);
435: if ($obj->exists) {
436: $items[] = $obj;
437: }
438: }
439: } else {
440: if (!is_array($album)) {
441: $album = array($album);
442: }
443: foreach ($album as $folder) {
444: $obj = newAlbum($folder, true);
445: if ($obj->exists) {
446: $items[] = $obj;
447: }
448: }
449: }
450: return $items;
451: }
452:
453: if ($this->feedtype == 'news' && $news = @$this->options['titlelink']) {
454: if (!is_array($news)) {
455: $news = array($news);
456: }
457: foreach ($news as $article) {
458: $obj = new ZenpageNews($article, false);
459: if ($obj->loaded) {
460: $items[] = array('titlelink' => $article);
461: }
462: }
463: return $items;
464: }
465: if ($this->feedtype == 'pages' && $pages = @$this->options['titlelink']) {
466: if (!is_array($pages)) {
467: $pages = array($pages);
468: }
469: foreach ($pages as $page) {
470: $obj = new ZenpagePage($page, false);
471: if ($obj->loaded) {
472: $items[] = array('titlelink' => $page);
473: }
474: }
475: return $items;
476: }
477: return parent::getitems();
478: }
479:
480: 481: 482: 483:
484: public function printFeed() {
485: global $_zp_gallery;
486: $feeditems = $this->getitems();
487: if (is_array($feeditems)) {
488: header('Content-Type: application/xml');
489: ?>
490: <external version="1.0" >
491: <?php
492: if ($this->key) {
493: $key = md5($this->key . serialize($_SERVER));
494: query('UPDATE ' . prefix('plugin_storage') . ' SET `data`=' . db_quote($key) . ' WHERE `type`="externalFeed" AND `data`=' . db_quote($this->key));
495: ?>
496: <accesskey><?php echo $key; ?></accesskey>
497: <?php
498: }
499: ?>
500:
501: <channel>
502: <link href="<?php echo PROTOCOL; ?>://<?php echo $this->host; ?><?php echo html_encode(getRequestURI()); ?>" />
503: <language><?php echo $this->locale_xml; ?></language>
504: <?php
505: foreach ($feeditems as $feeditem) {
506:
507: switch
508: ($this->feedtype) {
509: case 'gallery':
510: $item = $this->getItemGallery($feeditem);
511: break;
512: case 'news':
513: $item = $this->getItemNews($feeditem);
514: break;
515: case 'pages':
516: $item = $this->getitemPages($feeditem, getOption('externalFeed_truncate_length'));
517: break;
518: case 'comments':
519: $item = $this->getitemComments($feeditem);
520: break;
521: default:
522: $item = $feeditem;
523: break;
524: }
525: ?>
526: <item>
527: <title><![CDATA[<?php echo $item['title']; ?>]]></title>
528: <link><?php echo PROTOCOL . '://' . $_SERVER['HTTP_HOST'] . WEBPATH . '/' . html_encode(ltrim($item['link'], '/')); ?></link>
529: <description><![CDATA[<?php echo $item['desc']; ?>]]></description>
530: <?php
531: if (!empty($item['enclosure'])) {
532: echo $item['enclosure'] . "\n";
533: }
534: if (!empty($item['category'])) {
535: ?>
536: <category><![CDATA[<?php echo $item['category']; ?>]]></category>
537: <?php
538: }
539: if (!empty($item['media_content'])) {
540: echo $item['media_content'] . "\n";
541: }
542: if (!empty($item['media_thumbnail'])) {
543: echo $item['media_thumbnail'] . "\n";
544: }
545: ?>
546: <pubDate><?php echo $item['pubdate']; ?></pubDate>
547: </item>
548: <?php
549: }
550: ?>
551: </channel>
552: </external>
553: <?php
554: }
555: }
556:
557: }
558:
559:
560: if (!OFFSET_PATH && isset($_GET['external'])) {
561: if (!$_GET['external']) {
562: $_GET['external'] = 'gallery';
563: }
564:
565: $_zp_gallery_page = 'rss.php';
566: $e = new ExternalFeed(sanitize($_GET));
567: $e->printFeed();
568: exitZP();
569: }
570: ?>