Наступил Новый Год, пора сделать подарки своим пользователям, вот и мы решили внести некоторые полезные изменения в, пока единственный (только) в официальном репозитории Moodle, плагин авторизации через OAuth социальных сетей (Facebook, Google, Yahoo, Твиттер, ВКонтакте, Яндекс, Mail.ru). Изменения не такие уж грандиозные, но, надеемся, полезные для пользователей. Итак, кратко о том что мы сделали:
- Добавили автоматическую подгрузку аватара из социального профиля
- Исправили «баг» с повторной авторизацией через Твиттер
- Обновились до версии 5.27 API ВКонтакте
А теперь подробнее
Добавлена новая опция — выгрузка/получение аватара (фотографии) из профиля. Администратор Moodle/плагина LenAuth может выбрать эту опцию чтобы из профиля пользователя автоматически подгружался его аватар. Работает эта опция достаточно просто: в настройках LenAuth выберите опцию (галочку) «Подгружать аватар», теперь пользователи, имеющие в своих социальных профилях аватар и не имеющие до сих пор аватар в своей учетной записи Moodle, заходя/авторизируясь в Moodle через LenAuth будут загружать свои аватарки в учетную запись автоматически. Важное замечание: при первоначальной подгрузке фото из профиля вверху справа будет аватарка по-умолчанию, т.е. пользователь сможет ее увидеть (при только что автоматически загруженной аватарке) только зайдя в редактирование профиля или при следующей авторизации. Если у пользователя в его профиле социальной сети, через которую он авторизуется, нет аватарки или уже есть аватарка в профиле Moodle, то никакой подгрузки не будет.
Загрузка аватара с точки зрения программирования/разработки плагина
- Проверить наличие опции «Подгружать аватар»
- Если опция отмечена — получить ссылку на изображение из ответа OAuth
- Проверить наличие аватарки в ответе OAuth и наличие текущей аватарки в профиле Moodle
- Если в ответе подтверждается наличие изображения, а в профиле Moodle ее нет, то загружаем
Алгоритм загрузки такой:
- Facebook: после получения внутреннего id пользователя его аватар доступен по ссылке:
http://graph.facebook.com/id_пользователя/picture
- Google: ссылка на изображение содержится в ответе вебсервиса, если преобразовать ответ в ассоциативный массив
$array
, то получить ссылку можно таким образом:$array['image']['url']
- Yahoo: также как и у Google ссылка содержится в ответе:
$array['query']['results']['profile']['image']['imageUrl']
- Twitter: тут, как обычно, Твиттер имеет немного запутанный алгоритм получения ссылки на изображение, давайте его рассмотрим. В ответе OAuth твиттера приходит username или
$array['screen_name']
, и чтобы получить изображение, необходимо подставить этот screen_name в URL вида:https://twitter.com/screen_name/profile_image?size=original
. Но тут Twitter показывает картинку отдавая вместе с ним headerimage/jpeg
, что недостаточно, так как нужна именно ссылка. Поэтому мы использовали функцию phpget_headers
, которая возвращает всю внутреннюю информацию о контенте на странице изображения. Итак код://$array['screen_name'] - username Твиттера, полученный в ответе OAuth $image_url_pre = 'https://twitter.com/' . $array['screen_name'] . '/profile_image?size=original'; $image_header = get_headers( $image_url_pre, 1 ); //получаем всю информацию о контенте по URL $image_url_pre $image_url = $image_header['location']; //ключ location содержит ту самую ссылку на изображение
- ВКонтакте: у OAuth VK тоже довольно необычное получение дополнительных данных: после получения внутреннего id профиля, нужно сделать дополнительный запрос к URL вида
http://api.vk.com/method/users.get?user_ids=id_профиля&fields=параметры_fields
. Список параметров из метода users.get можно посмотреть тут. Ответ данного запроса представлен в JSON-формате. Лучше посмотрите все вместе://$curl - объект Moodle-класса curl, $id - id пользователя из ответа, photo_200 - ключ для фотографии среднего формата $additional_fields_pre = $curl->get( 'http://api.vk.com/method/users.get?user_ids=' . $id . '&fields=photo_200' ); //GET-запрос к URL $additional_fields = json_decode( $additional_fields_pre, true ); //преобразуем json в ассоциативный массив $image_url = $additional_fields['response'][0]['photo_200']; //ссылка на изображение
- Яндекс: вебсервис возвращает лишь id аватарки, а ссылку на нее достаточно просто получить подставив этот id в URL вида:
https://avatars.yandex.net/get-yapic/id_аватара/размер_аватара
. Подробнее о получении аватарок в Яндексе. Из всех доступных размеров мы выбрали размер 200×200 с ключомislands-200
. - Mail.ru: тут в ответе OAuth в массиве приходит ключ
pic_big
с URL изображения, в итоге:$array[0]['pic_big']
.
Итак, у OAuth каждой соцсети своя методика получения изображения пользователя:
Отлично, мы получили ссылку на конкретную аватарку по нужному нам провайдеру, теперь надо превратить ее в изображение профиля пользователя в Moodle. Этим занимается специальная функция из GDlib пакета Moodle (lib/gdlib.php
), называется она process_new_icon($context, $component, $filearea, $itemid, $originalfile)
, в нашем случае $context
это контекст пользователя context_user::instance( $newuser->id, MUST_EXIST )
, $component
это user
, $filearea
это icon
, $itemid = 0
, а вот $originalfile
— это как раз файл, который нужно обработать, но у нас не файл, а лишь ссылка на изображение, функция имеет проверку на существование файла, но раз нет файла — давайте его создадим. Для этого воспользуемся php-функцией copy
, эта функция копирует содержимое по передаваемой ссылке в файл. Нам необходимо скопировать изображение (по ссылке) в какой-то временный файл и его передать функции process_new_icon
в качестве параметра $originalfile
. Но куда копировать временный файл? У объекта конфигурации Moodle $CFG
есть параметр tempdir
— это путь к папке с временными файлами, туда и загрузим. ВАЖНО! Эта папка не создается при установке Moodle, поэтому необходимо проверять ее существование и, в случае отсутствия, создавать ее с помощью php-функции mkdir
. Придумав название временного файла и определив его путь во временную папку Moodle скопируем туда изображение и передадим в качество параметра $originalfile
функции process_new_icon
которая вернет нам id загруженного файла (все аттачменты и информация о них хранится в таблице БД mdl_files
) из базы данных, этот id нужно указать в запись в БД нужного пользователя в поле picture
таблицы mdl_user
и все. Код:
//создаем уникальное имя для временного файла $tempfilename = substr( microtime(), 0, 10 ) . '.tmp'; //указываем путь к временной папке для копирования в нее временного файла $templfolder = $CFG->tempdir . '/filestorage'; //проверка на существование временной папки, в случае отсутствия - создаем if ( !file_exists( $templfolder ) ) { mkdir( $templfolder, $CFG->directorypermissions ); } //указываем права на запись в эту папку @chmod( $templfolder, 0777 ); //полный путь к временному файлу $tempfile = $templfolder . '/' . $tempfilename; //копируем if ( copy( $image_url, $tempfile ) ) { //подключаем GDlib-библиотеку Moodle require_once( $CFG->libdir . '/gdlib.php' ); //загружаем аватар из временного файла $usericonid = process_new_icon( context_user::instance( $newuser->id, MUST_EXIST ), 'user', 'icon', 0, $tempfile ); //указываем id иконки для необходимого пользователя с id $newuser->id (в нашем случае) if ( $usericonid ) { $DB->set_field( 'user', 'picture', $usericonid, array( 'id' => $newuser->id ) ); } //удаляем временный файл unset( $tempfile ); } //возвращаем необходимые права папке для временных файлов @chmod( $templfolder, $CFG->directorypermissions );
А теперь о неприятном, мы сами обнаружили у нас «баг» в вычислении id профилей из OAuth и быстро исправили. ВКонтакте стал довольно часто обновлять свой API, мы также обновили эту версию.