-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issue256 - rss/atom feeds, WIP #771
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
<?php | ||
/** | ||
* Activity controller for feed endpoints | ||
* | ||
* @author Michel Valdrighi <[email protected]> | ||
*/ | ||
class FeedActivityController extends ApiActivityController | ||
{ | ||
/** | ||
* Call the parent constructor | ||
* | ||
* @return void | ||
*/ | ||
public function __construct() | ||
{ | ||
parent::__construct(); | ||
$this->activity = new Activity; | ||
|
||
$this->theme = getTheme(); | ||
$this->template->utility = $this->utility; | ||
$this->template->url = $this->url; | ||
} | ||
|
||
/** | ||
* Retrieve a list of the user's photo uploads from the remote datasource. | ||
* The $filterOpts are values from the path but can also be in _GET. | ||
* /photos/page-2/tags-favorites.json is identical to /photos.json?page=2&tags=favorites | ||
* | ||
* @param string $filterOpts Options on how to filter the list of photos. | ||
* @return string Standard JSON envelope | ||
*/ | ||
public function list_($filterOpts = null) | ||
{ | ||
$args = func_get_args(); | ||
$feed_format = $args[1]; | ||
if ($feed_format === null) | ||
$feed_format = 'atom'; | ||
|
||
// parse parameters in request | ||
extract($this->parseFilters($filterOpts)); | ||
$activities = $this->activity->list_($filters, $pageSize); | ||
if(isset($_GET['groupBy'])) | ||
$activities = $this->groupActivities($activities, $_GET['groupBy']); | ||
else | ||
$activities = $this->groupActivities($activities, 'hour'); | ||
|
||
if($activities !== false) { | ||
$last_activity = current($activities); | ||
$last_activity_item = current($last_activity); | ||
$last_updated_timestamp = $last_activity_item['data']['dateUploaded']; | ||
} else { | ||
$last_updated_timestamp = time(); | ||
} | ||
|
||
if($this->config->user) | ||
{ | ||
$author_email = $this->config->user->email; | ||
if ($this->config->user->name) | ||
$author_name = ''; | ||
else | ||
$author_name = $this->utility->getEmailHandle($author_email, false); | ||
} | ||
else | ||
{ | ||
$author_email = ''; | ||
$author_name = ''; | ||
} | ||
|
||
if($this->config->site->baseUrl) | ||
$site_base_url = $this->config->site->baseUrl; | ||
else | ||
$site_base_url = ''; | ||
|
||
if($feed_format == 'atom') | ||
{ | ||
$data = array( | ||
'title' => getConfig()->get('titles')->default, | ||
'link' => $site_base_url . '/activities/list.atom', | ||
'updated' => gmdate('Y-m-d\TH:i:s\Z', $last_updated_timestamp), | ||
'author' => array( | ||
'name' => $author_name, | ||
'email' => $author_email | ||
), | ||
'base_url' => $site_base_url, | ||
'id' => $site_base_url . '/' | ||
); | ||
|
||
header('Content-type: application/atom+xml'); | ||
|
||
$this->theme->display($this->utility->getTemplate('feed-atom.php'), array('items' => $this->prepareFeedItems($activities, $site_base_url), 'data' => $data)); | ||
} | ||
|
||
exit(0); | ||
} | ||
|
||
protected function prepareFeedItems($activities, $site_base_url) | ||
{ | ||
$feed_items = array(); | ||
$photoSize = $this->config->feed->photoSize; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a config option that must remain '100x100xCR' for the time being, as the Activity API doesn't return bigger sizes except "base" and "original". |
||
if ($photoSize === null) | ||
$photoSize = '100x100xCR'; | ||
|
||
if (count($activities) > 0) { | ||
foreach ($activities as $activity_title => $activity) { | ||
$feed_item = array(); | ||
|
||
$titles = array(); | ||
$photos = array(); | ||
$tags = array(); | ||
|
||
foreach ($activity as $item) { | ||
// TODO: support other activity types in the future? -- mv | ||
if ($item['type'] == 'photo-upload') { | ||
$data = $item['data']; | ||
|
||
if (isset($data['title'])) | ||
$titles[] = $data['title']; | ||
else | ||
$titles[] = $data['filenameOriginal']; | ||
|
||
$photo = array( | ||
'url' => $site_base_url . $this->url->photoView($data['id'], null, false), | ||
'src' => $data[sprintf('path%s', $photoSize)], | ||
'title' => $data['title'], | ||
'description' => $data['description'], | ||
); | ||
|
||
$photos[] = $photo; | ||
|
||
// add tags | ||
$tags = array_merge($tags, $data['tags']); | ||
|
||
// use the first photo's url and upload date for the item | ||
if (!isset($feed_item['link'])) { | ||
$feed_item['link'] = $photo['url']; | ||
$feed_item['updated'] = $data['dateUploaded']; | ||
$feed_item['license'] = $data['license']; | ||
} | ||
} | ||
} | ||
|
||
$feed_item['title'] = implode(', ', $titles); | ||
$feed_item['photos'] = $photos; | ||
$feed_item['tags'] = array_unique($tags); | ||
|
||
$feed_items[] = $feed_item; | ||
} | ||
} | ||
|
||
return $feed_items; | ||
} | ||
|
||
protected function parseFilters($filterOpts) | ||
{ | ||
$pageSize = $this->config->feed->pageSize; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I put a possibility to use a config option here, but it doesn't seem to have any effect, so I may have misunderstood something with the Activity API. |
||
if ($pageSize === null) | ||
$pageSize = 20; | ||
|
||
$filters = array('sortBy' => 'dateCreated,desc', 'groupBy' => 'hour', 'type' => 'photo-upload'); | ||
if($filterOpts !== null) | ||
{ | ||
$filterOpts = (array)explode('/', $filterOpts); | ||
foreach($filterOpts as $value) | ||
{ | ||
$dashPosition = strpos($value, '-'); | ||
if(!$dashPosition) | ||
continue; | ||
|
||
$parameterKey = substr($value, 0, $dashPosition); | ||
$parameterValue = substr($value, ($dashPosition+1)); | ||
switch($parameterKey) | ||
{ | ||
case 'pageSize': | ||
$pageSize = intval($parameterValue); | ||
break; | ||
case 'type': | ||
$filters['type'] = $value; | ||
default: | ||
$filters[$parameterKey] = $parameterValue; | ||
break; | ||
} | ||
} | ||
} | ||
// merge path parameters with GET parameters. GET parameters override | ||
if(isset($_GET['pageSize']) && intval($_GET['pageSize']) == $_GET['pageSize']) | ||
$pageSize = intval($_GET['pageSize']); | ||
$filters = array_merge($filters, $_GET); | ||
|
||
// force only public items | ||
$filters['permission'] = 0; | ||
|
||
return array('filters' => $filters, 'pageSize' => $pageSize); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,6 +84,19 @@ public function photosUpload($write = true) | |
return $utilityObj->returnValue('/photos/upload', $write); | ||
} | ||
|
||
public function photosFeed($options = null, $feed_format = 'atom', $write = true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Disregard this part, it's dead code. Sorry for including it in the pull request. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't had a look yet but feel free to prune code and update the pull request if needed. |
||
{ | ||
$utilityObj = new Utility; | ||
if(empty($options)) | ||
{ | ||
return $utilityObj->returnValue(sprintf('/photos/list.%s', $feed_format), $write); | ||
} | ||
else | ||
{ | ||
return $utilityObj->returnValue(sprintf('/photos/%s/list.%s', $options, $feed_format), $write); | ||
} | ||
} | ||
|
||
public function tagsView($write = true) | ||
{ | ||
$utilityObj = new Utility; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
/* | ||
* Activity endpoints | ||
* All activity endpoints follow the same convention. | ||
* Everything in []'s are optional | ||
* /activit(y|ies)/{action}.json | ||
*/ | ||
$routeObj->get('/activities/?(.+)?/list.(atom|rss)', array('FeedActivityController', 'list_'), EpiApi::external); // retrieve activities (/activities/list.atom) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php echo '<'; ?>?xml version="1.0" encoding="utf-8"?> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case it looks weird: that's to avoid PHP short-tags problems. (There may be a prettier solution.) |
||
<feed xmlns="http://www.w3.org/2005/Atom"> | ||
<title type="text"><?php echo $data['title']; ?></title> | ||
<link rel="self" href="<?php echo $data['link']; ?>"/> | ||
<updated><?php echo $data['updated']; ?></updated> | ||
<author> | ||
<name><?php $this->utility->safe($data['author']['name']); ?></name> | ||
<email><?php $this->utility->safe($data['author']['email']); ?></email> | ||
</author> | ||
<id><?php echo $data['id']; ?></id> | ||
<generator uri="http://theopenphotoproject.org"> | ||
The OpenPhoto Project | ||
</generator> | ||
<?php if($this->config->keywords->default) { ?> | ||
<?php $keywords = explode(',', $this->config->keywords->default); ?> | ||
<?php foreach($keywords as $keyword) { ?> | ||
<category term="<?php $this->utility->safe(trim($keyword)); ?>"/> | ||
<?php } ?> | ||
<?php } ?> | ||
|
||
<?php foreach($items as $item) { ?> | ||
<entry> | ||
<title><?php $this->utility->safe($item['title']); ?></title> | ||
<link href="<?php echo $item['link']; ?>"/> | ||
<id><?php echo $item['link']; ?></id> | ||
<updated><?php echo gmdate('Y-m-d\TH:i:s\Z', $item['updated']); ?></updated> | ||
<summary type="html"><![CDATA[ | ||
<?php foreach ($item['photos'] as $photo) { ?> | ||
<div> | ||
<a href="<?php echo $photo['url']; ?>"><img src="<?php echo $photo['src'] ?>" alt="<?php $this->utility->safe($photo['title']); ?>" /></a> | ||
<?php if ($photo['description'] != '') { ?> | ||
<p><?php $this->utility->safe($photo['description']); ?></p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps add some markup for the title if there is one? |
||
<?php } ?> | ||
</div> | ||
<?php } ?> | ||
]]></summary> | ||
<rights type="html"><?php $this->utility->licenseName($item['license']); ?></rights> | ||
<?php if(count($item['tags']) > 0) { ?> | ||
<?php foreach($item['tags'] as $tag) { ?> | ||
<category term="<?php $this->utility->safe($tag); ?>" scheme="<?php echo $data['base_url']; $this->url->photosView("tags-{$tag}"); ?>"/> | ||
<?php } ?> | ||
<?php } ?> | ||
</entry> | ||
<?php } ?> | ||
|
||
</feed> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Must use the proper way to use inheritable template files. Here this searches for the 'feed-atom.php' file in the current theme directory, so 1) it will break once you change themes… 2) it doesn't have anything to do with themes anyway unless one wants to customize the feed's markup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should store the
feed-atom.php
template assrc/templates/feed/atom.php
and share it across themes.