File: /var/www/gosurya-id/wp-content/plugins/akeebabackupwp/app/Solo/Model/Manage.php
<?php
/**
* @package solo
* @copyright Copyright (c)2014-2021 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace Solo\Model;
use Akeeba\Engine\Factory;
use Akeeba\Engine\Platform;
use Awf\Mvc\Model;
use Awf\Pagination\Pagination;
use Awf\Text\Text;
use Exception;
class Manage extends Model
{
/** @var Pagination The pagination model for this data */
protected $pagination = null;
public function __construct(\Awf\Container\Container $container = null)
{
parent::__construct($container);
$limit = $this->getUserStateFromRequest('solo_limit', 'limit', 10, 'int');
$limitStart = $this->getUserStateFromRequest('solo_manage_start', 'limitstart', 0, 'int');
$this->setState('limit', $limit);
$this->setState('limitStart', $limitStart);
}
/**
* Returns the same list as getStatisticsList(), but includes an extra field
* named 'meta' which categorises attempts based on their backup archive status
*
* @param boolean $overrideLimits Should I override all list limits?
* @param array $filters Filters to apply, see PlatformInterface::get_statistics_list
* @param array $order Record ordering information (By and Ordering)
*
* @return array An array of backup attempt objects
*/
public function &getStatisticsListWithMeta($overrideLimits = false, $filters = null, $order = null)
{
$limitstart = $this->getState('limitstart');
$limit = $this->getState('limit');
if ($overrideLimits)
{
$limitstart = 0;
$limit = 0;
$filters = null;
}
$allStats = Platform::getInstance()->get_statistics_list([
'limitstart' => $limitstart,
'limit' => $limit,
'filters' => $filters,
'order' => $order,
]);
$valid = Platform::getInstance()->get_valid_backup_records();
if (empty($valid))
{
$valid = [];
}
// This will hold the entries whose files are no longer present and are
// not already marked as such in the database
$updateNonExistent = [];
$new_stats = [];
if (!empty($allStats))
{
foreach ($allStats as $stat)
{
$total_size = 0;
if (in_array($stat['id'], $valid))
{
$archives = Factory::getStatistics()->get_all_filenames($stat);
$count = is_array($archives) ? count($archives) : 0;
$stat['meta'] = ($count > 0) ? 'ok' : 'obsolete';
if ($stat['meta'] == 'ok')
{
if ($stat['total_size'])
{
$total_size = $stat['total_size'];
}
else
{
$total_size = 0;
foreach ($archives as $filename)
{
$total_size += @filesize($filename);
}
}
}
else
{
if ($stat['total_size'])
{
$total_size = $stat['total_size'];
}
if ($stat['filesexist'])
{
$updateNonExistent[] = $stat['id'];
}
// If there is a "remote_filename", the record is "remote", not "obsolete"
if ($stat['remote_filename'])
{
$stat['meta'] = 'remote';
}
}
$stat['size'] = $total_size;
}
else
{
switch ($stat['status'])
{
case 'run':
$stat['meta'] = 'pending';
break;
case 'fail':
$stat['meta'] = 'fail';
break;
default:
if ($stat['remote_filename'])
{
// If there is a "remote_filename", the record is "remote", not "obsolete"
$stat['meta'] = 'remote';
}
else
{
// Else, it's "obsolete"
$stat['meta'] = 'obsolete';
}
break;
}
}
$new_stats[] = $stat;
}
}
// Update records found as not having files any more
if (count($updateNonExistent))
{
Platform::getInstance()->invalidate_backup_records($updateNonExistent);
}
unset($valid);
return $new_stats;
}
/**
* Delete the stats record whose ID is set in the model
*
* @return boolean True on success
*
* @throws \RuntimeException
*/
public function delete()
{
$id = $this->getState('id', 0);
if ((!is_numeric($id)) || ($id <= 0))
{
throw new \RuntimeException(Text::_('COM_AKEEBA_BUADMIN_ERROR_INVALIDID'), 500);
}
// Try to delete files
$this->deleteFile();
Platform::getInstance()->delete_statistics($id);
return true;
}
/**
* Delete the backup file of the stats record whose ID is set in the model
*
* @return boolean True on success
*
* @throws \RuntimeException
*/
public function deleteFile()
{
$id = $this->getState('id', 0);
if ((!is_numeric($id)) || ($id <= 0))
{
throw new \RuntimeException(Text::_('COM_AKEEBA_BUADMIN_ERROR_INVALIDID'), 500);
}
$stat = Platform::getInstance()->get_statistics($id);
$allFiles = Factory::getStatistics()->get_all_filenames($stat, false);
// Remove the custom log file if necessary
if (!is_null($stat))
{
$this->_deleteLogs($stat);
}
// Make sure we have some files
if (empty($allFiles))
{
return true;
}
// Get a reference to the filesystem abstraction
$fs = $this->container->fileSystem;
// Set the default status
$status = true;
// Delete all archive files
foreach ($allFiles as $filename)
{
try
{
$fs->delete($filename);
}
catch (\Exception $e)
{
// Ignore file deletion failure
$status = false;
}
}
return $status;
}
/**
* Get a pagination object
*
* @param array $filters Any filters to use
*
* @return Pagination
*/
public function &getPagination($filters = null)
{
if (!is_object($this->pagination))
{
// Prepare pagination values
$total = Platform::getInstance()->get_statistics_count($filters);
$limitStart = $this->getState('limitStart');
$limit = $this->getState('limit');
// Create the pagination object
$this->pagination = new Pagination($total, $limitStart, $limit, 10, $this->container->application);
}
return $this->pagination;
}
/**
* Gets the post-processing engine for each backup profile
*
* @return array Key/value where key=profile ID, value=post-processing engine
*/
public function getPostProcessingEnginePerProfile()
{
// Cache the current profile
$currentProfileID = Platform::getInstance()->get_active_profile();
$db = $this->container->db;
$query = $db->getQuery(true)
->select($db->qn('id'))
->from($db->qn('#__ak_profiles'));
$db->setQuery($query);
$profiles = $db->loadColumn();
$engines = [];
foreach ($profiles as $profileID)
{
Platform::getInstance()->load_configuration($profileID);
$pConf = Factory::getConfiguration();
$engines[$profileID] = $pConf->get('akeeba.advanced.postproc_engine');
}
Platform::getInstance()->load_configuration($currentProfileID);
return $engines;
}
public function hideRestorationInstructionsModal()
{
$config = $this->container->appConfig;
$config->set('options.show_howtorestoremodal', 0);
$config->saveConfiguration();
}
/**
* Freeze or melt a backup report
*
* @param array $ids Array of backup IDs that should be updated
* @param int $freeze 1= freeze, 0= melt
*
* @throws Exception
*/
public function freezeUnfreezeRecords(array $ids, $freeze)
{
if (!$ids)
{
return;
}
$freeze = (int) $freeze;
foreach ($ids as $id)
{
// If anything wrong happens, let the exception bubble up, so it will be reported
Platform::getInstance()->set_or_update_statistics($id, ['frozen' => $freeze]);
}
}
/**
* Deletes the backup-specific log files of a stats record
*
* @param array $stat The array holding the backup stats record
*
* @return void
*/
protected function _deleteLogs(array $stat)
{
// We can't delete logs if there is no backup ID in the record
if (!isset($stat['backupid']) || empty($stat['backupid']))
{
return;
}
$fs = $this->container->fileSystem;
$logFileNames = [
'akeeba.' . $stat['tag'] . '.' . $stat['backupid'] . '.log',
'akeeba.' . $stat['tag'] . '.' . $stat['backupid'] . '.log.php',
];
foreach ($logFileNames as $logFileName)
{
$logPath = dirname($stat['absolute_path']) . '/' . $logFileName;
try
{
$fs->delete($logPath);
}
catch (\Exception $e)
{
// Ignore file deletion failure
}
}
}
}