cms icon indicating copy to clipboard operation
cms copied to clipboard

Deprecation error for Craft CMS fields with handle `order`

Open Anubarak opened this issue 6 years ago • 6 comments

Description

I have a Craft CMS field with the handle order and I always receive a deprecation error because of this

The “order” element query param has been deprecated. Use “orderBy” instead.

The given stack trace looks like the following

27 | Deprecation error: The “order” element query param has been deprecated. Use “orderBy” instead. Called from /var/www/myspa/htdocs/vendor/craftcms/cms/src/elements/db/ElementQuery.php:402

26 | craft\elements\db\AssetQuery::__get("order") Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/base/ArrayableTrait.php:126

25 | craft\elements\db\AssetQuery::toArray() Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/helpers/BaseJson.php:157

24 | yii\helpers\BaseJson::processData(craft\elements\db\AssetQuery, [], "5cb088450119f2.57190485") Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/helpers/BaseJson.php:176

23 | yii\helpers\BaseJson::processData(["id" => "494", "typeId" => "1", "taxCategoryId" => "1", "shippingCategoryId" => "1", ...], [], "5cb088450119f2.57190485") Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/helpers/BaseJson.php:61

22 | yii\helpers\BaseJson::encode(["id" => "494", "typeId" => "1", "taxCategoryId" => "1", "shippingCategoryId" => "1", ...]) Called from /var/www/myspa/htdocs/vendor/craftcms/cms/src/helpers/Db.php:127

21 | craft\helpers\Db::prepareValueForDb(["id" => "494", "typeId" => "1", "taxCategoryId" => "1", "shippingCategoryId" => "1", ...]) Called from /var/www/myspa/htdocs/vendor/craftcms/cms/src/db/ActiveRecord.php:42

20 | craft\commerce\records\LineItem::prepareForDb() Called from /var/www/myspa/htdocs/vendor/craftcms/cms/src/db/ActiveRecord.php:32

19 | craft\commerce\records\LineItem::beforeSave(false) Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/db/BaseActiveRecord.php:794

18 | craft\commerce\records\LineItem::updateInternal(null) Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/db/ActiveRecord.php:676

17 | craft\commerce\records\LineItem::update(false, null) Called from /var/www/myspa/htdocs/vendor/yiisoft/yii2/db/BaseActiveRecord.php:681

16 | craft\commerce\records\LineItem::save(false) Called from /var/www/myspa/htdocs/vendor/craftcms/commerce/src/services/LineItems.php:211

15 | craft\commerce\services\LineItems::saveLineItem(craft\commerce\models\LineItem, false) Called from /var/www/myspa/htdocs/vendor/craftcms/commerce/src/elements/Order.php:2123

14 | craft\commerce\elements\Order::_saveLineItems() Called from /var/www/myspa/htdocs/vendor/craftcms/commerce/src/elements/Order.php:967

13 | craft\services\Elements::saveElement(craft\commerce\elements\Order, false) Called from /var/www/myspa/htdocs/modules/myspa/controllers/BookingController.php:789

Maybe this belongs to the Commerce Plugin since it's a little bit more related to this but I decided to post it here because the warning is created in the Craft CMS repo. No first world problem at all, just wanted to inform you

Anubarak avatar Apr 12 '19 12:04 Anubarak

@lukeholder why is an element query getting included in LineItem record data?

brandonkelly avatar Apr 16 '19 13:04 brandonkelly

@brandonkelly do you mean the order being added to the extraFields?: https://github.com/craftcms/commerce/commit/a880bea6cc13b690507a8237891d17cb03b83236#diff-95df435f4aafb29ba3c6f6677aa982deR228

lukeholder avatar Apr 16 '19 13:04 lukeholder

@Anubarak Just to confirm, where did you add the order field? to the Product or the Variant?

lukeholder avatar Apr 16 '19 18:04 lukeholder

None of both. Sorry I should have clarified it from the beginning. This field belongs to a totally different layout and is only used in a separate section that links to an order (the channel is some kind of feedback channel for orders to rate the service)

Neither the orders nor the lineitems or variants are related to those in any way and I'm totally sure I don't use the deprecated order function instead of orderBy in my code.

The message is there for about 5 months and I thought if it was a common/known issue it would have been fixed by the time + it's no first world problem so didn't contact you earlier.

To be honest I don't even know where the AssetQuery comes from because there is no assets field in the order/variant either. My purchasable has an assets field if that helps but as said the volume doesn't have the said order field

Anubarak avatar Apr 16 '19 19:04 Anubarak

We have been running into this for a while, have also put off reporting, it's nice to know me and my team are not the only ones @Anubarak 🤦

Just to clarify, we also have a custom field called order that we use in various field layouts, and when using it in a query it hitting the order > orderBy deprecation error in the craft ElementQuery class, as a result it never gets a chance to set the value (orderBy is updated with the provided value).

Issue occurs when trying to use the shorthand query syntax for element select fields or value of a standard field called order.

Looked at fixing, but not sure how / if you would go about, obviously you still need to pick up someone using the deprecated order() query method, but in the case that a custom field has been created named order it should probably be handled, unless order itself becomes a reserved field handle?

Example with an element select custom field:

// This incorrectly sets `orderBy` to $id and triggers the deprecation error
$entries = Entry::find()
    ->sectionId(1)
    ->order($id) 
    ->all();

// This is all good
$entries = Entry::find()
    ->sectionId(1)
    ->relatedTo([
        'field' => 'order',
        'targetElement' => $id
     ]) 
    ->all();

For other custom fields:

// This incorrectly sets `orderBy` to $id and triggers the deprecation error
$entries = Entry::find()
    ->sectionId(1)
    ->order($id) 
    ->all();

// This is all good
$entries = Entry::find()
    ->sectionId(1)
    ->andWhere(['field_order' => $id])
    ->all();

samhibberd avatar Feb 26 '21 07:02 samhibberd

Hey @samhibberd Thank you for your answer I think one "good" way around this might be to create a setting in the general config "allowDeprications" (default true) for Elements and when you turn it off depricated functions won't trigger. But I'm not so sure if it might be worth implementing that because you could potentially run in such cases with other classes as well and including all these conditions and params might be totally over the top. Nevertheless to say you would have to create DeprecationBehaviors in order to be able to conditionally trigger those....

While such a setting would be cool I guess it's not worth and I'll wait for Craft 4 to get rid of it.

Anubarak avatar Feb 26 '21 13:02 Anubarak

Just revisiting this as it caught us out again on a Craft 3 project, is there any way that to add a check before the depreciation is called (I know it gets called in quite a few places in ElementQuery __set() __get() order() sure there are others) that checks if 'order' is a custom field handle, and so set the custom field query value, rather than calling orderBy(). It could still register the deprecation message, to identify that it's not hitting the orderBy method, but it seems pretty solid that if someone has a field called 'order' then they would want that to be queried rather than the orderBy value being set.

samhibberd avatar Dec 06 '22 22:12 samhibberd

Although, one workaround that allows us to set a value for the query (because the customField methods also return the current Query object) is:

Entry::find()
    ->status(null)
    ->getBehavior('customFields')->order(':notempty:')
    ->limit(null)
    ->all();

Bit hacky, but solid enough I think?!?

Main benefit is that we can again use the :empty: and :notempty: params.

PS. I know, if we had started again we would never have used the name order!!

samhibberd avatar Dec 06 '22 23:12 samhibberd