updated core to 1.7.15

This commit is contained in:
2021-05-27 18:17:50 +02:00
parent dc1fdf21c9
commit 19ecb285ab
552 changed files with 80743 additions and 16675 deletions

View File

@@ -1,62 +1,61 @@
<?php
/**
* @package Grav.Common.GPM
* @package Grav\Common\GPM
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\GPM;
use DirectoryIterator;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use RuntimeException;
use ZipArchive;
use function count;
use function in_array;
use function is_string;
/**
* Class Installer
* @package Grav\Common\GPM
*/
class Installer
{
/** @const No error */
const OK = 0;
public const OK = 0;
/** @const Target already exists */
const EXISTS = 1;
public const EXISTS = 1;
/** @const Target is a symbolic link */
const IS_LINK = 2;
public const IS_LINK = 2;
/** @const Target doesn't exist */
const NOT_FOUND = 4;
public const NOT_FOUND = 4;
/** @const Target is not a directory */
const NOT_DIRECTORY = 8;
public const NOT_DIRECTORY = 8;
/** @const Target is not a Grav instance */
const NOT_GRAV_ROOT = 16;
public const NOT_GRAV_ROOT = 16;
/** @const Error while trying to open the ZIP package */
const ZIP_OPEN_ERROR = 32;
public const ZIP_OPEN_ERROR = 32;
/** @const Error while trying to extract the ZIP package */
const ZIP_EXTRACT_ERROR = 64;
public const ZIP_EXTRACT_ERROR = 64;
/** @const Invalid source file */
const INVALID_SOURCE = 128;
public const INVALID_SOURCE = 128;
/**
* Destination folder on which validation checks are applied
* @var string
*/
/** @var string Destination folder on which validation checks are applied */
protected static $target;
/**
* @var integer Error Code
*/
/** @var int|string Error code or string */
protected static $error = 0;
/**
* @var integer Zip Error Code
*/
/** @var int Zip Error Code */
protected static $error_zip = 0;
/**
* @var string Post install message
*/
/** @var string Post install message */
protected static $message = '';
/**
* Default options for the install
* @var array
*/
/** @var array Default options for the install */
protected static $options = [
'overwrite' => true,
'ignore_symlinks' => true,
@@ -73,30 +72,33 @@ class Installer
* @param string $zip the local path to ZIP package
* @param string $destination The local path to the Grav Instance
* @param array $options Options to use for installing. ie, ['install_path' => 'user/themes/antimatter']
* @param string $extracted The local path to the extacted ZIP package
* @param string|null $extracted The local path to the extacted ZIP package
* @param bool $keepExtracted True if you want to keep the original files
* @return bool True if everything went fine, False otherwise.
*/
public static function install($zip, $destination, $options = [], $extracted = null)
public static function install($zip, $destination, $options = [], $extracted = null, $keepExtracted = false)
{
$destination = rtrim($destination, DS);
$options = array_merge(self::$options, $options);
$install_path = rtrim($destination . DS . ltrim($options['install_path'], DS), DS);
if (!self::isGravInstance($destination) || !self::isValidDestination($install_path,
$options['exclude_checks'])
if (!self::isGravInstance($destination) || !self::isValidDestination(
$install_path,
$options['exclude_checks']
)
) {
return false;
}
if (self::lastErrorCode() == self::IS_LINK && $options['ignore_symlinks'] ||
self::lastErrorCode() == self::EXISTS && !$options['overwrite']
if ((self::lastErrorCode() === self::IS_LINK && $options['ignore_symlinks']) ||
(self::lastErrorCode() === self::EXISTS && !$options['overwrite'])
) {
return false;
}
// Create a tmp location
$tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true);
$tmp = $tmp_dir . '/Grav-' . uniqid();
$tmp = $tmp_dir . '/Grav-' . uniqid('', false);
if (!$extracted) {
$extracted = self::unZip($zip, $tmp);
@@ -111,7 +113,6 @@ class Installer
return false;
}
$is_install = true;
$installer = self::loadInstaller($extracted, $is_install);
@@ -134,13 +135,16 @@ class Installer
}
if (!$options['sophisticated']) {
if ($options['theme']) {
$isTheme = $options['theme'] ?? false;
// Make sure that themes are always being copied, even if option was not set!
$isTheme = $isTheme || preg_match('|/themes/[^/]+|ui', $install_path);
if ($isTheme) {
self::copyInstall($extracted, $install_path);
} else {
self::moveInstall($extracted, $install_path);
}
} else {
self::sophisticatedInstall($extracted, $install_path, $options['ignores']);
self::sophisticatedInstall($extracted, $install_path, $options['ignores'], $keepExtracted);
}
Folder::delete($tmp);
@@ -159,23 +163,22 @@ class Installer
self::$error = self::OK;
return true;
}
/**
* Unzip a file to somewhere
*
* @param $zip_file
* @param $destination
* @return bool|string
* @param string $zip_file
* @param string $destination
* @return string|false
*/
public static function unZip($zip_file, $destination)
{
$zip = new \ZipArchive();
$zip = new ZipArchive();
$archive = $zip->open($zip_file);
if ($archive === true) {
Folder::mkdir($destination);
Folder::create($destination);
$unzip = $zip->extractTo($destination);
@@ -187,15 +190,19 @@ class Installer
return false;
}
$package_folder_name = preg_replace('#\./$#', '', $zip->getNameIndex(0));
$package_folder_name = $zip->getNameIndex(0);
if ($package_folder_name === false) {
throw new \RuntimeException('Bad package file: ' . basename($zip_file));
}
$package_folder_name = preg_replace('#\./$#', '', $package_folder_name);
$zip->close();
$extracted_folder = $destination . '/' . $package_folder_name;
return $extracted_folder;
return $destination . '/' . $package_folder_name;
}
self::$error = self::ZIP_EXTRACT_ERROR;
self::$error_zip = $archive;
return false;
}
@@ -204,23 +211,20 @@ class Installer
*
* @param string $installer_file_folder The folder path that contains install.php
* @param bool $is_install True if install, false if removal
*
* @return null|string
* @return string|null
*/
private static function loadInstaller($installer_file_folder, $is_install)
{
$installer = null;
$installer_file_folder = rtrim($installer_file_folder, DS);
$install_file = $installer_file_folder . DS . 'install.php';
if (file_exists($install_file)) {
require_once($install_file);
} else {
if (!file_exists($install_file)) {
return null;
}
require_once $install_file;
if ($is_install) {
$slug = '';
if (($pos = strpos($installer_file_folder, 'grav-plugin-')) !== false) {
@@ -243,19 +247,18 @@ class Installer
return $class_name;
}
$class_name_alphanumeric = preg_replace('/[^a-zA-Z0-9]+/', '', $class_name);
$class_name_alphanumeric = preg_replace('/[^a-zA-Z0-9]+/', '', $class_name) ?? $class_name;
if (class_exists($class_name_alphanumeric)) {
return $class_name_alphanumeric;
}
return $installer;
return null;
}
/**
* @param $source_path
* @param $install_path
*
* @param string $source_path
* @param string $install_path
* @return bool
*/
public static function moveInstall($source_path, $install_path)
@@ -270,33 +273,32 @@ class Installer
}
/**
* @param $source_path
* @param $install_path
*
* @param string $source_path
* @param string $install_path
* @return bool
*/
public static function copyInstall($source_path, $install_path)
{
if (empty($source_path)) {
throw new \RuntimeException("Directory $source_path is missing");
} else {
Folder::rcopy($source_path, $install_path);
throw new RuntimeException("Directory $source_path is missing");
}
Folder::rcopy($source_path, $install_path);
return true;
}
/**
* @param $source_path
* @param $install_path
*
* @param string $source_path
* @param string $install_path
* @param array $ignores
* @param bool $keep_source
* @return bool
*/
public static function sophisticatedInstall($source_path, $install_path, $ignores = [])
public static function sophisticatedInstall($source_path, $install_path, $ignores = [], $keep_source = false)
{
foreach (new \DirectoryIterator($source_path) as $file) {
if ($file->isLink() || $file->isDot() || in_array($file->getFilename(), $ignores)) {
foreach (new DirectoryIterator($source_path) as $file) {
if ($file->isLink() || $file->isDot() || in_array($file->getFilename(), $ignores, true)) {
continue;
}
@@ -304,10 +306,15 @@ class Installer
if ($file->isDir()) {
Folder::delete($path);
Folder::move($file->getPathname(), $path);
if ($keep_source) {
Folder::copy($file->getPathname(), $path);
} else {
Folder::move($file->getPathname(), $path);
}
if ($file->getFilename() === 'bin') {
foreach (glob($path . DS . '*') as $bin_file) {
$glob = glob($path . DS . '*') ?: [];
foreach ($glob as $bin_file) {
@chmod($bin_file, 0755);
}
}
@@ -325,8 +332,7 @@ class Installer
*
* @param string $path The slug of the package(s)
* @param array $options Options to use for uninstalling
*
* @return boolean True if everything went fine, False otherwise.
* @return bool True if everything went fine, False otherwise.
*/
public static function uninstall($path, $options = [])
{
@@ -367,8 +373,7 @@ class Installer
*
* @param string $destination The directory to run validations at
* @param array $exclude An array of constants to exclude from the validation
*
* @return boolean True if validation passed. False otherwise
* @return bool True if validation passed. False otherwise
*/
public static function isValidDestination($destination, $exclude = [])
{
@@ -385,27 +390,25 @@ class Installer
self::$error = self::NOT_DIRECTORY;
}
if (count($exclude) && in_array(self::$error, $exclude)) {
if (count($exclude) && in_array(self::$error, $exclude, true)) {
return true;
}
return !(self::$error);
return !self::$error;
}
/**
* Validates if the given path is a Grav Instance
*
* @param string $target The local path to the Grav Instance
*
* @return boolean True if is a Grav Instance. False otherwise
* @return bool True if is a Grav Instance. False otherwise
*/
public static function isGravInstance($target)
{
self::$error = 0;
self::$target = $target;
if (
!file_exists($target . DS . 'index.php') ||
if (!file_exists($target . DS . 'index.php') ||
!file_exists($target . DS . 'bin') ||
!file_exists($target . DS . 'user') ||
!file_exists($target . DS . 'system' . DS . 'config' . DS . 'system.yaml')
@@ -418,6 +421,7 @@ class Installer
/**
* Returns the last message added by the installer
*
* @return string The message
*/
public static function getMessage()
@@ -427,6 +431,7 @@ class Installer
/**
* Returns the last error occurred in a string message format
*
* @return string The message of the last error
*/
public static function lastErrorMsg()
@@ -467,42 +472,46 @@ class Installer
case self::ZIP_EXTRACT_ERROR:
$msg = 'Unable to extract the package. ';
if (self::$error_zip) {
switch(self::$error_zip) {
case \ZipArchive::ER_EXISTS:
$msg .= "File already exists.";
switch (self::$error_zip) {
case ZipArchive::ER_EXISTS:
$msg .= 'File already exists.';
break;
case \ZipArchive::ER_INCONS:
$msg .= "Zip archive inconsistent.";
case ZipArchive::ER_INCONS:
$msg .= 'Zip archive inconsistent.';
break;
case \ZipArchive::ER_MEMORY:
$msg .= "Malloc failure.";
case ZipArchive::ER_MEMORY:
$msg .= 'Memory allocation failure.';
break;
case \ZipArchive::ER_NOENT:
$msg .= "No such file.";
case ZipArchive::ER_NOENT:
$msg .= 'No such file.';
break;
case \ZipArchive::ER_NOZIP:
$msg .= "Not a zip archive.";
case ZipArchive::ER_NOZIP:
$msg .= 'Not a zip archive.';
break;
case \ZipArchive::ER_OPEN:
case ZipArchive::ER_OPEN:
$msg .= "Can't open file.";
break;
case \ZipArchive::ER_READ:
$msg .= "Read error.";
case ZipArchive::ER_READ:
$msg .= 'Read error.';
break;
case \ZipArchive::ER_SEEK:
$msg .= "Seek error.";
case ZipArchive::ER_SEEK:
$msg .= 'Seek error.';
break;
}
}
break;
case self::INVALID_SOURCE:
$msg = 'Invalid source file';
break;
default:
$msg = 'Unknown Error';
break;
@@ -513,7 +522,8 @@ class Installer
/**
* Returns the last error code of the occurred error
* @return integer The code of the last error
*
* @return int|string The code of the last error
*/
public static function lastErrorCode()
{
@@ -524,8 +534,8 @@ class Installer
* Allows to manually set an error
*
* @param int|string $error the Error code
* @return void
*/
public static function setError($error)
{
self::$error = $error;