<?php
/*
	Resale is forbidden!
	Copyright © Alexander Sunvas*
	http://eleanor-cms.ru
	a@eleanor-cms.ru
	*Pseudonym
*/
defined('CMS')||die;

class TaskSpecial_YaBackUp extends BaseClass implements Task
{
	private
		$opts=array(),
		$data=array();

	public function __construct($opts)
	{
		$this->opts=$opts;
	}

	public function Run($data)
	{
		$data=(array)$data;
		$config=Eleanor::$root.'addons/config_yabackup.php';

		if(!is_file($config))
			return true;

		$config=include$config;

		if(isset($data['files']))
		{#Шаг 3: заливка на Яндекс

			include Eleanor::$root.'core/others/yabackup/YaAuth.php';
			include Eleanor::$root.'core/others/yabackup/YaDisk.php';

			try
			{
				$Auth=new YaAuth($config);
				$token=$Auth->GetToken();
				$Disk=new YaDisk($token);

				$Disk->MkDir($config['server']);
				$Disk->Upload($data['archive'],$config['server'].'/'.basename($data['archive']));

				if(is_file($data['archive']))
					Files::Delete($data['archive']);

				if($config['cnt']>0)
				{
					$list=$Disk->Scandir($config['server']);

					$paths=array();
					foreach($list['files'] as $file)
					{
						$item=basename($file,'.zip');
						$item=preg_split('/\D+/',$item);
						$item=mktime($item[3],$item[4],$item[5],$item[1],$item[2],$item[0]);

						if($item)
							$paths[ $item ]=$file;
					}

					if(count($paths)>$config['cnt'])
					{
						krsort($paths,SORT_NUMERIC);
						array_splice($paths,0,$config['cnt']);
						foreach($paths as $file)
							$Disk->Unlink($config['server'].'/'.$file);
					}

				}
			}
			catch(EE$E)
			{
				$error=$E->getMessage();

				if($error=='EMPTY_TOKEN')
					$error='Неправильные данные аутентификации.';

				file_put_contents(Eleanor::$root.'addons/logs/yabackup.txt',date('Y-m-d H:i:s')." - Бэкап не состоялся: {$error}\n");
			}

			$this->data=array();

			return true;
		}
		elseif(isset($data['db']))
		{#Шаг 2: Добавляем файлы
			$zip=new ZipArchive;
			$zip->open($data['archive'], ZIPARCHIVE::CREATE);

			if($config['files'])
			{
				foreach(explode(',',$config['files']) as $v)
				{
					$v=Eleanor::$root.trim($v);

					if(file_exists($v))
						static::Zip($zip,$v,'files/'.basename($v),$data['dest']);
				}
			}
			else
				static::Zip($zip,Eleanor::$root,'files/',$data['dest']);

			if(is_file($data['tables']))
				$zip->addFile($data['tables'],'tables.sql');

			if(is_file($data['data']))
				$zip->addFile($data['data'],'data.sql');

			$zip->close();

			$data['files']=true;;
		}
		else
		{
			$dest=$config['local'] ? Eleanor::$root.rtrim($config['local'],'/\\') : Eleanor::$root;

			Files::MkDir($dest);
			$dest=realpath($dest).DIRECTORY_SEPARATOR;

			$data=array(
				'dest'=>$dest,
				'archive'=>$dest.date('Y-m-d_H-i-s').'.zip',
				'tables'=>$dest.'tables.sql',
				'data'=>$dest.'data.sql',
			);

			#Шаг 1: бэкап базы данных
			if(Eleanor::$os=='u')
			{
				$conf=file_get_contents(Eleanor::$root.'config_general.php');
				$conf=strchr($conf,'return ');
				$conf=eval($conf);

				$user=$conf['db_user'];
				$password=$conf['db_pass'];
				$host=$conf['db_host'];
				$database=$conf['db'];

				$charset=DB_CHARSET;
				$file=$data['tables'];
				$tables=$config['tables'];

				`mysqldump -u$user -p$password -h$host -d --default-character-set=$charset --quote-names --allow-keywords --add-drop-table --set-charset --result-file=$file $database $tables`;

				$file=$data['data'];

				`mysqldump -u$user -p$password -h$host -t --default-character-set=$charset --add-drop-table --create-options --quick --allow-keywords --max_allowed_packet=16M --quote-names --complete-insert --set-charset --result-file=$file $database $tables`;

				$data['db']=true;
			}
			else
				$data['db']=true;
		}

		$this->data=$data;

		return false;
	}

	public function GetNextRunInfo()
	{
		return$this->data;
	}

	/**
	 * Копирование файлов и каталогов
	 * @param string $source Источник: путь откуда будет происходить копирование
	 * @param string $dest Назначение: путь, куда будет происходить копирование
	 */
	protected static function Zip($zip,$source,$dest,$exclude)
	{
		#Путь может быть неполным
		$source=realpath($source);

		if(is_file($source))
			return $zip->addFile($source,$dest.basename($source));

		$zip->addEmptyDir($dest);

		$f=__FUNCTION__;
		$files=array_diff(scandir($source),array('.','..'));

		foreach($files as $entry)
		{
			$fullentry=$source.DIRECTORY_SEPARATOR.$entry;

			if(strpos($fullentry,$exclude)===false)
				if(is_dir($fullentry))
					static::$f($zip,$fullentry,$dest.$entry.'/',$exclude);
				else
					$zip->addFile($fullentry,$dest.$entry);
		}

		return true;
	}
}