Browse Source

Fix #15383 drop PJAX (#15809)

PJAX support removed
tags/3.0.0-alpha1
Paul Klimov 7 years ago committed by GitHub
parent
commit
603c084fbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      docs/guide/README.md
  2. 36
      docs/guide/input-forms.md
  3. 39
      docs/guide/output-data-widgets.md
  4. 3
      docs/guide/start-installation.md
  5. 1
      framework/CHANGELOG.md
  6. 2
      framework/UPGRADE.md
  7. 1
      framework/grid/ActionColumn.php
  8. 6
      framework/web/Controller.php
  9. 10
      framework/web/Request.php
  10. 12
      framework/web/Response.php
  11. 216
      framework/widgets/Pjax.php
  12. 35
      framework/widgets/PjaxAsset.php
  13. 6
      tests/framework/grid/ActionColumnTest.php
  14. 33
      tests/framework/web/RequestTest.php
  15. 59
      tests/framework/widgets/PjaxTest.php

1
docs/guide/README.md

@ -172,7 +172,6 @@ Widgets
* [ListView](http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html)
* [DetailView](http://www.yiiframework.com/doc-2.0/yii-widgets-detailview.html)
* [ActiveForm](http://www.yiiframework.com/doc-2.0/guide-input-forms.html#activerecord-based-forms-activeform)
* [Pjax](http://www.yiiframework.com/doc-2.0/yii-widgets-pjax.html)
* [Menu](http://www.yiiframework.com/doc-2.0/yii-widgets-menu.html)
* [LinkPager](http://www.yiiframework.com/doc-2.0/yii-widgets-linkpager.html)
* [LinkSorter](http://www.yiiframework.com/doc-2.0/yii-widgets-linksorter.html)

36
docs/guide/input-forms.md

@ -198,39 +198,6 @@ echo $form->field($model, 'category')->checkboxList([
]);
```
Working with Pjax <span id="working-with-pjax"></span>
-----------------------
The [[yii\widgets\Pjax|Pjax]] widget allows you to update a certain section of a
page instead of reloading the entire page. You can use it to update only the form
and replace its contents after the submission.
You can configure [[yii\widgets\Pjax::$formSelector|$formSelector]] to specify
which form submission may trigger pjax. If not set, all forms with `data-pjax`
attribute within the enclosed content of Pjax will trigger pjax requests.
```php
use yii\widgets\Pjax;
use yii\widgets\ActiveForm;
Pjax::begin([
// Pjax options
]);
$form = ActiveForm::begin([
'options' => ['data' => ['pjax' => true]],
// more ActiveForm options
]);
// ActiveForm content
ActiveForm::end();
Pjax::end();
```
> Tip: Be careful with the links inside the [[yii\widgets\Pjax|Pjax]] widget since
> the response will also be rendered inside the widget. To prevent this, use the
> `data-pjax="0"` HTML attribute.
#### Values in Submit Buttons and File Upload
There are known issues using `jQuery.serializeArray()` when dealing with
@ -240,8 +207,7 @@ won't be solved and are instead deprecated in favor of the `FormData` class
introduced in HTML5.
That means the only official support for files and submit button values with
ajax or using the [[yii\widgets\Pjax|Pjax]] widget depends on the
[browser support](https://developer.mozilla.org/en-US/docs/Web/API/FormData#Browser_compatibility)
ajax depends on the [browser support](https://developer.mozilla.org/en-US/docs/Web/API/FormData#Browser_compatibility)
for the `FormData` class.
Further Reading <span id="further-reading"></span>

39
docs/guide/output-data-widgets.md

@ -734,45 +734,6 @@ echo GridView::widget([
]);
```
### Using GridView with Pjax <span id="using-gridview-with-pjax"></span>
The [[yii\widgets\Pjax|Pjax]] widget allows you to update a certain section of a
page instead of reloading the entire page. You can use it to update only the
[[yii\grid\GridView|GridView]] content when using filters.
```php
use yii\widgets\Pjax;
use yii\grid\GridView;
Pjax::begin([
// PJax options
]);
Gridview::widget([
// GridView options
]);
Pjax::end();
```
Pjax also works for the links inside the [[yii\widgets\Pjax|Pjax]] widget and
for the links specified by [[yii\widgets\Pjax::$linkSelector|Pjax::$linkSelector]].
But this might be a problem for the links of an [[yii\grid\ActionColumn|ActionColumn]].
To prevent this, add the HTML attribute `data-pjax="0"` to the links when you edit
the [[yii\grid\ActionColumn::$buttons|ActionColumn::$buttons]] property.
#### GridView/ListView with Pjax in Gii
Since 2.0.5, the CRUD generator of [Gii](start-gii.md) has an option called
`$enablePjax` that can be used via either web interface or command line.
```php
yii gii/crud --controllerClass="backend\\controllers\PostController" \
--modelClass="common\\models\\Post" \
--enablePjax=1
```
Which generates a [[yii\widgets\Pjax|Pjax]] widget wrapping the
[[yii\grid\GridView|GridView]] or [[yii\widgets\ListView|ListView]] widgets.
Further reading
---------------

3
docs/guide/start-installation.md

@ -126,8 +126,7 @@ In order to prevent assets installation via Composer, add the following lines to
"replace": {
"bower-asset/jquery": ">=1.11.0",
"bower-asset/inputmask": ">=3.2.0",
"bower-asset/punycode": ">=1.3.0",
"bower-asset/yii2-pjax": ">=2.0.0"
"bower-asset/punycode": ">=1.3.0"
},
```

1
framework/CHANGELOG.md

@ -25,6 +25,7 @@ Yii Framework 2 Change Log
- Enh: Objects `yii\helpers\ReplaceArrayValue`, `yii\helpers\UnsetArrayValue` now support restoring after being exported with `var_export()` function (silverfire)
- Chg: Removed methods marked as deprecated in 2.0.x (samdark)
- Chg #8452: Packages 'captcha', 'jquery', 'rest', 'mssql' and 'oracle' have been extracted into extensions (klimov-paul)
- Chg #15383: PJAX support removed (klimov-paul)
- Chg #14784: Signature of `yii\web\RequestParserInterface::parse()` changed to accept `yii\web\Request` instance as a sole argument (klimov-paul)
- Chg #10771: Consistent behavior of `run()` method in all framework widgets. All return the result now for better extensibility (pkirill99, cebe)
- Chg #11397: Minimum required version of PHP is 7.1 now (samdark)

2
framework/UPGRADE.md

@ -75,6 +75,8 @@ Upgrade from Yii 2.0.x
Include it in your composer.json if you use it.
* Masked input field widget was moved into separate extension https://github.com/yiisoft/yii2-maskedinput.
Include it in your composer.json if you use it.
* PJAX support has been removed: widget `yii\widget\Pjax`, method `yii\web\Request::getIsPjax()`, PJAX related checks and
headers are no longer available. If you wish to use PJAX further you should create your own integration for it.
* If you've used ApcCache and set `useApcu` in your config, remove the option.
* During mail view rendering the `$message` variable is no longer set by default to be an instance of `yii\mail\MessageInterface`. Instead it is available via `$this->context->message` expression.
* `yii\mail\BaseMailer::render()` method has been removed. Make sure you do not use it anywhere in your program.

1
framework/grid/ActionColumn.php

@ -177,7 +177,6 @@ class ActionColumn extends Column
$options = array_merge([
'title' => $title,
'aria-label' => $title,
'data-pjax' => '0',
], $additionalOptions, $this->buttonOptions);
$icon = Html::tag('span', '', ['class' => "glyphicon glyphicon-$iconName"]);
return Html::a($icon, $url, $options);

6
framework/web/Controller.php

@ -197,9 +197,9 @@ class Controller extends \yii\base\Controller
* See <https://tools.ietf.org/html/rfc2616#section-10>
* for details about HTTP status code
*
* @param boolean $checkAjax whether to specially handle AJAX (and PJAX) requests. Defaults to false,
* meaning a `Location` header will be sent, which when received as an AJAX/PJAX response, may NOT cause
* browser redirection. If this is true, the current request is an AJAX or PJAX request, then calling this method
* @param boolean $checkAjax whether to specially handle AJAX requests. Defaults to false,
* meaning a `Location` header will be sent, which when received as an AJAX response, may NOT cause
* browser redirection. If this is true, the current request is an AJAX request, then calling this method
* will cause the browser to redirect to the given URL.
* Takes effect only when request header `X-Ie-Redirect-Compatibility` is absent.
* @return Response the current response object

10
framework/web/Request.php

@ -67,7 +67,6 @@ use yii\validators\IpValidator;
* @property bool $isHead Whether this is a HEAD request. This property is read-only.
* @property bool $isOptions Whether this is a OPTIONS request. This property is read-only.
* @property bool $isPatch Whether this is a PATCH request. This property is read-only.
* @property bool $isPjax Whether this is a PJAX request. This property is read-only.
* @property bool $isPost Whether this is a POST request. This property is read-only.
* @property bool $isPut Whether this is a PUT request. This property is read-only.
* @property bool $isSecureConnection If the request is sent via secure channel (https). This property is
@ -609,15 +608,6 @@ class Request extends \yii\base\Request implements ServerRequestInterface
}
/**
* Returns whether this is a PJAX request
* @return bool whether this is a PJAX request
*/
public function getIsPjax()
{
return $this->getIsAjax() && $this->hasHeader('x-pjax');
}
/**
* Returns whether this is an Adobe Flash or Flex request.
* @return bool whether this is an Adobe Flash or Adobe Flex request.
*/

12
framework/web/Response.php

@ -866,10 +866,10 @@ class Response extends \yii\base\Response implements ResponseInterface
* @param int $statusCode the HTTP status code. Defaults to 302.
* See <https://tools.ietf.org/html/rfc2616#section-10>
* for details about HTTP status code
* @param bool $checkAjax whether to specially handle AJAX (and PJAX) requests. Defaults to true,
* meaning if the current request is an AJAX or PJAX request, then calling this method will cause the browser
* @param bool $checkAjax whether to specially handle AJAX requests. Defaults to true,
* meaning if the current request is an AJAX request, then calling this method will cause the browser
* to redirect to the given URL. If this is false, a `Location` header will be sent, which when received as
* an AJAX/PJAX response, may NOT cause browser redirection.
* an AJAX response, may NOT cause browser redirection.
* Takes effect only when request header `X-Ie-Redirect-Compatibility` is absent.
* @return $this the response object itself
*/
@ -890,11 +890,7 @@ class Response extends \yii\base\Response implements ResponseInterface
// Ajax 302 redirect in IE does not work. Change status code to 200. See https://github.com/yiisoft/yii2/issues/9670
$statusCode = 200;
}
if (Yii::$app->getRequest()->getIsPjax()) {
$this->setHeader('X-Pjax-Url', $url);
} else {
$this->setHeader('X-Redirect', $url);
}
$this->setHeader('X-Redirect', $url);
} else {
$this->setHeader('Location', $url);
}

216
framework/widgets/Pjax.php

@ -1,216 +0,0 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\widgets;
use Yii;
use yii\base\Widget;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Json;
use yii\web\Response;
/**
* Pjax is a widget integrating the [pjax](https://github.com/yiisoft/jquery-pjax) jQuery plugin.
*
* Pjax only deals with the content enclosed between its [[begin()]] and [[end()]] calls, called the *body content* of the widget.
* By default, any link click or form submission (for those forms with `data-pjax` attribute) within the body content
* will trigger an AJAX request. In responding to the AJAX request, Pjax will send the updated body content (based
* on the AJAX request) to the client which will replace the old content with the new one. The browser's URL will then
* be updated using pushState. The whole process requires no reloading of the layout or resources (js, css).
*
* You may configure [[linkSelector]] to specify which links should trigger pjax, and configure [[formSelector]]
* to specify which form submission may trigger pjax.
*
* You may disable pjax for a specific link inside the container by adding `data-pjax="0"` attribute to this link.
*
* The following example shows how to use Pjax with the [[\yii\grid\GridView]] widget so that the grid pagination,
* sorting and filtering can be done via pjax:
*
* ```php
* use yii\widgets\Pjax;
*
* Pjax::begin();
* echo GridView::widget([...]);
* Pjax::end();
* ```
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Pjax extends Widget
{
/**
* @var array the HTML attributes for the widget container tag. The following special options are recognized:
*
* - `tag`: string, the tag name for the container. Defaults to `div`
* This option is available since version 2.0.7.
* See also [[\yii\helpers\Html::tag()]].
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var string|false the jQuery selector of the links that should trigger pjax requests.
* If not set, all links within the enclosed content of Pjax will trigger pjax requests.
* If set to false, no code will be registered to handle links.
* Note that if the response to the pjax request is a full page, a normal request will be sent again.
*/
public $linkSelector;
/**
* @var string|false the jQuery selector of the forms whose submissions should trigger pjax requests.
* If not set, all forms with `data-pjax` attribute within the enclosed content of Pjax will trigger pjax requests.
* If set to false, no code will be registered to handle forms.
* Note that if the response to the pjax request is a full page, a normal request will be sent again.
*/
public $formSelector;
/**
* @var string The jQuery event that will trigger form handler. Defaults to "submit".
* @since 2.0.9
*/
public $submitEvent = 'submit';
/**
* @var bool whether to enable push state.
*/
public $enablePushState = true;
/**
* @var bool whether to enable replace state.
*/
public $enableReplaceState = false;
/**
* @var int pjax timeout setting (in milliseconds). This timeout is used when making AJAX requests.
* Use a bigger number if your server is slow. If the server does not respond within the timeout,
* a full page load will be triggered.
*/
public $timeout = 1000;
/**
* @var bool|int how to scroll the page when pjax response is received. If false, no page scroll will be made.
* Use a number if you want to scroll to a particular place.
*/
public $scrollTo = false;
/**
* @var array additional options to be passed to the pjax JS plugin. Please refer to the
* [pjax project page](https://github.com/yiisoft/jquery-pjax) for available options.
*/
public $clientOptions;
/**
* {@inheritdoc}
* @internal
*/
public static $counter = 0;
/**
* {@inheritdoc}
*/
public static $autoIdPrefix = 'p';
/**
* {@inheritdoc}
*/
public function init()
{
parent::init();
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
if ($this->requiresPjax()) {
ob_start();
ob_implicit_flush(false);
$view = $this->getView();
$view->clear();
$view->beginPage();
$view->head();
$view->beginBody();
if ($view->title !== null) {
echo Html::tag('title', Html::encode($view->title));
}
} else {
$options = $this->options;
$tag = ArrayHelper::remove($options, 'tag', 'div');
echo Html::beginTag($tag, array_merge([
'data-pjax-container' => '',
'data-pjax-push-state' => $this->enablePushState,
'data-pjax-replace-state' => $this->enableReplaceState,
'data-pjax-timeout' => $this->timeout,
'data-pjax-scrollto' => $this->scrollTo,
], $options));
}
}
/**
* {@inheritdoc}
*/
public function run()
{
if (!$this->requiresPjax()) {
echo Html::endTag(ArrayHelper::remove($this->options, 'tag', 'div'));
$this->registerClientScript();
return;
}
$view = $this->getView();
$view->endBody();
$view->endPage(true);
$content = ob_get_clean();
// only need the content enclosed within this widget
$response = Yii::$app->getResponse();
$response->clearOutputBuffers();
$response->setStatusCode(200);
$response->format = Response::FORMAT_HTML;
$response->content = $content;
$response->headers->setDefault('X-Pjax-Url', Yii::$app->request->url);
$response->send();
Yii::$app->end();
}
/**
* @return bool whether the current request requires pjax response from this widget
*/
protected function requiresPjax()
{
$request = Yii::$app->getRequest();
return $request->hasHeader('X-Pjax') && explode(' ', $request->getHeader('X-Pjax-Container')[0])[0] === '#' . $this->options['id'];
}
/**
* Registers the needed JavaScript.
*/
public function registerClientScript()
{
$id = $this->options['id'];
$this->clientOptions['push'] = $this->enablePushState;
$this->clientOptions['replace'] = $this->enableReplaceState;
$this->clientOptions['timeout'] = $this->timeout;
$this->clientOptions['scrollTo'] = $this->scrollTo;
if (!isset($this->clientOptions['container'])) {
$this->clientOptions['container'] = "#$id";
}
$options = Json::htmlEncode($this->clientOptions);
$js = '';
if ($this->linkSelector !== false) {
$linkSelector = Json::htmlEncode($this->linkSelector !== null ? $this->linkSelector : '#' . $id . ' a');
$js .= "jQuery(document).pjax($linkSelector, $options);";
}
if ($this->formSelector !== false) {
$formSelector = Json::htmlEncode($this->formSelector !== null ? $this->formSelector : '#' . $id . ' form[data-pjax]');
$submitEvent = Json::htmlEncode($this->submitEvent);
$js .= "\njQuery(document).on($submitEvent, $formSelector, function (event) {jQuery.pjax.submit(event, $options);});";
}
$view = $this->getView();
PjaxAsset::register($view);
if ($js !== '') {
$view->registerJs($js);
}
}
}

35
framework/widgets/PjaxAsset.php

@ -1,35 +0,0 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\widgets;
use yii\web\AssetBundle;
use yii\web\YiiAsset;
/**
* This asset bundle provides the javascript files required by [[Pjax]] widget.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class PjaxAsset extends AssetBundle
{
/**
* {@inheritdoc}
*/
public $sourcePath = '@bower/yii2-pjax';
/**
* {@inheritdoc}
*/
public $js = ['jquery.pjax.js',];
/**
* {@inheritdoc}
*/
public $depends = [YiiAsset::class];
}

6
tests/framework/grid/ActionColumnTest.php

@ -41,9 +41,9 @@ class ActionColumnTest extends \yiiunit\TestCase
return 'http://test.com';
};
$columnContents = $column->renderDataCell(['id' => 1], 1, 0);
$viewButton = '<a href="http://test.com" title="View" aria-label="View" data-pjax="0"><span class="glyphicon glyphicon-eye-open"></span></a>';
$updateButton = '<a href="http://test.com" title="Update" aria-label="Update" data-pjax="0"><span class="glyphicon glyphicon-pencil"></span></a>';
$deleteButton = '<a href="http://test.com" title="Delete" aria-label="Delete" data-pjax="0" data-confirm="Are you sure you want to delete this item?" data-method="post"><span class="glyphicon glyphicon-trash"></span></a>';
$viewButton = '<a href="http://test.com" title="View" aria-label="View"><span class="glyphicon glyphicon-eye-open"></span></a>';
$updateButton = '<a href="http://test.com" title="Update" aria-label="Update"><span class="glyphicon glyphicon-pencil"></span></a>';
$deleteButton = '<a href="http://test.com" title="Delete" aria-label="Delete" data-confirm="Are you sure you want to delete this item?" data-method="post"><span class="glyphicon glyphicon-trash"></span></a>';
$expectedHtml = "<td>$viewButton $updateButton $deleteButton</td>";
$this->assertEquals($expectedHtml, $columnContents);

33
tests/framework/web/RequestTest.php

@ -599,39 +599,6 @@ class RequestTest extends TestCase
$_SERVER = $original;
}
public function getIsPjaxDataProvider()
{
return [
[
[
],
false,
],
[
[
'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest',
'HTTP_X_PJAX' => 'any value',
],
true,
],
];
}
/**
* @dataProvider getIsPjaxDataProvider
* @param array $server
* @param bool $expected
*/
public function testGetIsPjax($server, $expected)
{
$original = $_SERVER;
$_SERVER = $server;
$request = new Request();
$this->assertEquals($expected, $request->getIsPjax());
$_SERVER = $original;
}
public function testGetOrigin()
{
$_SERVER['HTTP_ORIGIN'] = 'https://www.w3.org';

59
tests/framework/widgets/PjaxTest.php

@ -1,59 +0,0 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\widgets;
use yii\data\ArrayDataProvider;
use yii\widgets\ListView;
use yii\widgets\Pjax;
use yiiunit\TestCase;
class PjaxTest extends TestCase
{
public function testGeneratedIdByPjaxWidget()
{
ListView::$counter = 0;
Pjax::$counter = 0;
$nonPjaxWidget1 = new ListView(['dataProvider' => new ArrayDataProvider()]);
ob_start();
$pjax1 = new Pjax();
ob_end_clean();
$nonPjaxWidget2 = new ListView(['dataProvider' => new ArrayDataProvider()]);
ob_start();
$pjax2 = new Pjax();
ob_end_clean();
$this->assertEquals('w0', $nonPjaxWidget1->options['id']);
$this->assertEquals('w1', $nonPjaxWidget2->options['id']);
$this->assertEquals('p0', $pjax1->options['id']);
$this->assertEquals('p1', $pjax2->options['id']);
}
protected function setUp()
{
parent::setUp();
$this->mockWebApplication();
}
/**
* @see https://github.com/yiisoft/yii2/issues/15536
*/
public function testShouldTriggerInitEvent()
{
$initTriggered = false;
ob_start();
$pjax = new Pjax(
[
'on init' => function () use (&$initTriggered) {
$initTriggered = true;
}
]
);
ob_end_clean();
$this->assertTrue($initTriggered);
}
}
Loading…
Cancel
Save