Moving Google Analytics property to a different account

If you buy a website with a long history online, you’ll likely want to preserve the google analytics account history. If the previous owner can’t give you control of the account with this history, things can get a little weird. The options I’ve found so far are:

-The prior owner can just add your login to the account in analytics. This works fine, but if they only give you a read-only login, you don’t have control over this and they could delete your access at any time.

-I’ve seen an option for moving a property to a new account in my analytics account, so I have a theory that if I create a new account and give the original owner’s login full admin access to this newly created account, they might be able to move control to it. I haven’t been able to test this, and I think it might be a new feature.

-You can create a new analytics tracker in your own account and add it to the site. If combined with the first option above, you can view the old account for historical data, but also start gathering all new data in your new account. Not the best solution, but better than nothing. Here is sample code showing how to do two trackers at once – notice you have to give a tracker name to the second one, as they can’t both be the default tracker. In this example, “clientTracker” is the name given to the second one. THEN be sure to include it in the send command, by PREPENDING the tracker name + “.” to the send command. See below.

ga('create', 'UA-XXXXX-Y', 'auto');
ga('create', 'UA-XXXXX-Z', 'auto', 'clientTracker');

ga('send', 'pageview');
ga('clientTracker.send', 'pageview');

Margarita Recipe

My latest rendition is: the “3 man margarita” – serves about 3 men (wow?)

4 shots tequila
2 shots triple
1 lime
1 small orange
1 big squeeze lime juice (or, more limes)
splash of truvia- powder is good, liquid is ok
giant spoon of orange concentrate (really big)
3 tall glasses of crushed ice
blend it for long time

PHP code for Bing/Microsoft/Azure translator

Microsoft has yet again changed the API service for the translator api they offer (formerly known as Bing translator, Microsoft Translator, Azure Translator?). It’s now been moved to Azure, and is under the “Cognitive Services” offerings. Maybe it will stay here for more than a couple months before they mess with it again?

I needed to update a PHP app that calls the bing translator API, and couldn’t find anything that did the trick. Prior to the full Azure move, the service has been put under a data market portal, and later the simple basic auth api was updated to use OAuth for security. The latest iteration still uses Oath, but it’s simplified now to the point that all you need to pass is the secret key to get the authorization token – as opposed to previously requiring an app name, some domain scope thing, etc- a lot of moving parts. Now all that is needed to get a token is this:

Option 1: Pass key using header

curl --header 'Ocp-Apim-Subscription-Key: ' --data "" 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken'

Option 2: Pass key using query string parameter
curl --data "" 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key='

The body of the request is the token you use- so you don’t need to parse a JSON result or anything.

Here is a PHP class you can use with the latest greatest api- Note that this code hits the issuetoken request with every request, the tokens are good for a period of time (30 minutes if I recall) so this code could use caching to only request a new token after it expires. I’ll update this later. Also the code is pretty hackish, needs a lot of cleanup.

Edit the file to with your actual key. Then create an instance of AzureTranslator, set properties for the src and dest languages, and the phrase to translate. Call getTranslateByCurl() and it will return your translated phrase.

class AccessTokenAuthentication {

function getTokens2($clientKey, $authUrl){
try {
//Initialize the Curl Session.
$ch = curl_init();
//Set the Curl URL.
curl_setopt($ch, CURLOPT_URL, $authUrl . '?Subscription-Key=' . $clientKey);
//Set HTTP POST Request.
curl_setopt($ch, CURLOPT_POST, TRUE);
//Set data to POST in HTTP "POST" Operation.
curl_setopt($ch, CURLOPT_POSTFIELDS, ""); // $paramArr);
//CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec().
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
//CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate.
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//Execute the cURL session.
$strResponse = curl_exec($ch);
//Get the Error Code returned by Curl.
$curlErrno = curl_errno($ch);
if($curlErrno){
$curlError = curl_error($ch);
throw new Exception($curlError);
}
//Close the Curl Session.
curl_close($ch);
return $strResponse ;
} catch (Exception $e) {
return ""; // echo "Exception-".$e->getMessage();
}
}
}

/*
* Class:AzureTranslator
*
* Processing the translator request.
*/
Class AzureTranslator {

private $clientSecret = "";
private $authUrl = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
private $phrase = null;
private $sourceLang = "";
private $targetLang = "";

public function setPhrase ($phrase = "")
{
$this->phrase = "";
if (!empty($phrase))
$this->phrase = trim($phrase);
}

public function setSourceLang ($sLang = "")
{
$this->sourceLang = "";
if (!empty($sLang))
$this->sourceLang = trim($sLang);
}

public function setTargetLang ($tLang = "")
{
$this->targetLang = "";
if (!empty($tLang))
$this->targetLang = trim($tLang);
}

public function getTranslateByCurl()
{
try {

//Create the AccessTokenAuthentication object.
$authObj = new AccessTokenAuthentication();

$accessToken = $authObj->getTokens2($this->clientSecret, $this->authUrl);
//Create the authorization Header string.
$authHeader = "Authorization: Bearer ". $accessToken;

$contentType = 'text/plain';
$category = 'general';

$params = "text=".urlencode($this->phrase)."&to=".$this->targetLang."&from=".$this->sourceLang;

$translateUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?$params";

//Get the curlResponse.
$curlResponse = $this->curlRequest($translateUrl, $authHeader);

//Interprets a string of XML into an object.
$xmlObj = simplexml_load_string($curlResponse);
foreach((array)$xmlObj[0] as $val){
$translatedStr = $val;
}

return $translatedStr;
//return $curlResponse;

} catch (Exception $e) {
return "";
//return $e->getMessage();
}
}

/*
* Create and execute the HTTP CURL request.
*
* @param string $url HTTP Url.
* @param string $authHeader Authorization Header string.
* @param string $postData Data to post.
*
* @return string.
*
*/
function curlRequest($url, $authHeader, $postData=''){
//Initialize the Curl Session.
$ch = curl_init();
//Set the Curl url.
curl_setopt ($ch, CURLOPT_URL, $url);
//Set the HTTP HEADER Fields.
curl_setopt ($ch, CURLOPT_HTTPHEADER, array($authHeader,"Content-Type: text/xml"));
//CURLOPT_RETURNTRANSFER- TRUE to return the transfer as a string of the return value of curl_exec().
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, TRUE);
//CURLOPT_SSL_VERIFYPEER- Set FALSE to stop cURL from verifying the peer's certificate.
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, False);
if($postData) {
//Set HTTP POST Request.
curl_setopt($ch, CURLOPT_POST, TRUE);
//Set data to POST in HTTP "POST" Operation.
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
}
//Execute the cURL session.
$curlResponse = curl_exec($ch);
//Get the Error Code returned by Curl.
$curlErrno = curl_errno($ch);
if ($curlErrno) {
$curlError = curl_error($ch);
throw new Exception($curlError);
}
//Close a cURL session.
curl_close($ch);
return $curlResponse;
}
}