Поскольку ваш вопрос довольно широкий, я дам вам довольно широкий ответ; обычно я даже не отвечал на подобные вопросы, но у меня просто есть соответствующий сценарий, который я сделал некоторое время назад.
Это НЕ подключи и играй и имеет некоторые сторонние зависимости от CakePHP, которые должны быть автоматически загружены.
Сценарий создает изображение всех указанных папок в массиве, добавляет манифест файлов и файл идентификатора, например, ВЕРСИЯ 2. Изображение (zip-файл) затем может быть загружено на сайт под управлением ВЕРСИИ 1, если оно имеет ту же модель обновления. После загрузки модель извлекает файлы, если в zip-файле содержится действительный файл идентификатора (чтобы пользователи не могли загружать несвязанный zip-файл и очищать систему от ядра); Сценарий также создает текущее изображение сайта (на ВЕРСИИ 1) на случай необходимости восстановления.
Скрипт также имеет функцию восстановления предыдущей версии, которая удалит все дополнительные файлы, которые были в версии 2, а не 1, и восстановит исходные файлы 1.
Я не предлагаю никакой поддержки для этого. Но, надеюсь, вы найдете это немного полезным - это вроде как взломано вместе, но в моем ограниченном тестировании это работало нормально.
Контроллер:
<?php
if (!defined('BASEPATH')) {
exit('No direct script access allowed');
}
/**
*
* NEOU CMS v4 CI Edition
* @copyright (c) 2018, Alexander Fagard
* @requires PHP version >= 5.6
*
* You cannot redistribute this document without written permission from the author
*
*/
class Update extends MY_Backend {
static $perm = ['admin_only' => true];
public function __construct() {
parent::__construct();
$this->lang->load('core_update');
$this->load->model('backend/core_update_model', 'update');
}
public function index() {
$this->tpl->head($this->lang->line('update_heading'));
$this->tpl->body();
$this->output->append_output($this->messages->display());
$data = array(
'is_local' => $this->localization->is_local(),
'previous_exist' => $this->update->previous_exists()
);
$this->parser->parse('backend/core_update', $data);
$this->tpl->footer();
}
public function restore() {
try {
$this->update->restore_previous();
rmdir_recursive($this->update->updates_folder);
$this->messages->success($this->lang->line('update_previous_restored'));
} catch (Exception $e) {
$this->messages->error($e->getMessage());
} finally {
redirect(CMS_DIR_NAME . '/update');
}
}
public function apply() {
$this->load->helper('byte_helper');
try {
$this->update->mk_update_dir();
$config['upload_path'] = $this->update->updates_folder;
$config['overwrite'] = true;
$config['allowed_types'] = 'zip';
$config['max_size'] = convert_bytes_to_type(file_upload_max_size(), 'KB');
$config['file_ext_tolower'] = true;
$this->load->library('upload', $config);
if (!$this->upload->do_upload('update')) {
throw new Exception($this->upload->display_errors('', ''));
}
$data = $this->upload->data();
$this->update->apply_update($data['full_path']);
$this->messages->success($this->lang->line('update_applied'));
} catch (Exception $e) {
$this->messages->error($e->getMessage());
} finally {
redirect(CMS_DIR_NAME . '/update');
}
}
public function create() {
if (!$this->localization->is_local()) {
show_error($this->lang->line('update_localhost'), 500);
}
try {
$this->update->create_update();
$this->messages->success(sprintf($this->lang->line('update_created'), $this->update->files_processed));
} catch (Exception $e) {
$this->messages->error($e->getMessage());
} finally {
redirect(CMS_DIR_NAME . '/update');
}
}
}
Модель: https://pastebin.com/UuzQ1tds