Last active
June 30, 2017 03:54
-
-
Save patpawlowski/486ea6d6b84bb6b7e90c5474ae5f001c to your computer and use it in GitHub Desktop.
PHP Script to download Sugar backups from the pbs_Backups module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Created by NetBeans. | |
* User: patpawlowski | |
* Date: Mar 3, 2017 at 3:25:54 PM <- My 51st birthday ;) -pat | |
* File: sugarbackupdownload.php | |
* Create: curl https://gist.github.com/patpawlowski/486ea6d6b84bb6b7e90c5474ae5f001c/raw/ce08c191c8b3656d8749ef15c446b706a786b02b/sugarbackupdownload.php > sugarbackupdownload | |
* Make Executable: chmod +xxx sugarbackupdownload | |
* Run: php sugarbackupdownload | |
*/ | |
ini_set('display_errors', 1); | |
class SugarAPI{ | |
private $oauthtoken = FALSE; | |
private $oathrefreshtoken = ''; | |
private $base_url = ''; | |
private $username = ''; | |
private $password = ''; | |
private $starttime = ''; | |
private $curl_error = ''; | |
private $debug = false; | |
public function __construct($base_url, $username, $password) | |
{ | |
if ($this->debug) echo "<pre>\nConstructor starting\n"; | |
if(strpos($base_url, '/rest/v10')){ | |
$this->base_url = $base_url; | |
}else{ | |
$this->base_url = $base_url.'/rest/v10'; | |
} | |
$this->username = $username; | |
$this->password = $password; | |
$url_ext = "/oauth2/token"; | |
$oauth2_token_parameters = array( | |
"grant_type" => "password", | |
"client_id" => "sugar", | |
"client_secret" => "", | |
"username" => $username, | |
"password" => $password, | |
"platform" => "base" | |
); | |
$this->starttime = new DateTime(); // $this->starttime must be defined before calling "call" the first time. | |
$oauth2_token_result = $this->call($url_ext, 'POST', $oauth2_token_parameters); | |
if($oauth2_token_result) | |
{ | |
$this->oauthtoken = $oauth2_token_result->access_token; | |
$this->oathrefreshtoken = $oauth2_token_result->refresh_token; | |
}else{ | |
} | |
// print_r($oauth2_token_result); | |
if ($this->debug) | |
{ | |
echo PHP_EOL.json_encode($oauth2_token_parameters).PHP_EOL; | |
echo "oauth2_token_result:\n"; | |
print_r($oauth2_token_result); | |
echo "OAUTH Token: ".$this->oauthtoken."\n"; | |
echo "Constructor ending\n\n"; | |
} | |
} | |
public function search($module, $filter){ | |
return $this->call('/'.$module, 'GET', $filter); | |
} | |
public function create($module, $record_parameters){ | |
return $this->call('/'.$module, 'POST', $record_parameters); | |
} | |
public function read($module, $id){ | |
return $this->call('/'.$module.'/'.$id, 'GET'); | |
} | |
public function update($module, $id, $record_parameters){ | |
return $this->call('/'.$module.'/'.$id, 'PUT', $record_parameters); | |
} | |
public function upsert($module, $record_parameters){ | |
if(!empty($record_parameters['id'])){ | |
$Result = $this->update($module, $record_parameters['id'], $record_parameters); | |
if(!(isset($Result->error) && $Result->error = 'not_found')){ | |
return $Result; | |
} | |
} | |
return $this->create($module, $record_parameters); | |
} | |
public function delete($module, $id){ | |
return $this->call('/'.$module.'/'.$id, 'DELETE'); | |
} | |
public function createRelationship($module, $id, $link_name, $remote_id) { | |
return $this->call('/'.$module.'/'.$id.'/link/'.$link_name.'/'.$remote_id, 'POST'); | |
} | |
public function readRelatedRecords($module, $id, $link_name) { | |
return $this->call('/'.$module.'/'.$id.'/link/'.$link_name); | |
} | |
public function deleteRelationship($module, $id, $link_name, $remote_id) { | |
return $this->call('/'.$module.'/'.$id.'/link/'.$link_name.'/'.$remote_id, 'DELETE'); | |
} | |
public function bulkAPICall($parameters) { | |
return $this->call('/bulk', 'POST', $parameters); | |
} | |
public function getOathToken() | |
{ | |
return $this->oauthtoken; | |
} | |
public function checkID($module, $id) { | |
$Return = $this->read($module, $id); | |
if(isset($Return->id)){ | |
return TRUE; | |
}else{ | |
return FALSE; | |
} | |
} | |
/** | |
* Generic function to make cURL request. | |
* @param $url - The URL route to use. | |
* @param string $oauthtoken - The oauth token. | |
* @param string $type - GET, POST, PUT. Defaults to GET. | |
* @param array $parameters - Endpoint parameters. | |
* @param array $encodeData - Whether or not to JSON encode the data. | |
* @param array $returnHeaders - Whether or not to return the headers. | |
* @return mixed | |
*/ | |
public function call( | |
$url_ext, | |
$type = 'GET', | |
$parameters=array(), | |
$encodeData=true, | |
$returnHeaders=false | |
) | |
{ | |
if ($this->debug) | |
{ | |
echo "call function starting\n"; | |
echo "url_ext: ".$type."\n"; | |
echo "type: ".$url_ext."\n"; | |
echo "parameters: \n"; | |
print_r($parameters); | |
} | |
// Check for OAUTH Token Expiration | |
$this->checkToken(); | |
$url = $this->base_url.$url_ext; | |
$oauthtoken = $this->oauthtoken; | |
$type = strtoupper($type); | |
if ($type == 'GET') | |
{ | |
if(is_array($parameters)) | |
{ | |
$url .= "?" . http_build_query($parameters); | |
} | |
} | |
/* | |
* $filter_arguments = array( | |
* "filter" => array( | |
* array( | |
* "name" => 'ACME, Inc.' | |
* ), | |
* ), | |
* "max_num" => 2, | |
* "offset" => 0, | |
* "fields" => "name,description", | |
* "order_by" => "name:DESC", | |
* "favorites" => false, | |
* "my_items" => false, | |
* ); | |
*/ | |
if ($this->debug) echo "CURL URL: ".$url."\n"; | |
$curl_request = curl_init($url); | |
if ($type == 'POST') | |
{ | |
curl_setopt($curl_request, CURLOPT_POST, 1); | |
} | |
elseif ($type == 'PUT') | |
{ | |
curl_setopt($curl_request, CURLOPT_CUSTOMREQUEST, "PUT"); | |
} | |
elseif ($type == 'DELETE') | |
{ | |
curl_setopt($curl_request, CURLOPT_CUSTOMREQUEST, "DELETE"); | |
} | |
curl_setopt($curl_request, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | |
curl_setopt($curl_request, CURLOPT_HEADER, $returnHeaders); | |
curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, 0); | |
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($curl_request, CURLOPT_FOLLOWLOCATION, 0); | |
$header = array('Content-Type: application/json'); | |
if (!empty($oauthtoken)) | |
{ | |
$header[] = "oauth-token: $oauthtoken"; | |
} | |
curl_setopt($curl_request, CURLOPT_HTTPHEADER, $header); | |
if (!empty($parameters) && $type !== 'GET') | |
{ | |
if ($encodeData) | |
{ | |
//encode the parameters as JSON | |
$parameters = json_encode($parameters); | |
} | |
curl_setopt($curl_request, CURLOPT_POSTFIELDS, $parameters); | |
} | |
$result = curl_exec($curl_request); | |
if(!$result) | |
{ | |
$this->curl_error = curl_error($curl_request); | |
} | |
if ($this->debug) | |
{ | |
echo "Raw CURL response:\n"; | |
print_r($result); | |
echo "CURL ERROR: ".curl_error($curl_request); | |
} | |
if ($returnHeaders) | |
{ | |
//set headers from response | |
list($headers, $content) = explode("\r\n\r\n", $result ,2); | |
foreach (explode("\r\n",$headers) as $header) | |
{ | |
header($header); | |
} | |
//return the nonheader data | |
return trim($content); | |
} | |
curl_close($curl_request); | |
//decode the response from JSON | |
$response = json_decode($result); | |
if ($this->debug) echo "\ncall function ending\n"; | |
return $response; | |
} | |
private function refreshToken() | |
{ | |
// $this->starttime must be reset before calling $this->call or an endless loop will be initiated | |
$Now = new DateTime(); | |
$this->starttime = $Now; | |
$this->oauthtoken = FALSE; | |
$url_ext = "/oauth2/token"; | |
$oauth2_token_parameters = array( | |
"grant_type" => "refresh_token", | |
"refresh_token" => $this->oathrefreshtoken, | |
"client_id" => "sugar", | |
"client_secret" => "" | |
); | |
$oauth2_token_result = $this->call($url_ext, 'POST', $oauth2_token_parameters); | |
print_r($oauth2_token_result); | |
$this->oauthtoken = $oauth2_token_result->access_token; | |
$this->oathrefreshtoken = $oauth2_token_result->refresh_token; | |
echo "OAUTH Token refreshed\n"; | |
} | |
public function checkToken() | |
{ | |
$Now = new DateTime(); | |
$TokenAge = date_diff($this->starttime, $Now, true); | |
if ($TokenAge->i > 59 || $TokenAge->h > 0) | |
{ | |
echo "OAUTH Token about to expire. Refreshing. . . \n"; | |
$this->refreshToken(); | |
} | |
} | |
public function isConnected() { | |
if($this->oauthtoken) | |
{ | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} | |
public function getCurlError() { | |
return $this->curl_error; | |
} | |
} | |
class SugarBackupDownloader { | |
private $BaseURL = ''; | |
private $UserName = ''; | |
private $Password = ''; | |
private $APIURL = ''; | |
private $SugarAPI = false; | |
private $Backups = array(); | |
public function __construct() { | |
$this->getConnectionParameters(); | |
$this->loadBackups(); | |
$this->getBackupNumber(); | |
} | |
public function getConnectionParameters() { | |
echo "Enter base URL. ex: https://mysugar.sugarondemand.com:> "; | |
$BaseURL = trim(fgets(STDIN)); | |
echo "Enter username:> "; | |
$UserName = trim(fgets(STDIN)); | |
echo "Enter password:> "; | |
system('stty -echo'); | |
$Password = trim(fgets(STDIN)); | |
system('stty echo'); | |
$this->BaseURL = $BaseURL; | |
$this->UserName = $UserName; | |
$this->Password = $Password; | |
$this->APIURL = $this->BaseURL . '/rest/v10'; | |
echo "Connecting to Sugar and getting list of backups . . . \n"; | |
$this->SugarAPI = new SugarAPI($this->APIURL, $this->UserName, $this->Password); | |
} | |
private function loadBackups() { | |
$Result = $this->SugarAPI->search('ops_Backups', array()); | |
$this->Backups = $Result->records; | |
// print_r($Result); | |
} | |
private function getBackupNumber() { | |
foreach($this->Backups as $Index => $Backup){ | |
echo "$Index \t $Backup->name $Backup->date_entered\n"; | |
} | |
echo "\n\tEnter the number of the backup to download:> "; | |
$BackupNumber = trim(fgets(STDIN)); // reads one line from STDIN | |
$this->downloadBackup($BackupNumber); | |
} | |
private function downloadBackup($BackupNumber) { | |
echo $this->Backups[$BackupNumber]->download_url.PHP_EOL; | |
$URL = $this->Backups[$BackupNumber]->download_url; | |
$Filename = basename($URL); | |
exec("wget $URL -O $Filename"); | |
} | |
} | |
$SugarBackupDownloader = new SugarBackupDownloader(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't know about everyone else but when I need to download a Sugar backup it's usually to a headless Linux machine and not to a machine with a UI and a browser. I created this script for just that.
You can download it from here or just run
Make it executable:
And then run it:
Connecting to Sugar and getting list of backups . . .
0 mysugar.sugarondemand.com - 7821ent 2017-06-26T00:26:33+00:00
1 mysugar.sugarondemand.com - 7820ent 2017-05-02T20:50:31+00:00
Connecting to xxxxxxxxxx|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 59485709 (57M) [binary/octet-stream]
Saving to: `mysugar.sugarondemand.com.7821ent.1498436798.ca3984af5135c32c706fd36cf6e47ba0cae7c840.tar.gz'
100%[====================================================================================================================>] 59,485,709 18.6M/s in 3.0s
2017-06-26 10:02:54 (18.6 MB/s) - `mysugar.sugarondemand.com.7821ent.1498436798.ca3984af5135c32c706fd36cf6e47ba0cae7c840.tar.gz' saved [59485709/59485709]
And that's all there is to it.