PK     &!]TFz_?  ?  	  IsPro.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

/**
 * Is this Akeeba Backup Pro?
 *
 * @since   7.5.0
 */
trait IsPro
{
	/**
	 * Caches whether this is the Pro version of the software.
	 *
	 * @var   null|bool
	 * @since 7.5.0
	 */
	private $isPro = null;

	/**
	 * is this the Professional version of the software?
	 *
	 * @return  bool
	 * @since   7.5.0
	 */
	private function isPro(): bool
	{
		if (!is_null($this->isPro))
		{
			return $this->isPro;
		}

		$componentFolder = JPATH_ADMINISTRATOR . '/components/com_akeeba';
		$this->isPro     = is_dir($componentFolder . '/AliceEngine');

		return $this->isPro;
	}
}
PK     &!]E!|M  M    FilterRoots.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

use Akeeba\Backup\Admin\Model\DatabaseFilters;
use Akeeba\Engine\Factory;
use FOF40\Container\Container;

trait FilterRoots
{
	/**
	 * @param   string  $target
	 *
	 * @return  array
	 *
	 * @since   7.5.0
	 */
	private function getRoots(string $target): array
	{
		$container = Container::getInstance('com_akeeba', [], 'admin');
		$filters   = Factory::getFilters();
		$output    = [];

		switch ($target)
		{
			case 'fs':
				$rootInfo = $filters->getInclusions('dir');

				foreach ($rootInfo as $item)
				{
					$output[] = $item[0];
				}

				break;

			case 'db':
				/** @var DatabaseFilters $model */
				$model    = $container->factory->model('DatabaseFilters')->tmpInstance();
				$rootInfo = $model->get_roots();

				foreach ($rootInfo as $item)
				{
					$output[] = $item->value;
				}

				break;
		}

		return $output;
	}

}
PK     &!]c2      JsonGuiDataParser.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

use Akeeba\Engine\Factory;

trait JsonGuiDataParser
{
	/**
	 * Parse the JSON GUI definition returned by Akeeba Engine into something I can use to provide information about
	 * the options.
	 *
	 * @return  array
	 *
	 * @since   7.5.0
	 */
	private function parseJsonGuiData(): array
	{
		$jsonGUIData = Factory::getEngineParamsProvider()->getJsonGuiDefinition();
		$guiData     = json_decode($jsonGUIData, true);

		$ret = [
			'engines'    => [],
			'installers' => [],
			'options'    => [],
		];

		// Parse engines
		foreach ($guiData['engines'] as $engineType => $engineRecords)
		{
			if (!isset($ret['engines'][$engineType]))
			{
				$ret['engines'][$engineType] = [];
			}

			foreach ($engineRecords as $engineName => $record)
			{
				$ret['engines'][$engineType][$engineName] = [
					'title'       => $record['information']['title'],
					'description' => $record['information']['description'],
				];

				foreach ($record['parameters'] as $key => $optionRecord)
				{
					$ret['options'][$key] = array_merge($optionRecord, [
						'section' => $record['information']['title'],
					]);
				}
			}
		}

		// Parse installers
		foreach ($guiData['installers'] as $installerName => $installerInfo)
		{
			$ret['installers'][$installerName] = $installerInfo['name'];
		}

		// Parse GUI sections
		foreach ($guiData['gui'] as $section => $options)
		{
			foreach ($options as $key => $optionRecord)
			{
				$ret['options'][$key] = array_merge($optionRecord, [
					'section' => $section,
				]);
			}
		}

		return $ret;
	}

	/**
	 * Flattens the option tree returned by exportToJson into an array with dotted notation for each option.
	 *
	 * @param   array   $rawOptions  The option tree
	 * @param   string  $prefix      Current prefix, used for recursion
	 *
	 * @return  array
	 * @since   7.5.0
	 */
	private function flattenOptions(array $rawOptions, string $prefix = ''): array
	{
		$ret = [];

		foreach ($rawOptions as $k => $v)
		{
			if (is_array($v))
			{
				$ret = array_merge($ret, $this->flattenOptions($v, $prefix . $k . '.'));

				continue;
			}

			$ret[$prefix . $k] = $v;
		}

		return $ret;
	}

	/**
	 * Get the information for an option record.
	 *
	 * @param   string  $key   The option key
	 * @param   array   $info  The array returned by parseJsonGuiData
	 *
	 * @return  array
	 *
	 * @since   7.5.0
	 */
	private function getOptionInfo(string $key, array &$info): array
	{
		$ret = [];

		if (!isset($info['options'][$key]))
		{
			return $ret;
		}

		$keyInfo = $info['options'][$key];

		$ret = [
			'title'        => $keyInfo['title'],
			'description'  => $keyInfo['description'],
			'section'      => $keyInfo['section'],
			'type'         => $keyInfo['type'],
			'default'      => $keyInfo['default'],
			'options'      => [],
			'optionTitles' => [],
			'limits'       => [],
		];

		switch ($keyInfo['type'])
		{
			case 'integer':
				if (isset($keyInfo['shortcuts']))
				{
					$ret['options'] = explode('|', $keyInfo['shortcuts']);
				}

				$ret['limits'] = [
					'min' => $keyInfo['min'],
					'max' => $keyInfo['max'],
				];
				break;

			case 'bool':
				$ret['type']    = 'integer';
				$ret['options'] = [0, 1];
				$ret['limits']  = [
					'min' => 0,
					'max' => 1,
				];
				break;

			case 'engine':
				$ret['type']         = 'enum';
				$ret['type']         = 'string';
				$ret['options']      = array_keys($info['engines'][$keyInfo['subtype']]);
				$ret['optionTitles'] = [];

				foreach ($info['engines'][$keyInfo['subtype']] as $k => $details)
				{
					$ret['optionTitles'][$k] = $details['title'];
				}

				break;

			case 'installer':
				$ret['type']         = 'enum';
				$ret['type']         = 'string';
				$ret['options']      = array_keys($info['installers']);
				$ret['optionTitles'] = $info['installers'];

				break;

			case 'enum':
				$ret['type']         = 'string';
				$ret['options']      = explode('|', $keyInfo['enumvalues']);
				$ret['optionTitles'] = explode('|', $keyInfo['enumkeys']);

				break;

			case 'hidden':
			case 'button':
			case 'separator':
				$ret['type'] = 'hidden';
				break;

			case 'string':
			case 'browsedir':
			case 'password':
			default:
				$ret['type'] = 'string';
				break;
		}

		return $ret;
	}

}
PK     &!]~1!  !    PrintFormattedArray.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;


trait PrintFormattedArray
{
	/**
	 * Prints the array formatted with the specific format and returns an integer result
	 *
	 * @param   array   $data    The data to format and print
	 * @param   string  $format  One of table, json, yaml, csv, count
	 *
	 * @return  int
	 * @since   7.5.0
	 */
	private function printFormattedAndReturn(?array $data, string $format): int
	{
		if (empty($data) && ($format != 'count'))
		{
			return 0;
		}
		elseif (empty($data))
		{
			$data = [];
		}

		if (!empty($data))
		{
			$keys     = array_keys($data);
			$firstKey = array_shift($keys);
			$row      = $data[$firstKey];

			if (is_array($row))
			{
				$headers = array_keys($row);
			}
			else
			{
				$headers = array_keys($data);

				if (!in_array($format, ['json', 'yaml']))
				{
					$data = [$data];
				}
			}
		}

		switch ($format)
		{
			default:
			case 'table':
				$this->ioStyle->table($headers, $data);
				break;

			case 'json':
				$this->ioStyle->writeln(json_encode($data, JSON_PRETTY_PRINT));
				break;

			case 'yaml':
				if (!function_exists('yaml_emit'))
				{
					$this->ioStyle->error(<<< ERROR
Cannot generate YAML

Your PHP installation does not have the PHP YAML extension installed or enabled.

ERROR

					);

					return 1;
				}

				$this->ioStyle->writeln(yaml_emit($data));
				break;

			case 'csv':
				$this->ioStyle->writeln($this->toCsv($data));
				break;

			case 'count':
				$this->ioStyle->writeln(count($data));
				break;
		}

		return 0;
	}

	/**
	 * Converts an array to its CSV representation
	 *
	 * @param   array  $data       The array data to convert to CSV
	 * @param   bool   $csvHeader  Should I print a CSV header row?
	 *
	 * @return  string
	 * @since   7.5.0
	 */
	private function toCsv(array $data, bool $csvHeader = true): string
	{
		$output = '';
		$item   = array_pop($data);
		$data[] = $item;
		$keys   = array_keys($item);

		if ($csvHeader)
		{
			$csv = [];

			foreach ($keys as $k)
			{
				$k = str_replace('"', '""', $k);
				$k = str_replace("\r", '\\r', $k);
				$k = str_replace("\n", '\\n', $k);
				$k = '"' . $k . '"';

				$csv[] = $k;
			}

			$output .= implode(",", $csv) . "\r\n";
		}

		foreach ($data as $item)
		{
			$csv = [];

			foreach ($keys as $k)
			{
				$v = $item[$k];

				if (is_array($v))
				{
					$v = 'Array';
				}
				elseif (is_object($v))
				{
					$v = 'Object';
				}

				$v = str_replace('"', '""', $v);
				$v = str_replace("\r", '\\r', $v);
				$v = str_replace("\n", '\\n', $v);
				$v = '"' . $v . '"';

				$csv[] = $v;
			}

			$output .= implode(",", $csv) . "\r\n";
		}

		return $output;
	}
}
PK     &!]5KE  E    ComponentOptions.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

use Akeeba\Engine\Platform;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Form\FormField;

trait ComponentOptions
{
	private function getComponentOptions(bool $defaultValuesOnly = false): array
	{
		$output     = [];
		$fieldNames = [];

		$form = new Form('config');
		$form->loadFile(JPATH_ADMINISTRATOR . '/components/com_akeeba/config.xml', true, '//config');

		foreach ($form->getFieldsets() as $group => $fieldSetInfo)
		{
			$fields = $form->getFieldset($group);

			if (empty($fields))
			{
				continue;
			}

			foreach ($fields as $fieldName => $v)
			{
				if (!is_object($v) || !($v instanceof FormField))
				{
					continue;
				}

				if (substr((string) $v->type, -5) === 'Rules')
				{
					continue;
				}

				if (in_array(strtolower((string) $v->type), ['hidden', 'rules', 'spacer']))
				{
					continue;
				}

				$fieldNames[$fieldName] = $v->value ?? null;
			}
		}

		if (!$defaultValuesOnly)
		{
			foreach ($fieldNames as $k => $default)
			{
				$output[$k] = Platform::getInstance()->get_platform_configuration_option($k, $default);
			}
		}

		return $output;
	}
}
PK     &!]\      ConfigureIO.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Set up the Symfony I/O objects
 *
 * @since   7.5.0
 */
trait ConfigureIO
{
	/**
	 * @var   SymfonyStyle
	 * @since 7.5.0
	 */
	private $ioStyle;

	/**
	 * @var   InputInterface
	 * @since 7.5.0
	 */
	private $cliInput;

	/**
	 * Configure the IO.
	 *
	 * @param   InputInterface   $input   The input to inject into the command.
	 * @param   OutputInterface  $output  The output to inject into the command.
	 *
	 * @return  void
	 *
	 * @since   7.5.0
	 */
	private function configureSymfonyIO(InputInterface $input, OutputInterface $output)
	{
		$this->cliInput = $input;
		$this->ioStyle  = new SymfonyStyle($input, $output);
	}

}
PK     &!]7^P      TimeInfo.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

/**
 * Utility methods to get time information
 *
 * @since   7.5.0
 */
trait TimeInfo
{
	/**
	 * Returns a fancy formatted time lapse code
	 *
	 * @param   integer   $referenceDateTime  Timestamp of the reference date/time
	 * @param   int|null  $currentDateTime    Timestamp of the current date/time
	 * @param   string    $measureBy          One of s, m, h, d, or y (time unit)
	 * @param   boolean   $autoText           Append text automatically?
	 *
	 * @return  string
	 *
	 * @since   7.5.0
	 */
	private function timeAgo(int $referenceDateTime = 0, ?int $currentDateTime = null, string $measureBy = '', bool $autoText = true): string
	{
		if (is_null($currentDateTime))
		{
			$currentDateTime = time();
		}

		// Raw time difference
		$raw   = $currentDateTime - $referenceDateTime;
		$clean = abs($raw);

		$calcNum = [
			['s', 60],
			['m', 60 * 60],
			['h', 60 * 60 * 60],
			['d', 60 * 60 * 60 * 24],
			['y', 60 * 60 * 60 * 24 * 365],
		];

		$calc = [
			's' => [1, 'second'],
			'm' => [60, 'minute'],
			'h' => [60 * 60, 'hour'],
			'd' => [60 * 60 * 24, 'day'],
			'y' => [60 * 60 * 24 * 365, 'year'],
		];

		if ($measureBy == '')
		{
			$usemeasure = 's';

			for ($i = 0; $i < count($calcNum); $i++)
			{
				if ($clean <= $calcNum[$i][1])
				{
					$usemeasure = $calcNum[$i][0];
					$i          = count($calcNum);
				}
			}
		}
		else
		{
			$usemeasure = $measureBy;
		}

		$datedifference = floor($clean / $calc[$usemeasure][0]);

		if ($autoText == true && ($currentDateTime == time()))
		{
			if ($raw < 0)
			{
				$prospect = ' from now';
			}
			else
			{
				$prospect = ' ago';
			}
		}
		else
		{
			$prospect = '';
		}

		if ($referenceDateTime != 0)
		{
			if ($datedifference == 1)
			{
				return $datedifference . ' ' . $calc[$usemeasure][1] . ' ' . $prospect;
			}
			else
			{
				return $datedifference . ' ' . $calc[$usemeasure][1] . 's ' . $prospect;
			}
		}
		else
		{
			return 'No input time referenced.';
		}
	}
}
PK     &!]I{  {    ArgumentUtilities.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

/**
 * Utility methods to manage command arguments
 *
 * @since   7.5.0
 */
trait ArgumentUtilities
{
	/**
	 * Parse the overrides provided in the command line.
	 *
	 * Input: "key1=value1, key2= value2, key3 = value3"
	 * Output: ['key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3']
	 *
	 * @param   string  $rawString  The raw string
	 *
	 * @return  array  The parsed overrides
	 *
	 * @since   7.5.0
	 */
	private function commaListToMap(string $rawString): array
	{
		if (empty($rawString) || (trim($rawString) == ''))
		{
			return [];
		}

		$rawString = trim($rawString);
		$ret       = [];
		$lines     = explode($rawString, ",");

		foreach ($lines as $line)
		{
			if (strpos($line, '=') === false)
			{
				continue;
			}

			[$key, $value] = explode('=', $line);
			$key       = trim($key);
			$value     = trim($value);
			$ret[$key] = $value;
		}

		return $ret;
	}
}
PK     &!]}  }    MemoryInfo.phpnu &1i        <?php
/**
 * @package   akeebabackup
 * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\Backup\Admin\CliCommands\MixIt;

defined('_JEXEC') || die;

/**
 * Utility methods to get memory information
 *
 * @since   7.5.0
 */
trait MemoryInfo
{
	/**
	 * Returns the current memory usage
	 *
	 * @return  string
	 *
	 * @since   7.5.0
	 */
	private function memUsage(): string
	{
		if (function_exists('memory_get_usage'))
		{
			$size = memory_get_usage();
			$unit = ['b', 'KB', 'MB', 'GB', 'TB', 'PB'];

			return @round($size / 1024 ** ($i = floor(log($size, 1024))), 2) . ' ' . $unit[$i];
		}
		else
		{
			return "(unknown)";
		}
	}

	/**
	 * Returns the peak memory usage
	 *
	 * @return  string
	 *
	 * @since   7.5.0
	 */
	private function peakMemUsage(): string
	{
		if (function_exists('memory_get_peak_usage'))
		{
			$size = memory_get_peak_usage();
			$unit = ['b', 'KB', 'MB', 'GB', 'TB', 'PB'];

			return @round($size / 1024 ** ($i = floor(log($size, 1024))), 2) . ' ' . $unit[$i];
		}
		else
		{
			return "(unknown)";
		}
	}
}
PK       &!]TFz_?  ?  	                IsPro.phpnu &1i        PK       &!]E!|M  M              x  FilterRoots.phpnu &1i        PK       &!]c2                  JsonGuiDataParser.phpnu &1i        PK       &!]~1!  !                PrintFormattedArray.phpnu &1i        PK       &!]5KE  E              G%  ComponentOptions.phpnu &1i        PK       &!]\                *  ConfigureIO.phpnu &1i        PK       &!]7^P                -/  TimeInfo.phpnu &1i        PK       &!]I{  {              8  ArgumentUtilities.phpnu &1i        PK       &!]}  }              <  MemoryInfo.phpnu &1i        PK    	 	   A 