Skip to content
Draft

5.11 #19062

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
564ba01
5.11 changelog
brandonkelly Jun 9, 2026
f4b5945
Merge branch '5.x' into 5.11
brandonkelly Jun 16, 2026
8278917
UrlHelper::removeParams(), removeAllParams()
brandonkelly Jun 16, 2026
95ef394
Release notes
brandonkelly Jun 16, 2026
3b0c332
Merge pull request #19102 from craftcms/feature/url-params
brandonkelly Jun 16, 2026
e8e7855
Merge branch '5.x' into 5.11
brandonkelly Jun 25, 2026
45ac9aa
craft\web\DbSession
brandonkelly Jun 25, 2026
cd5e40a
Merge branch '5.x' into 5.11
brandonkelly Jul 6, 2026
0ccf9a7
Twig 3.28
brandonkelly Jul 6, 2026
dd9b6f1
Release note
brandonkelly Jul 6, 2026
f9213a9
Merge pull request #19211 from craftcms/chore/twig-3.28
brandonkelly Jul 6, 2026
80a44d6
Merge branch '5.x' into 5.11
brandonkelly Jul 15, 2026
81cb974
Merge branch '5.x' into 5.11
brandonkelly Jul 28, 2026
ad1ee56
Sort lines
brandonkelly Jul 28, 2026
2ba19b3
reorderNestedElements()
brandonkelly Jul 28, 2026
7af7169
Merge pull request #19331 from craftcms/feature/reorderNestedElements
brandonkelly Jul 28, 2026
db3ad48
Merge branch '5.x' into 5.11
brandonkelly Aug 1, 2026
8de14b0
yii2-debug 2.1.28
brandonkelly Aug 1, 2026
4ad6779
Add support for .well-known/passkey-endpoints
brandonkelly Aug 3, 2026
9ae1316
Release note
brandonkelly Aug 3, 2026
b87577d
Merge pull request #19364 from craftcms/feature/well-known-passkey-en…
brandonkelly Aug 3, 2026
c796b83
Wrong changelog
brandonkelly Aug 3, 2026
9fd2b6c
Merge branch '5.x' into 5.11
brandonkelly Aug 4, 2026
fdb997f
Merge branch '5.x' into 5.11
brandonkelly Aug 5, 2026
500ed4b
Merge branch '5.x' into 5.11
brandonkelly Aug 5, 2026
24371bd
Fill in the gaps when converting a LinkData object to an array
brandonkelly Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG-5.11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Release Notes for Craft CMS 5.11 (WIP)

### Development
- The `params` argument of the `url()` Twig function now accepts `false` to remove all params from the passed-in URL. ([#19102](https://github.com/craftcms/cms/pull/19102))
- Added `craft\web\DbSession`, which should be used instead of `yii\web\DbSession` to prevent “headers already sent” warnings from getting logged. ([#19139](https://github.com/craftcms/cms/issues/19139))
- Arrays created from `craft\fields\data\LinkData` objects now include `type`, `value`, `url`, `label`, `filename`, `link`, `attributes`, `defaultLabel`, `elementType`, `elementId`, `elementSiteId`, and `elementTitle` keys. ([craftcms/element-api#201](https://github.com/craftcms/element-api/issues/201))

### Extensibility
- Added `craft\helpers\UrlHelper::removeAllParams()`. ([#19102](https://github.com/craftcms/cms/pull/19102))
- Added `craft\helpers\UrlHelper::removeParams()`. ([#19102](https://github.com/craftcms/cms/pull/19102))
- Added `craft\services\Elements::reorderNestedElements()`. ([#19321](https://github.com/craftcms/cms/issues/19321))
- The `$params` argument of `craft\helpers\UrlHelper::url()` now accepts `false` to remove all params from the passed-in URL. ([#19102](https://github.com/craftcms/cms/pull/19102))

### System
- Added support for `.well-known/passkey-endpoints` requests. ([#19364](https://github.com/craftcms/cms/pull/19364))
- Updated Twig to 3.28.
- Updated yii2-debug to 2.1.28.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@
"symfony/var-dumper": "^5.0|^6.0|^7.0",
"symfony/yaml": "^5.2.3|^6.0|^7.0",
"theiconic/name-parser": "^1.2",
"twig/twig": "~3.27.0",
"twig/twig": "~3.28.0",
"voku/portable-ascii": "^2.0",
"web-auth/webauthn-lib": "~5.3.5",
"yiisoft/yii2": "~2.0.55.0",
"yiisoft/yii2-debug": "~2.1.27.0",
"yiisoft/yii2-debug": "~2.1.28.0",
"yiisoft/yii2-queue": "~2.3.2",
"yiisoft/yii2-symfonymailer": "^4.0.0"
},
Expand Down
72 changes: 31 additions & 41 deletions composer.lock

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

34 changes: 1 addition & 33 deletions src/controllers/NestedElementsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

use Craft;
use craft\base\ElementInterface;
use craft\base\NestedElementInterface;
use craft\db\Table;
use craft\elements\db\ElementQueryInterface;
use craft\elements\ElementCollection;
Expand Down Expand Up @@ -82,38 +81,7 @@ public function actionReorder(): Response
$ids = array_map(fn($id) => (int)$id, $this->request->getRequiredBodyParam('elementIds'));
$offset = $this->request->getRequiredBodyParam('offset');

if ($this->nestedElements instanceof ElementQueryInterface) {
$oldSortOrders = (clone $this->nestedElements)
->status(null)
->asArray()
->select(['id', 'sortOrder'])
->pairs();
} else {
$oldSortOrders = $this->nestedElements
->keyBy(fn(ElementInterface $element) => $element->id)
/** @phpstan-ignore-next-line */
->map(fn(NestedElementInterface $element) => $element->getSortOrder())
->all();
}

// Build the full list of IDs in the new sort order
$allIds = array_diff(array_keys($oldSortOrders), $ids);
array_splice($allIds, $offset, 0, $ids);

// Update all the incorrect sort orders
foreach ($allIds as $i => $id) {
$sortOrder = $i + 1;
if (!isset($oldSortOrders[$id]) || $sortOrder !== $oldSortOrders[$id]) {
Db::update(Table::ELEMENTS_OWNERS, [
'sortOrder' => $sortOrder,
], [
'ownerId' => $this->owner->id,
'elementId' => $id,
]);
}
}

Craft::$app->getElements()->invalidateCachesForElement($this->owner);
Craft::$app->getElements()->reorderNestedElements($this->owner, $this->nestedElements, $ids, $offset);

return $this->asSuccess(Craft::t('app', 'New {total, plural, =1{position} other{positions}} saved.', [
'total' => count($ids),
Expand Down
30 changes: 30 additions & 0 deletions src/controllers/WellKnownController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/

namespace craft\controllers;

use craft\web\Controller;
use yii\web\Response;

/**
* Class WellKnownController
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 5.11.0
*/
class WellKnownController extends Controller
{
protected array|bool|int $allowAnonymous = self::ALLOW_ANONYMOUS_LIVE;

public function actionPasskeyEndpoints(): Response
{
// Just return an empty object to signal support for passkeys, w/o leaking the CP URL.
$this->response->format = Response::FORMAT_JSON;
$this->response->content = '{}';
return $this->response;
}
}
31 changes: 30 additions & 1 deletion src/fields/data/LinkData.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use craft\helpers\Template;
use craft\web\twig\AllowedInSandbox;
use Twig\Markup;
use yii\base\Arrayable;
use yii\base\ArrayableTrait;
use yii\base\BaseObject;

/**
Expand All @@ -35,8 +37,12 @@
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 5.3.0
*/
class LinkData extends BaseObject implements Serializable
class LinkData extends BaseObject implements Serializable, Arrayable
{
use ArrayableTrait {
fields as traitFields;
}

/**
* @var string|null The link’s URL suffix value.
* @since 5.6.0
Expand Down Expand Up @@ -110,6 +116,29 @@ public function __toString(): string
return $this->getUrl();
}

/**
* @inheritdoc
*/
public function fields(): array
{
$fields = $this->traitFields();

$fields['type'] = 'type';
$fields['value'] = 'value';
$fields['url'] = 'url';
$fields['label'] = 'label';
$fields['filename'] = 'filename';
$fields['link'] = 'link';
$fields['attributes'] = 'attributes';
$fields['defaultLabel'] = fn() => $this->getLabel(false);
$fields['elementType'] = fn() => $this->getElement() ? $this->getElement()::class : null;
$fields['elementId'] = fn() => $this->getElement()?->id;
$fields['elementSiteId'] = fn() => $this->getElement()?->siteId;
$fields['elementTitle'] = fn() => $this->getElement() ? (string)$this->getElement() : null;

return $fields;
}

/**
* Returns the link type ID.
*
Expand Down
Loading
Loading