PageRenderTime 52ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/backend/formwidgets/RecordFinder.php

https://gitlab.com/gideonmarked/PLCPortal
PHP | 297 lines | 159 code | 47 blank | 91 comment | 10 complexity | e3bd4e46d7af815d7d1b48f2a0fa4e67 MD5 | raw file
  1. <?php namespace Backend\FormWidgets;
  2. use Lang;
  3. use ApplicationException;
  4. use Backend\Classes\FormWidgetBase;
  5. /**
  6. * Record Finder
  7. * Renders a record finder field.
  8. *
  9. * user:
  10. * label: User
  11. * type: recordfinder
  12. * list: ~/plugins/rainlab/user/models/user/columns.yaml
  13. * title: Find Record
  14. * prompt: Click the Find button to find a user
  15. * nameFrom: name
  16. * descriptionFrom: email
  17. *
  18. * @package october\backend
  19. * @author Alexey Bobkov, Samuel Georges
  20. */
  21. class RecordFinder extends FormWidgetBase
  22. {
  23. use \Backend\Traits\FormModelWidget;
  24. //
  25. // Configurable properties
  26. //
  27. /**
  28. * @var string Field name to use for key.
  29. */
  30. public $keyFrom = 'id';
  31. /**
  32. * @var string Relation column to display for the name
  33. */
  34. public $nameFrom;
  35. /**
  36. * @var string Relation column to display for the description
  37. */
  38. public $descriptionFrom;
  39. /**
  40. * @var string Text to display for the title of the popup list form
  41. */
  42. public $title = 'backend::lang.recordfinder.find_record';
  43. /**
  44. * @var string Prompt to display if no record is selected.
  45. */
  46. public $prompt = 'Click the %s button to find a record';
  47. /**
  48. * @var int Maximum rows to display for each page.
  49. */
  50. public $recordsPerPage = 10;
  51. /**
  52. * @var string Use a custom scope method for the list query.
  53. */
  54. public $scope;
  55. /**
  56. * @var string Filters the relation using a raw where query statement.
  57. */
  58. public $conditions;
  59. /**
  60. * @var string If searching the records, specifies a policy to use.
  61. * - all: result must contain all words
  62. * - any: result can contain any word
  63. * - exact: result must contain the exact phrase
  64. */
  65. public $searchMode;
  66. /**
  67. * @var string Use a custom scope method for performing searches.
  68. */
  69. public $searchScope;
  70. //
  71. // Object properties
  72. //
  73. /**
  74. * {@inheritDoc}
  75. */
  76. protected $defaultAlias = 'recordfinder';
  77. /**
  78. * @var Model Relationship model
  79. */
  80. public $relationModel;
  81. /**
  82. * @var \Backend\Classes\WidgetBase Reference to the widget used for viewing (list or form).
  83. */
  84. protected $listWidget;
  85. /**
  86. * @var \Backend\Classes\WidgetBase Reference to the widget used for searching.
  87. */
  88. protected $searchWidget;
  89. /**
  90. * {@inheritDoc}
  91. */
  92. public function init()
  93. {
  94. $this->fillFromConfig([
  95. 'title',
  96. 'prompt',
  97. 'keyFrom',
  98. 'nameFrom',
  99. 'descriptionFrom',
  100. 'scope',
  101. 'conditions',
  102. 'searchMode',
  103. 'searchScope',
  104. 'recordsPerPage',
  105. ]);
  106. if (post('recordfinder_flag')) {
  107. $this->listWidget = $this->makeListWidget();
  108. $this->listWidget->bindToController();
  109. $this->searchWidget = $this->makeSearchWidget();
  110. $this->searchWidget->bindToController();
  111. $this->listWidget->setSearchTerm($this->searchWidget->getActiveTerm());
  112. /*
  113. * Link the Search Widget to the List Widget
  114. */
  115. $this->searchWidget->bindEvent('search.submit', function () {
  116. $this->listWidget->setSearchTerm($this->searchWidget->getActiveTerm());
  117. return $this->listWidget->onRefresh();
  118. });
  119. }
  120. }
  121. /**
  122. * {@inheritDoc}
  123. */
  124. public function render()
  125. {
  126. $this->prepareVars();
  127. return $this->makePartial('container');
  128. }
  129. public function onRefresh()
  130. {
  131. list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
  132. $model->{$attribute} = post($this->formField->getName());
  133. $this->prepareVars();
  134. return ['#'.$this->getId('container') => $this->makePartial('recordfinder')];
  135. }
  136. /**
  137. * Prepares the list data
  138. */
  139. public function prepareVars()
  140. {
  141. $this->relationModel = $this->getLoadValue();
  142. $this->vars['value'] = $this->getKeyValue();
  143. $this->vars['field'] = $this->formField;
  144. $this->vars['nameValue'] = $this->getNameValue();
  145. $this->vars['descriptionValue'] = $this->getDescriptionValue();
  146. $this->vars['listWidget'] = $this->listWidget;
  147. $this->vars['searchWidget'] = $this->searchWidget;
  148. $this->vars['title'] = $this->title;
  149. $this->vars['prompt'] = str_replace('%s', '<i class="icon-th-list"></i>', e(trans($this->prompt)));
  150. }
  151. /**
  152. * {@inheritDoc}
  153. */
  154. protected function loadAssets()
  155. {
  156. $this->addJs('js/recordfinder.js', 'core');
  157. }
  158. /**
  159. * {@inheritDoc}
  160. */
  161. public function getSaveValue($value)
  162. {
  163. return strlen($value) ? $value : null;
  164. }
  165. /**
  166. * {@inheritDoc}
  167. */
  168. public function getLoadValue()
  169. {
  170. list($model, $attribute) = $this->resolveModelAttribute($this->valueFrom);
  171. if (!is_null($model)) {
  172. return $model->{$attribute};
  173. }
  174. return null;
  175. }
  176. public function getKeyValue()
  177. {
  178. if (!$this->relationModel) {
  179. return null;
  180. }
  181. return $this->relationModel->{$this->keyFrom};
  182. }
  183. public function getNameValue()
  184. {
  185. if (!$this->relationModel || !$this->nameFrom) {
  186. return null;
  187. }
  188. return $this->relationModel->{$this->nameFrom};
  189. }
  190. public function getDescriptionValue()
  191. {
  192. if (!$this->relationModel || !$this->descriptionFrom) {
  193. return null;
  194. }
  195. return $this->relationModel->{$this->descriptionFrom};
  196. }
  197. public function onFindRecord()
  198. {
  199. $this->prepareVars();
  200. /*
  201. * Purge the search term stored in session
  202. */
  203. if ($this->searchWidget) {
  204. $this->listWidget->setSearchTerm(null);
  205. $this->searchWidget->setActiveTerm(null);
  206. }
  207. return $this->makePartial('recordfinder_form');
  208. }
  209. protected function makeListWidget()
  210. {
  211. $config = $this->makeConfig($this->getConfig('list'));
  212. $config->model = $this->getRelationModel();
  213. $config->alias = $this->alias . 'List';
  214. $config->showSetup = false;
  215. $config->showCheckboxes = false;
  216. $config->recordsPerPage = $this->recordsPerPage;
  217. $config->recordOnClick = sprintf("$('#%s').recordFinder('updateRecord', this, ':" . $this->keyFrom . "')", $this->getId());
  218. $widget = $this->makeWidget('Backend\Widgets\Lists', $config);
  219. $widget->setSearchOptions([
  220. 'mode' => $this->searchMode,
  221. 'scope' => $this->searchScope,
  222. ]);
  223. if ($sqlConditions = $this->conditions) {
  224. $widget->bindEvent('list.extendQueryBefore', function($query) use ($sqlConditions) {
  225. $query->whereRaw($sqlConditions);
  226. });
  227. }
  228. elseif ($scopeMethod = $this->scope) {
  229. $widget->bindEvent('list.extendQueryBefore', function($query) use ($scopeMethod) {
  230. $query->$scopeMethod($this->model);
  231. });
  232. }
  233. else {
  234. $widget->bindEvent('list.extendQueryBefore', function($query) {
  235. $this->getRelationObject()->addDefinedConstraintsToQuery($query);
  236. });
  237. }
  238. return $widget;
  239. }
  240. protected function makeSearchWidget()
  241. {
  242. $config = $this->makeConfig();
  243. $config->alias = $this->alias . 'Search';
  244. $config->growable = false;
  245. $config->prompt = 'backend::lang.list.search_prompt';
  246. $widget = $this->makeWidget('Backend\Widgets\Search', $config);
  247. $widget->cssClasses[] = 'recordfinder-search';
  248. return $widget;
  249. }
  250. }