1<?php 2/** 3 * Horde_Service_Facebook class abstracts communication with Facebook's 4 * rest interface. 5 * 6 * This code was originally a Hordified version of Facebook's official PHP 7 * client. However, since that client was very buggy and incomplete, very little 8 * of the original code or design is left. I left the original copyright notice 9 * intact below. 10 * 11 * Copyright 2009-2017 Horde LLC (http://www.horde.org/) 12 * 13 * @author Michael J. Rubinsky <mrubinsk@horde.org> 14 * @category Horde 15 * @package Service_Facebook 16 */ 17 18/** 19 * Facebook Platform PHP5 client 20 * 21 * Copyright 2004-2009 Facebook. All Rights Reserved. 22 * 23 * Copyright (c) 2007 Facebook, Inc. 24 * All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions 28 * are met: 29 * 30 * 1. Redistributions of source code must retain the above copyright 31 * notice, this list of conditions and the following disclaimer. 32 * 2. Redistributions in binary form must reproduce the above copyright 33 * notice, this list of conditions and the following disclaimer in the 34 * documentation and/or other materials provided with the distribution. 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 37 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 39 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 45 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 * 47 * For help with this library, contact developers-help@facebook.com 48 */ 49class Horde_Service_Facebook 50{ 51 /** 52 * Use only ssl resource flag 53 * 54 * @var boolean 55 */ 56 public $useSslResources = false; 57 58 /** 59 * The API Secret Key 60 * 61 * @var string 62 */ 63 protected $_secret; 64 65 /** 66 * Holds an optional logger object 67 * 68 * @var Horde_Log_Logger 69 */ 70 protected $_logger; 71 72 /** 73 * 74 * @var Horde_Http_Client 75 */ 76 protected $_http; 77 78 79 /** 80 * Cache for the various objects we lazy load in __get() 81 * 82 * @var hash of Horde_Service_Facebook_* objects 83 */ 84 protected $_objCache = array(); 85 86 87 const API_VALIDATION_ERROR = 1; 88 const REST_SERVER_ADDR = 'https://api.facebook.com/method/'; 89 const GRAPH_SERVER_ADDR = 'https://graph.facebook.com'; 90 91 /** 92 * Const'r 93 * 94 * @param string $appId Application ID. 95 * @param string $secret Developer API secret. 96 * @param array $context Array of context information containing: 97 * <pre> 98 * http_client - required 99 * logger 100 * use_ssl 101 * </pre> 102 */ 103 public function __construct($appId, $secret, $context) 104 { 105 // We require a http client object. 106 if (empty($context['http_client'])) { 107 throw new InvalidArgumentException('A http client object is required'); 108 } else { 109 $this->_http = $context['http_client']; 110 } 111 112 // Optional Horde_Log_Logger 113 if (!empty($context['logger'])) { 114 $this->_logger = $context['logger']; 115 } else { 116 $this->_logger = new Horde_Support_Stub(); 117 } 118 119 $this->_logger->debug('Initializing Horde_Service_Facebook'); 120 121 $this->_appId = $appId; 122 $this->secret = $secret; 123 124 if (!empty($context['use_ssl'])) { 125 $this->useSslResources = true; 126 } 127 } 128 129 /** 130 * Lazy load the facebook classes. 131 * 132 * @param string $value The lowercase representation of the subclass. 133 * 134 * @return mixed 135 * @throws Horde_Service_Facebook_Exception 136 */ 137 public function __get($value) 138 { 139 // First, see if it's an allowed protected value. 140 switch ($value) { 141 case 'appId': 142 return $this->_appId; 143 case 'secret': 144 return $this->_secret; 145 case 'http': 146 return $this->_http; 147 case 'logger': 148 return $this->_logger; 149 } 150 151 // If not, assume it's a method/action class... 152 $class = 'Horde_Service_Facebook_' . Horde_String::ucfirst($value); 153 if (!class_exists($class)) { 154 throw new Horde_Service_Facebook_Exception(sprintf("%s class not found", $class)); 155 } 156 157 if (empty($this->_objCache[$class])) { 158 $this->_objCache[$class] = new $class($this); 159 } 160 161 return $this->_objCache[$class]; 162 } 163 164 /** 165 * Helper function to get the appropriate facebook url 166 * 167 * @param string $subdomain The subdomain to use (www). 168 * 169 * @return string 170 */ 171 public static function getFacebookUrl($subdomain = 'www') 172 { 173 return 'https://' . $subdomain . '.facebook.com'; 174 } 175 176 /** 177 * Calls the specified normal REST API method. 178 * 179 * @param string $method Name of the Facebook method to invoke 180 * @param array $params A map of param names => param values 181 * 182 * @return mixed Result of method call 183 */ 184 public function callMethod($method, array $params = array()) 185 { 186 $this->_logger->debug(sprintf('Calling method %s with parameters %s', $method, print_r($params, true))); 187 $request = new Horde_Service_Facebook_Request_Rest($this, $method, $params); 188 return $request->run(); 189 } 190 191 /** 192 * Call the Facebook Graph API. 193 * 194 * @param string $method The endpoint (method) to call. 195 * @param array $params An array of parameters to pass along with the call. 196 * @param array $options Additional request options: 197 * - request: (string) 'POST', 'GET', 'DELETE' etc.. 198 * 199 * @return mixed The results of the API call. 200 */ 201 public function callGraphApi( 202 $method = '', array $params = array(), array $options = array()) 203 { 204 $request = new Horde_Service_Facebook_Request_Graph( 205 $this, 206 $method, 207 $params, 208 $options); 209 210 return $request->run(); 211 } 212 213}