/modules/cms/widgets/ComponentList.php

https://gitlab.com/gideonmarked/atls-express · PHP · 260 lines · 191 code · 50 blank · 19 comment · 19 complexity · 1a9dd72da685856a7866427c15fd1347 MD5 · raw file

  1. <?php namespace Cms\Widgets;
  2. use App;
  3. use Str;
  4. use Lang;
  5. use Input;
  6. use System\Classes\PluginManager;
  7. use Cms\Classes\ComponentHelpers;
  8. use Backend\Classes\WidgetBase;
  9. /**
  10. * Component list widget.
  11. *
  12. * @package october\cms
  13. * @author Alexey Bobkov, Samuel Georges
  14. */
  15. class ComponentList extends WidgetBase
  16. {
  17. use \Backend\Traits\CollapsableWidget;
  18. protected $searchTerm = false;
  19. protected $pluginComponentList;
  20. public function __construct($controller, $alias)
  21. {
  22. $this->alias = $alias;
  23. parent::__construct($controller, []);
  24. $this->bindToController();
  25. }
  26. /**
  27. * Renders the widget.
  28. * @return string
  29. */
  30. public function render()
  31. {
  32. return $this->makePartial('body', [
  33. 'data' => $this->getData()
  34. ]);
  35. }
  36. /**
  37. * Returns information about this widget, including name and description.
  38. */
  39. public function widgetDetails()
  40. {
  41. }
  42. /*
  43. * Event handlers
  44. */
  45. public function onSearch()
  46. {
  47. $this->setSearchTerm(Input::get('search'));
  48. return $this->updateList();
  49. }
  50. /*
  51. * Methods for th internal use
  52. */
  53. protected function getData()
  54. {
  55. $searchTerm = Str::lower($this->getSearchTerm());
  56. $searchWords = [];
  57. if (strlen($searchTerm)) {
  58. $searchWords = explode(' ', $searchTerm);
  59. }
  60. $pluginManager = PluginManager::instance();
  61. $plugins = $pluginManager->getPlugins();
  62. $this->prepareComponentList();
  63. $items = [];
  64. foreach ($plugins as $plugin) {
  65. $components = $this->getPluginComponents($plugin);
  66. if (!is_array($components)) {
  67. continue;
  68. }
  69. $pluginDetails = $plugin->pluginDetails();
  70. $pluginName = isset($pluginDetails['name'])
  71. ? $pluginDetails['name']
  72. : Lang::get('system::lang.plugin.unnamed');
  73. $pluginIcon = isset($pluginDetails['icon'])
  74. ? $pluginDetails['icon']
  75. : 'icon-puzzle-piece';
  76. $pluginDescription = isset($pluginDetails['description'])
  77. ? $pluginDetails['description']
  78. : null;
  79. $pluginClass = get_class($plugin);
  80. $pluginItems = [];
  81. foreach ($components as $componentInfo) {
  82. $className = $componentInfo->className;
  83. $alias = $componentInfo->alias;
  84. $component = App::make($className);
  85. if ($component->isHidden) {
  86. continue;
  87. }
  88. $componentDetails = $component->componentDetails();
  89. $component->alias = '--alias--';
  90. $item = (object)[
  91. 'title' => ComponentHelpers::getComponentName($component),
  92. 'description' => ComponentHelpers::getComponentDescription($component),
  93. 'plugin' => $pluginName,
  94. 'propertyConfig' => ComponentHelpers::getComponentsPropertyConfig($component),
  95. 'propertyValues' => ComponentHelpers::getComponentPropertyValues($component, $alias),
  96. 'className' => get_class($component),
  97. 'pluginIcon' => $pluginIcon,
  98. 'alias' => $alias,
  99. 'name' => $componentInfo->duplicateAlias
  100. ? $componentInfo->className
  101. : $componentInfo->alias
  102. ];
  103. if ($searchWords && !$this->itemMatchesSearch($searchWords, $item)) {
  104. continue;
  105. }
  106. if (!array_key_exists($pluginClass, $items)) {
  107. $group = (object)[
  108. 'title' => $pluginName,
  109. 'description' => $pluginDescription,
  110. 'pluginClass' => $pluginClass,
  111. 'icon' => $pluginIcon,
  112. 'items' => []
  113. ];
  114. $items[$pluginClass] = $group;
  115. }
  116. $pluginItems[] = $item;
  117. }
  118. usort($pluginItems, function ($a, $b) {
  119. return strcmp($a->title, $b->title);
  120. });
  121. if (isset($items[$pluginClass])) {
  122. $items[$pluginClass]->items = $pluginItems;
  123. }
  124. }
  125. uasort($items, function ($a, $b) {
  126. return strcmp($a->title, $b->title);
  127. });
  128. return $items;
  129. }
  130. protected function prepareComponentList()
  131. {
  132. $pluginManager = PluginManager::instance();
  133. $plugins = $pluginManager->getPlugins();
  134. $componentList = [];
  135. foreach ($plugins as $plugin) {
  136. $components = $plugin->registerComponents();
  137. if (!is_array($components)) {
  138. continue;
  139. }
  140. foreach ($components as $className => $alias) {
  141. $duplicateAlias = false;
  142. foreach ($componentList as $componentInfo) {
  143. if ($componentInfo->alias == $alias) {
  144. $componentInfo->duplicateAlias = true;
  145. $duplicateAlias = true;
  146. }
  147. }
  148. $componentList[] = (object)[
  149. 'className' => $className,
  150. 'alias' => $alias,
  151. 'duplicateAlias' => $duplicateAlias,
  152. 'pluginClass' => get_class($plugin)
  153. ];
  154. }
  155. }
  156. $this->pluginComponentList = $componentList;
  157. }
  158. protected function getPluginComponents($plugin)
  159. {
  160. $result = [];
  161. $pluginClass = get_class($plugin);
  162. foreach ($this->pluginComponentList as $componentInfo) {
  163. if ($componentInfo->pluginClass == $pluginClass) {
  164. $result[] = $componentInfo;
  165. }
  166. }
  167. return $result;
  168. }
  169. protected function getSearchTerm()
  170. {
  171. return $this->searchTerm !== false ? $this->searchTerm : $this->getSession('search');
  172. }
  173. protected function setSearchTerm($term)
  174. {
  175. $this->searchTerm = trim($term);
  176. $this->putSession('search', $this->searchTerm);
  177. }
  178. protected function updateList()
  179. {
  180. return ['#'.$this->getId('component-list') => $this->makePartial('items', [
  181. 'items' => $this->getData()]
  182. )];
  183. }
  184. protected function itemMatchesSearch(&$words, $item)
  185. {
  186. foreach ($words as $word) {
  187. $word = trim($word);
  188. if (!strlen($word)) {
  189. continue;
  190. }
  191. if (!$this->itemContainsWord($word, $item)) {
  192. return false;
  193. }
  194. }
  195. return true;
  196. }
  197. protected function itemContainsWord($word, $item)
  198. {
  199. if (Str::contains(Str::lower($item->title), $word)) {
  200. return true;
  201. }
  202. if (Str::contains(Str::lower($item->description), $word) && strlen($item->description)) {
  203. return true;
  204. }
  205. if (Str::contains(Str::lower($item->plugin), $word) && strlen($item->plugin)) {
  206. return true;
  207. }
  208. return false;
  209. }
  210. }