Current Directory: /home/astoriaah/www/old15/administrator/components/com_akeeba/engine/Postproc
Viewing File: /home/astoriaah/www/old15/administrator/components/com_akeeba/engine/Postproc/Dropbox.php
<?php
/**
* Akeeba Engine
* The modular PHP5 site backup engine
*
* @copyright Copyright (c)2006-2015 Nicholas K. Dionysopoulos
* @license GNU GPL version 3 or, at your option, any later version
* @package akeebaengine
*
*
*/
namespace Akeeba\Engine\Postproc;
// Protection against direct access
defined('AKEEBAENGINE') or die();
use Psr\Log\LogLevel;
use Akeeba\Engine\Factory;
use Akeeba\Engine\Platform;
use Akeeba\Engine\Postproc\Connector\Dropbox as ConnectorDropbox;
class Dropbox extends Base
{
/** @var string DropBox login email */
protected $email;
/** @var string DropBox password */
protected $password;
/** @var bool Are we logged in DropBox yet? */
protected $loggedIn = false;
/** @var string DropBox cookies */
protected $cookies = array();
/** @var int The retry count of this file (allow up to 2 retries after the first upload failure) */
private $tryCount = 0;
/** @var ConnectorDropbox The DropBox API instance */
private $dropbox;
/** @var string The currently configured directory */
private $directory;
/** @var bool Are we using chunk uploads? */
private $chunked = false;
/** @var int Chunk size (Mb) */
private $chunk_size = 4;
public function __construct()
{
$this->can_download_to_browser = false;
$this->can_delete = true;
$this->can_download_to_file = true;
}
/**
* Opens the OAuth window
*
* @param array $params Not used :)
*
* @return boolean False on failure, redirects on success
*/
public function oauthOpen($params = array())
{
$keys = $this->_getKeys();
$api = new ConnectorDropbox();
$api->setAppKeys($keys);
$url = null;
try
{
$url = $api->getAuthoriseUrl();
}
catch (\Exception $e)
{
$api->setSignatureMethod('PLAINTEXT');
}
if (is_null($url))
{
try
{
$url = $api->getAuthoriseUrl();
}
catch (\Exception $e)
{
echo "<h1>Dropbox API Error</h1>";
echo "<pre>" . $e->getMessage() . '</pre>';
die();
}
}
$reqtoken = $api->getReqToken();
$data = base64_encode(serialize($reqtoken));
Platform::getInstance()->set_flash_variable('dropbox.reqtoken', $data);
Platform::getInstance()->redirect($url);
}
/**
* Fetches the authentication token from Dropbox.com, after you've run the
* first step of the OAuth process.
*
* @return array
*/
public function getauth()
{
$keys = $this->_getKeys();
$api = new ConnectorDropbox();
$api->setAppKeys($keys);
$data = Platform::getInstance()->get_flash_variable('dropbox.reqtoken', null);
$reqToken = unserialize(base64_decode($data));
$api->setReqToken($reqToken);
$token = null;
try
{
$api->setSignatureMethod('HMAC-SHA1');
$api->getAccessToken();
$token = true;
}
catch (\Exception $e)
{
$api->setSignatureMethod('PLAINTEXT');
}
if (is_null($token))
{
try
{
$api->getAccessToken();
}
catch (\Exception $e)
{
return array(
'error' => 'Did not receive token from Dropbox',
'token' => $e->getMessage()
);
}
}
$token = $api->getToken();
return array(
'error' => '',
'token' => $token
);
}
public function processPart($absolute_filename, $upload_as = null)
{
$settings = $this->_getSettings();
$config = Factory::getConfiguration();
if ($settings === false)
{
return false;
}
$directory = $this->directory;
// Store the absolute remote path in the class property
$basename = empty($upload_as) ? basename($absolute_filename) : $upload_as;
$this->remote_path = $directory . '/' . $basename;
// Do not use multipart uploads when in an immediate post-processing step,
// i.e. we are uploading a part right after its creation
if ($this->chunked)
{
// Retrieve engine configuration data
$config = Factory::getConfiguration();
$immediateEnabled = $config->get('engine.postproc.common.after_part', 0);
if ($immediateEnabled)
{
$this->chunked = false;
}
}
// Are we already processing a multipart upload?
if ($this->chunked)
{
$offset = $config->get('volatile.engine.postproc.dropbox.offset', null);
$upload_id = $config->get('volatile.engine.postproc.dropbox.upload_id', null);
try
{
$result = $this->dropbox->putChunkedFile($absolute_filename, $directory, $this->chunk_size, $basename, true, $offset, $upload_id);
Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . '::' . __METHOD__ . " - Got putChunkedFile result " . print_r($result, true));
}
catch (\Exception $e)
{
Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . '::' . __METHOD__ . " - Got putChunkedFile \Exception " . $e->getCode() . ': ' . $e->getMessage());
// If we fail at first, retry using the PLAINTEXT signature method
if ($this->dropbox->getSignatureMethod() != 'PLAINTEXT')
{
$this->dropbox->setSignatureMethod('PLAINTEXT');
return -1;
}
$result = false;
}
// Did we fail uploading?
if ($result === false)
{
return false;
}
// Are we done uploading?
elseif (isset($result->rev))
{
$config->set('volatile.engine.postproc.dropbox.offset', null);
$config->set('volatile.engine.postproc.dropbox.upload_id', null);
return true;
}
// Continue uploading
else
{
$config->set('volatile.engine.postproc.dropbox.offset', $result->offset);
$config->set('volatile.engine.postproc.dropbox.upload_id', $result->upload_id);
return -1;
}
}
// Single part upload
try
{
$result = $this->dropbox->putFile($absolute_filename, false, $directory, true);
}
catch (\Exception $e)
{
$result = false;
$this->dropbox->setSignatureMethod('PLAINTEXT');
}
if ($result === false)
{
// Let's retry
$this->tryCount++;
// However, if we've already retried twice, we stop retrying and call it a failure
if ($this->tryCount > 2)
{
return false;
}
return -1;
}
else
{
// Upload complete. Reset the retry counter.
$this->tryCount = 0;
return true;
}
}
public function downloadToFile($remotePath, $localFile, $fromOffset = null, $length = null)
{
// Get settings
$settings = $this->_getSettings();
if ($settings === false)
{
return false;
}
if (!is_null($fromOffset))
{
// Ranges are not supported
return -1;
}
// Get the remote path's components
$remoteDirectory = trim(dirname($remotePath), '/');
$remoteFilename = basename($remotePath);
// Download the file
$done = false;
try
{
$this->dropbox->setResponseFormat('php');
$this->dropbox->getFile($remotePath, $localFile);
$done = true;
}
catch (\Exception $e)
{
$this->dropbox->setSignatureMethod('PLAINTEXT');
}
if (!$done)
{
try
{
$this->dropbox->getFile($remotePath, $localFile);
$downloaded = true;
}
catch (\Exception $e)
{
$this->setWarning($e->getMessage());
return false;
}
}
return true;
}
public function delete($path)
{
// Get settings
$settings = $this->_getSettings();
if ($settings === false)
{
return false;
}
$done = false;
try
{
$this->dropbox->delete($path);
$done = true;
}
catch (\Exception $e)
{
$this->dropbox->setSignatureMethod('PLAINTEXT');
}
if (!$done)
{
try
{
$this->dropbox->delete($path);
}
catch (\Exception $e)
{
$this->setWarning($e->getMessage());
return false;
}
}
return true;
}
protected function _getSettings()
{
// Retrieve engine configuration data
$config = Factory::getConfiguration();
$token = trim($config->get('engine.postproc.dropbox.token', ''));
$token_secret = trim($config->get('engine.postproc.dropbox.token_secret', ''));
$token_uid = trim($config->get('engine.postproc.dropbox.uid', ''));
$this->chunked = $config->get('engine.postproc.dropbox.chunk_upoad', true);
$this->chunk_size = $config->get('engine.postproc.dropbox.chunk_upoad_size', 4);
$this->directory = $config->get('volatile.postproc.directory', null);
if (empty($this->directory))
{
$this->directory = $config->get('engine.postproc.dropbox.directory', '');
}
// Sanity checks
if (empty($token) || empty($token_secret) || empty($token_uid))
{
$this->setError('You have not linked Akeeba Backup with your DropBox account');
return false;
}
if(!function_exists('curl_init'))
{
$this->setWarning('cURL is not enabled, please enable it in order to post-process your archives');
return false;
}
// Fix the directory name, if required
if (!empty($this->directory))
{
$this->directory = trim($this->directory);
$this->directory = ltrim(Factory::getFilesystemTools()->TranslateWinPath($this->directory), '/');
}
else
{
$this->directory = '';
}
// Parse tags
$this->directory = Factory::getFilesystemTools()->replace_archive_name_variables($this->directory);
$config->set('volatile.postproc.directory', $this->directory);
$token = (object)array(
'oauth_token_secret' => $token_secret,
'oauth_token' => $token,
'uid' => $token_uid,
);
$keys = $this->_getKeys();
$this->dropbox = new ConnectorDropbox();
$this->dropbox->setAppKeys($keys);
$this->dropbox->setToken($token);
return true;
}
protected function _getKeys()
{
return json_decode(base64_decode('eyJhcHAiOiJqZng4enFwdGwyYXc1NGQiLCJzZWNyZXQiOiJuZ2prZmxkY2R3ZDhnd3EifQ=='));
}
}