1 <?php
2 /**
3 * @copyright Copyright © 2amigOS! Consulting Group 2013-
4 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
5 * @package foundation.components
6 * @version 1.0.0
7 */
8 namespace foundation\widgets;
9
10 use foundation\helpers\ArrayHelper;
11 use foundation\helpers\Html;
12 use foundation\enum\Enum;
13
14 /**
15 * JoyRide renders a foundation tour plugin.
16 *
17 * @see http://foundation.zurb.com/docs/components/joyride.html
18 *
19 * @author Antonio Ramirez <amigo.cobos@gmail.com>
20 * @package foundation\widgets
21 */
22 class JoyRide extends base\Widget
23 {
24 /**
25 * @var array plugin initialization options. The following are available:
26 *
27 * <pre>
28 * array(
29 * 'tipLocation' => 'bottom', // 'top' or 'bottom' in relation to parent
30 * 'nubPosition' => 'auto', // override on a per tooltip bases
31 * 'scrollSpeed' => '300', // Page scrolling speed in milliseconds
32 * 'timer' => '0', // 0 = no timer , all other numbers = timer in milliseconds
33 * 'startTimerOnClick => 'true', // true or false - true requires clicking the first button start the timer
34 * 'startOffset' => '0', // the index of the tooltip you want to start on (index of the li)
35 * 'nextButton' => 'true', // true or false to control whether a next button is used
36 * 'tipAnimation' => 'fade', // 'pop' or 'fade' in each tip
37 * 'pauseAfter' => array(), // array of indexes where to pause the tour after
38 * 'tipAnimationFadeSpeed' => '300', // when tipAnimation = 'fade' this is speed in milliseconds for the transition
39 * 'cookieMonster' => 'false', // true or false to control whether cookies are used
40 * 'cookieName' => 'joyride', // Name the cookie you'll use
41 * 'cookieDomain' => 'false', // Will this cookie be attached to a domain, ie. '.notableapp.com'
42 * 'cookieExpires' => '365', // set when you would like the cookie to expire.
43 * 'tipContainer' => 'body', // Where will the tip be attached
44 * 'postRideCallback' => 'js:function (){}, // A method to call once the tour closes (canceled or complete)
45 * 'postStepCallback' => 'js:function (){}, // A method to call after each step
46 * 'template' => array( // HTML segments for tip layout
47 * 'link' => '<a href="#close" class="joyride-close-tip">×</a>',
48 * 'timer' => '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>',
49 * 'tip' => '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>',
50 * 'wrapper' => '<div class="joyride-content-wrapper"></div>',
51 * 'button' => '<a href="#" class="small button joyride-next-tip"></a>'
52 * ),
53 * )
54 * </pre>
55 */
56 public $pluginOptions = array();
57 /**
58 * The tour stops. Each stop has the following syntax
59 *
60 * <pre>
61 * 'stops' => array(
62 * array(
63 * 'id' => 'id-of-element', // if null will be displayed as a modal
64 * 'title' => 'title of the box',
65 * 'body' => 'content of the box',
66 * 'text' => 'Next', // button text,
67 * 'button' => 'Next', // button text,
68 * 'class' => 'custom css class',
69 * 'options' => array(...), // optional joyride options for the element
70 * )
71 * )
72 * </pre>
73 */
74 public $stops = array();
75 /**
76 * @var bool whether to autostart joyride plugin or not
77 */
78 public $autoStart = true;
79
80
81 /**
82 * Initializes the widget
83 */
84 public function init()
85 {
86 $this->assets = array(
87 'js' => YII_DEBUG ? 'foundation/foundation.joyride.js' : 'foundation.min.js'
88 );
89
90 Html::addCssClass($this->htmlOptions, Enum::JOYRIDE_LIST);
91 ArrayHelper::addValue('data-joyride', 'data-joyride', $this->htmlOptions);
92 $this->registerClientScript();
93
94 parent::init();
95 }
96
97 /**
98 * Initializes the widget
99 */
100 public function run()
101 {
102 echo $this->renderJoyRide();
103 }
104
105 public function renderJoyRide()
106 {
107 if (empty($this->stops)) {
108 return true;
109 }
110 $items = array();
111
112 foreach ($this->stops as $stop) {
113 $items[] = $this->renderStop($stop);
114 }
115
116 return \CHtml::tag('ol', $this->htmlOptions, implode("\n", $items));
117 }
118
119 /**
120 * Renders a single stop
121 * @param array $stop the stop configuration
122 * @return string the resulting li tag
123 */
124 public function renderStop($stop)
125 {
126 $options = array();
127 $options['data-id'] = ArrayHelper::getValue($stop, 'id');
128 $options['data-text'] = ArrayHelper::getValue($stop, 'text');
129 $options['data-button'] = ArrayHelper::getValue($stop, 'button');
130 $options['data-class'] = ArrayHelper::getValue($stop, 'class');
131 $options['data-options'] = ArrayHelper::getValue($stop, 'options');
132 if ($options['data-options'] !== null) {
133 $config = array();
134 foreach ($options['data-options'] as $key => $option) {
135 $config[] = $key . ':' . $option;
136 }
137 $options['data-options'] = implode(';', $config);
138 }
139 $title = ArrayHelper::getValue($stop, 'title');
140 if (!empty($title)) {
141 $title = "<h4>{$title}</h4>";
142 }
143 $content = '<p>' . ArrayHelper::getValue($stop, 'body', '') . '</p>';
144
145 return \CHtml::tag('li', $options, $title . $content);
146 }
147
148 /**
149 * Starts joyride if [[autostart]] has been set to true.
150 * @return bool
151 */
152 public function registerClientScript()
153 {
154 if (!$this->autoStart) {
155 return true;
156 }
157 $options = !empty($this->pluginOptions)
158 ? \CJavaScript::encode($this->pluginOptions)
159 : '{}';
160 \Yii::app()->clientScript
161 ->registerScript('JoyRide#' . $this->getId(), "$(document).foundation('joyride','start',{$options});");
162 }
163 }