Skip to content

Instantly share code, notes, and snippets.

@mylk
Last active August 14, 2016 16:57
Show Gist options
  • Save mylk/e8f309d9a2e23f93b2ed6fb6e6616294 to your computer and use it in GitHub Desktop.
Save mylk/e8f309d9a2e23f93b2ed6fb6e6616294 to your computer and use it in GitHub Desktop.
A Google Shortener API wrapper
<?php
/**
* Supports URL shortening, expanding and analytics retrieval of a given period type.
*/
/*
* Installation (Symfony):
* =======================
* # services.yml
* services:
* # ...
* acme.url_shortener:
* class: Acme\AcmeBundle\Service\UrlShortenerService
* calls: [ [setDependencies, [%google.url_shortener_api.url%, %google.url_shortener_api.key%]] ]
*
* # parameters.yml
* # ...
* parameters:
* google.url_shortener_api.key: "XXX"
* google.url_shortener_api.url: "https://www.googleapis.com/urlshortener/v1/url"
*/
namespace Acme\AcmeBundle\Service;
class UrlShortenerService
{
const ANALYTICS_PERIOD_TWO_HOURS = "twoHours";
const ANALYTICS_PERIOD_DAY = "day";
const ANALYTICS_PERIOD_WEEK = "week";
const ANALYTICS_PERIOD_MONTH = "month";
const ANALYTICS_PERIOD_EVER = "allTime";
private $apiUrl;
private $apiKey;
/**
* Used by the dependency injection container to inject the dependencies of the service.
*
* @param string $apiUrl
* @param string $apiKey
*/
public function setDependencies($apiUrl, $apiKey)
{
$this->apiUrl = $apiUrl;
$this->apiKey = $apiKey;
}
/**
* Issues an HTTP GET request and returns the response.
*
* @param array $data
* @return array
* @throws \Exception
*/
private function get($data = array())
{
$data = \array_merge($data, array("key" => $this->apiKey));
$url = $this->apiUrl . "?" . \http_build_query($data);
$curlClient = \curl_init();
\curl_setopt_array($curlClient, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 10
));
$responseJson = \curl_exec($curlClient);
\curl_close($curlClient);
$response = \json_decode($responseJson, true);
if (isset($response["error"])) {
$errorMessages = $this->getErrorMessages($response);
throw new \Exception(\implode(" ", $errorMessages));
}
return $response;
}
/**
* Issues an HTTP POST request and returns the response.
*
* @param array $data
* @return array
* @throws \Exception
*/
private function post($data)
{
$url = $this->apiUrl . "?key=" . $this->apiKey;
$dataJson = \json_encode($data);
$curlClient = \curl_init();
\curl_setopt_array($curlClient, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $dataJson,
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"Content-Length: " . \strlen($dataJson)
)
));
$responseJson = \curl_exec($curlClient);
\curl_close($curlClient);
$response = \json_decode($responseJson, true);
if (isset($response["error"])) {
$errorMessages = $this->getErrorMessages($response);
throw new \Exception(\implode(" ", $errorMessages));
}
return $response;
}
/**
* Returns the shortened URL of a given long URL.
*
* @param array $url
* @return string
* @throws \Exception
*/
public function shorten($url)
{
$response = $this->post(array("longUrl" => $url));
if (!isset($response["id"])) {
throw new \Exception("Malformed response");
}
return $response["id"];
}
/**
* Returns the long URL of the given shortened URL.
*
* @param string $url
* @return string
* @throws \Exception
*/
public function expand($url)
{
$response = $this->get(array("shortUrl" => $url));
if ("MALWARE" === $response["status"]) {
throw new \Exception("Full URL seems fishy.");
} elseif ("REMOVED" === $response["status"]) {
throw new \Exception("Shortened URL has been removed.");
} elseif (!isset($response["longUrl"])) {
throw new \Exception("Malformed response");
}
return $response["longUrl"];
}
/**
* Returns the analytics of a shortened URL for a requested period segment.
*
* @param string $url
* @param string $period
* @return array
* @throws \Exception
*/
public function getAnalytics($url, $period = self::ANALYTICS_PERIOD_EVER)
{
$response = $this->get(array("shortUrl" => $url, "projection" => "FULL"));
if (!isset($response["analytics"][$period])) {
throw new \Exception("Malformed response");
}
return $response["analytics"][$period];
}
/**
* Returns the error messages contained in a response.
*
* @param array $response
* @return array
*/
private function getErrorMessages($response)
{
$messages = array();
foreach ($response["error"]["errors"] as $error) {
$messages[] = $error["message"];
}
return $messages;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment