Current Directory: /home/astoriaah/www/old15/administrator/components/com_akeeba/engine/Postproc
Viewing File: /home/astoriaah/www/old15/administrator/components/com_akeeba/engine/Postproc/Cloudfiles.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\Postproc\Connector\Cloudfiles as ConnectorCloudfiles;
/**
* A post processing engine used to upload files to RackSpace CloudFiles
*/
class Cloudfiles extends Base
{
/**
* Public constructor. Initialises the advertised properties of this processing engine
*/
public function __construct()
{
$this->can_delete = true;
$this->can_download_to_file = true;
$this->can_download_to_browser = false;
}
/**
* Uploads a backup archive part to CloudFiles
*
* @param string $absolute_filename
* @param null $upload_as
*
* @return bool|int
*/
public function processPart($absolute_filename, $upload_as = null)
{
$settings = $this->_getEngineSettings();
if ($settings === false)
{
return false;
}
extract($settings);
// Calculate relative remote filename
$filename = empty($upload_as) ? basename($absolute_filename) : $upload_as;
if (!empty($directory) && ($directory != '/'))
{
$filename = $directory . '/' . $filename;
}
// Store the absolute remote path in the class property
$this->remote_path = $filename;
// Do I have authorisation options already stored in the volatile settings?
$options = Factory::getConfiguration()->get('volatile.postproc.cloudfiles.options', array(), false);
try
{
Factory::getLog()->log(LogLevel::DEBUG, 'Authenticating to CloudFiles');
// Create the API connector object
$cf = new ConnectorCloudfiles($username, $apikey, $options);
// Authenticate
$cf->authenticate();
// Cache the tokens in the volatile engine parameters to speed up further uploads
Factory::getConfiguration()->set('volatile.postproc.cloudfiles.options', $cf->getCurrentOptions());
// Upload the file
Factory::getLog()->log(LogLevel::DEBUG, 'Uploading ' . basename($absolute_filename));
$input = array(
'file' => $absolute_filename
);
$cf->putObject($input, $container, $filename, 'application/octet-stream');
}
catch (\Exception $e)
{
$this->setWarning($e->getMessage());
return false;
}
return true;
}
/**
* Implements object deletion
*/
public function delete($path)
{
$settings = $this->_getEngineSettings();
if ($settings === false)
{
return false;
}
extract($settings);
try
{
Factory::getLog()->log(LogLevel::DEBUG, 'Authenticating to CloudFiles');
// Create the API connector object
$cf = new ConnectorCloudfiles($username, $apikey);
// Authenticate
$cf->authenticate();
// Delete the file
Factory::getLog()->log(LogLevel::DEBUG, 'Deleting ' . $path);
$cf->deleteObject($container, $path);
}
catch (\Exception $e)
{
$this->setWarning($e->getMessage());
return false;
}
return true;
}
public function downloadToFile($remotePath, $localFile, $fromOffset = null, $length = null)
{
$settings = $this->_getEngineSettings();
if ($settings === false)
{
return false;
}
extract($settings);
try
{
Factory::getLog()->log(LogLevel::DEBUG, 'Authenticating to CloudFiles');
// Create the API connector object
$cf = new ConnectorCloudfiles($username, $apikey);
// Authenticate
$cf->authenticate();
Factory::getLog()->log(LogLevel::DEBUG, 'Checking that container «' . $container . '» exists');
// Do we need to set a range header?
$headers = array();
if (!is_null($fromOffset) && is_null($length))
{
$headers['Range'] = 'bytes=' . $fromOffset;
}
elseif (!is_null($fromOffset) && !is_null($length))
{
$headers['Range'] = 'bytes=' . $fromOffset . '-' . ($fromOffset + $length - 1);
}
elseif (!is_null($length))
{
$headers['Range'] = 'bytes=0-' . ($fromOffset + $length);
}
if (!empty($headers))
{
Factory::getLog()->log(LogLevel::DEBUG, 'Sending Range header «' . $headers['Range'] . '»');
}
$fp = @fopen($localFile, 'wb');
if ($fp === false)
{
throw new \Exception("Can't open $localFile for writing");
}
Factory::getLog()->log(LogLevel::DEBUG, 'Downloading ' . $remotePath);
$cf->downloadObject($container, $remotePath, $fp, $headers);
@fclose($fp);
}
catch (\Exception $e)
{
$this->setWarning($e->getMessage());
return false;
}
return true;
}
/**
* Returns the post-processing engine settings in array format. If something is amiss it returns boolean false.
*
* @return array|bool
*/
protected function _getEngineSettings()
{
// Retrieve engine configuration data
$config = Factory::getConfiguration();
$username = trim($config->get('engine.postproc.cloudfiles.username', ''));
$apikey = trim($config->get('engine.postproc.cloudfiles.apikey', ''));
$container = $config->get('engine.postproc.cloudfiles.container', 0);
$directory = $config->get('volatile.postproc.directory', null);
if (empty($directory))
{
$directory = $config->get('engine.postproc.cloudfiles.directory', 0);
}
// Sanity checks
if (empty($username))
{
$this->setWarning('You have not set up your CloudFiles user name');
return false;
}
if (empty($apikey))
{
$this->setWarning('You have not set up your CoudFiles API Key');
return false;
}
if (empty($container))
{
$this->setWarning('You have not set up your CloudFiles container');
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($directory))
{
$directory = trim($directory);
$directory = ltrim(Factory::getFilesystemTools()->TranslateWinPath($directory), '/');
}
else
{
$directory = '';
}
// Parse tags
$directory = Factory::getFilesystemTools()->replace_archive_name_variables($directory);
$config->set('volatile.postproc.directory', $directory);
return array(
'username' => $username,
'apikey' => $apikey,
'container' => $container,
'directory' => $directory,
);
}
}