IndexAction.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\rest;
  8. use Yii;
  9. use yii\data\ActiveDataProvider;
  10. use yii\data\DataFilter;
  11. /**
  12. * IndexAction implements the API endpoint for listing multiple models.
  13. *
  14. * For more details and usage information on IndexAction, see the [guide article on rest controllers](guide:rest-controllers).
  15. *
  16. * @author Qiang Xue <qiang.xue@gmail.com>
  17. * @since 2.0
  18. */
  19. class IndexAction extends Action
  20. {
  21. /**
  22. * @var callable a PHP callable that will be called to prepare a data provider that
  23. * should return a collection of the models. If not set, [[prepareDataProvider()]] will be used instead.
  24. * The signature of the callable should be:
  25. *
  26. * ```php
  27. * function (IndexAction $action) {
  28. * // $action is the action object currently running
  29. * }
  30. * ```
  31. *
  32. * The callable should return an instance of [[ActiveDataProvider]].
  33. *
  34. * If [[dataFilter]] is set the result of [[DataFilter::build()]] will be passed to the callable as a second parameter.
  35. * In this case the signature of the callable should be the following:
  36. *
  37. * ```php
  38. * function (IndexAction $action, mixed $filter) {
  39. * // $action is the action object currently running
  40. * // $filter the built filter condition
  41. * }
  42. * ```
  43. */
  44. public $prepareDataProvider;
  45. /**
  46. * @var callable a PHP callable that will be called to prepare query in prepareDataProvider
  47. * Should return $query
  48. * For example:
  49. *
  50. * ```php
  51. * function ($query, $requestParams) {
  52. * $query->andFilterWhere(['id' => 1]);
  53. * ...
  54. * return $query;
  55. * }
  56. * ```
  57. *
  58. * @since 2.0.42
  59. */
  60. public $prepareSearchQuery;
  61. /**
  62. * @var DataFilter|null data filter to be used for the search filter composition.
  63. * You must setup this field explicitly in order to enable filter processing.
  64. * For example:
  65. *
  66. * ```php
  67. * [
  68. * 'class' => 'yii\data\ActiveDataFilter',
  69. * 'searchModel' => function () {
  70. * return (new \yii\base\DynamicModel(['id' => null, 'name' => null, 'price' => null]))
  71. * ->addRule('id', 'integer')
  72. * ->addRule('name', 'trim')
  73. * ->addRule('name', 'string')
  74. * ->addRule('price', 'number');
  75. * },
  76. * ]
  77. * ```
  78. *
  79. * @see DataFilter
  80. *
  81. * @since 2.0.13
  82. */
  83. public $dataFilter;
  84. /**
  85. * @return ActiveDataProvider
  86. */
  87. public function run()
  88. {
  89. if ($this->checkAccess) {
  90. call_user_func($this->checkAccess, $this->id);
  91. }
  92. return $this->prepareDataProvider();
  93. }
  94. /**
  95. * Prepares the data provider that should return the requested collection of the models.
  96. * @return ActiveDataProvider
  97. */
  98. protected function prepareDataProvider()
  99. {
  100. $requestParams = Yii::$app->getRequest()->getBodyParams();
  101. if (empty($requestParams)) {
  102. $requestParams = Yii::$app->getRequest()->getQueryParams();
  103. }
  104. $filter = null;
  105. if ($this->dataFilter !== null) {
  106. $this->dataFilter = Yii::createObject($this->dataFilter);
  107. if ($this->dataFilter->load($requestParams)) {
  108. $filter = $this->dataFilter->build();
  109. if ($filter === false) {
  110. return $this->dataFilter;
  111. }
  112. }
  113. }
  114. if ($this->prepareDataProvider !== null) {
  115. return call_user_func($this->prepareDataProvider, $this, $filter);
  116. }
  117. /* @var $modelClass \yii\db\BaseActiveRecord */
  118. $modelClass = $this->modelClass;
  119. $query = $modelClass::find();
  120. if (!empty($filter)) {
  121. $query->andWhere($filter);
  122. }
  123. if (is_callable($this->prepareSearchQuery)) {
  124. $query = call_user_func($this->prepareSearchQuery, $query, $requestParams);
  125. }
  126. return Yii::createObject([
  127. 'class' => ActiveDataProvider::className(),
  128. 'query' => $query,
  129. 'pagination' => [
  130. 'params' => $requestParams,
  131. ],
  132. 'sort' => [
  133. 'params' => $requestParams,
  134. ],
  135. ]);
  136. }
  137. }