MDL-37541 Wikimedia returns more information about images
[moodle.git] / repository / wikimedia / wikimedia.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * wikimedia class
20  * class for communication with Wikimedia Commons API
21  *
22  * @author Dongsheng Cai <dongsheng@moodle.com>, Raul Kern <raunator@gmail.com>
23  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
24  */
26 define('WIKIMEDIA_THUMBS_PER_PAGE', 24);
27 define('WIKIMEDIA_FILE_NS', 6);
28 define('WIKIMEDIA_IMAGE_SIDE_LENGTH', 1024);
30 class wikimedia {
31     private $_conn  = null;
32     private $_param = array();
34     public function __construct($url = '') {
35         if (empty($url)) {
36             $this->api = 'http://commons.wikimedia.org/w/api.php';
37         } else {
38             $this->api = $url;
39         }
40         $this->_param['format'] = 'php';
41         $this->_param['redirects'] = true;
42         $this->_conn = new curl(array('cache'=>true, 'debug'=>false));
43     }
44     public function login($user, $pass) {
45         $this->_param['action']   = 'login';
46         $this->_param['lgname']   = $user;
47         $this->_param['lgpassword'] = $pass;
48         $content = $this->_conn->post($this->api, $this->_param);
49         $result = unserialize($content);
50         if (!empty($result['result']['sessionid'])) {
51             $this->userid = $result['result']['lguserid'];
52             $this->username = $result['result']['lgusername'];
53             $this->token = $result['result']['lgtoken'];
54             return true;
55         } else {
56             return false;
57         }
58     }
59     public function logout() {
60         $this->_param['action']   = 'logout';
61         $content = $this->_conn->post($this->api, $this->_param);
62         return;
63     }
64     public function get_image_url($titles) {
65         $image_urls = array();
66         $this->_param['action'] = 'query';
67         if (is_array($titles)) {
68             foreach ($titles as $title) {
69                 $this->_param['titles'] .= ('|'.urldecode($title));
70             }
71         } else {
72             $this->_param['titles'] = urldecode($title);
73         }
74         $this->_param['prop']   = 'imageinfo';
75         $this->_param['iiprop'] = 'url';
76         $content = $this->_conn->post($this->api, $this->_param);
77         $result = unserialize($content);
78         foreach ($result['query']['pages'] as $page) {
79             if (!empty($page['imageinfo'][0]['url'])) {
80                 $image_urls[] = $page['imageinfo'][0]['url'];
81             }
82         }
83         return $image_urls;
84     }
85     public function get_images_by_page($title) {
86         $image_urls = array();
87         $this->_param['action'] = 'query';
88         $this->_param['generator'] = 'images';
89         $this->_param['titles'] = urldecode($title);
90         $this->_param['prop']   = 'images|info|imageinfo';
91         $this->_param['iiprop'] = 'url';
92         $content = $this->_conn->post($this->api, $this->_param);
93         $result = unserialize($content);
94         if (!empty($result['query']['pages'])) {
95             foreach ($result['query']['pages'] as $page) {
96                 $image_urls[$page['title']] = $page['imageinfo'][0]['url'];
97             }
98         }
99         return $image_urls;
100     }
101     /**
102      * Generate thumbnail URL from image URL.
103      *
104      * @param string $image_url
105      * @param int $orig_width
106      * @param int $orig_height
107      * @param int $thumb_width
108      * @global object OUTPUT
109      * @return string
110      */
111     public function get_thumb_url($image_url, $orig_width, $orig_height, $thumb_width=75) {
112         global $OUTPUT;
114         if ($orig_width <= $thumb_width AND $orig_height <= $thumb_width) {
115             return $image_url;
116         } else {
117             $thumb_url = '';
118             $commons_main_dir = 'http://upload.wikimedia.org/wikipedia/commons/';
119             if ($image_url) {
120                 $short_path = str_replace($commons_main_dir, '', $image_url);
121                 $extension = strtolower(pathinfo($short_path, PATHINFO_EXTENSION));
122                 if (strcmp($extension, 'gif') == 0) {  //no thumb for gifs
123                     return $OUTPUT->pix_url(file_extension_icon('.gif', $thumb_width))->out(false);
124                 }
125                 $dir_parts = explode('/', $short_path);
126                 $file_name = end($dir_parts);
127                 if ($orig_height > $orig_width) {
128                     $thumb_width = round($thumb_width * $orig_width/$orig_height);
129                 }
130                 $thumb_url = $commons_main_dir . 'thumb/' . implode('/', $dir_parts) . '/'. $thumb_width .'px-' . $file_name;
131                 if (strcmp($extension, 'svg') == 0) {  //png thumb for svg-s
132                     $thumb_url .= '.png';
133                 }
134             }
135             return $thumb_url;
136         }
137     }
138     /**
139      * Search for images and return photos array.
140      *
141      * @param string $keyword
142      * @return array
143      */
144     public function search_images($keyword, $page = 0) {
145         global $OUTPUT;
146         $files_array = array();
147         $this->_param['action'] = 'query';
148         $this->_param['generator'] = 'search';
149         $this->_param['gsrsearch'] = $keyword;
150         $this->_param['gsrnamespace'] = WIKIMEDIA_FILE_NS;
151         $this->_param['gsrlimit'] = WIKIMEDIA_THUMBS_PER_PAGE;
152         $this->_param['gsroffset'] = $page * WIKIMEDIA_THUMBS_PER_PAGE;
153         $this->_param['prop']   = 'imageinfo';
154         $this->_param['iiprop'] = 'url|dimensions|mime|timestamp|size|user';
155         $this->_param['iiurlwidth'] = WIKIMEDIA_IMAGE_SIDE_LENGTH;
156         $this->_param['iiurlheight'] = WIKIMEDIA_IMAGE_SIDE_LENGTH;
157         //didn't work with POST
158         $content = $this->_conn->get($this->api, $this->_param);
159         $result = unserialize($content);
160         if (!empty($result['query']['pages'])) {
161             foreach ($result['query']['pages'] as $page) {
162                 $title = $page['title'];
163                 $file_type = $page['imageinfo'][0]['mime'];
164                 $image_types = array('image/jpeg', 'image/png', 'image/gif', 'image/svg+xml');
165                 if (in_array($file_type, $image_types)) {  //is image
166                     $extension = pathinfo($title, PATHINFO_EXTENSION);
167                     if (strcmp($extension, 'svg') == 0) {               //upload png version of svg-s
168                         $title .= '.png';
169                     }
170                     if ($page['imageinfo'][0]['thumbwidth'] < $page['imageinfo'][0]['width']) {
171                         $attrs = array(
172                             //upload scaled down image
173                             'source' => $page['imageinfo'][0]['thumburl'],
174                             'image_width' => $page['imageinfo'][0]['thumbwidth'],
175                             'image_height' => $page['imageinfo'][0]['thumbheight']
176                         );
177                     } else {
178                         $attrs = array(
179                             //upload full size image
180                             'source' => $page['imageinfo'][0]['url'],
181                             'image_width' => $page['imageinfo'][0]['width'],
182                             'image_height' => $page['imageinfo'][0]['height'],
183                             'size' => $page['imageinfo'][0]['size']
184                         );
185                     }
186                     $attrs += array(
187                         'thumbnail' => $this->get_thumb_url($page['imageinfo'][0]['url'], $page['imageinfo'][0]['width'], $page['imageinfo'][0]['height'], 120),
188                         'icon' => $this->get_thumb_url($page['imageinfo'][0]['url'], $page['imageinfo'][0]['width'], $page['imageinfo'][0]['height'], 24),
189                         'author' => $page['imageinfo'][0]['user'],
190                         'datemodified' => strtotime($page['imageinfo'][0]['timestamp']),
191                         );
192                 } else {  // other file types
193                     $attrs = array(
194                         'thumbnail' => $OUTPUT->pix_url(file_extension_icon(substr($title, 5), 120))->out(false),
195                         'source' => $page['imageinfo'][0]['url']);
196                 }
197                 $files_array[] = array(
198                     'title'=>substr($title, 5),         //chop off 'File:'
199                     'thumbnail_width'=>120,
200                     'thumbnail_height'=>120,
201                     'license' => 'cc-sa',
202                     // the accessible url of the file
203                     'url'=>$page['imageinfo'][0]['descriptionurl']
204                 ) + $attrs;
205             }
206         }
207         return $files_array;
208     }