Yii2: Widgets afterRun's result cannot be used in events.

Created on 21 Aug 2018  路  5Comments  路  Source: yiisoft/yii2

When using almost any of the core Yii 2 widgets you cannot attach afterRun event and change the result, because most of the core widgets are using echo instead of returning the value, effectively making $result always being an empty string.

What steps will reproduce the problem?

Run any widget which has echo in their run() method or uses other methods which have echo command in it. For instance GridView widget.
Affected widgets:

List view / Grid view:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/BaseListView.php#L145

Block:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Block.php#L67

Breadcrumbs:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Breadcrumbs.php#L150

Content decorator:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/ContentDecorator.php#L79

Detail view:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/DetailView.php#L164

Fragement cache:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/FragmentCache.php#L104

https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/FragmentCache.php#L117

Link Pager:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/LinkPager.php#L158

Link sorter:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/LinkSorter.php#L69

Masked Input:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/MaskedInput.php#L127

Menu:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Menu.php#L185

Pjax:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Pjax.php#L130

https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Pjax.php#L135

https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Pjax.php#L151

Spaceless:
https://github.com/yiisoft/yii2/blob/9e5c4abdb8d99811b8c4fdc5dc376e22c9f0d662/framework/widgets/Spaceless.php#L68

What is the expected result?

image

image

$event->result should not be empty to have at least some data after running any of the affected widgets.

What do you get instead?

$event->result is empty.

Additional info

| Q | A
| ---------------- | ---
| Yii version | 2.0.15
| PHP version | 7.0
| Operating system | Linux Mint

ready for adoption bug

All 5 comments

The Problem

Hi. That change is backwards incompatible. Here's the example:

https://github.com/yiisoft/yii2/blob/master/framework/widgets/BaseListView.php#L145 (return instead of echo)
https://github.com/yiisoft/yii2/blob/master/framework/grid/GridView.php#L301 (return instead of echo)

https://github.com/kartik-v/yii2-grid/blob/master/src/GridView.php#L1143 (External package).
It assumes that BaseListView should echo widget content instead of return it.

So, with following dependency chain:

  1. "kartik-v/yii2-grid" depends on "kartik-v/yii2-krajee-base": ">=1.9.8"
  2. "kartik-v/yii2-krajee-base" depends on "yiisoft/yii2-bootstrap": "@dev"
  3. "yiisoft/yii2-bootstrap" depends on "yiisoft/yii2": "~2.0.6".

And "minimum-stability": "dev" in your composer.json.

The result of $res = \kartik\grid\GridView::widget([...]) would be '' (empty string)


The Question

  1. Will you move those changes from 2.0.16 to 2.1 or 3.0?
  2. Or developers need to update libraries that rely on this code?

@samdark, could you please give any comments on this?

Both echo and return should be supported.

This probably breaks yii\widgets\Pjax widget as well - since the default usage for Pjax Widget is to include a content between Pjax::begin and Pjax::end - somehow the Pjax::begin does not echo the begin content out. It seems Pjax widget code includes the begin part of the content within the Pjax::init method and that part returned is not echoed.

Can you check the usage? Pjax widget code may need some redesign if this BC breaking update is included.

Was this page helpful?
0 / 5 - 0 ratings