Skip to content

Commit

Permalink
Merge branch 'release/4.3.5' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonkelly committed Dec 13, 2022
2 parents f8b4934 + a73ffd2 commit bb51407
Show file tree
Hide file tree
Showing 41 changed files with 616 additions and 105 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ src/templates/*
src/web/assets/**/dist/*
tests/_craft/*
vendor/*
.ddev/*
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Release Notes for Craft CMS 4

## 4.3.5 - 2022-12-13

- Fixed a bug where entry tab contents could remain visible when switching to other tabs, after changing the entry type.
- Fixed a bug where it wasn’t possible to enter `0` in Number fields, Money fields, and numeric column cells within editable tables, using certain keyboard layouts. ([#12412](https://github.com/craftcms/cms/issues/12412))
- Fixed a bug where the default MySQL restore command would attempt to use credentials from `~/.my.cnf` if it existed, instead of Craft’s configured database connection settings. ([#12349](https://github.com/craftcms/cms/issues/12349), [#12430](https://github.com/craftcms/cms/pull/12430))
- Fixed a JavaScript error that could occur when autosaving an entry draft. ([#12445](https://github.com/craftcms/cms/issues/12445))
- Added `craft\base\ApplicationTrait::onInit()`. ([#12439](https://github.com/craftcms/cms/pull/12439))
- Added `craft\console\Controller::createDirectory()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::do()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::failure()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::note()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::success()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::tip()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::warning()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::writeJson()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\console\Controller::writeToFile()`. ([#12438](https://github.com/craftcms/cms/pull/12438))
- Added `craft\helpers\FileHelper::absolutePath()`.
- Added `craft\helpers\FileHelper::findClosestFile()`.
- Added `craft\helpers\FileHelper::isWithin()`.
- Added `craft\helpers\FileHelper::relativePath()`.
- Added `craft\helpers\Json::decodeFromFile()`.
- Added `Craft.filterInputVal()`.
- Added `Craft.filterNumberInputVal()`.

## 4.3.4 - 2022-11-29

- The `serve` command now routes requests for nonexistent files to Craft. ([#12310](https://github.com/craftcms/cms/pull/12310))
Expand Down
17 changes: 17 additions & 0 deletions src/base/ApplicationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,23 @@ public function getIsInitialized(): bool
return $this->_isInitialized;
}

/**
* Invokes a callback method when Craft is fully initialized.
*
* @param callable $callback
* @since 4.3.5
*/
public function onInit(callable $callback): void
{
if ($this->_isInitialized) {
$callback();
} else {
$this->on(WebApplication::EVENT_INIT, function() use ($callback) {
$callback();
});
}
}

/**
* Returns whether this Craft install has multiple sites.
*
Expand Down
2 changes: 1 addition & 1 deletion src/config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
return [
'id' => 'CraftCMS',
'name' => 'Craft CMS',
'version' => '4.3.4',
'version' => '4.3.5',
'schemaVersion' => '4.0.0.9',
'minVersionRequired' => '3.7.11',
'basePath' => dirname(__DIR__), // Defines the @app alias
Expand Down
155 changes: 155 additions & 0 deletions src/console/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
use craft\events\DefineConsoleActionsEvent;
use craft\helpers\ArrayHelper;
use craft\helpers\Console;
use craft\helpers\FileHelper;
use craft\helpers\Json;
use craft\helpers\StringHelper;
use ReflectionFunction;
use ReflectionFunctionAbstract;
use ReflectionMethod;
use Seld\CliPrompt\CliPrompt;
use Throwable;
use yii\base\Action;
use yii\base\InvalidConfigException;
use yii\console\Controller as YiiController;
Expand Down Expand Up @@ -349,6 +352,22 @@ private function _isCustomOption(string $name): bool
);
}

/**
* Converts Markdown to be better readable in console environments by applying some ANSI format.
*
* @param string $markdown
* @return string
* @since 4.3.5
*/
public function markdownToAnsi(string $markdown): string
{
if (!$this->isColorEnabled()) {
return $markdown;
}

return trim(Console::markdownToAnsi($markdown));
}

/**
* Prompts the user for a password and validates it.
*
Expand Down Expand Up @@ -436,4 +455,140 @@ public function table(array $headers, array $data, array $options = []): void

Console::table($headers, $data, $options);
}

/**
* Outputs a note to the console.
*
* @param string $message The message. Supports Markdown formatting.
* @since 4.3.5
*/
public function note(string $message, string $icon = 'ℹ️ '): void
{
$this->stdout("\n$icon ", Console::FG_YELLOW, Console::BOLD);
$this->stdout(trim(preg_replace('/^/m', ' ', $this->markdownToAnsi($message))) . "\n\n");
}

/**
* Outputs a success message to the console.
*
* @param string $message The message. Supports Markdown formatting.
* @since 4.3.5
*/
public function success(string $message): void
{
$this->note($message, '');
}

/**
* Outputs a failure message to the console.
*
* @param string $message The message. Supports Markdown formatting.
* @since 4.3.5
*/
public function failure(string $message): void
{
$this->note($message, '');
}

/**
* Outputs a tip to the console.
*
* @param string $message The message. Supports Markdown formatting.
* @since 4.3.5
*/
public function tip(string $message): void
{
$this->note($message, '💡');
}

/**
* Outputs a warning to the console.
*
* @param string $message The message. Supports Markdown formatting.
* @since 4.3.5
*/
public function warning(string $message): void
{
$this->note($message, '⚠️ ');
}

/**
* Performs an action with descriptive output.
*
* @param string $description The action description. Supports Markdown formatting.
* @param callable $action The action callable
* @param bool $withDuration Whether to output the action duration upon completion
* @since 4.3.5
*/
public function do(string $description, callable $action, bool $withDuration = false): void
{
$this->stdout('', Console::FG_GREY);
$this->stdout($this->markdownToAnsi($description));
$this->stdout('', Console::FG_GREY);

if ($withDuration) {
$time = microtime(true);
}

try {
$action();
} catch (Throwable $e) {
$this->stdout('' . PHP_EOL, Console::FG_RED, Console::BOLD);
$this->stdout(" Error: {$e->getMessage()}" . PHP_EOL, Console::FG_RED);
throw $e;
}

$this->stdout('', Console::FG_GREEN, Console::BOLD);
if ($withDuration) {
$this->stdout(sprintf(' (time: %.3fs', microtime(true) - $time), Console::FG_GREY);
}
$this->stdout(PHP_EOL);
}

/**
* Creates a directory, and outputs to the console.
*
* @param string $path The path to the directory
* @since 4.3.5
*/
public function createDirectory(string $path): void
{
$path = FileHelper::relativePath($path);
$this->do(
sprintf('Creating %s', $this->ansiFormat("$path/", Console::FG_CYAN)),
function() use ($path) {
FileHelper::createDirectory($path);
},
);
}

/**
* Writes contents to a file, and outputs to the console.
*
* @param string $file The path to the file to write to
* @param string $contents The file contents
* @param array $options Options for [[FileHelper::writeToFile()]]
* @since 4.3.5
*/
public function writeToFile(string $file, string $contents, array $options = []): void
{
$file = FileHelper::relativePath($file);
$description = file_exists($file) ? "Updating `$file`" : "Creating `$file`";
$this->do($description, function() use ($file, $contents, $options) {
FileHelper::writeToFile($file, $contents, $options);
});
}

/**
* JSON-encodes a value and writes it to a file.
*
* @param string $file The path to the file to write to
* @param mixed $value The value to be JSON-encoded and written out
* @since 4.3.5
*/
public function writeJson(string $file, mixed $value): void
{
$json = Json::encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) . "\n";
$this->writeToFile($file, "$json\n");
}
}
32 changes: 32 additions & 0 deletions src/console/MarkdownParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\console;

use yii\console\Markdown;
use yii\helpers\Console;

/**
* Markdown parser
*
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 4.3.5
*/
class MarkdownParser extends Markdown
{
protected function renderCode($block)
{
$lines = preg_split('/[\r\n]/', $block['content']);
$maxLength = max(array_map(fn(string $line) => strlen($line), $lines));
return implode("\n", array_map(fn(string $line) => Console::ansiFormat(str_pad($line, $maxLength), [Console::NEGATIVE]), $lines)) . "\n\n";
}

protected function renderInlineCode($element)
{
return Console::ansiFormat($element[1], [Console::FG_CYAN]);
}
}
2 changes: 1 addition & 1 deletion src/db/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
* @property bool $supportsMb4 Whether the database supports 4+ byte characters.
* @method MysqlQueryBuilder|PgsqlQueryBuilder getQueryBuilder() Returns the query builder for the current DB connection.
* @method MysqlSchema|PgsqlSchema getSchema() Returns the schema information for the database opened by this connection.
* @method TableSchema getTableSchema($name, $refresh = false) Obtains the schema information for the named table.
* @method TableSchema|null getTableSchema($name, $refresh = false) Obtains the schema information for the named table.
* @method Command createCommand($sql = null, $params = []) Creates a command for execution.
* @author Pixel & Tonic, Inc. <[email protected]>
* @since 3.0.0
Expand Down
2 changes: 1 addition & 1 deletion src/db/mysql/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public function getDefaultBackupCommand(?array $ignoreTables = null): string
public function getDefaultRestoreCommand(): string
{
return 'mysql' .
' --defaults-extra-file="' . $this->_createDumpConfigFile() . '"' .
' --defaults-file="' . $this->_createDumpConfigFile() . '"' .
' {database}' .
' < "{file}"';
}
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/CopyReferenceTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
activate: \$selectedItems => {
Craft.ui.createCopyTextPrompt({
label: Craft.t('app', 'Copy the reference tag'),
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/CopyUrl.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => !!\$selectedItems.find('.element').data('url'),
activate: \$selectedItems => {
Craft.ui.createCopyTextPrompt({
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/DeleteUsers.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: true,
bulk: true,
validateSelection: \$selectedItems => {
for (let i = 0; i < \$selectedItems.length; i++) {
if ($.inArray(\$selectedItems.eq(i).find('.element').data('id').toString(), $undeletableIds) != -1) {
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/Edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => Garnish.hasAttr(\$selectedItems.find('.element'), 'data-savable'),
activate: \$selectedItems => {
const \$element = \$selectedItems.find('.element:first');
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/EditImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => Garnish.hasAttr(\$selectedItems.find('.element'), 'data-editable-image'),
activate: \$selectedItems => {
const \$element = \$selectedItems.find('.element:first');
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/NewChild.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function getTriggerHtml(): ?string
(() => {
let trigger = new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => !$maxLevels || $maxLevels > \$selectedItems.find('.element').data('level'),
activate: \$selectedItems => {
const url = Craft.getUrl($newChildUrl, 'parentId=' + \$selectedItems.find('.element').data('id'));
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/NewSiblingAfter.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
activate: \$selectedItems => {
Craft.redirectTo(Craft.getUrl($newSiblingUrl, 'after=' + \$selectedItems.find('.element').data('id')));
},
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/NewSiblingBefore.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
activate: \$selectedItems => {
Craft.redirectTo(Craft.getUrl($newSiblingUrl, 'before=' + \$selectedItems.find('.element').data('id')));
},
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/PreviewAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => \$selectedItems.length === 1,
activate: \$selectedItems => {
const \$element = \$selectedItems.find('.element');
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/RenameFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => Garnish.hasAttr(\$selectedItems.find('.element'), 'data-movable'),
activate: \$selectedItems => {
const \$element = \$selectedItems.find('.element')
Expand Down
2 changes: 1 addition & 1 deletion src/elements/actions/ReplaceFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function getTriggerHtml(): ?string
(() => {
new Craft.ElementActionTrigger({
type: $type,
batch: false,
bulk: false,
validateSelection: \$selectedItems => Garnish.hasAttr(\$selectedItems.find('.element'), 'data-replaceable'),
activate: \$selectedItems => {
$('.replaceFile').remove();
Expand Down
Loading

0 comments on commit bb51407

Please sign in to comment.