MDL-59645 repository_flickr: Make the Flickr repository work again
The patch makes the Flickr repository use the new oauth1 based client. Beside that, other improvements include: * Does not attempt to guess the photo URL any more. Instead uses url_sq and url_o extras of the flickr.photos.search call. * The photos.search does not return the information about the photo size so we set it to null (previously was returned as 'unknown' which made it be displayed as zero). * Does not perform additional API request to obtain the manage URL, uses https://www.flickr.com/photos/organize instead.
This commit is contained in:
+138
-114
@@ -23,7 +23,7 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
require_once($CFG->dirroot . '/repository/lib.php');
|
||||
require_once($CFG->libdir.'/flickrlib.php');
|
||||
require_once($CFG->libdir.'/flickrclient.php');
|
||||
|
||||
/**
|
||||
* This plugin is used to access user's private flickr repository
|
||||
@@ -34,7 +34,22 @@ require_once($CFG->libdir.'/flickrlib.php');
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class repository_flickr extends repository {
|
||||
private $flickr;
|
||||
|
||||
/** @var flickr_client */
|
||||
protected $flickr;
|
||||
|
||||
/** @var string oauth consumer key */
|
||||
protected $api_key;
|
||||
|
||||
/** @var string oauth consumer secret */
|
||||
protected $secret;
|
||||
|
||||
/** @var string oauth access token */
|
||||
protected $accesstoken;
|
||||
|
||||
/** @var string oauth access token secret */
|
||||
protected $accesstokensecret;
|
||||
|
||||
public $photos;
|
||||
|
||||
/**
|
||||
@@ -53,44 +68,45 @@ class repository_flickr extends repository {
|
||||
$options['page'] = optional_param('p', 1, PARAM_INT);
|
||||
parent::__construct($repositoryid, $context, $options);
|
||||
|
||||
$this->setting = 'flickr_';
|
||||
|
||||
$this->api_key = $this->get_option('api_key');
|
||||
$this->secret = $this->get_option('secret');
|
||||
|
||||
$this->token = get_user_preferences($this->setting, '');
|
||||
$this->nsid = get_user_preferences($this->setting.'_nsid', '');
|
||||
|
||||
$this->flickr = new phpFlickr($this->api_key, $this->secret, $this->token);
|
||||
|
||||
$frob = optional_param('frob', '', PARAM_RAW);
|
||||
if (empty($this->token) && !empty($frob)) {
|
||||
$auth_info = $this->flickr->auth_getToken($frob);
|
||||
$this->token = $auth_info['token'];
|
||||
$this->nsid = $auth_info['user']['nsid'];
|
||||
set_user_preference($this->setting, $auth_info['token']);
|
||||
set_user_preference($this->setting.'_nsid', $auth_info['user']['nsid']);
|
||||
}
|
||||
$this->accesstoken = get_user_preferences('repository_flickr_access_token');
|
||||
$this->accesstokensecret = get_user_preferences('repository_flickr_access_token_secret');
|
||||
|
||||
$callbackurl = new moodle_url('/repository/repository_callback.php', ['repo_id' => $repositoryid]);
|
||||
$this->flickr = new flickr_client($this->api_key, $this->secret, $callbackurl);
|
||||
$this->flickr->set_access_token($this->accesstoken, $this->accesstokensecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has authorized us to make requests to Flickr API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function check_login() {
|
||||
return !empty($this->token);
|
||||
|
||||
if (empty($this->accesstoken) || empty($this->accesstokensecret)) {
|
||||
return false;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the stored access token and related user data.
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function logout() {
|
||||
set_user_preference($this->setting, '');
|
||||
set_user_preference($this->setting.'_nsid', '');
|
||||
$this->token = '';
|
||||
$this->nsid = '';
|
||||
|
||||
set_user_preference('repository_flickr_access_token', null);
|
||||
set_user_preference('repository_flickr_access_token_secret', null);
|
||||
|
||||
$this->accesstoken = null;
|
||||
$this->accesstokensecret = null;
|
||||
|
||||
return $this->print_login();
|
||||
}
|
||||
|
||||
@@ -143,77 +159,104 @@ class repository_flickr extends repository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the interface to log in to Flickr..
|
||||
*
|
||||
* @return null
|
||||
* @return string|array
|
||||
*/
|
||||
public function print_login() {
|
||||
|
||||
$reqtoken = $this->flickr->request_token();
|
||||
$this->flickr->set_request_token_secret(['caller' => 'repository_flickr'], $reqtoken['oauth_token_secret']);
|
||||
|
||||
// Even when the Flick auth docs states the "perms" argument is
|
||||
// optional, it does not work without it.
|
||||
$authurl = new moodle_url($reqtoken['authorize_url'], array('perms' => 'read'));
|
||||
|
||||
if ($this->options['ajax']) {
|
||||
$ret = array();
|
||||
$popup_btn = new stdClass();
|
||||
$popup_btn->type = 'popup';
|
||||
$popup_btn->url = $this->flickr->auth();
|
||||
$ret['login'] = array($popup_btn);
|
||||
return $ret;
|
||||
return [
|
||||
'login' => [
|
||||
[
|
||||
'type' => 'popup',
|
||||
'url' => $authurl->out(false),
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
} else {
|
||||
echo '<a target="_blank" href="'.$this->flickr->auth().'">'.get_string('login', 'repository').'</a>';
|
||||
echo '<a target="_blank" href="'.$authurl->out().'">'.get_string('login', 'repository').'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts result received from phpFlickr::photo_search to Filepicker/repository format
|
||||
* Search for the user's photos at Flickr
|
||||
*
|
||||
* @param mixed $photos
|
||||
* @param string $searchtext Photos with title, description or tags containing the text will be returned
|
||||
* @param int $page Page number to load
|
||||
* @return array
|
||||
*/
|
||||
private function build_list($photos) {
|
||||
$photos_url = $this->flickr->urls_getUserPhotos($this->nsid);
|
||||
$ret = array();
|
||||
$ret['manage'] = $photos_url;
|
||||
$ret['list'] = array();
|
||||
$ret['pages'] = $photos['pages'];
|
||||
$ret['total'] = $photos['total'];
|
||||
$ret['perpage'] = $photos['perpage'];
|
||||
$ret['page'] = $photos['page'];
|
||||
if (!empty($photos['photo'])) {
|
||||
foreach ($photos['photo'] as $p) {
|
||||
if(empty($p['title'])) {
|
||||
$p['title'] = get_string('notitle', 'repository_flickr');
|
||||
public function search($searchtext, $page = 0) {
|
||||
|
||||
$response = $this->flickr->call('photos.search', [
|
||||
'user_id' => 'me',
|
||||
'per_page' => 24,
|
||||
'extras' => 'original_format,url_sq,url_o,date_upload,owner_name',
|
||||
'page' => $page,
|
||||
'text' => $searchtext,
|
||||
]);
|
||||
|
||||
if ($response === false) {
|
||||
$this->logout();
|
||||
return [];
|
||||
}
|
||||
|
||||
// Convert the response to the format expected by the filepicker.
|
||||
|
||||
$ret = [
|
||||
'manage' => 'https://www.flickr.com/photos/organize',
|
||||
'list' => [],
|
||||
'pages' => $response->photos->pages,
|
||||
'total' => $response->photos->total,
|
||||
'perpage' => $response->photos->perpage,
|
||||
'page' => $response->photos->page,
|
||||
];
|
||||
|
||||
if (!empty($response->photos->photo)) {
|
||||
foreach ($response->photos->photo as $p) {
|
||||
if (empty($p->title)) {
|
||||
$p->title = get_string('notitle', 'repository_flickr');
|
||||
}
|
||||
if (isset($p['originalformat'])) {
|
||||
$format = $p['originalformat'];
|
||||
|
||||
if (isset($p->originalformat)) {
|
||||
$format = $p->originalformat;
|
||||
} else {
|
||||
$format = 'jpg';
|
||||
}
|
||||
$format = '.'.$format;
|
||||
// append extensions to the files
|
||||
if (substr($p['title'], strlen($p['title'])-strlen($format)) != $format) {
|
||||
$p['title'] .= $format;
|
||||
|
||||
// Append extension to the file name.
|
||||
if (substr($p->title, strlen($p->title) - strlen($format)) != $format) {
|
||||
$p->title .= $format;
|
||||
}
|
||||
$ret['list'][] = array('title'=>$p['title'],'source'=>$p['id'],
|
||||
'id'=>$p['id'],'thumbnail'=>$this->flickr->buildPhotoURL($p, 'Square'),
|
||||
'thumbnail_width'=>75, 'thumbnail_height'=>75,
|
||||
'date'=>'', 'size'=>'unknown', 'url'=>$photos_url.$p['id']);
|
||||
|
||||
$ret['list'][] = [
|
||||
'title' => $p->title,
|
||||
'source' => $p->id,
|
||||
'id' => $p->id,
|
||||
'thumbnail' => $p->url_sq,
|
||||
'thumbnail_width' => $p->width_sq,
|
||||
'thumbnail_height' => $p->height_sq,
|
||||
'date' => $p->dateupload,
|
||||
'url' => $p->url_o,
|
||||
'author' => $p->ownername,
|
||||
'size' => null,
|
||||
'license' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $search_text
|
||||
* @param int $page
|
||||
* @return array
|
||||
*/
|
||||
public function search($search_text, $page = 0) {
|
||||
$photos = $this->flickr->photos_search(array(
|
||||
'user_id'=>$this->nsid,
|
||||
'per_page'=>24,
|
||||
'extras'=>'original_format',
|
||||
'page'=>$page,
|
||||
'text'=>$search_text
|
||||
));
|
||||
$ret = $this->build_list($photos);
|
||||
$ret['list'] = array_filter($ret['list'], array($this, 'filter')); // TODO this breaks pagination
|
||||
// Filter file listing to display specific types only.
|
||||
$ret['list'] = array_filter($ret['list'], array($this, 'filter'));
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@@ -227,45 +270,8 @@ class repository_flickr extends repository {
|
||||
return $this->search('', $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return photo url by given photo id
|
||||
* @param string $photoid
|
||||
* @return string
|
||||
*/
|
||||
private function build_photo_url($photoid) {
|
||||
$bestsize = $this->get_best_size($photoid);
|
||||
if (!isset($bestsize['source'])) {
|
||||
throw new repository_exception('cannotdownload', 'repository');
|
||||
}
|
||||
return $bestsize['source'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the best size for a photo
|
||||
*
|
||||
* @param string $photoid the photo identifier
|
||||
* @return array of information provided by the API
|
||||
*/
|
||||
protected function get_best_size($photoid) {
|
||||
if (!isset(self::$sizes[$photoid])) {
|
||||
// Sizes are returned from smallest to greatest.
|
||||
self::$sizes[$photoid] = $this->flickr->photos_getSizes($photoid);
|
||||
}
|
||||
$sizes = self::$sizes[$photoid];
|
||||
$bestsize = array();
|
||||
if (is_array($sizes)) {
|
||||
while ($bestsize = array_pop($sizes)) {
|
||||
// Make sure the source is set. Exit the loop if found.
|
||||
if (isset($bestsize['source'])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $bestsize;
|
||||
}
|
||||
|
||||
public function get_link($photoid) {
|
||||
return $this->build_photo_url($photoid);
|
||||
return $this->flickr->get_photo_url($photoid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,8 +281,7 @@ class repository_flickr extends repository {
|
||||
* @return string
|
||||
*/
|
||||
public function get_file($photoid, $file = '') {
|
||||
$url = $this->build_photo_url($photoid);
|
||||
return parent::get_file($url, $file);
|
||||
return parent::get_file($this->flickr->get_photo_url($photoid), $file);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,6 +349,25 @@ class repository_flickr extends repository {
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_file_source_info($photoid) {
|
||||
return $this->build_photo_url($photoid);
|
||||
return $this->flickr->get_photo_url($photoid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the oauth authorize callback
|
||||
*
|
||||
* This is to exchange the approved request token for an access token.
|
||||
*/
|
||||
public function callback() {
|
||||
|
||||
$token = required_param('oauth_token', PARAM_RAW);
|
||||
$verifier = required_param('oauth_verifier', PARAM_RAW);
|
||||
$secret = $this->flickr->get_request_token_secret(['caller' => 'repository_flickr']);
|
||||
|
||||
// Exchange the request token for the access token.
|
||||
$accesstoken = $this->flickr->get_access_token($token, $secret, $verifier);
|
||||
|
||||
// Store the access token and the access token secret in the user preferences.
|
||||
set_user_preference('repository_flickr_access_token', $accesstoken['oauth_token']);
|
||||
set_user_preference('repository_flickr_access_token_secret', $accesstoken['oauth_token_secret']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user