Skip to content

Commit

Permalink
Merge branch '4.13' into feature/conditional-filters
Browse files Browse the repository at this point in the history
  • Loading branch information
timkelty committed Oct 23, 2024
2 parents 65d2b41 + 87bdf34 commit 735a661
Show file tree
Hide file tree
Showing 22 changed files with 90 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
### Development
- Added the `encodeUrl()` Twig function. ([#15838](https://github.com/craftcms/cms/issues/15838))
- Added support for passing aliased field handles into element queries’ `select()`/`addSelect()` methods. ([#15827](https://github.com/craftcms/cms/issues/15827))
- Added support for appending subpaths to environment variable names in environmental settings (e.g. `$PRIMARY_SITE_URL/uploads`).

### Extensibility
- Added `craft\base\RequestTrait::getIsWebRequest()`. ([#15690](https://github.com/craftcms/cms/pull/15690))
Expand Down
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Release Notes for Craft CMS 4

## Unreleased
## 4.12.8 - 2024-10-22

- The `install` command now runs through database connection setup, if Craft can’t yet connect to the database. ([#15943](https://github.com/craftcms/cms/issues/15943))
- Fixed a bug where admin table header cells weren’t indicating when they were sorted. ([#15897](https://github.com/craftcms/cms/issues/15897))
- Fixed an error that occurred when creating a database backup, if the System Name contained any quote-like characters. ([#15933](https://github.com/craftcms/cms/issues/15933))
- Fixed a bug where buttons could bleed out of their containers. ([#15931](https://github.com/craftcms/cms/issues/15931), [#15946](https://github.com/craftcms/cms/pull/15946))
- Fixed a PHP error. ([#15915](https://github.com/craftcms/cms/issues/15915))
- Fixed an information disclosure vulnerability.

## 4.12.7 - 2024-10-15

- Fixed a privilege escalation vulnerability.

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.12.6.1',
'version' => '4.12.8',
'schemaVersion' => '4.5.3.0',
'minVersionRequired' => '3.7.11',
'basePath' => dirname(__DIR__), // Defines the @app alias
Expand Down
11 changes: 9 additions & 2 deletions src/console/controllers/InstallController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Craft;
use craft\console\Controller;
use craft\elements\User;
use craft\errors\DbConnectException;
use craft\errors\MigrationException;
use craft\errors\OperationAbortedException;
use craft\helpers\Console;
Expand Down Expand Up @@ -99,15 +100,21 @@ public function actionCheck(): int
/**
* Runs the install migration.
*
* @return int
* @return mixed
*/
public function actionCraft(): int
public function actionCraft(): mixed
{
if (Craft::$app->getIsInstalled(true)) {
$this->stdout('Craft is already installed!' . PHP_EOL, Console::FG_YELLOW);
return ExitCode::OK;
}

try {
Craft::$app->getDb()->open();
} catch (DbConnectException $e) {
return $this->run('setup/welcome');
}

$this->run('setup/keys');

$configService = Craft::$app->getConfig();
Expand Down
5 changes: 3 additions & 2 deletions src/db/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,10 @@ public function close(): void
public function getBackupFilePath(): string
{
// Determine the backup file path
$systemName = mb_strtolower(FileHelper::sanitizeFilename(Craft::$app->getSystemName(), [
$systemName = FileHelper::sanitizeFilename(Craft::$app->getSystemName(), [
'asciiOnly' => true,
]));
]);
$systemName = str_replace(['\'', '"'], '', strtolower($systemName));
$version = Craft::$app->getInfo()->version ?? Craft::$app->getVersion();
$filename = ($systemName ? "$systemName--" : '') . gmdate('Y-m-d-His') . "--v$version";
$backupPath = Craft::$app->getPath()->getDbBackupPath();
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,15 @@ public static function parseEnv(?string $value): bool|string|null
return null;
}

if (preg_match('/^\$(\w+)$/', $value, $matches)) {
if (preg_match('/^\$(\w+)(\/.*)?/', $value, $matches)) {
$env = static::env($matches[1]);

if ($env === null) {
// starts with $ but not an environment variable/constant, so just give up, it's hopeless!
return $value;
}

$value = $env;
$value = $env . ($matches[2] ?? '');
}

if (is_string($value) && str_starts_with($value, '@')) {
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/Cp.php
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,9 @@ public static function autosuggestFieldHtml(array $config): string
$value = $config['value'] ?? '';
if (!isset($config['tip']) && (!isset($value[0]) || !in_array($value[0], ['$', '@']))) {
if ($config['suggestAliases'] ?? false) {
$config['tip'] = Craft::t('app', 'This can be set to an environment variable, or begin with an alias.');
$config['tip'] = Craft::t('app', 'This can begin with an environment variable or alias.');
} else {
$config['tip'] = Craft::t('app', 'This can be set to an environment variable.');
$config['tip'] = Craft::t('app', 'This can begin with an environment variable.');
}
$config['tip'] .= ' ' .
Html::a(Craft::t('app', 'Learn more'), 'https://craftcms.com/docs/4.x/config#control-panel-settings', [
Expand Down
6 changes: 6 additions & 0 deletions src/helpers/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,12 @@ public static function dataUrl(string $file, ?string $mimeType = null): string

$file = FileHelper::absolutePath(Craft::getAlias($file), '/');

// make sure it's contained within the project rot
$rootPath = FileHelper::absolutePath(Craft::getAlias('@root'), '/');
if (!str_starts_with($file, "$rootPath/")) {
throw new InvalidArgumentException(sprintf('%s cannot be passed a path outside of the project root.', __METHOD__));
}

if (Craft::$app->getSecurity()->isSystemDir(dirname($file))) {
throw new InvalidArgumentException(sprintf('%s cannot be passed a path within or above system directories.', __METHOD__));
}
Expand Down
10 changes: 6 additions & 4 deletions src/services/Elements.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
use craft\validators\HandleValidator;
use craft\validators\SlugValidator;
use DateTime;
use Illuminate\Support\Collection;
use Throwable;
use UnitEnum;
use yii\base\Behavior;
Expand Down Expand Up @@ -2452,7 +2453,7 @@ public function getRecentActivity(ElementInterface $element, ?int $excludeUserId
->indexBy('id')
->all();

$activity = [];
$activity = Collection::make();
/** @var ElementActivity[] $activityByUserId */
$activityByUserId = [];
$elements = [];
Expand All @@ -2468,7 +2469,7 @@ public function getRecentActivity(ElementInterface $element, ?int $excludeUserId
$newerRecord->type === ElementActivity::TYPE_VIEW &&
$result['type'] !== ElementActivity::TYPE_VIEW
) {
array_splice($activity, array_search($newerRecord, $activity), 1);
$activity = $activity->filter(fn(ElementActivity $record) => $record !== $newerRecord);
unset($activityByUserId[$result['userId']]);
} else {
continue;
Expand Down Expand Up @@ -2501,15 +2502,16 @@ public function getRecentActivity(ElementInterface $element, ?int $excludeUserId
$elements[$elementKey][$result['siteId']] = $resultElement;
}

$activity[] = $activityByUserId[$result['userId']] = new ElementActivity(
$record = $activityByUserId[$result['userId']] = new ElementActivity(
$users[$result['userId']],
$elements[$elementKey][$result['siteId']],
$result['type'],
DateTimeHelper::toDateTime($result['timestamp']),
);
$activity->push($record);
}

return $activity;
return $activity->values()->all();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/templates/_includes/forms.twig
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@
{% set config = config|merge({
tip: (config.allowedEnvValues is not defined)
? 'This can be set to an environment variable matching one of the option values.'|t('app')
: 'This can be set to an environment variable.'|t('app'),
: 'This can begin with an environment variable.'|t('app'),
}) %}
{% endif %}
{{ _self.field(config, 'template:_includes/forms/selectize') }}
Expand Down Expand Up @@ -324,8 +324,8 @@
{% if config.tip is not defined and value[0:1] not in ['$', '@'] %}
{% set config = config|merge({
tip: ((config.suggestAliases ?? false)
? 'This can be set to an environment variable, or begin with an alias.'|t('app')
: 'This can be set to an environment variable.'|t('app')) ~ ' ' ~ tag('a', {
? 'This can begin with an environment variable or alias.'|t('app')
: 'This can begin with an environment variable.'|t('app')) ~ ' ' ~ tag('a', {
href: 'https://craftcms.com/docs/4.x/config/#control-panel-settings',
class: 'go',
text: 'Learn more'|t('app'),
Expand Down
2 changes: 2 additions & 0 deletions src/test/TestSetup.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ public static function configureCraft(): bool

$configPath = realpath(CRAFT_CONFIG_PATH);
$contentMigrationsPath = realpath(CRAFT_MIGRATIONS_PATH);
$rootPath = realpath(CRAFT_ROOT_PATH);
$storagePath = realpath(CRAFT_STORAGE_PATH);
$templatesPath = realpath(CRAFT_TEMPLATES_PATH);
$testsPath = realpath(CRAFT_TESTS_PATH);
Expand Down Expand Up @@ -355,6 +356,7 @@ public static function configureCraft(): bool
Craft::setAlias('@appicons', $srcPath . DIRECTORY_SEPARATOR . 'icons');
Craft::setAlias('@config', $configPath);
Craft::setAlias('@contentMigrations', $contentMigrationsPath);
Craft::setAlias('@root', $rootPath);
Craft::setAlias('@storage', $storagePath);
Craft::setAlias('@templates', $templatesPath);
Craft::setAlias('@tests', $testsPath);
Expand Down
4 changes: 2 additions & 2 deletions src/translations/en/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -1547,8 +1547,8 @@
'This can be set to an environment variable with a boolean value ({examples}).' => 'This can be set to an environment variable with a boolean value ({examples}).',
'This can be set to an environment variable with a value of a [supported time zone]({url}).' => 'This can be set to an environment variable with a value of a [supported time zone]({url}).',
'This can be set to an environment variable, or a Twig template that outputs an ID.' => 'This can be set to an environment variable, or a Twig template that outputs an ID.',
'This can be set to an environment variable, or begin with an alias.' => 'This can be set to an environment variable, or begin with an alias.',
'This can be set to an environment variable.' => 'This can be set to an environment variable.',
'This can begin with an environment variable or alias.' => 'This can begin with an environment variable or alias.',
'This can begin with an environment variable.' => 'This can begin with an environment variable.',
'This element is conditional' => 'This element is conditional',
'This field has been modified.' => 'This field has been modified.',
'This field is conditional' => 'This field is conditional',
Expand Down
2 changes: 1 addition & 1 deletion src/translations/fa/app.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/translations/sk/app.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/css/cp.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/css/cp.css.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/src/css/_cp.scss
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ a#system-info {
padding: 4px 5px;
margin: 0 2px;
color: var(--error-color);
height: calc(30rem / 16);
min-height: calc(30rem / 16);

.flex & {
margin: 0;
Expand Down
34 changes: 29 additions & 5 deletions src/web/assets/cp/src/css/_main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,6 @@ ul.icons {
padding: 7px 14px;
border: none;
text-align: center;
white-space: nowrap;
user-select: none;
box-sizing: border-box;
appearance: none;
Expand Down Expand Up @@ -1609,7 +1608,9 @@ ul.icons {
}
}

.btn,
.btn {
min-height: var(--ui-control-height);
}
.spinner {
height: var(--ui-control-height);
}
Expand Down Expand Up @@ -1901,7 +1902,7 @@ ul.icons {
.btngroup.small input.btn,
.btn.small,
.btn.small + .spinner {
height: 22px;
min-height: 22px;
}

/* big buttons */
Expand All @@ -1922,7 +1923,7 @@ ul.icons {
.btngroup.big input.btn,
.btn.big,
.btn.big + .spinner {
height: 36px;
min-height: 36px;
}

/* special buttons */
Expand Down Expand Up @@ -2734,6 +2735,29 @@ table {
border-top-color: var(--gray-300);
}
}

&.vuetable {
th.sortable {
&:hover {
color: var(--text-color);
background-color: var(--gray-100);
}

&.ordered {
background-color: var(--light-sel-color);

.sort-icon {
@include angle(up);
margin-top: 7px;
}

&.desc .sort-icon {
transform: rotate(45deg);
margin-top: 5px;
}
}
}
}
}

// collapsable data tables for small screens
Expand Down Expand Up @@ -6290,7 +6314,7 @@ fieldset {
.expand-status-btn {
@include margin-left(5px);
width: 30px;
height: 17px;
min-height: 17px;
padding: 0;
line-height: 16px;
border-radius: var(--small-border-radius);
Expand Down
2 changes: 2 additions & 0 deletions tests/_bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
ini_set('date.timezone', 'UTC');
date_default_timezone_set('UTC');

define('CRAFT_ROOT_PATH', dirname(__DIR__));

// Use the current installation of Craft
const CRAFT_TESTS_PATH = __DIR__;
const CRAFT_STORAGE_PATH = __DIR__ . DIRECTORY_SEPARATOR . '_craft' . DIRECTORY_SEPARATOR . 'storage';
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/PageRenderChecksCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ protected function pagesDataProvider(): array
[
'url' => '/settings/email', 'title' => 'Email Settings', 'extraContent' => [
['rendered' => 'System Email Address'],
['rendered' => 'This can be set to an environment variable. Learn more'],
['rendered' => 'This can begin with an environment variable. Learn more'],
['rendered' => 'Sender Name'],
['rendered' => 'HTML Email Template'],
['rendered' => 'Transport Type'],
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/helpers/AppHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ public function testParseEnv(): void
{
self::assertNull(App::parseEnv(null));
self::assertSame(CRAFT_TESTS_PATH, App::parseEnv('$CRAFT_TESTS_PATH'));
self::assertSame(CRAFT_TESTS_PATH . '/foo/bar', App::parseEnv('$CRAFT_TESTS_PATH/foo/bar'));
self::assertSame('CRAFT_TESTS_PATH', App::parseEnv('CRAFT_TESTS_PATH'));
self::assertSame('$TEST_MISSING', App::parseEnv('$TEST_MISSING'));
self::assertSame(Craft::getAlias('@vendor/foo'), App::parseEnv('@vendor/foo'));
self::assertSame(Craft::getAlias('@vendor/foo/bar'), App::parseEnv('@vendor/foo/bar'));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/web/twig/ExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ public function testCloneFunction(): void
*/
public function testDataUrlFunction(): void
{
$path = dirname(__DIR__, 4) . '/.github/workflows/ci.yml';
$path = '@root/.github/workflows/ci.yml';
$dataUrl = $this->view->renderString('{{ dataUrl(path) }}', compact('path'));
self::assertStringStartsWith('data:application/x-yaml;base64,', $dataUrl);
}
Expand Down

0 comments on commit 735a661

Please sign in to comment.