4 Star 3 Fork 5

Gitee 极速下载 / Mautic

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/mautic/mautic
克隆/下载
upgrade.php 33.79 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
<?php
ini_set('display_errors', 'Off');
date_default_timezone_set('UTC');
// Running this script standalone is no longer supported
$standalone = 0;
$task = getVar('task');
define('IN_CLI', 'cli' === php_sapi_name());
define('MAUTIC_ROOT', (IN_CLI || empty($task)) ? __DIR__ : dirname(__DIR__));
define('MAUTIC_APP_ROOT', MAUTIC_ROOT.'/app');
if (IN_CLI) {
if (!file_exists(__DIR__.'/upgrade')) {
mkdir(__DIR__.'/upgrade');
}
define('MAUTIC_UPGRADE_ROOT', __DIR__.'/upgrade');
} else {
define('MAUTIC_UPGRADE_ROOT', __DIR__);
}
// Fail-safe PHP version check
if (file_exists(MAUTIC_UPGRADE_ROOT.'/app/release_metadata.json')) {
$metadata = json_decode(file_get_contents(MAUTIC_UPGRADE_ROOT.'/app/release_metadata.json'), true);
// Are we running the minimum version?
if (version_compare(PHP_VERSION, $metadata['minimum_php_version'], 'lt')) {
echo 'Your server does not meet the minimum PHP requirements. Mautic requires PHP version '.$metadata['minimum_php_version'].' while your server has '
.PHP_VERSION.'. Please contact your host to update your PHP installation.'."\n";
exit;
}
// Are we running a version newer than what Mautic supports?
if (version_compare(PHP_VERSION, $metadata['maximum_php_version'], 'gt')) {
echo 'Mautic does not support PHP version '.PHP_VERSION.' at this time. To use Mautic, you will need to downgrade to an earlier version.'
."\n";
exit;
}
}
// Get local parameters
$localParameters = get_local_config();
$cacheDir = (isset($localParameters['cache_path'])) ? str_replace('%kernel.project_dir%', MAUTIC_ROOT, $localParameters['cache_path'].'/prod') : MAUTIC_ROOT.'/var/cache/prod';
$logDir = (isset($localParameters['log_path'])) ? str_replace('%kernel.project_dir%', MAUTIC_ROOT, $localParameters['log_path'].'/prod') : MAUTIC_ROOT.'/var/logs';
define('MAUTIC_CACHE_DIR', $cacheDir);
define('MAUTIC_UPGRADE_ERROR_LOG', $logDir.'/upgrade_errors.php');
/*
* Updating to 2.8.1: Check to see if we have a mautic_session_name
* and use that to populate the actual session name that will be
* generated after a successful update.
*/
if (isset($_COOKIE['mautic_session_name'])) {
$sessionValue = $_COOKIE[$_COOKIE['mautic_session_name']];
include MAUTIC_APP_ROOT.'/config/paths.php';
$localConfigPath = str_replace('%kernel.project_dir%', MAUTIC_ROOT, $paths['local_config']);
$newSessionName = md5(md5($localConfigPath).$localParameters['secret_key']);
setcookie($newSessionName, $sessionValue, 0, '/', '', false, true);
unset($_COOKIE['mautic_session_name']);
setcookie('mautic_session_name', '', -1);
}
// Fetch the update state out of the request if applicable
$state = json_decode(base64_decode(getVar('updateState', 'W10=')), true);
// Prime the state if it's empty
if (empty($state)) {
$state['pluginComplete'] = false;
$state['bundleComplete'] = false;
$state['cacheComplete'] = false;
$state['coreComplete'] = false;
$state['vendorComplete'] = false;
}
$status = ['complete' => false, 'error' => false, 'updateState' => $state, 'stepStatus' => 'In Progress'];
if (IN_CLI) {
echo "Upgrading through upgrade.php using the CLI is no longer supported. Please use 'php bin/console mautic:update:find' instead. \n";
exit(1);
}
// Web request upgrade
$request = explode('?', $_SERVER['REQUEST_URI'])[0];
$url = "//{$_SERVER['HTTP_HOST']}{$request}";
$isSSL = (!empty($_SERVER['HTTPS']) && 'off' != $_SERVER['HTTPS']);
$cookie_path = (isset($localParameters['cookie_path'])) ? $localParameters['cookie_path'] : '/';
$cookie_domain = (isset($localParameters['cookie_domain'])) ? $localParameters['cookie_domain'] : '';
$cookie_secure = (isset($localParameters['cookie_secure'])) ? $localParameters['cookie_secure'] : $isSSL;
$cookie_httponly = (isset($localParameters['cookie_httponly'])) ? $localParameters['cookie_httponly'] : false;
setcookie('mautic_update', $task, time() + 300, $cookie_path, $cookie_domain, $cookie_secure, $cookie_httponly);
$query = '';
$maxCount = 5;
switch ($task) {
case '':
html_body("<div class='well text-center'>This script cannot run standalone. Please log into Mautic to check for updates.</div>");
// no break
case 'moveBundles':
$status = move_mautic_bundles($status, $maxCount);
if (empty($status['complete'])) {
if (!isset($state['refresh_count'])) {
$state['refresh_count'] = 1;
}
$nextTask = 'moveBundles';
$query = 'count='.$state['refresh_count'].'&';
++$state['refresh_count'];
} else {
$nextTask = 'moveCore';
unset($state['refresh_count']);
}
break;
case 'moveCore':
$status = move_mautic_core($status);
$nextTask = 'moveVendors';
break;
case 'moveVendors':
$status = move_mautic_vendors($status, $maxCount);
$nextTask = (!empty($status['complete'])) ? 'clearCache' : 'moveVendors';
if (empty($status['complete'])) {
if (!isset($state['refresh_count'])) {
$state['refresh_count'] = 1;
}
$nextTask = 'moveVendors';
$query = 'count='.$state['refresh_count'].'&';
++$state['refresh_count'];
} else {
$nextTask = 'clearCache';
unset($state['refresh_count']);
}
break;
case 'clearCache':
clear_mautic_cache();
$nextTask = 'finish';
break;
case 'finish':
$status['complete'] = true;
$status['stepStatus'] = 'Success';
$status['nextStep'] = 'Processing Database Updates';
$status['nextStepStatus'] = 'In Progress';
$status['updateState']['cacheComplete'] = true;
break;
default:
$status['error'] = true;
$status['message'] = 'Invalid task';
$status['stepStatus'] = 'Failed';
break;
}
// Request through Mautic's UI
$status['updateState'] = get_state_param($status['updateState']);
send_response($status);
/**
* Get local parameters.
*
* @return mixed
*/
function get_local_config()
{
static $parameters;
if (null === $parameters) {
// Used in paths.php
$root = MAUTIC_APP_ROOT;
/** @var array<string> $paths */
$paths = [];
include MAUTIC_APP_ROOT.'/config/paths.php';
// Include local config to get cache_path
$localConfig = str_replace('%kernel.project_dir%', MAUTIC_ROOT, $paths['local_config']);
/** @var array<string, mixed> $parameters */
$parameters = [];
include $localConfig;
$localParameters = $parameters;
// check for parameter overrides
if (file_exists(MAUTIC_APP_ROOT.'/../config/parameters_local.php')) {
/** @var array<string, mixed> $parameters */
include MAUTIC_APP_ROOT.'/../config/parameters_local.php';
$localParameters = array_merge($localParameters, $parameters);
}
foreach ($localParameters as $k => &$v) {
if (!empty($v) && is_string($v) && preg_match('/getenv\((.*?)\)/', $v, $match)) {
$v = (string) getenv($match[1]);
}
}
$parameters = $localParameters;
}
return $parameters;
}
/**
* Clears the application cache.
*
* Since this script is being executed via web requests and standalone from the Mautic application, we don't have access to Symfony's
* CLI suite. So we'll go with Option B in this instance and just nuke the entire production cache and let Symfony rebuild it on the next
* application cycle.
*
* @return bool
*/
function clear_mautic_cache()
{
if (!recursive_remove_directory(MAUTIC_CACHE_DIR)) {
process_error_log(['Could not remove the application cache. You will need to manually delete '.MAUTIC_CACHE_DIR.'.']);
return false;
}
// Follow the same pattern as the console command and flush opcache/apc as appropriate.
if (function_exists('opcache_reset')) {
opcache_reset();
}
if (function_exists('apcu_clear_cache')) {
apcu_clear_cache();
}
return true;
}
/**
* Copy a folder.
*
* This function is based on \Joomla\Filesystem\Folder:copy()
*
* @param string $src The path to the source folder
* @param string $dest The path to the destination folder
*
* @return array<string>|string|bool True on success, a single error message on a "boot" fail, or an array of errors from the recursive operation
*/
function copy_directory($src, $dest)
{
@set_time_limit((int) ini_get('max_execution_time'));
$errorLog = [];
// Eliminate trailing directory separators, if any
$src = rtrim($src, DIRECTORY_SEPARATOR);
$dest = rtrim($dest, DIRECTORY_SEPARATOR);
// Make sure the destination exists
if (!is_dir($dest)) {
if (!@mkdir($dest, 0777, true)) {
return sprintf(
'Could not move files from %s to production since the folder could not be created.',
str_replace(MAUTIC_UPGRADE_ROOT, '', $src)
);
}
}
if (!($dh = @opendir($src))) {
return sprintf('Could not read directory %s to move files.', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
// Walk through the directory copying files and recursing into folders.
while (false !== ($file = readdir($dh))) {
$sfid = $src.'/'.$file;
$dfid = $dest.'/'.$file;
switch (filetype($sfid)) {
case 'dir':
if ('.' != $file && '..' != $file) {
$ret = copy_directory($sfid, $dfid);
if (true !== $ret) {
if (is_array($ret)) {
$errorLog += $ret;
} else {
$errorLog[] = $ret;
}
}
}
break;
case 'file':
if (!@rename($sfid, $dfid)) {
$errorLog[] = sprintf('Could not move file %s to production.', str_replace(MAUTIC_UPGRADE_ROOT, '', $sfid));
}
break;
}
}
if (!empty($errorLog)) {
return $errorLog;
}
return true;
}
/**
* Fetches a request variable and returns the sanitized version of it.
*
* @param string $name
* @param string $default
* @param int $filter
*
* @return mixed|string
*/
function getVar($name, $default = '', $filter = FILTER_SANITIZE_STRING)
{
if (isset($_REQUEST[$name])) {
return filter_var($_REQUEST[$name], $filter);
}
return $default;
}
/**
* Moves the Mautic bundles from the upgrade directory to production.
*
* A typical update package will only include changed files in the bundles. However, in this script we will assume that all of
* the bundle resources are included here and recursively iterate over the bundles in batches to update the filesystem.
*
* @param array<mixed> $status
* @param int $maxCount
*
* @return array<mixed>
*/
function move_mautic_bundles(array $status, $maxCount = 5)
{
$errorLog = [];
// First, we will move any addon bundles into position
if (is_dir(MAUTIC_UPGRADE_ROOT.'/plugins') && !$status['updateState']['pluginComplete']) {
$iterator = new DirectoryIterator(MAUTIC_UPGRADE_ROOT.'/plugins');
// Sanity check, make sure there are actually directories here to process
$dirs = glob(MAUTIC_UPGRADE_ROOT.'/plugins/*', GLOB_ONLYDIR);
if (count($dirs)) {
/** @var DirectoryIterator $directory */
foreach ($iterator as $directory) {
// Sanity checks
if (!$directory->isDot() && $directory->isDir()) {
$src = $directory->getPath().'/'.$directory->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
$result = copy_directory($src, $dest);
if (true !== $result) {
if (is_array($result)) {
$errorLog += $result;
} else {
$errorLog[] = $result;
}
}
$deleteDir = recursive_remove_directory($src);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
}
}
}
// At this point, there shouldn't be any plugins remaining; nuke the folder
$deleteDir = recursive_remove_directory(MAUTIC_UPGRADE_ROOT.'/plugins');
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', '/plugins');
}
process_error_log($errorLog);
$status['updateState']['pluginComplete'] = true;
if (-1 != $maxCount) {
// Finished with plugins, get a response back to the app so we can iterate to the next part
return $status;
}
}
// Now we move the main app bundles into production
if (is_dir(MAUTIC_UPGRADE_ROOT.'/app/bundles') && !$status['updateState']['bundleComplete']) {
// Initialize the bundle state if it isn't
if (!isset($status['updateState']['completedBundles'])) {
$status['updateState']['completedBundles'] = [];
}
$completed = true;
$iterator = new DirectoryIterator(MAUTIC_UPGRADE_ROOT.'/app/bundles');
// Sanity check, make sure there are actually directories here to process
$dirs = glob(MAUTIC_UPGRADE_ROOT.'/app/bundles/*', GLOB_ONLYDIR);
if (count($dirs)) {
$count = 0;
/** @var DirectoryIterator $directory */
foreach ($iterator as $directory) {
// Exit the loop if the count has reached 5
if (-1 != $maxCount && $count === $maxCount) {
$completed = false;
break;
}
// Sanity checks
if (!$directory->isDot() && $directory->isDir()) {
// Don't process this bundle if we've already tried it
if (isset($status['updateState']['completedBundles'][$directory->getFilename()])) {
continue;
}
$src = $directory->getPath().'/'.$directory->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
$result = copy_directory($src, $dest);
if (true !== $result) {
if (is_array($result)) {
$errorLog += $result;
} else {
$errorLog[] = $result;
}
}
$deleteDir = recursive_remove_directory($src);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
$status['updateState']['completedBundles'][$directory->getFilename()] = true;
++$count;
}
}
}
if ($completed) {
$status['updateState']['bundleComplete'] = true;
// At this point, there shouldn't be any bundles remaining; nuke the folder
$deleteDir = recursive_remove_directory(MAUTIC_UPGRADE_ROOT.'/app/bundles');
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', '/app/bundles');
}
}
process_error_log($errorLog);
// If we haven't finished the bundles yet, throw a response back to repeat the step
if (!$status['updateState']['bundleComplete']) {
return $status;
}
}
// To get here, all of the bundle updates must have been processed (or there are literally none). Step complete.
$status['complete'] = true;
return $status;
}
/**
* Moves the Mautic core files that are not part of bundles or vendors into production.
*
* The "core" files are broken into groups for purposes of the update script: bundles, vendor, and everything else. This step
* will take care of the everything else.
*
* @param array<mixed> $status
*
* @return array<mixed>
*/
function move_mautic_core(array $status)
{
$errorLog = [];
// Multilevel directories
$nestedDirectories = [
'/media',
'/themes',
'/translations',
'/app/middlewares',
];
foreach ($nestedDirectories as $dir) {
if (is_dir(MAUTIC_UPGRADE_ROOT.$dir)) {
copy_directories($dir, $errorLog);
// At this point, we can remove the media directory
$deleteDir = recursive_remove_directory(MAUTIC_UPGRADE_ROOT.$dir);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', $dir);
}
}
}
// Single level directories with files only
$fileOnlyDirectories = [
'/app/config',
'/app/migrations',
'/app',
'/bin',
];
foreach ($fileOnlyDirectories as $dir) {
if (copy_files($dir, $errorLog)) {
// At this point, we can remove the config directory
$deleteDir = recursive_remove_directory(MAUTIC_UPGRADE_ROOT.$dir);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', $dir);
}
}
}
// Now move any root level files
$iterator = new FilesystemIterator(MAUTIC_UPGRADE_ROOT);
/** @var FilesystemIterator $file */
foreach ($iterator as $file) {
// Sanity checks
if ($file->isFile() && !in_array($file->getFilename(), ['deleted_files.txt', 'critical_migrations.txt', 'upgrade.php'])) {
$src = $file->getPath().'/'.$file->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
if (!@rename($src, $dest)) {
$errorLog[] = sprintf('Could not move file %s to production.', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
}
}
process_error_log($errorLog);
// In this step, we'll also go ahead and remove deleted files, return the results from that
return remove_mautic_deleted_files($status);
}
/**
* Moves the Mautic dependencies from the upgrade directory to production.
*
* Since the /vendor folder is not stored under version control, we cannot accurately track changes in third party dependencies
* between releases. Therefore, this step will recursively iterate over the vendors in batches to remove each package completely
* and replace it with the new version.
*
* @param array<mixed> $status
* @param int $maxCount
*
* @return array<mixed>
*/
function move_mautic_vendors(array $status, $maxCount = 5)
{
$errorLog = [];
// If there isn't even a vendor directory, just skip this step
if (!is_dir(MAUTIC_UPGRADE_ROOT.'/vendor')) {
$status['complete'] = true;
$status['stepStatus'] = 'Success';
$status['nextStep'] = 'Clearing Application Cache';
$status['nextStepStatus'] = 'In Progress';
$status['updateState']['vendorComplete'] = true;
return $status;
}
// Initialize the vendor state if it isn't
if (!isset($status['updateState']['completedVendors'])) {
$status['updateState']['completedVendors'] = [];
}
// Symfony is the largest of our vendors, we will process it first
if (is_dir(MAUTIC_UPGRADE_ROOT.'/vendor/symfony') && !isset($status['updateState']['completedVendors']['symfony'])) {
// Initialize the Symfony state if it isn't, this step will recurse
if (!isset($status['updateState']['completedSymfony'])) {
$status['updateState']['completedSymfony'] = [];
}
$completed = true;
$iterator = new DirectoryIterator(MAUTIC_UPGRADE_ROOT.'/vendor/symfony');
// Sanity check, make sure there are actually directories here to process
$dirs = glob(MAUTIC_UPGRADE_ROOT.'/vendor/symfony/*', GLOB_ONLYDIR);
if (count($dirs)) {
$count = 0;
/** @var DirectoryIterator $directory */
foreach ($iterator as $directory) {
// Exit the loop if the count has reached 5
if (-1 != $maxCount && $count === $maxCount) {
$completed = false;
break;
}
// Sanity checks
if (!$directory->isDot() && $directory->isDir()) {
// Don't process this directory if we've already tried it
if (isset($status['updateState']['completedSymfony'][$directory->getFilename()])) {
continue;
}
$src = $directory->getPath().'/'.$directory->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
// We'll need to completely remove the existing vendor first
recursive_remove_directory($dest);
$result = copy_directory($src, $dest);
if (true !== $result) {
if (is_array($result)) {
$errorLog += $result;
} else {
$errorLog[] = $result;
}
}
$deleteDir = recursive_remove_directory($src);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
$status['updateState']['completedSymfony'][$directory->getFilename()] = true;
++$count;
}
}
}
if ($completed) {
$status['updateState']['completedVendors']['symfony'] = true;
// At this point, there shouldn't be any Symfony code remaining; nuke the folder
$deleteDir = recursive_remove_directory(MAUTIC_UPGRADE_ROOT.'/vendor/symfony');
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', '/vendor/symfony');
}
}
process_error_log($errorLog);
// If we haven't finished Symfony yet, throw a response back to repeat the step
if (!isset($status['updateState']['completedVendors']['symfony'])) {
return $status;
}
}
// Once we've gotten here, we can safely iterate through the rest of the vendor directory; the rest of the contents are rather small in size
$completed = true;
$iterator = new DirectoryIterator(MAUTIC_UPGRADE_ROOT.'/vendor');
// Sanity check, make sure there are actually directories here to process
$dirs = glob(MAUTIC_UPGRADE_ROOT.'/vendor/*', GLOB_ONLYDIR);
if (count($dirs)) {
$count = 0;
/** @var DirectoryIterator $directory */
foreach ($iterator as $directory) {
// Exit the loop if the count has reached 5
if (-1 != $maxCount && $count === $maxCount) {
$completed = false;
break;
}
// Sanity checks
if (!$directory->isDot() && $directory->isDir()) {
// Don't process this directory if we've already tried it
if (isset($status['updateState']['completedVendors'][$directory->getFilename()])) {
continue;
}
$src = $directory->getPath().'/'.$directory->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
// We'll need to completely remove the existing vendor first
recursive_remove_directory($dest);
$result = copy_directory($src, $dest);
if (true !== $result) {
if (is_array($result)) {
$errorLog += $result;
} else {
$errorLog[] = $result;
}
}
$deleteDir = recursive_remove_directory($src);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
$status['updateState']['completedVendors'][$directory->getFilename()] = true;
++$count;
}
}
}
if ($completed) {
$status['updateState']['vendorComplete'] = true;
// Move the autoload.php file over now
if (!@rename(MAUTIC_UPGRADE_ROOT.'/vendor/autoload.php', MAUTIC_ROOT.'/vendor/autoload.php')) {
$errorLog[] = 'Could not move file /vendor/autoload.php to production.';
}
// At this point, there shouldn't be any vendors remaining; nuke the folder
$deleteDir = recursive_remove_directory(MAUTIC_UPGRADE_ROOT.'/vendor');
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', '/vendor');
}
}
process_error_log($errorLog);
// If we haven't finished the vendors yet, throw a response back to repeat the step
if (!$status['updateState']['vendorComplete']) {
return $status;
}
// Once we get here, we have finished the moving files step; notifiy Mautic of this
$status['complete'] = true;
$status['stepStatus'] = 'Success';
$status['nextStep'] = 'Clearing Application Cache';
$status['nextStepStatus'] = 'In Progress';
$status['updateState']['vendorComplete'] = true;
return $status;
}
/**
* Copy files from the directory.
*
* @param string $dir
* @param array<string> &$errorLog
*
* @return bool
*/
function copy_files($dir, &$errorLog)
{
if (is_dir(MAUTIC_UPGRADE_ROOT.$dir)) {
$iterator = new FilesystemIterator(MAUTIC_UPGRADE_ROOT.$dir);
/** @var FilesystemIterator $file */
foreach ($iterator as $file) {
// Sanity checks
if ($file->isFile()) {
$src = $file->getPath().'/'.$file->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
if (!@rename($src, $dest)) {
$errorLog[] = sprintf('Could not move file %s to production.', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
}
}
return true;
}
return false;
}
/**
* Copy directories.
*
* @param string $dir
* @param array<string> &$errorLog
* @param bool $createDest
*/
function copy_directories($dir, &$errorLog, $createDest = true): bool
{
// Ensure the destination directory exists
$exists = file_exists(MAUTIC_ROOT.$dir);
if ($createDest && !$exists) {
mkdir(MAUTIC_ROOT.$dir, 0755, true);
} elseif (!$exists) {
$errorLog[] = sprintf('%s does not exist.', MAUTIC_ROOT.$dir);
return false;
}
// Copy root level files first
copy_files($dir, $errorLog);
$iterator = new DirectoryIterator(MAUTIC_UPGRADE_ROOT.$dir);
/** @var DirectoryIterator $directory */
foreach ($iterator as $directory) {
// Sanity checks
if (!$directory->isDot() && $directory->isDir()) {
$src = $directory->getPath().'/'.$directory->getFilename();
$dest = str_replace(MAUTIC_UPGRADE_ROOT, MAUTIC_ROOT, $src);
$result = copy_directory($src, $dest);
if (true !== $result) {
if (is_array($result)) {
$errorLog += $result;
} else {
$errorLog[] = $result;
}
}
$deleteDir = recursive_remove_directory($src);
if (!$deleteDir) {
$errorLog[] = sprintf('Failed to remove the upgrade directory %s folder', str_replace(MAUTIC_UPGRADE_ROOT, '', $src));
}
}
}
return true;
}
/**
* Processes the error log for each step.
*
* @param array<string> $errorLog
*/
function process_error_log(array $errorLog): void
{
// If there were any errors, add them to the error log
if (count($errorLog)) {
// Check if the error log exists first
if (file_exists(MAUTIC_UPGRADE_ERROR_LOG)) {
$errors = file_get_contents(MAUTIC_UPGRADE_ERROR_LOG);
} else {
$errors = "<?php die('no access'); \n\n";
}
$errors .= implode(PHP_EOL, $errorLog)."\n";
@file_put_contents(MAUTIC_UPGRADE_ERROR_LOG, $errors);
}
}
/**
* Tries to recursively delete a directory.
*
* This code is based on the recursive_remove_directory function used by Akeeba Restore
*
* @param string $directory
*
* @return bool
*/
function recursive_remove_directory($directory)
{
// if the path has a slash at the end we remove it here
if ('/' == substr($directory, -1)) {
$directory = substr($directory, 0, -1);
}
// if the path is not valid or is not a directory ...
if (!file_exists($directory)) {
return true;
} elseif (!is_dir($directory)) {
return false;
// ... if the path is not readable
} elseif (!is_readable($directory)) {
// ... we return false and exit the function
return false;
// ... else if the path is readable
} else {
// we open the directory
$handle = opendir($directory);
// and scan through the items inside
while (false !== ($item = readdir($handle))) {
// if the filepointer is not the current directory
// or the parent directory
if ('.' != $item && '..' != $item) {
// we build the new path to delete
$path = $directory.'/'.$item;
// if the new path is a directory
if (is_dir($path)) {
// we call this function with the new path
recursive_remove_directory($path);
// if the new path is a file
} else {
// we remove the file
@unlink($path);
}
}
}
// close the directory
closedir($handle);
// try to delete the now empty directory
if (!@rmdir($directory)) {
// return false if not possible
return false;
}
// return success
return true;
}
}
/**
* Removes deleted files from the system.
*
* While packaging updates, the script will generate a list of deleted files in comparison to the previous version. In this step,
* we will process that list to remove files which are no longer included in the application.
*
* @param array<mixed> $status
*
* @return array<mixed>
*/
function remove_mautic_deleted_files(array $status)
{
$errorLog = [];
// Make sure we have a deleted_files list otherwise we can't process this step
if (file_exists(MAUTIC_UPGRADE_ROOT.'/deleted_files.txt')) {
$deletedFiles = json_decode(file_get_contents(MAUTIC_UPGRADE_ROOT.'/deleted_files.txt'), true);
foreach ($deletedFiles as $file) {
$path = MAUTIC_ROOT.'/'.$file;
// If it doesn't exist, don't even bother
if (file_exists($path)) {
// Try setting the permissions to 777 just to make sure we can get rid of the file
@chmod($path, 0777);
if (!@unlink($path)) {
// Failed to delete, reset the permissions to 644 for safety
@chmod($path, 0644);
$errorLog[] = sprintf(
'Failed removing the file at %s from the production path. As this is a deleted file, you can manually remove this file.',
$file
);
} else {
// Check to see if directory is now empty and if so, delete it
$dirpath = dirname($path);
if (file_exists($dirpath) && !glob($dirpath.'/*')) {
@chmod($dirpath, 0777);
if (!@unlink($dirpath)) {
// Failed to delete, reset the permissions to 0755 for safety
@chmod($dirpath, 0755);
}
}
}
}
}
} else {
$errorLog[] = 'The file containing the list of deleted files was not found, could not process the deleted file list.';
}
process_error_log($errorLog);
$status['complete'] = true;
$status['updateState']['coreComplete'] = true;
return $status;
}
/**
* @param array<mixed> $state
*
* @return string
*/
function get_state_param(array $state)
{
return base64_encode(json_encode($state));
}
/**
* Send the response back to the main application.
*
* @param array<mixed> $status
*/
function send_response(array $status): void
{
header('Content-Type: application/json; charset=utf-8');
echo json_encode($status);
}
/**
* Wrap content in some HTML.
*/
function html_body(string $content): void
{
$html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Upgrade Mautic</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div class="container" style="padding: 25px;">
$content
</div>
</body>
</html>
HTML;
echo $html;
exit;
}
PHP
1
https://gitee.com/mirrors/Mautic.git
git@gitee.com:mirrors/Mautic.git
mirrors
Mautic
Mautic
5.x

搜索帮助

53164aa7 5694891 3bd8fe86 5694891