Current Directory: /home/astoriaah/www/old15/administrator/components/com_akeeba/engine/Postproc
Viewing File: /home/astoriaah/www/old15/administrator/components/com_akeeba/engine/Postproc/Webdav.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\Davclient as ConnectorDavclient;
class Webdav extends Base
{
/** @var string Username */
protected $username;
/** @var string Password */
protected $password;
/** @var int The retry count of this file (allow up to 2 retries after the first upload failure) */
private $tryCount = 0;
/** @var ConnectorDavclient WebDAV client */
private $webdav;
/** @var string The currently configured directory */
private $directory;
public function __construct()
{
$this->can_download_to_browser = false;
$this->can_delete = true;
$this->can_download_to_file = true;
}
public function processPart($absolute_filename, $upload_as = null)
{
$settings = $this->_getSettings();
if ($settings === false)
{
return false;
}
$directory = $this->directory;
$basename = empty($upload_as) ? basename($absolute_filename) : $upload_as;
try
{
$result = $this->putFile($absolute_filename, $directory, $basename);
}
catch (\Exception $e)
{
$result = false;
$this->setWarning($e->getMessage());
}
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;
}
// Download the file
$done = false;
try
{
$handle = fopen($localFile, 'w+');
$this->webdav->request('GET', $remotePath, $handle);
$done = true;
fclose($handle);
}
catch (\Exception $e)
{
fclose($handle);
}
if (!$done)
{
try
{
$handle = fopen($localFile, 'w+');
$this->webdav->request('GET', $remotePath, $handle);
fclose($handle);
}
catch (\Exception $e)
{
fclose($handle);
$this->setWarning($e->getMessage());
return false;
}
}
return true;
}
public function delete($path)
{
// Get settings
$settings = $this->_getSettings();
if ($settings === false)
{
return false;
}
// Remove starting slash, or CloudMe will read it as an absolute path
$path = '/' . ltrim($path, '/');
$done = false;
try
{
$this->webdav->request('DELETE', $path);
$done = true;
}
catch (\Exception $e)
{
//Do nothing
}
if (!$done)
{
try
{
$this->webdav->request('DELETE', $path);
}
catch (\Exception $e)
{
$this->setWarning($e->getMessage());
return false;
}
}
return true;
}
protected function _getSettings()
{
// Retrieve engine configuration data
$config = Factory::getConfiguration();
$username = trim($config->get('engine.postproc.webdav.username', ''));
$password = trim($config->get('engine.postproc.webdav.password', ''));
$url = trim($config->get('engine.postproc.webdav.url', ''));
$this->directory = $config->get('volatile.postproc.directory', null);
if (empty($this->directory))
{
$this->directory = $config->get('engine.postproc.webdav.directory', '');
}
// Sanity checks
if (empty($username) || empty($password))
{
$this->setError('You have not linked Akeeba Backup with your WebDav 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);
$settings = array(
'baseUri' => $url,
'userName' => $username,
'password' => $password,
);
$this->webdav = new ConnectorDavclient($settings);
$this->webdav->addTrustedCertificates(AKEEBA_CACERT_PEM);
return true;
}
protected function putFile($absolute_filename, $directory, $basename)
{
// Store the absolute remote path in the class property
// Let's remove the starting slash, otherwise it read as an absolute path
$this->remote_path = trim(trim($directory, '/') . '/' . $basename, '/');
// A directory is supplied, let's check if it really exists or not
if ($directory)
{
$checkPath = '';
$parts = explode('/', $directory);
foreach ($parts as $part)
{
if (!$part)
{
continue;
}
$checkPath .= $part . '/';
try
{
Factory::getLog()->log(LogLevel::DEBUG, "Checking if the following remote path exists: " . $checkPath);
$this->webdav->propFind($checkPath, array('{DAV:}resourcetype'));
}
catch (\Exception $e)
{
Factory::getLog()->log(LogLevel::DEBUG, "Received the following exception while checking if the remote folder exists: " . $e->getCode() . ' - ' . $e->getMessage());
// If the folder doesn't exists an error 404 is returned
if ($e->getCode() != 404)
{
Factory::getLog()->log(LogLevel::DEBUG, "Error code different than 404, this means that a real error occurred");
return false;
}
Factory::getLog()->log(LogLevel::DEBUG, "Remote path $checkPath does not exists, I'm going to create it");
// Folder doesn't exist, let's create it
try
{
$this->webdav->request('MKCOL', $checkPath);
}
catch (\Exception $e)
{
Factory::getLog()->log(LogLevel::DEBUG, "The following error occurred while creating the remote folder $checkPath: " . $e->getCode() . ' - ' . $e->getMessage());
return false;
}
Factory::getLog()->log(LogLevel::DEBUG, "Remote path $checkPath created");
}
}
}
$this->remote_path = '/' . ltrim($this->remote_path, '/');
$result = $this->webdav->request('PUT', $this->remote_path, file_get_contents($absolute_filename));
return $result;
}
}