diff --git a/Model/StreamPost.php b/Model/StreamPost.php new file mode 100644 index 0000000..fd3dce9 --- /dev/null +++ b/Model/StreamPost.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\FacebookBundle\Model; + +use \InvalidArgumentException; + +/** + * + * This class functions as a model for messages to be sent by the facebookPush-service to the Facebook api. + * @author Teemu Reisbacka + * + */ +class StreamPost +{ + protected $accessToken; + protected $message; + protected $attachment; + protected $linkout; + + /** + * Sets the access token used in message body. This is set automatically inside facebookPush-service. + * + * @param string $accessToken + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + } + + /** + * Sets the actual text content of the message + * + * @param string $message + */ + public function setMessage($message) + { + $this->message = $message; + } + + /** + * Adds an attachment-picture to your Facebook message. If you specify a link, the image will function as a link. + * If you set an attachment, you cannot set any additional links with setLink(...). + * + * @param string $name This is the title of the attachment (top-most descriptive text) + * @param string $caption This is the image caption (text under the title) + * @param string $uriAttachment Full uri to the image you wish to attach. This location must be visible to Facebook, they will cache the picture. + * @param string $uriLinkOut Full uri to where you sish the image to link to + * @param string $description Description field in the message. If you do not specify this, Facebook may crawl the website specified in the link/image and attach a meta-description foiund from there to the message. + */ + public function setAttachment($name, $caption, $uriAttachment, $uriLinkOut = null, $description = null) + { + $attachment = array( + 'name' => $name, + 'caption' => $caption, + 'picture' => $uriAttachment, + ); + + if (!empty($description)) { + $attachment['description'] = $description; + } + if (!empty($uriLinkOut)) { + $attachment['link'] = $uriLinkOut; + } + $this->attachment = $attachment; + } + + /** + * Shortcut for adding a link to you Facebook-message without an image. If you + * specify an attachment with setAttachment(...), that will be used instead of this link. + * + * @param string $name This is the title of the link (top-most descriptive text) + * @param string $linkOut Full uri to where you wish to link to + * @param string $caption Optional description of the link + */ + public function setLink($name, $linkOut, $caption = null) + { + $this->linkout = array( + 'name' => $name, + 'link' => $linkOut + ); + if (!empty($caption)) { + $this->linkout['caption'] = $caption; + } + } + + /** + * Formats this object into on array that can be fed to the php-api class. This function will be called automatically. + * + * @throws \InvalidArgumentException; + * @return array + */ + public function formatData() + { + if (empty($this->accessToken)) { + throw new \InvalidArgumentException('cannot format Facebook message: Facebook access token is empty'); + } + if (empty($this->message)) { + throw new \InvalidArgumentException('cannot format Facebook message: Message is empty, nothing to send'); + } + $streamPost = array( + 'access_token' => $this->accessToken, + 'message' => $this->message + ); + if (!empty($this->linkout)) { + $streamPost = array_merge($streamPost, $this->linkout); + } + if (!empty($this->attachment)) { + $streamPost = array_merge($streamPost, $this->attachment); + } + + return $streamPost; + } +} \ No newline at end of file diff --git a/Resources/config/facebook.xml b/Resources/config/facebook.xml index 983aaf9..53adce3 100644 --- a/Resources/config/facebook.xml +++ b/Resources/config/facebook.xml @@ -31,5 +31,9 @@ + + + + diff --git a/Services/FacebookPush.php b/Services/FacebookPush.php new file mode 100644 index 0000000..b7a2aa1 --- /dev/null +++ b/Services/FacebookPush.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\FacebookBundle\Services; + +use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use FOS\FacebookBundle\Model\StreamPost as BaseMessage; +use \BaseFacebook; +use \FacebookApiException; +use \InvalidArgumentException; +use \UnexpectedValueException; + +/** + * + * This class provides a service that abstracts Facebook API functionality such as retrieving user information and + * posting data to Facebook API. + * @author Teemu Reisbacka + * + */ +class FacebookPush +{ + protected $facebook; + protected $errorMessage; + + public function __construct(BaseFacebook $facebook) + { + $this->facebook = $facebook; + } + + /** + * Returns error message if an executed function returned a failure (false value). + * + * @return string + */ + public function getErrorMessage() + { + + return empty($this->errorMessage) ? '' : $this->errorMessage; + } + + /** + * Retrieves available user information from Facebook for the logged in user. Available information + * depends on what access privileges the user has granted to your app. + * + * @return array|null + */ + public function getUserInfromation() + { + $accessToken = $this->facebook->getAccessToken(); + /* Adding the locale parameter is important, because otherwise Facebook api might localize some + * variable values, such as gender. + */ + $me = json_decode(file_get_contents("https://graph.facebook.com/me?access_token={$accessToken}&locale=en_US"), true); + + return $me; + } + + /** + * Retrieves the profile picture of the logged in user in binary format, so that you can + * save it locally. + * + * @return string|boolean + */ + public function getProfilePicture() + { + $facebookUID = $this->facebook->getUser(); + if (empty($facebookUID)) { + return null; + } + + $binaryImage = file_get_contents("http://graph.facebook.com/{$facebookUID}/picture?type=large"); + + return $binaryImage; + } + + /** + * Publishes a message to user's Facebook stream as the user. You application name will be displayed at the bottom + * of the message. + * REQUIRES Facebook access permission "publish_stream" + * + * @param Rohea\FacebookBundle\Models\streamPost $streamPost Stream post object + * @param string $accessToken Optional Facebook Access token, if not given, logged in user is used + * @return boolean + */ + public function publishStream(BaseMessage $streamPost, $accessToken = null) + { + if (empty($accessToken)) { + $accessToken = $this->facebook->getAccessToken(); + } + if (empty($accessToken)) { + throw new InvalidArgumentException('No facebook access token, cannot post to stream'); + } + + $streamPost->setAccessToken($accessToken); + $message = $streamPost->formatData(); + try { + $result = $this->facebook->api( '/me/feed/', 'post', $message ); + + /* Confirm that the post went through -> Facebook api return message id + */ + if (!is_array($result) || empty($result["id"])) { + $this->errorMessage = "Did not receive message id back from the api, post failed."; + return false; + } + } catch (FacebookApiException $e) { + $this->errorMessage = $e->getMessage(); + + return false; + } + + return true; + } + + /** + * Publishes a message to user's Facebook page as the page. + * REQUIRES Facebook access permission "manage_pages" + * + * @param Rohea\FacebookBundle\Models\streamPost $streamPost Stream post object + * @param string $pageID Your page facebook id. You can see this for examnple in your browser uri-bar when browsing the page. + * @return boolean + */ + public function publishPage(BaseMessage $streamPost, $pageID) + { + try { + $accessToken = $this->getPageAccessToken($pageID); + $streamPost->setAccessToken($accessToken); + $message = $streamPost->formatData(); + $result = $this->facebook->api( "/{$pageID}/feed/", 'post', $message ); + + /* Confirm that the post went through -> Facebook api return message id + */ + if (!is_array($result) || empty($result["id"])) { + $this->errorMessage = "Did not receive message id back from the api, post failed."; + return false; + } + } catch (FacebookApiException $e) { + $this->errorMessage = $e->getMessage(); + + return false; + } + + return true; + } + + /** + * Attempts to query access token for give Facebook page + * REQUIRES Facebook access permission "manage_pages" + * + * @param string $pageID Facebook page id + * @throws \UnexpectedValueException + * @return string + */ + public function getPageAccessToken($pageID) + { + $pageInfo = $this->facebook->api("/$pageID?fields=access_token"); + + if (empty($pageInfo['access_token'])) { + throw new UnexpectedValueException("Could not retrieve access token for the page $pageID"); + } + + return $pageInfo['access_token']; + } +} \ No newline at end of file