SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/Widgets.php

  1. <?php
  2. /*
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  */
  13.  
  14. namespace Sprout\Helpers;
  15.  
  16. use Exception;
  17. use Kohana;
  18. use Sprout\Helpers\Enc;
  19. use Sprout\Helpers\View;
  20.  
  21.  
  22. /**
  23. * Provided functions for the display of widgets
  24. **/
  25. class Widgets
  26. {
  27. private static $widget_areas = array();
  28.  
  29. /**
  30.   * Add a widget to the list of widgets for a specific area
  31.   *
  32.   * @param int $area_id The widget area to add the widget to
  33.   * @param string $name The name of the widget to add
  34.   * @param array $settings The widget settings to use
  35.   * @param string $heading HTML H2 rendered front-end within widget
  36.   * @param string $template Optional wrapping template name
  37.   **/
  38. public static function add($area_id, $name, $settings, $heading = '', $template = '')
  39. {
  40. if (! preg_match('/^[0-9]+$/', $area_id)) {
  41. $area = WidgetArea::findAreaByName($area_id);
  42. if (! $area) return;
  43. $area_id = $area->getIndex();
  44. }
  45.  
  46. self::$widget_areas[$area_id][] = array($name, $settings, $heading, $template);
  47. }
  48.  
  49. /**
  50.   * Remove a widget to the list of widgets for a specific area
  51.   *
  52.   * @param int $area_id The widget area to add the widget to
  53.   * @param string $name The name of the widget to remove
  54.   **/
  55. public static function remove($area_id, $name)
  56. {
  57. if (! preg_match('/^[0-9]+$/', $area_id)) {
  58. $area = WidgetArea::findAreaByName($area_id);
  59. if (! $area) return;
  60. $area_id = $area->getIndex();
  61. }
  62.  
  63. foreach (self::$widget_areas[$area_id] as $idx => $def) {
  64. if ($def[0] === $name) unset (self::$widget_areas[$area_id][$idx]);
  65. }
  66. }
  67.  
  68. /**
  69.   * Create an instance of a specific widget in memory
  70.   *
  71.   * @param string $name The name of the widget to instantiate.
  72.   * @return Widget The instance
  73.   **/
  74. public static function instantiate($name)
  75. {
  76. $class = $name;
  77. if (substr($class, -6) != 'Widget') $class .= 'Widget';
  78. if (strpos($class, '\\') === false) {
  79. $class = 'Sprout\\Widgets\\' . $class;
  80. }
  81. if (!class_exists($class)) {
  82. throw new Exception("Unknown widget {$name}");
  83. }
  84.  
  85. return new $class();
  86. }
  87.  
  88. /**
  89.   * Instantiate, import settings, and render
  90.   * @param int $orientation See ORIENTATION_* constants in {@see WidgetArea}
  91.   * @param string $name Class name of the widget
  92.   * @param array $settings Widget settings (keys and values vary with widget subclass)
  93.   * @param string $pre_html HTML to go before the rendered widget
  94.   * @param string $post_html HTML to go after the rendered widget
  95.   * @param string $heading String Optional HTML H2 rendered on front-end of given widget
  96.   * @param string $template String Optional wrapping template name
  97.   * @return string Front-end HTML of widget
  98.   */
  99. public static function render($orientation, $name, array $settings, $pre_html = null, $post_html = null, $heading = null, $template = null)
  100. {
  101. $inst = self::instantiate($name);
  102. if ($inst == null) return null;
  103.  
  104. $inst->importSettings($settings);
  105. $inst->setTitle($heading);
  106. $html = $inst->render($orientation);
  107. if ($html == null) return null;
  108.  
  109. if ($orientation != WidgetArea::ORIENTATION_EMAIL and AdminAuth::isLoggedIn()) {
  110. $infobox = true;
  111. }
  112.  
  113. if (! $pre_html) {
  114. $class = 'widget widget-' . Enc::id(str_replace('\\', '-', (isset($inst->classname) ? $inst->classname : $name)));
  115. if (!empty($infobox)) $class .= ' widget-hasinfobox';
  116. $class .= ' orientation-' . WidgetArea::$orientation_classes[$orientation];
  117.  
  118. $pre_html = "<div class=\"{$class}\">";
  119. }
  120.  
  121. if (! $post_html) $post_html = "</div>";
  122.  
  123. $ret = '';
  124. $ret .= $pre_html;
  125.  
  126. $title = $inst->getTitle();
  127. if (!empty($title)) {
  128. $heading_html = '<h2 class="widget-title">TITLE</h2>';
  129.  
  130. if (!empty(Kohana::config('sprout.widget_title'))) {
  131. $heading_html = Kohana::config('sprout.widget_title');
  132. }
  133.  
  134. $ret .= str_replace('TITLE', Enc::html($title), $heading_html);
  135. }
  136.  
  137. $ret .= $html;
  138.  
  139. if (!empty($infobox)) {
  140. $ret .= self::infobox($inst);
  141. }
  142.  
  143. $ret .= $post_html;
  144.  
  145. // Wrap widget HTML within template snippet
  146. if (!empty($template)) {
  147. $view = new View($template);
  148. $ret = str_replace('{{widget}}', $ret, $view->render());
  149. }
  150.  
  151. return $ret;
  152. }
  153.  
  154. /**
  155.   * Render extra widget info for admins
  156.   **/
  157. private static function infobox($inst)
  158. {
  159. $ret = '<div class="widget-infobox">';
  160. $ret .= '<i>' . Enc::html($inst->getFriendlyName()) . ' Addon</i> &nbsp; ';
  161.  
  162. $info_lab = $inst->getInfoLabels();
  163. if ($info_lab) {
  164. foreach ($info_lab as $name => $val) {
  165. $ret .= '<b>' . Enc::html($name) . ':</b> ' . Enc::html($val) . ' &nbsp; ';
  166. }
  167. }
  168.  
  169. $edit_url = $inst->getEditUrl();
  170. if ($edit_url) {
  171. $ret .= '<a href="SITE/' . $edit_url . '" target="_blank">Edit content</a>';
  172. }
  173.  
  174. $ret .= '</div>';
  175.  
  176. return $ret;
  177. }
  178.  
  179.  
  180. /**
  181.   * Draw the widgets for a specific area
  182.   *
  183.   * The available widget areas are defined in the {@link /config/sprout.php} file.
  184.   * Typically there are two areas defined, 'sidebar' and 'embedded'.
  185.   *
  186.   * @param string $area_name The name of the widget area to draw.
  187.   * @return string HTML representing the rendered widgets
  188.   */
  189. public static function renderArea($area_name)
  190. {
  191. $area = WidgetArea::findAreaByName($area_name);
  192. if ($area == null) {
  193. return;
  194. }
  195.  
  196. $area_id = $area->getIndex();
  197. if (empty(self::$widget_areas[$area_id])) {
  198. return;
  199. }
  200.  
  201. $out = '';
  202. foreach (self::$widget_areas[$area_id] as $widget_details) {
  203. list($name, $settings, $heading, $template) = $widget_details;
  204. $out .= self::render($area->getOrientation(), $name, $settings, null, null, $heading, $template);
  205. }
  206.  
  207. return $out;
  208. }
  209.  
  210.  
  211. /**
  212.   * Render a widget area, and output directly
  213.   *
  214.   * @deprecated Use {@see Widgets::renderArea} instead
  215.   */
  216. public static function area($area_name)
  217. {
  218. echo self::renderArea($area_name);
  219. }
  220.  
  221.  
  222. /**
  223.   * Does the specified widget area have widgets?
  224.   *
  225.   * @param string $area_name The name of the widget area to query.
  226.   *
  227.   * @tag api
  228.   * @tag designer-api
  229.   **/
  230. public static function hasWidgets($area_name)
  231. {
  232. $area = WidgetArea::findAreaByName($area_name);
  233. if ($area == null) return;
  234. $area_id = $area->getIndex();
  235.  
  236. if (!empty(self::$widget_areas[$area_id])) return true;
  237.  
  238. return false;
  239. }
  240.  
  241.  
  242. /**
  243.   * Check whether the widget is allowed to be displayed
  244.   *
  245.   * @param array $env Calling environment, e.g. page id
  246.   * @param array $conditions Conditions to check; each condition would be an array witj 'field', 'op', 'val' keys
  247.   * @return bool True if conditions match and display is allowed, false otherwise
  248.   */
  249. public static function checkDisplayConditions(array $env, array $conditions)
  250. {
  251. foreach ($conditions as $cond) {
  252. try {
  253. $inst = Sprout::instance($cond['field'], ['Sprout\\Helpers\\DisplayConditions\\DisplayCondition']);
  254. } catch (Exception $ex) {
  255. continue;
  256. }
  257.  
  258. $result = $inst->match($env, $cond['op'], $cond['val']);
  259. if (!$result) {
  260. return false;
  261. }
  262. }
  263.  
  264. return true;
  265. }
  266.  
  267. }
  268.