Skip to content

Instantly share code, notes, and snippets.

@delphinpro
Created December 24, 2019 20:52
Show Gist options
  • Save delphinpro/11c816c355970e797a8dfc88953755a3 to your computer and use it in GitHub Desktop.
Save delphinpro/11c816c355970e797a8dfc88953755a3 to your computer and use it in GitHub Desktop.
Backup & Restore content data in EvolutionCMS 2.x
  php artisan backup
  php artisan backup:restore
<?php
/**
* @author delphinpro <[email protected]>
* @copyright copyright © 2019 delphinpro
* @license licensed under the MIT license
*
* File: core/custom/packages/custom/src/Console/BackupCommand.php
*/
namespace EvolutionCMS\Custom\Console;
use EvolutionCMS\Models\SiteContent;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class BackupCommand extends Command
{
protected $signature = 'backup';
protected $description = 'Backup content data';
protected $directory = EVO_STORAGE_PATH.'backup/';
protected $currentDir = '';
/** @var \DocumentParser */
protected $evo;
public function __construct()
{
parent::__construct();
$this->evo = EvolutionCMS();
$dir = date('Y-m-d-Hi');
$this->currentDir = $this->directory.$dir.'/';
}
public function handle()
{
$this->comment('Backup into '.$this->currentDir);
if (!is_dir($this->currentDir)) {
if (!mkdir($this->currentDir, 0777, true)) {
$this->comment('Can\'t create directory: '.$this->currentDir);
return;
}
} else {
self::rmDir($this->currentDir);
if (!mkdir($this->currentDir, 0777, true)) {
$this->comment('Can\'t create directory: '.$this->currentDir);
return;
}
}
$this->comment('Directory OK');
$this->saveContent();
}
private function saveContent()
{
$this->info("Processing ...");
$filename = $this->currentDir.'content'.'.json';
if (!$handle = fopen($filename, 'wb')) {
$this->error("Can\'t open file: ($filename)");
return;
}
/** @var SiteContent $doc */
foreach (SiteContent::select()->get() as $doc) {
$pb = [];
$tvs = [];
foreach ($doc->getTvAttribute()->toArray() as $tv) {
$tvs[$tv['name']] = $tv['value'];
}
$docArr = $doc->toArray();
foreach ($docArr['tpl']['tvs'] as $item) {
if ($item['type'] == 'custom_tv:pagebuilder') {
$pb[$item['name']] = [];
foreach (DB::table('pagebuilder')->where('document_id', $doc->id)->get() as $block) {
$data = ((array)$block);
$data['values'] = json_decode($data['values'], true);
$pb[$item['name']][] = array_values($data);
}
}
}
unset($docArr['tpl']);
unset($docArr['template_values']);
$template = $doc->tpl()->get()->toArray();
$data = [
'document' => $docArr,
'template' => empty($template) ? null : $template[0]['templatealias'],
'pb' => $pb,
'tvs' => $tvs,
];
$itemContent = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
if (fwrite($handle, $itemContent."\n") === false) {
echo "Can\'t write to file: ($filename)";
break;
}
$this->info('['.$docArr['id'].'] '.$docArr['alias'].' OK');
}
fclose($handle);
$this->info("OK");
}
private static function rmDir($dir)
{
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
if (is_dir($dir.DIRECTORY_SEPARATOR.$object)
&& !is_link($dir.DIRECTORY_SEPARATOR.$object)
) {
self::rmDir($dir.DIRECTORY_SEPARATOR.$object);
} else {
unlink($dir.DIRECTORY_SEPARATOR.$object);
}
}
}
rmdir($dir);
}
}
}
<?php
/**
* @author delphinpro <[email protected]>
* @copyright copyright © 2019 delphinpro
* @license licensed under the MIT license
*
* File: core/custom/packages/custom/src/CustomServiceProvider.php
*/
namespace EvolutionCMS\Custom;
use EvolutionCMS\ServiceProvider;
class CustomServiceProvider extends ServiceProvider
{
protected $namespace = 'custom';
protected $commands = [
'EvolutionCMS\Custom\Console\BackupCommand',
'EvolutionCMS\Custom\Console\RestoreCommand',
];
public function register()
{
$this->commands($this->commands);
}
}
<?php
/**
* @author delphinpro <[email protected]>
* @copyright copyright © 2019 delphinpro
* @license licensed under the MIT license
*
* File: core/custom/packages/custom/src/Console/RestoreCommand.php
*/
namespace EvolutionCMS\Custom\Console;
use EvolutionCMS\Models\SiteContent;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class RestoreCommand extends Command
{
/** @var string */
protected $signature = 'backup:restore';
/** @var string */
protected $description = 'Restore backup data';
protected $directory = EVO_STORAGE_PATH.'backup/';
protected $currentDir = '';
/** @var \DocumentParser */
protected $evo;
public function __construct()
{
parent::__construct();
$this->evo = EvolutionCMS();
$objects = scandir($this->directory, SCANDIR_SORT_ASCENDING);
$objects = array_filter($objects, function ($item) { return $item != '.' && $item != '..'; });
if (!empty($objects)) {
$dir = array_pop($objects);
$this->currentDir = $this->directory.$dir.'/';
}
}
public function handle()
{
$this->comment('Restore backup from '.$this->currentDir);
if (!is_dir($this->currentDir)) {
$this->comment('Directory is exists! Cancelled.');
return;
}
$this->restoreContent();
}
private function restoreContent()
{
$this->info("Clear tables ...");
DB::table('site_content')->truncate();
$this->info(" site_content: OK");
DB::table('site_tmplvar_contentvalues')->truncate();
$this->info(" site_tmplvar_contentvalues: OK");
DB::table('pagebuilder')->truncate();
$this->info(" pagebuilder: OK");
$this->info("Processing ...");
$filename = $this->currentDir.'content'.'.json';
if (!$handle = fopen($filename, 'r')) {
$this->error("Can\'t open file: ($filename)");
return;
}
$pageBuilderKeys = [
'id',
'document_id',
'container',
'title',
'config',
'values',
'visible',
'index',
];
while (($buffer = fgets($handle)) !== false) {
$data = json_decode($buffer, true);
if ($data['template']) {
$templateId = $this->evo->getConfig('tpl:'.$data['template']);
if ($templateId) {
$data['document']['template'] = (int)$templateId;
}
}
SiteContent::insert($data['document']);
$doc = SiteContent::find($data['document']['id']);
foreach ($data['tvs'] as $tvName => $tvValue) {
$doc->templateValues()->create([
'tmplvarid' => $this->evo->getConfig('tv:'.$tvName),
'value' => $tvValue,
]);
}
foreach ($data['pb'] as $pbName => $tvContainer) {
foreach ($tvContainer as $pbBlock) {
$pbBlock[5] = json_encode($pbBlock[5], JSON_UNESCAPED_UNICODE);
DB::table('pagebuilder')->insert(
array_combine($pageBuilderKeys, $pbBlock)
);
}
}
$s = ''
.'['.$data['document']['id'].'] '
.'/'.$data['document']['alias'].' '
.' OK';
$this->info($s);
}
if (!feof($handle)) {
$this->error("Error: fgets() unexpectedly failed");
}
fclose($handle);
$this->evo->clearCache('full');
$this->info("Complete.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment