_headers = $headers; $this->_response = $response; parent::__construct($message, $code); } public function getHeaders() { return $this->_headers; } public function getResponse() { return $this->_response; } } // TODO - Add comments api methods // TODO - Add events api methods class ArkliApi { const DEFAULT_API_URL = 'https://www.arkli.com/api'; protected $_requestTokenUrl = ''; protected $_authorizeUrl = ''; protected $_accessTokenUrl = ''; protected $_apiUrl = self::DEFAULT_API_URL; protected $_consumer = null; protected $_accessToken = null; protected $_sigMethod = null; public function __construct($consumerKey, $consumerSecret) { $this->_consumer = new OAuthConsumer($consumerKey, $consumerSecret); $this->_sigMethod = new OAuthSignatureMethod_HMAC_SHA1(); $this->setApiUrl(self::DEFAULT_API_URL); } public function setApiUrl($url) { $this->_requestTokenUrl = "{$url}/oauth/request_token"; $this->_authorizeUrl = "{$url}/oauth/authorize"; $this->_accessTokenUrl = "{$url}/oauth/access_token"; $this->_apiUrl = $url; } public function setAccessToken($token, $secret) { $this->_accessToken = new OAuthToken($token, $secret); } protected function _getResponse($url, $request, $params, $method) { $options = array( CURLOPT_URL => $url, // CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_HTTPHEADER => array( $request->to_header(), ), ); if ($method == 'GET') { $options[CURLOPT_URL] = $request->to_url(); } else if ($method == 'POST') { $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = OAuthUtil::build_http_query($params); } $ch = curl_init(); curl_setopt_array($ch, $options); $response = curl_exec($ch); $headers = curl_getinfo($ch); $errorNumber = curl_errno($ch); $errorMessage = curl_error($ch); curl_close($ch); if ($errorNumber) { throw new ArkliApiHttpException($errorMessage, $errorNumber, $headers, $response); } return array($headers, $response); } public function getAuthorizationUrl($callbackUrl) { $params = array( 'oauth_callback' => $callbackUrl, ); $request = OAuthRequest::from_consumer_and_token($this->_consumer, null, 'POST', $this->_requestTokenUrl, $params); $request->sign_request($this->_sigMethod, $this->_consumer, null); list($headers, $response) = $this->_getResponse($this->_requestTokenUrl, $request, $params, 'POST'); parse_str($response, $result); if (!isset($result['oauth_token']) || !isset($result['oauth_token_secret'])) { throw new ArkliApiHttpException('oauth_token/oauth_token_secret missing', 0, $headers, $response); } return ($this->_authorizeUrl . '?oauth_token=' . rawurlencode($result['oauth_token'])); } public function fetchAccessToken($tokenKey, $verifier) { $requestToken = new OAuthToken($tokenKey, ''); $params = array('oauth_verifier' => $verifier); $request = OAuthRequest::from_consumer_and_token($this->_consumer, $requestToken, 'POST', $this->_accessTokenUrl, $params); $request->sign_request($this->_sigMethod, $this->_consumer, null); list($headers, $response) = $this->_getResponse($this->_accessTokenUrl, $request, $params, 'POST'); parse_str($response, $result); if (!isset($result['oauth_token']) || !isset($result['oauth_token_secret'])) { throw new ArkliApiHttpException('oauth_token/oauth_token_secret missing', 0, $headers, $response); } $this->setAccessToken($result['oauth_token'], $result['oauth_token_secret']); return $this->_accessToken; } public function call($component, $endpoint, $params=array(), $id=null, $method='GET') { $component = (string)$component; $endpoint = (string)$endpoint; $method = (string)$method; if (isset($id)) { $callUrl = "{$this->_apiUrl}/{$component}/{$id}/{$endpoint}.json"; } else { $callUrl = "{$this->_apiUrl}/{$component}/{$endpoint}.json"; } $request = OAuthRequest::from_consumer_and_token($this->_consumer, $this->_accessToken, $method, $callUrl, $params); $request->sign_request($this->_sigMethod, $this->_consumer, $this->_accessToken); list($headers, $response) = $this->_getResponse($callUrl, $request, $params, $method, $method); $data = @json_decode($response, true); if ($data === null) { throw new ArkliApiHttpException('Invalid JSON', 0, $headers, $response); } if ($data['status'] == 'error') { throw new ArkliApiException($data['message'], (isset($data['code']) ? intval($data['code']) : 0)); } return $data; } public function mooShow($error=false) { return $this->call('moo', 'show', array( 'error' => $error, )); } public function channelsList($type=null, $accountName=null, $identifier=null) { $params = array(); if ($type !== null) { $params['type'] = $type; } if ($accountName !== null) { $params['account_name'] = $accountName; } if ($identifier !== null) { $params['identifier'] = $identifier; } $result = $this->call('channels', 'list', $params); return $result['data']; } public function channelsShow($id) { $result = $this->call('channels', 'show', array(), $id); return $result['channel']; } public function campaignsList($active=null, $sparse=null, $metrics=null) { $params = array(); if ($active !== null) { $params['active'] = $active; } if ($sparse !== null) { $params['sparse'] = $sparse; } if ($metrics !== null) { $params['metrics'] = $metrics; } $result = $this->call('campaigns', 'list', $params); return $result['data']; } public function campaignsShow($id, $sparse=null, $metrics=null, $errors=null) { $params = array(); if ($sparse !== null) { $params['sparse'] = $sparse; } if ($metrics !== null) { $params['metrics'] = $metrics; } if ($errors !== null) { $params['errors'] = $errors; } $result = $this->call('campaigns', 'show', $params, $id); return $result['campaign']; } public function campaignsDelete($id) { $result = $this->call('campaigns', 'delete', array(), $id, 'POST'); return ($result['status'] == 'success'); } public function campaignsUpdate($id, $name=null, $tags=null) { $params = array(); if ($name !== null) { $params['name'] = $name; } if ($tags !== null) { $params['tags'] = $tags; } return $this->call('campaigns', 'update', $params, $id, 'POST'); } public function campaignsCreate( $name, $tags, $publicationChannelId=null, $publicationPostAt=null, $publicationBody=null, array $publicationHeaders=null ) { $params = array( 'name' => $name, 'tags' => $tags, ); if ($publicationChannelId !== null) { $params['publication_channel_id'] = $publicationChannelId; } if ($publicationPostAt !== null) { if (!is_int($publicationPostAt)) { $publicationPostAt = strtotime($publicationPostAt); } $params['publication_post_at'] = gmdate('c', $publicationPostAt); } if ($publicationBody !== null) { $params['publication_body'] = (string)$publicationBody; } if ($publicationHeaders !== null && count($publicationHeaders)) { foreach ($publicationHeaders as $key => $value) { $params['publication_' . $key] = $value; } } $result = $this->call('campaigns', 'create', $params, null, 'POST'); return $result['campaign']; } public function publicationsShow($id) { $result = $this->call('publications', 'show', array(), $id); return $result['publication']; } public function publicationsDelete($id) { $result = $this->call('publications', 'delete', array(), $id, 'POST'); return ($result['status'] == 'success'); } public function publicationsUpdate( $id, $postAt=null, $body=null, array $headers=array() ) { // TODO - Its possible to change the channel and the campaign of a publication $params = array(); if ($postAt !== null) { if (!is_int($postAt)) { $postAt = strtotime($postAt); } $params['post_at'] = gmdate('c', $postAt); } if ($body !== null) { $params['body'] = $body; } $params = array_merge($headers, $params); $result = $this->call('publications', 'update', $params, $id, 'POST'); return $result['publication']; } public function publicationsCreate( $campaignId, $channelId, $postAt, $body=null, array $headers=array() ) { $params['campaign_id'] = $campaignId; $params['channel_id'] = $channelId; if (!is_int($postAt)) { $postAt = strtotime($postAt); } $params['post_at'] = gmdate('c', $postAt); if ($body !== null) { $params['body'] = $body; } $params = array_merge($headers, $params); $result = $this->call('publications', 'create', $params, null, 'POST'); return $result['publication']; } }