diff --git a/CHANGELOG.md b/CHANGELOG.md index 35fdff1f3..14070c11e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Upgraded `bin/composer.phar` to `2.0.2` which is all new and much faster * Added search option `same_as` to Flex Objects * Added PHP 8 compatible `function_exists()`: `Utils::functionExists()` + * New sites have `compatibility` features turned off by default, upgrading from older versions will keep the settings on 1. [](#improved) * Updated bundled JQuery to latest version `3.5.1` * Forward a `sid` to GPM when downloading a premium package via CLI diff --git a/composer.json b/composer.json index a055e5aa3..02c12c3de 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,6 @@ "ext-libxml": "*", "symfony/polyfill-mbstring": "~1.20", "symfony/polyfill-iconv": "^1.20", - "symfony/polyfill-php73": "^1.20", "symfony/polyfill-php74": "^1.20", "symfony/polyfill-php80": "^1.20", "psr/simple-cache": "^1.0", diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 573fe2012..9fa9f0194 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -846,7 +846,8 @@ form: type: toggle label: PLUGIN_ADMIN.AUTOESCAPE_VARIABLES help: PLUGIN_ADMIN.AUTOESCAPE_VARIABLES_HELP - highlight: 0 + highlight: 1 + default: 1 options: 1: PLUGIN_ADMIN.YES 0: PLUGIN_ADMIN.NO @@ -1565,8 +1566,8 @@ form: strict_mode.blueprint_compat: type: toggle label: PLUGIN_ADMIN.STRICT_BLUEPRINT_COMPAT - highlight: 1 - default: 1 + highlight: 0 + default: 0 help: PLUGIN_ADMIN.STRICT_BLUEPRINT_COMPAT_HELP options: 1: PLUGIN_ADMIN.YES @@ -1577,8 +1578,8 @@ form: strict_mode.yaml_compat: type: toggle label: PLUGIN_ADMIN.STRICT_YAML_COMPAT - highlight: 1 - default: 1 + highlight: 0 + default: 0 help: PLUGIN_ADMIN.STRICT_YAML_COMPAT_HELP options: 1: PLUGIN_ADMIN.YES @@ -1589,8 +1590,8 @@ form: strict_mode.twig_compat: type: toggle label: PLUGIN_ADMIN.STRICT_TWIG_COMPAT - highlight: 1 - default: 1 + highlight: 0 + default: 0 help: PLUGIN_ADMIN.STRICT_TWIG_COMPAT_HELP options: 1: PLUGIN_ADMIN.YES diff --git a/system/config/system.yaml b/system/config/system.yaml index c8d8b04bc..6484bc95d 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -108,7 +108,7 @@ twig: cache: true # Set to true to enable Twig caching debug: true # Enable Twig debug auto_reload: true # Refresh cache on changes - autoescape: false # Autoescape Twig vars (DEPRECATED, always enabled in strict mode) + autoescape: true # Autoescape Twig vars (DEPRECATED, always enabled in strict mode) undefined_functions: true # Allow undefined functions undefined_filters: true # Allow undefined filters umask_fix: false # By default Twig creates cached files as 755, fix switches this to 775 @@ -196,6 +196,6 @@ flex: lifetime: 600 # Lifetime of cached HTML in seconds (0 = infinite) strict_mode: - yaml_compat: true # Grav 1.5+: Enables YAML backwards compatibility - twig_compat: true # Grav 1.5+: Enables deprecated Twig autoescape setting (autoescape: false) - blueprint_compat: true # Grav 1.7+: Enables backward compatible strict support for blueprints + yaml_compat: false # Set to true to enable YAML backwards compatibility + twig_compat: false # Set to true to enable deprecated Twig settings (autoescape: false) + blueprint_compat: false # Set to true to enable backward compatible strict support for blueprints diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index d61bad8a9..65a2a3ff0 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -1106,6 +1106,14 @@ class Pages if (null === self::$types) { $grav = Grav::instance(); + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Prevent calls made before theme:// has been initialized (happens when upgrading old version of Admin plugin). + if (!$locator->isStream('theme://')) { + return new Types(); + } + $scanBlueprintsAndTemplates = static function (Types $types) use ($grav) { // Scan blueprints $event = new Event(); diff --git a/system/src/Grav/Installer/Install.php b/system/src/Grav/Installer/Install.php index 7d4ca4eea..ba8b22434 100644 --- a/system/src/Grav/Installer/Install.php +++ b/system/src/Grav/Installer/Install.php @@ -14,13 +14,14 @@ use Grav\Common\Cache; use Grav\Common\GPM\Installer; use Grav\Common\Grav; use Grav\Common\Plugins; +use function dirname; /** * Grav installer. * * NOTE: This class can be initialized during upgrade from an older version of Grav. Make sure it runs there! */ -class Install +final class Install { /** @var int Installer version. */ public $version = 1; @@ -39,8 +40,7 @@ class Install 'name' => 'Grav', 'versions' => [ '1.6' => '1.6.0', - '1.5' => '1.5.0', - '' => '1.6.22' + '' => '1.6.28' ] ], 'plugins' => [ @@ -49,7 +49,6 @@ class Install 'optional' => true, 'versions' => [ '1.9' => '1.9.0', - '1.8' => '1.8.0', '' => '1.9.13' ] ], @@ -58,28 +57,26 @@ class Install 'optional' => true, 'versions' => [ '3.0' => '3.0.0', - '2.7' => '2.7.0', - '' => '3.0.7' + '' => '3.0.10' ] ], 'form' => [ 'name' => 'Form', 'optional' => true, 'versions' => [ + '4.1' => '4.1.0', '4.0' => '4.0.0', '3.0' => '3.0.0', - '2.16' => '2.16.0', - '' => '4.0.5' + '' => '4.1.2' ] ], 'login' => [ 'name' => 'Login', 'optional' => true, 'versions' => [ - '3.1' => '3.1.0', + '3.3' => '3.3.0', '3.0' => '3.0.0', - '2.8' => '2.8.0', - '' => '3.1.0' + '' => '3.3.6' ] ], ] @@ -99,7 +96,11 @@ class Install /** @var array */ private $classMap = [ - // 'Grav\\Installer\\Test' => __DIR__ . '/Test.php', + InstallException::class => __DIR__ . '/InstallException.php', + Versions::class => __DIR__ . '/Versions.php', + VersionUpdate::class => __DIR__ . '/VersionUpdate.php', + VersionUpdater::class => __DIR__ . '/VersionUpdater.php', + YamlUpdater::class => __DIR__ . '/YamlUpdater.php', ]; /** @var string|null */ @@ -108,9 +109,15 @@ class Install /** @var string|null */ private $location; + /** @var VersionUpdater */ + private $updater; + /** @var static */ private static $instance; + /** + * @return static + */ public static function instance() { if (null === self::$instance) { @@ -143,7 +150,19 @@ class Install $error[] = "{$req['title']} >= v{$req['minimum']} required, you have v{$req['installed']}"; } - throw new \RuntimeException(implode("
\n", $error)); + $errors = implode("
\n", $error); + if (\defined('GRAV_CLI') && GRAV_CLI) { + $errors = "\n\n" . strip_tags($errors) . "\n\n"; + $errors .= <<prepare(); @@ -200,7 +219,14 @@ class Install // Override Grav\Installer classes by using this version of Grav. $loader->addClassMap($this->classMap); + $this->legacySupport(); + $this->location = dirname($location, 4); + + $versions = Versions::instance(GRAV_ROOT . '/user/config/versions.yaml'); + $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', $versions); + + $this->updater->preflight(); } /** @@ -238,6 +264,8 @@ class Install */ public function finalize(): void { + $this->updater->postflight(); + Cache::clearCache(); clearstatcache(); @@ -305,4 +333,10 @@ class Install $this->checkVersion($results, 'plugin', $name, $check, $version); } } + + protected function legacySupport(): void + { + // Support install for Grav 1.6.0 - 1.6.20 by loading the original class from the older version of Grav. + class_exists(\Grav\Console\Cli\CacheCommand::class, true); + } } diff --git a/system/src/Grav/Installer/InstallException.php b/system/src/Grav/Installer/InstallException.php new file mode 100644 index 000000000..4471107d9 --- /dev/null +++ b/system/src/Grav/Installer/InstallException.php @@ -0,0 +1,29 @@ +getCode(), $previous); + } +} diff --git a/system/src/Grav/Installer/VersionUpdate.php b/system/src/Grav/Installer/VersionUpdate.php new file mode 100644 index 000000000..faaf2a2d9 --- /dev/null +++ b/system/src/Grav/Installer/VersionUpdate.php @@ -0,0 +1,82 @@ +revision = $name; + [$this->version, $this->date, $this->patch] = explode('_', $name); + $this->updater = $updater; + $this->methods = require $file; + } + + public function getRevision(): string + { + return $this->revision; + } + + public function getVersion(): string + { + return $this->version; + } + + public function getDate(): string + { + return $this->date; + } + + public function getPatch(): string + { + return $this->date; + } + + public function getUpdater(): VersionUpdater + { + return $this->updater; + } + + /** + * Run right before installation. + */ + public function preflight(VersionUpdater $updater): void + { + $method = $this->methods['preflight'] ?? null; + if ($method instanceof Closure) { + $method->call($this); + } + } + + /** + * Runs right after installation. + */ + public function postflight(VersionUpdater $updater): void + { + $method = $this->methods['postflight'] ?? null; + if ($method instanceof Closure) { + $method->call($this); + } + } +} diff --git a/system/src/Grav/Installer/VersionUpdater.php b/system/src/Grav/Installer/VersionUpdater.php new file mode 100644 index 000000000..e90ba4f42 --- /dev/null +++ b/system/src/Grav/Installer/VersionUpdater.php @@ -0,0 +1,114 @@ +name = $name; + $this->path = $path; + $this->versions = $versions; + + $this->loadUpdates(); + } + + /** + * Pre-installation methods. + */ + public function preflight(): void + { + foreach ($this->updates as $revision => $update) { + $update->preflight($this); + } + } + + /** + * Post-installation methods. + */ + public function postflight(): void + { + $versions = $this->getVersions(); + + foreach ($this->updates as $revision => $update) { + $update->postflight($this); + + $versions->setSchema($this->name, $revision); + $versions->save(); + } + } + + /** + * @return Versions + */ + public function getVersions(): Versions + { + return $this->versions; + } + + /** + * @param string|null $name + * @return string|null + */ + public function getExtensionVersion(string $name = null): ?string + { + return $this->versions->getVersion($name ?? $this->name); + } + + /** + * @param string|null $name + * @return string|null + */ + public function getExtensionSchema(string $name = null): ?string + { + return $this->versions->getSchema($name ?? $this->name); + } + + /** + * @param string|null $name + * @return array + */ + public function getExtensionHistory(string $name = null): array + { + return $this->versions->getHistory($name ?? $this->name); + } + + protected function loadUpdates(): void + { + $schema = $this->getExtensionSchema(); + $iterator = new DirectoryIterator($this->path); + foreach ($iterator as $item) { + if (!$item->isFile() || $item->getExtension() !== 'php') { + continue; + } + + $revision = $item->getBasename('.php'); + if (!$schema || version_compare($revision, $schema, '>')) { + $this->updates[$revision] = new VersionUpdate($item->getRealPath(), $this); + } + } + + uksort($this->updates, 'version_compare'); + } +} diff --git a/system/src/Grav/Installer/Versions.php b/system/src/Grav/Installer/Versions.php new file mode 100644 index 000000000..76a6ecfd9 --- /dev/null +++ b/system/src/Grav/Installer/Versions.php @@ -0,0 +1,308 @@ +updated) { + return false; + } + + file_put_contents($this->filename, Yaml::dump($this->items, 5, 2)); + + $this->updated = false; + + return true; + } + + /** + * @return array + */ + public function getAll(): array + { + return $this->items; + } + + /** + * @return array|null + */ + public function getGrav(): ?array + { + return $this->get('core/grav'); + } + + /** + * @return array + */ + public function getPlugins(): array + { + return $this->get('plugins', []); + } + + /** + * @param string $name + * @return array|null + */ + public function getPlugin(string $name): ?array + { + return $this->get("plugins/{$name}"); + } + + /** + * @return array + */ + public function getThemes(): array + { + return $this->get('themes', []); + } + + /** + * @param string $name + * @return array|null + */ + public function getTheme(string $name): ?array + { + return $this->get("themes/{$name}"); + } + + /** + * @param string $extension + * @return array|null + */ + public function getExtension(string $extension): ?array + { + return $this->get($extension); + } + + /** + * @param string $extension + * @param array|null $value + */ + public function setExtension(string $extension, ?array $value): void + { + if (null !== $value) { + $this->set($extension, $value); + } else { + $this->undef($extension); + } + } + + /** + * @param string $extension + * @return string|null + */ + public function getVersion(string $extension): ?string + { + $version = $this->get("{$extension}/version", null); + + return is_string($version) ? $version : null; + } + + /** + * @param string $extension + * @param string|null $version + */ + public function setVersion(string $extension, ?string $version): void + { + $this->updateHistory($extension, $version); + } + + /** + * NOTE: Updates also history. + * + * @param string $extension + * @param string|null $version + */ + public function updateVersion(string $extension, ?string $version): void + { + $this->set("{$extension}/version", $version); + $this->updateHistory($extension, $version); + } + + /** + * @param string $extension + * @return string|null + */ + public function getSchema(string $extension): ?string + { + $version = $this->get("{$extension}/schema", null); + + return is_string($version) ? $version : null; + } + + /** + * @param string $extension + * @param string|null $schema + */ + public function setSchema(string $extension, ?string $schema): void + { + if (null !== $schema) { + $this->set("{$extension}/schema", $schema); + } else { + $this->undef("{$extension}/schema"); + } + } + + /** + * @param string $extension + * @return array + */ + public function getHistory(string $extension): array + { + $name = "{$extension}/history"; + + return $this->get($name, []); + } + + /** + * @param string $extension + * @param string|null $version + */ + public function updateHistory(string $extension, ?string $version): void + { + $name = "{$extension}/history"; + $history = $this->get($name, []); + $history[] = ['version' => $version, 'date' => gmdate('Y-m-d H:i:s')]; + $this->set($name, $history); + } + + /** + * Clears extension history. Useful when creating skeletons. + * + * @param string|null $extension + */ + public function removeHistory(string $extension): void + { + $this->undef("{$extension}/history"); + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @param string $name Slash separated path to the requested value. + * @param mixed $default Default value (or null). + * @return mixed Value. + */ + private function get(string $name, $default = null) + { + $path = explode('/', $name) ?: []; + $current = $this->items; + + foreach ($path as $field) { + if (is_array($current) && isset($current[$field])) { + $current = $current[$field]; + } else { + return $default; + } + } + + return $current; + } + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @param string $name Slash separated path to the requested value. + * @param mixed $value New value. + */ + private function set(string $name, $value): void + { + $path = explode('/', $name) ?: []; + $current = &$this->items; + + foreach ($path as $field) { + // Handle arrays and scalars. + if (!is_array($current)) { + $current = [$field => []]; + } elseif (!isset($current[$field])) { + $current[$field] = []; + } + $current = &$current[$field]; + } + + $current = $value; + $this->updated = true; + } + + /** + * Unset value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + */ + private function undef(string $name): void + { + $path = $name !== '' ? explode('/', $name) : []; + if (!$path) { + return; + } + + $var = array_pop($path); + $current = &$this->items; + + foreach ($path as $field) { + if (!is_array($current) || !isset($current[$field])) { + return; + } + $current = &$current[$field]; + } + + unset($current[$var]); + $this->updated = true; + } + + private function __construct(string $filename) + { + $this->filename = $filename; + $content = is_file($filename) ? file_get_contents($filename) : null; + if (false === $content) { + throw new \RuntimeException('Versions file cannot be read'); + } + $this->items = $content ? Yaml::parse($content) : []; + } +} diff --git a/system/src/Grav/Installer/YamlUpdater.php b/system/src/Grav/Installer/YamlUpdater.php new file mode 100644 index 000000000..628167a9a --- /dev/null +++ b/system/src/Grav/Installer/YamlUpdater.php @@ -0,0 +1,407 @@ +updated) { + return false; + } + + try { + if (!$this->isHandWritten()) { + $yaml = Yaml::dump($this->items, 5, 2); + } else { + $yaml = implode("\n", $this->lines); + + $items = Yaml::parse($yaml); + if ($items !== $this->items) { + throw new \RuntimeException('Failed saving the content'); + } + } + + file_put_contents($this->filename, $yaml); + + } catch (\Exception $e) { + throw new \RuntimeException('Failed to update ' . basename($this->filename) . ': ' . $e->getMessage()); + } + + return true; + } + + /** + * @return bool + */ + public function isHandWritten(): bool + { + return !empty($this->comments); + } + + /** + * @return array + */ + public function getComments(): array + { + $comments = []; + foreach ($this->lines as $i => $line) { + if ($this->isLineEmpty($line)) { + $comments[$i+1] = $line; + } elseif ($comment = $this->getInlineComment($line)) { + $comments[$i+1] = $comment; + } + } + + return $comments; + } + + /** + * @param string $variable + * @param mixed $value + */ + public function define(string $variable, $value) + { + // If variable has already value, we're good. + if ($this->get($variable) !== null) { + return; + } + + // If one of the parents isn't array, we're good, too. + if (!$this->canDefine($variable)) { + return; + } + + $this->set($variable, $value); + if (!$this->isHandWritten()) { + return; + } + + $parts = explode('.', $variable); + + $lineNos = $this->findPath($this->lines, $parts); + $count = count($lineNos); + $last = array_key_last($lineNos); + + $value = explode("\n", trim(Yaml::dump([$last => $this->get(implode('.', array_keys($lineNos)))], max(0, 5-$count), 2))); + $currentLine = array_pop($lineNos) ?: 0; + $parentLine = array_pop($lineNos); + + if ($parentLine !== null) { + $c = $this->getLineIndentation($this->lines[$parentLine] ?? 0); + $n = $this->getLineIndentation($this->lines[$parentLine+1] ?? $this->lines[$parentLine] ?? 0); + $indent = $n > $c ? $n : $c + 2; + } else { + $indent = 0; + array_unshift($value, ''); + } + $spaces = str_repeat(' ', $indent); + foreach ($value as &$line) { + $line = $spaces . $line; + } + unset($line); + + array_splice($this->lines, abs($currentLine)+1, 0, $value); + } + + private function __construct(string $filename) + { + $content = is_file($filename) ? file_get_contents($filename) : ''; + $content = rtrim(str_replace(["\r\n", "\r"], "\n", $content)); + + $this->filename = $filename; + $this->lines = explode("\n", $content); + $this->comments = $this->getComments(); + $this->items = $content ? Yaml::parse($content) : []; + } + + /** + * Return array of offsets for the parent nodes. Negative value means position, but not found. + * + * @param array $lines + * @param array $parts + * @return array + */ + private function findPath(array $lines, array $parts) + { + $test = true; + $indent = -1; + $current = array_shift($parts); + + $j = 1; + $found = []; + $space = ''; + foreach ($lines as $i => $line) { + if ($this->isLineEmpty($line)) { + if ($this->isLineComment($line) && $this->getLineIndentation($line) > $indent) { + $j = $i; + } + continue; + } + + if ($test === true) { + $test = false; + $spaces = strlen($line) - strlen(ltrim($line, ' ')); + if ($spaces <= $indent) { + $found[$current] = -$j; + + return $found; + } + + $indent = $spaces; + $space = $indent ? str_repeat(' ', $indent) : ''; + } + + + if (0 === \strncmp($line, $space, strlen($space))) { + $pattern = "/^{$space}(['\"]?){$current}\\1\:/"; + + if (preg_match($pattern, $line)) { + $found[$current] = $i; + $current = array_shift($parts); + if ($current === null) { + return $found; + } + $test = true; + } + } else { + $found[$current] = -$j; + + return $found; + } + + $j = $i; + } + + $found[$current] = -$j; + + return $found; + } + + /** + * Returns true if the current line is blank or if it is a comment line. + * + * @param string $line Contents of the line + * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise + */ + private function isLineEmpty(string $line): bool + { + return $this->isLineBlank($line) || $this->isLineComment($line); + } + + /** + * Returns true if the current line is blank. + * + * @param string $line Contents of the line + * @return bool Returns true if the current line is blank, false otherwise + */ + private function isLineBlank(string $line): bool + { + return '' === trim($line, ' '); + } + + /** + * Returns true if the current line is a comment line. + * + * @param string $line Contents of the line + * @return bool Returns true if the current line is a comment line, false otherwise + */ + private function isLineComment(string $line): bool + { + //checking explicitly the first char of the trim is faster than loops or strpos + $ltrimmedLine = ltrim($line, ' '); + + return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0]; + } + + /** + * @param string $line + * @return bool + */ + private function isInlineComment(string $line): bool + { + return $this->getInlineComment($line) !== null; + } + + /** + * @param string $line + * @return string|null + */ + private function getInlineComment(string $line): ?string + { + $pos = strpos($line, ' #'); + if (false === $pos) { + return null; + } + + $parts = explode(' #', $line); + $part = ''; + while ($part .= array_shift($parts)) { + // Remove quoted values. + $part = preg_replace('/(([\'"])[^\2]*\2)/', '', $part); + $part = preg_split('/[\'"]/', $part, 2); + if (!isset($part[1])) { + $part = $part[0]; + array_unshift($parts, str_repeat(' ', strlen($part) - strlen(trim($part, ' ')))); + break; + } + $part = $part[1]; + } + + + return implode(' #', $parts); + } + + /** + * Returns the current line indentation. + * + * @param string $line + * @return int The current line indentation + */ + private function getLineIndentation(string $line): int + { + return \strlen($line) - \strlen(ltrim($line, ' ')); + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @return mixed Value. + */ + private function get(string $name, $default = null) + { + $path = explode('.', $name) ?: []; + $current = $this->items; + + foreach ($path as $field) { + if (is_array($current) && isset($current[$field])) { + $current = $current[$field]; + } else { + return $default; + } + } + + return $current; + } + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value New value. + */ + private function set(string $name, $value): void + { + $path = explode('.', $name) ?: []; + $current = &$this->items; + + foreach ($path as $field) { + // Handle arrays and scalars. + if (!is_array($current)) { + $current = [$field => []]; + } elseif (!isset($current[$field])) { + $current[$field] = []; + } + $current = &$current[$field]; + } + + $current = $value; + $this->updated = true; + } + + /** + * Unset value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + */ + private function undef(string $name): void + { + $path = $name !== '' ? explode('.', $name) : []; + if (!$path) { + return; + } + + $var = array_pop($path); + $current = &$this->items; + + foreach ($path as $field) { + if (!is_array($current) || !isset($current[$field])) { + return; + } + $current = &$current[$field]; + } + + unset($current[$var]); + $this->updated = true; + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @return bool + */ + private function canDefine(string $name): bool + { + $path = explode('.', $name) ?: []; + $current = $this->items; + + foreach ($path as $field) { + if (is_array($current)) { + if (!isset($current[$field])) { + return true; + } + $current = $current[$field]; + } else { + return false; + } + } + + return true; + } +} diff --git a/system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php b/system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php new file mode 100644 index 000000000..554bfd8b1 --- /dev/null +++ b/system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php @@ -0,0 +1,24 @@ + + function () { + /** @var VersionUpdate $this */ + try { + // Keep old defaults for backwards compatibility. + $yaml = YamlUpdater::instance(GRAV_ROOT . '/user/config/system.yaml'); + $yaml->define('twig.autoescape', false); + $yaml->define('strict_mode.yaml_compat', true); + $yaml->define('strict_mode.twig_compat', true); + $yaml->define('strict_mode.blueprint_compat', true); + $yaml->save(); + } catch (\Exception $e) { + throw new InstallException('Could not update system configuration to maintain backwards compatibility', $e); + } + }, + 'postflight' => null +];