diff --git a/plugins/YammerImport/sn_yammerclient.php b/plugins/YammerImport/sn_yammerclient.php index 21caa7b7ca..f7382abae1 100644 --- a/plugins/YammerImport/sn_yammerclient.php +++ b/plugins/YammerImport/sn_yammerclient.php @@ -38,25 +38,34 @@ class SN_YammerClient } /** - * Make an HTTP hit with OAuth headers and return the response body on success. + * Make an HTTP GET request with OAuth headers and return an HTTPResponse + * with the returned body and codes. * - * @param string $path URL chunk for the API method - * @param array $params - * @return array + * @param string $url + * @return HTTPResponse * - * @throws Exception for HTTP error + * @throws Exception on low-level network error */ - protected function fetch($path, $params=array()) + protected function httpGet($url) { - $url = $this->apiBase . '/' . $path; - if ($params) { - $url .= '?' . http_build_query($params, null, '&'); - } $headers = array('Authorization: ' . $this->authHeader()); $client = HTTPClient::start(); - $response = $client->get($url, $headers); + return $client->get($url, $headers); + } + /** + * Make an HTTP GET request with OAuth headers and return the response body + * on success. + * + * @param string $url + * @return string + * + * @throws Exception on low-level network or HTTP error + */ + public function fetchUrl($url) + { + $response = $this->httpGet($url); if ($response->isOk()) { return $response->getBody(); } else { @@ -64,6 +73,24 @@ class SN_YammerClient } } + /** + * Make an HTTP hit with OAuth headers and return the response body on success. + * + * @param string $path URL chunk for the API method + * @param array $params + * @return string + * + * @throws Exception on low-level network or HTTP error + */ + protected function fetchApi($path, $params=array()) + { + $url = $this->apiBase . '/' . $path; + if ($params) { + $url .= '?' . http_build_query($params, null, '&'); + } + return $this->fetchUrl($url); + } + /** * Hit the main Yammer API point and decode returned JSON data. * @@ -75,7 +102,7 @@ class SN_YammerClient */ protected function api($method, $params=array()) { - $body = $this->fetch("api/v1/$method.json", $params); + $body = $this->fetchApi("api/v1/$method.json", $params); $data = json_decode($body, true); if (!$data) { throw new Exception("Invalid JSON response from Yammer API"); diff --git a/plugins/YammerImport/yamdump.php b/plugins/YammerImport/yamdump.php index 96127dd176..ef39275981 100644 --- a/plugins/YammerImport/yamdump.php +++ b/plugins/YammerImport/yamdump.php @@ -11,7 +11,7 @@ require INSTALLDIR . "/scripts/commandline.inc"; // temp stuff require 'yam-config.php'; $yam = new SN_YammerClient($consumerKey, $consumerSecret, $token, $tokenSecret); -$imp = new YammerImporter(); +$imp = new YammerImporter($yam); $data = $yam->messages(); var_dump($data); diff --git a/plugins/YammerImport/yammer-import.php b/plugins/YammerImport/yammer-import.php index d6ec975132..da99c48e90 100644 --- a/plugins/YammerImport/yammer-import.php +++ b/plugins/YammerImport/yammer-import.php @@ -11,7 +11,7 @@ require INSTALLDIR . "/scripts/commandline.inc"; // temp stuff require 'yam-config.php'; $yam = new SN_YammerClient($consumerKey, $consumerSecret, $token, $tokenSecret); -$imp = new YammerImporter(); +$imp = new YammerImporter($yam); $data = $yam->messages(); /* diff --git a/plugins/YammerImport/yammerimporter.php b/plugins/YammerImport/yammerimporter.php index 08cbbf790b..48bb5dda29 100644 --- a/plugins/YammerImport/yammerimporter.php +++ b/plugins/YammerImport/yammerimporter.php @@ -25,11 +25,16 @@ */ class YammerImporter { - + protected $client; protected $users=array(); protected $groups=array(); protected $notices=array(); + function __construct(SN_YammerClient $client) + { + $this->client = $client; + } + /** * Load or create an imported profile from Yammer data. * @@ -95,17 +100,39 @@ class YammerImporter if ($noticeId) { return Notice::staticGet('id', $noticeId); } else { - $notice = Notice::saveNew($data['profile'], - $data['content'], + $content = $data['content']; + $user = User::staticGet($data['profile']); + + // Fetch file attachments and add the URLs... + $uploads = array(); + foreach ($data['attachments'] as $url) { + try { + $upload = $this->saveAttachment($url, $user); + $content .= ' ' . $upload->shortUrl(); + $uploads[] = $upload; + } catch (Exception $e) { + common_log(LOG_ERROR, "Error importing Yammer attachment: " . $e->getMessage()); + } + } + + // Here's the meat! Actually save the dang ol' notice. + $notice = Notice::saveNew($user->id, + $content, $data['source'], $data['options']); + + // Save "likes" as favorites... foreach ($data['faves'] as $nickname) { $user = User::staticGet('nickname', $nickname); if ($user) { Fave::addNew($user->getProfile(), $notice); } } - // @fixme attachments? + + // And finally attach the upload records... + foreach ($uploads as $upload) { + $upload->attachToNotice($notice); + } $this->recordImportedNotice($data['orig_id'], $notice->id); return $notice; } @@ -219,8 +246,14 @@ class YammerImporter $faves[] = $liker['permalink']; } - // Parse/save rendered text? - // @todo attachments? + $attachments = array(); + foreach ($item['attachments'] as $attach) { + if ($attach['type'] == 'image') { + $attachments[] = $attach['image']['url']; + } else { + common_log(LOG_WARNING, "Unrecognized Yammer attachment type: " . $attach['type']); + } + } return array('orig_id' => $origId, 'orig_url' => $origUrl, @@ -228,7 +261,8 @@ class YammerImporter 'content' => $content, 'source' => $source, 'options' => $options, - 'faves' => $faves); + 'faves' => $faves, + 'attachments' => $attachments); } private function findImportedUser($origId) @@ -326,4 +360,34 @@ class YammerImporter $dest->setOriginal($filename); } + + /** + * Fetch an attachment from Yammer and save it into our system. + * Unlike avatars, the attachment URLs are guarded by authentication, + * so we need to run the HTTP hit through our OAuth API client. + * + * @param string $url + * @param User $user + * @return MediaFile + * + * @throws Exception on low-level network or HTTP error + */ + private function saveAttachment($url, User $user) + { + // Fetch the attachment... + // WARNING: file must fit in memory here :( + $body = $this->client->fetchUrl($url); + + // Save to a temporary file and shove it into our file-attachment space... + $temp = tmpfile(); + fwrite($temp, $body); + try { + $upload = MediaFile::fromFileHandle($temp, $user); + fclose($temp); + return $upload; + } catch (Exception $e) { + fclose($temp); + throw $e; + } + } }