From cc4bd9a9c39ac9f05baa45fcd576221f99f27e6b Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Sat, 28 Feb 2009 16:29:24 -0500 Subject: [PATCH] Bunch of stuff - mostly add proper upload support. Adding images to a facebook gallery now works properly. - Add/fix upload support - No need to pass around params, they are instance variables - Fix some member visibility --- .../lib/Horde/Service/Facebook.php | 85 ++-------------------- .../lib/Horde/Service/Facebook/Photos.php | 5 ++ .../lib/Horde/Service/Facebook/Request.php | 53 ++++++++------ .../lib/Horde/Service/Facebook/UploadRequest.php | 75 +++++++++++++++++++ framework/Service_Facebook/package.xml | 2 + 5 files changed, 119 insertions(+), 101 deletions(-) create mode 100644 framework/Service_Facebook/lib/Horde/Service/Facebook/UploadRequest.php diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook.php b/framework/Service_Facebook/lib/Horde/Service/Facebook.php index cdfe8cbcc..d4dfb190d 100644 --- a/framework/Service_Facebook/lib/Horde/Service/Facebook.php +++ b/framework/Service_Facebook/lib/Horde/Service/Facebook.php @@ -327,96 +327,27 @@ class Horde_Service_Facebook * * @return array A dictionary representing the response. */ - public function call_upload_method($method, $params, $file, $server_addr = null) + public function call_upload_method($method, $params, $file) { - if ($this->batch_queue === null) { + if ($this->_batchRequest === null) { if (!file_exists($file)) { $code = Horde_Service_Facebook_ErrorCodes::API_EC_PARAM; $description = Horde_Service_Facebook_ErrorCodes::$api_error_descriptions[$code]; throw new Horde_Service_Facebook_Exception($description, $code); } - } - - $json = $this->post_upload_request($method, $params, $file, $server_addr); - $result = json_decode($json, true); - if (is_array($result) && isset($result['error_code'])) { - throw new Horde_Service_Facebook_Exception($result['error_msg'], $result['error_code']); } else { $code = Horde_Service_Facebook_ErrorCodes::API_EC_BATCH_METHOD_NOT_ALLOWED_IN_BATCH_MODE; $description = Horde_Service_Facebook_ErrorCodes::$api_error_descriptions[$code]; throw new Horde_Service_Facebook_Exception($description, $code); } - - return $result; - } - - private function post_upload_request($method, $params, $file, $server_addr = null) - { - // Ensure we ask for JSON - $params['format'] = 'json'; - $server_addr = $server_addr ? $server_addr : self::REST_SERVER_ADDR; - $this->finalize_params($method, $params); - $result = $this->run_multipart_http_transaction($method, $params, $file, $server_addr); - return $result; - } - - private function run_http_post_transaction($content_type, $content, $server_addr) - { - $user_agent = 'Facebook API PHP5 Client 1.1 (non-curl) ' . phpversion(); - $content_length = strlen($content); - $context = - array('http' => array('method' => 'POST', - 'user_agent' => $user_agent, - 'header' => 'Content-Type: ' . $content_type . "\r\n" . 'Content-Length: ' . $content_length, - 'content' => $content)); - $context_id = stream_context_create($context); - $sock = fopen($server_addr, 'r', false, $context_id); - $result = ''; - if ($sock) { - while (!feof($sock)) { - $result .= fgets($sock, 4096); - } - fclose($sock); + $request = new Horde_Service_Facebook_UploadRequest($this, $method, $this->_http, $file, $params); + $result = $request->run(); + $result = json_decode($result, true); + if (is_array($result) && isset($result['error_code'])) { + throw new Horde_Service_Facebook_Exception($result['error_msg'], $result['error_code']); } - return $result; - } - /** - * TODO: This will probably be replaced - * @param $method - * @param $params - * @param $file - * @param $server_addr - * @return unknown_type - */ - private function run_multipart_http_transaction($method, $params, $file, $server_addr) - { - // the format of this message is specified in RFC1867/RFC1341. - // we add twenty pseudo-random digits to the end of the boundary string. - $boundary = '--------------------------FbMuLtIpArT' . - sprintf("%010d", mt_rand()) . - sprintf("%010d", mt_rand()); - $content_type = 'multipart/form-data; boundary=' . $boundary; - // within the message, we prepend two extra hyphens. - $delimiter = '--' . $boundary; - $close_delimiter = $delimiter . '--'; - $content_lines = array(); - foreach ($params as $key => &$val) { - $content_lines[] = $delimiter; - $content_lines[] = 'Content-Disposition: form-data; name="' . $key . '"'; - $content_lines[] = ''; - $content_lines[] = $val; - } - // now add the file data - $content_lines[] = $delimiter; - $content_lines[] = 'Content-Disposition: form-data; filename="' . $file . '"'; - $content_lines[] = 'Content-Type: application/octet-stream'; - $content_lines[] = ''; - $content_lines[] = file_get_contents($file); - $content_lines[] = $close_delimiter; - $content_lines[] = ''; - $content = implode("\r\n", $content_lines); - return $this->run_http_post_transaction($content_type, $content, $server_addr); + return $result; } protected function _logDebug($message) diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook/Photos.php b/framework/Service_Facebook/lib/Horde/Service/Facebook/Photos.php index 212a5c0e7..15b06e832 100644 --- a/framework/Service_Facebook/lib/Horde/Service/Facebook/Photos.php +++ b/framework/Service_Facebook/lib/Horde/Service/Facebook/Photos.php @@ -2,6 +2,11 @@ /** * Photos methods for Horde_Service_Facebook * + * Copyright 2009 The Horde Project (http://www.horde.org) + * + * @author Michael J. Rubinsky + * @category Horde + * @package Horde_Service_Facebook */ class Horde_Service_Facebook_Photos extends Horde_Service_Facebook_Base { diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook/Request.php b/framework/Service_Facebook/lib/Horde/Service/Facebook/Request.php index edff4a2fb..a3ebfcd23 100644 --- a/framework/Service_Facebook/lib/Horde/Service/Facebook/Request.php +++ b/framework/Service_Facebook/lib/Horde/Service/Facebook/Request.php @@ -2,14 +2,19 @@ /** * Horde_Service_Facebook_Request:: encapsulate a request to the Facebook API. * + * Copyright 2009 The Horde Project (http://www.horde.org) + * + * @author Michael J. Rubinsky + * @category Horde + * @package Horde_Service_Facebook */ class Horde_Service_Facebook_Request { protected $_facebook; protected $_last_call_id = 0; protected $_http; - private $_method; - private $_params; + protected $_method; + protected $_params; public function __construct($facebook, $method, $http_client, $params = array()) { @@ -28,7 +33,7 @@ class Horde_Service_Facebook_Request */ public function &run() { - $data = $this->_postRequest($this->_method, $this->_params); + $data = $this->_postRequest(); switch ($this->_facebook->dataFormat) { case Horde_Service_Facebook::DATA_FORMAT_JSON: case Horde_Service_Facebook::DATA_FORMAT_XML: @@ -48,13 +53,13 @@ class Horde_Service_Facebook_Request return $result; } - protected function _postRequest($method, $params) + protected function _postRequest() { - $this->_finalizeParams($method, $params); + $this->_finalizeParams(); // TODO: Figure out why passing the array to ->post doesn't work - // we have to manually create the post string or we get an // invalid signature error from FB - $post_string = $this->_createPostString($params); + $post_string = $this->_createPostString($this->_params); $result = $this->_http->post(Horde_Service_Facebook::REST_SERVER_ADDR, $post_string); return $result->getBody(); } @@ -65,41 +70,41 @@ class Horde_Service_Facebook_Request * @param $params * @return unknown_type */ - protected function _finalizeParams($method, &$params) + protected function _finalizeParams() { - $this->_addStandardParams($method, $params); + $this->_addStandardParams(); // we need to do this before signing the params - $this->_convertToCsv($params); - $params['sig'] = Horde_Service_Facebook_Auth::generateSignature($params, $this->_facebook->secret); + $this->_convertToCsv(); + $this->_params['sig'] = Horde_Service_Facebook_Auth::generateSignature($this->_params, $this->_facebook->secret); } - protected function _addStandardParams($method, &$params) + protected function _addStandardParams() { // Select the correct data format. if ($this->_facebook->dataFormat == Horde_Service_Facebook::DATA_FORMAT_ARRAY) { - $params['format'] = $this->_facebook->internalFormat; + $this->_params['format'] = $this->_facebook->internalFormat; } else { - $params['format'] = $this->_facebook->dataFormat; + $this->_params['format'] = $this->_facebook->dataFormat; } - $params['method'] = $method; - $params['api_key'] = $this->_facebook->apiKey; - $params['call_id'] = microtime(true); - if ($params['call_id'] <= $this->_last_call_id) { - $params['call_id'] = $this->_last_call_id + 0.001; + $this->_params['method'] = $this->_method; + $this->_params['api_key'] = $this->_facebook->apiKey; + $this->_params['call_id'] = microtime(true); + if ($this->_params['call_id'] <= $this->_last_call_id) { + $this->_params['call_id'] = $this->_last_call_id + 0.001; } - $this->_last_call_id = $params['call_id']; - if (!isset($params['v'])) { - $params['v'] = '1.0'; + $this->_last_call_id = $this->_params['call_id']; + if (!isset($this->_params['v'])) { + $this->_params['v'] = '1.0'; } if (!empty($this->_facebook->useSslResources)) { - $params['return_ssl_resources'] = true; + $this->_params['return_ssl_resources'] = true; } } - protected function _convertToCsv(&$params) + protected function _convertToCsv() { - foreach ($params as $key => &$val) { + foreach ($this->_params as $key => &$val) { if (is_array($val)) { $val = implode(',', $val); } diff --git a/framework/Service_Facebook/lib/Horde/Service/Facebook/UploadRequest.php b/framework/Service_Facebook/lib/Horde/Service/Facebook/UploadRequest.php new file mode 100644 index 000000000..087c9b645 --- /dev/null +++ b/framework/Service_Facebook/lib/Horde/Service/Facebook/UploadRequest.php @@ -0,0 +1,75 @@ + + * @category Horde + * @package Horde_Service_Facebook + */ +class Horde_Service_Facebook_UploadRequest extends Horde_Service_Facebook_Request +{ + protected $_filename; + + public function __construct($facebook, $method, $http_client, $file, $params = array()) + { + parent::__construct($facebook, $method, $http_client, $params); + $this->_filename = $file; + } + + public function run() + { + // Ensure we ask for JSON + $this->_params['format'] = 'json'; + $result = $this->_multipartHttpTransaction(); + return $result; + } + + /** + * TODO + * + * @param $method + * @param $params + * @param $file + * @param $server_addr + * @return unknown_type + */ + private function _multipartHttpTransaction() + { + // the format of this message is specified in RFC1867/RFC1341. + // we add twenty pseudo-random digits to the end of the boundary string. + $boundary = '--------------------------FbMuLtIpArT' . + sprintf("%010d", mt_rand()) . + sprintf("%010d", mt_rand()); + $content_type = 'multipart/form-data; boundary=' . $boundary; + // within the message, we prepend two extra hyphens. + $delimiter = '--' . $boundary; + $close_delimiter = $delimiter . '--'; + $content_lines = array(); + $this->_finalizeParams(); + foreach ($this->_params as $key => &$val) { + $content_lines[] = $delimiter; + $content_lines[] = 'Content-Disposition: form-data; name="' . $key . '"'; + $content_lines[] = ''; + $content_lines[] = $val; + } + + // now add the file data + $content_lines[] = $delimiter; + $content_lines[] = 'Content-Disposition: form-data; filename="' . $this->_filename . '"'; + $content_lines[] = 'Content-Type: application/octet-stream'; + $content_lines[] = ''; + $content_lines[] = file_get_contents($this->_filename); + $content_lines[] = $close_delimiter; + $content_lines[] = ''; + $content = implode("\r\n", $content_lines); + $result = $this->_http->request('POST', + Horde_Service_Facebook::REST_SERVER_ADDR, + $content, + array('Content-Type' => $content_type, + 'Content-Length' => strlen($content))); + return $result->getBody(); + } + +} \ No newline at end of file diff --git a/framework/Service_Facebook/package.xml b/framework/Service_Facebook/package.xml index 53717e262..ba5c3aa32 100644 --- a/framework/Service_Facebook/package.xml +++ b/framework/Service_Facebook/package.xml @@ -39,6 +39,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + @@ -78,6 +79,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + -- 2.11.0