PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / helpers / widgets / sticky_notes.php

sticky_notes.php in VikBooking Hotel Booking Engine & PMS 1.6.4, at admin/helpers/widgets/sticky_notes.php

723 lines 26.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 /**
14 * Class handler for admin widget "sticky notes". This widget has settings.
15 *
16 * @since 1.4.0
17 */
18 class VikBookingAdminWidgetStickyNotes extends VikBookingAdminWidget
19 {
20 /**
21 * The instance counter of this widget. Since we do not load individual parameters
22 * for each widget's instance, we use a static counter to determine its settings.
23 *
24 * @var int
25 */
26 protected static $instance_counter = -1;
27
28 /**
29 * We detect the Operating System through the browser useer agent
30 * to display different information about the shortcuts to use.
31 *
32 * @var string
33 */
34 protected $isMac = false;
35
36 /**
37 * Class constructor will define the widget name and identifier.
38 */
39 public function __construct()
40 {
41 // call parent constructor
42 parent::__construct();
43
44 // declare name, description and identifier
45 $this->widgetName = JText::translate('VBO_W_STICKYN_TITLE');
46 $this->widgetDescr = JText::translate('VBO_W_STICKYN_DESCR');
47 $this->widgetId = basename(__FILE__, '.php');
48
49 /**
50 * Define widget and icon and style name.
51 *
52 * @since 1.15.0 (J) - 1.5.0 (WP)
53 */
54 $this->widgetIcon = '<i class="' . VikBookingIcons::i('thumbtack') . '"></i>';
55 $this->widgetStyleName = 'yellow';
56
57 // load widget's settings
58 $this->widgetSettings = $this->loadSettings();
59
60 // determine if the operating system is MacOS or iOS
61 $ua = JFactory::getApplication()->input->server->getString('HTTP_USER_AGENT', '');
62 if (stripos($ua, 'windows') === false && (stripos($ua, 'mac') !== false || stripos($ua, 'iphone') !== false || stripos($ua, 'ipad') !== false)) {
63 $this->isMac = true;
64 }
65 }
66
67 /**
68 * Custom method for this widget only to update one sticky note.
69 * The method is called by the admin controller through an AJAX request.
70 * The visibility should be public, it should not exit the process, and
71 * any content sent to output will be returned to the AJAX response.
72 *
73 * @param int $force_note_index the new index can be forced to insert a new note.
74 * @param int $force_instance the widget's instance to force.
75 * @param string $force_txt the text of the sticky note to force.
76 *
77 * @return void it may output a log with the new widget instance assigned.
78 */
79 public function updateStickyNote($force_note_index = null, $force_instance = null, $force_txt = null)
80 {
81 $note_instance = VikRequest::getInt('note_instance', -1, 'request');
82 $note_txt = VikRequest::getString('note_txt', '', 'request', VIKREQUEST_ALLOWRAW);
83 $note_index = VikRequest::getInt('note_index', 0, 'request');
84
85 if ($force_note_index !== null && $force_note_index >= 0) {
86 // use the forced index instead
87 $note_index = $force_note_index;
88 }
89
90 if ($force_instance !== null && $force_instance >= 0) {
91 // use the forced instance instead
92 $note_instance = $force_instance;
93 }
94
95 if (is_string($force_txt) && strlen($force_txt)) {
96 // use the forced text instead
97 $note_txt = $force_txt;
98 }
99
100 // make sure the settings of the widget are an array
101 if (!is_array($this->widgetSettings)) {
102 $this->widgetSettings = array();
103 }
104
105 // create the new sticky note object
106 $username = $this->getLoggedUserName();
107 $sticky_note = new stdClass;
108 $sticky_note->html = $note_txt;
109 $sticky_note->ts = time();
110 if (!empty($username)) {
111 $sticky_note->user = $username;
112 }
113
114 // eventually append debugging result
115 $result_log = '';
116
117 // eventually append the new widget instance assigned for newly added widgets via AJAX
118 $new_instance_response = '';
119
120 if (!count($this->widgetSettings)) {
121 // push the first sticky note as the first instance of this widget
122 $this->widgetSettings = array(
123 array($sticky_note)
124 );
125 $result_log = 'pushing the first sticky note as the first instance of the widget';
126 $new_instance_response = '[instance=0]';
127 } elseif (isset($this->widgetSettings[$note_instance])) {
128 // this instance was saved already
129 if (isset($this->widgetSettings[$note_instance][$note_index])) {
130 // we already have this exact sticky note index, so we replace it
131 $this->widgetSettings[$note_instance][$note_index] = $sticky_note;
132 $result_log = 'replacing requested note index in existing widget instance';
133 } else {
134 // we push a new sticky note
135 array_push($this->widgetSettings[$note_instance], $sticky_note);
136 $result_log = 'adding a new note to the existing widget instance';
137 }
138 } else {
139 // this is a new instance of the widget, which has settings already - push the new instance and the new sticky note
140 array_push($this->widgetSettings, array($sticky_note));
141 $result_log = 'pushing a new instance and note to the settings';
142 $new_instance_response = '[instance=' . (count($this->widgetSettings) - 1) . ']';
143 }
144
145 // update widget's settings
146 $this->updateSettings(json_encode($this->widgetSettings));
147
148 echo 'e4j.ok' . (!empty($result_log) ? '(' . $result_log . ')' : '') . $new_instance_response;
149 }
150
151 /**
152 * Custom method for this widget only to delete one sticky note.
153 * The method is called by the admin controller through an AJAX request.
154 * The visibility should be public, it should not exit the process, and
155 * any content sent to output will be returned to the AJAX response.
156 */
157 public function deleteStickyNote()
158 {
159 $note_instance = VikRequest::getInt('note_instance', -1, 'request');
160 $note_index = VikRequest::getInt('note_index', 0, 'request');
161
162 // make sure the settings of the widget are an array
163 if (!is_array($this->widgetSettings)) {
164 echo 'e4j.error.no settings found';
165 return;
166 }
167
168 // make sure the instance of the widget exists
169 if (!isset($this->widgetSettings[$note_instance]) || !is_array($this->widgetSettings[$note_instance])) {
170 echo 'e4j.error.instance not found';
171 return;
172 }
173
174 // make sure the index of the note exists
175 if (!isset($this->widgetSettings[$note_instance][$note_index])) {
176 echo 'e4j.error.note index not found, maybe it was never updated before';
177 return;
178 }
179
180 // splice the array to remove the requested note
181 array_splice($this->widgetSettings[$note_instance], $note_index, 1);
182
183 // update widget's settings
184 $this->updateSettings(json_encode($this->widgetSettings));
185
186 echo 'e4j.ok';
187 }
188
189 /**
190 * Custom method for this widget only to sort one sticky note.
191 * The method is called by the admin controller through an AJAX request.
192 * The visibility should be public, it should not exit the process, and
193 * any content sent to output will be returned to the AJAX response.
194 */
195 public function sortStickyNote()
196 {
197 $note_instance = VikRequest::getInt('note_instance', -1, 'request');
198 $note_index_new = VikRequest::getInt('note_index_new', 0, 'request');
199 $note_index_old = VikRequest::getInt('note_index_old', 0, 'request');
200
201 if ($note_index_new == $note_index_old) {
202 // nothing to do, as notes can be sorted only within the same instance
203 echo 'e4j.error.same position given for sticky note';
204 return;
205 }
206
207 // make sure the settings of the widget are an array
208 if (!is_array($this->widgetSettings)) {
209 echo 'e4j.error.no settings found';
210 return;
211 }
212
213 // make sure the instance of the widget exists
214 if (!isset($this->widgetSettings[$note_instance]) || !is_array($this->widgetSettings[$note_instance])) {
215 echo 'e4j.error.instance not found';
216 return;
217 }
218
219 // make sure the old index of the note exists
220 if (!isset($this->widgetSettings[$note_instance][$note_index_old])) {
221 // check if this note was moved before getting saved, so as soon as it was added
222 if (count($this->widgetSettings[$note_instance]) == $note_index_old) {
223 // append the newly created (empty) note before moving it
224 $this->updateStickyNote($note_index_old, $note_instance);
225 // reload the widget's settings after they have been updated with the new note
226 $this->widgetSettings = $this->loadSettings();
227 // proceed below with moving the sticky note
228 } else {
229 // unable to proceed
230 echo 'e4j.error.original note index not found, maybe it was never updated before';
231 return;
232 }
233 }
234
235 // make sure the new index can fit
236 if ($note_index_new > (count($this->widgetSettings[$note_instance]) - 1)) {
237 echo 'e4j.error.new index exceeds the highest position available';
238 return;
239 }
240
241 // move the sticky note from the old index to the new index
242 $extracted = array_splice($this->widgetSettings[$note_instance], $note_index_old, 1);
243 array_splice($this->widgetSettings[$note_instance], $note_index_new, 0, $extracted);
244
245 // update widget's settings
246 $this->updateSettings(json_encode($this->widgetSettings));
247
248 echo 'e4j.ok';
249 }
250
251 public function render(VBOMultitaskData $data = null)
252 {
253 // increase widget's instance counter
254 static::$instance_counter++;
255
256 // check whether the widget is being rendered via AJAX when adding it through the customizer
257 $is_ajax = $this->isAjaxRendering();
258
259 // check whether we are in the multitask panel
260 $is_multitask = $this->isMultitaskRendering();
261
262 // check whether the widget requires settings
263 $needs_settings = !$is_ajax;
264 $data_instance = !$is_ajax ? static::$instance_counter : '-1';
265 if ($is_multitask && $is_ajax) {
266 $guess_inst_counter = $this->guessMultitaskStickyInstance($data);
267 if ($guess_inst_counter !== false) {
268 // force the loading of the guessed widget instance's settings
269 static::$instance_counter = $guess_inst_counter;
270 $data_instance = $guess_inst_counter;
271 $needs_settings = true;
272 }
273 }
274
275 /**
276 * This widget requires the jQuery UI Sortable library, but we do not preload it
277 * in order to save resources. We only load this JS asset when the widget is saved.
278 * The page Dashboard always loads the Sortable library, but not the Multitask panel.
279 *
280 * @since 1.15.0 (J) - 1.5.0 (WP)
281 */
282 if (!$is_ajax) {
283 // load assets (with no "preloading")
284 JHtml::fetch('script', VBO_SITE_URI.'resources/jquery-ui.sortable.min.js');
285 }
286
287 // generate a unique ID for the sticky notes wrapper instance
288 $wrapper_instance = !$is_ajax ? static::$instance_counter : rand();
289 $wrapper_id = 'vbo-widget-sticky-' . $wrapper_instance;
290
291 // load the settings for this specific instance of the widget
292 $instance_settings = array();
293 if ($needs_settings && is_array($this->widgetSettings) && isset($this->widgetSettings[static::$instance_counter])) {
294 $instance_settings = is_array($this->widgetSettings[static::$instance_counter]) ? $this->widgetSettings[static::$instance_counter] : array();
295 }
296
297 ?>
298 <div class="vbo-admin-widget-wrapper">
299 <div class="vbo-admin-widget-head">
300 <h4><?php echo $this->widgetIcon; ?> <span><?php echo $this->widgetName; ?></span></h4>
301 <div class="btn-toolbar pull-right vbo-btn-toolbar-hastext">
302 <span class="vbo-sticky-shortcuts-help"<?php echo count($instance_settings) ? ' style="display: none;"' : ''; ?>>
303 <?php
304 echo $this->vbo_app->createPopover(array(
305 'title' => JText::translate('VBO_W_STICKYN_HELP_TITLE'),
306 'content' => JText::translate(($this->isMac ? 'VBO_W_STICKYN_HELP_DESCR_MAC' : 'VBO_W_STICKYN_HELP_DESCR')),
307 'icon_class' => VikBookingIcons::i('keyboard'),
308 'placement' => 'left'
309 ));
310 ?>
311 </span>
312 </div>
313 </div>
314 <div id="<?php echo $wrapper_id; ?>" class="vbo-admin-widget-sticky-notes-wrap" data-instance="<?php echo $data_instance; ?>">
315 <ul class="vbo-admin-widget-sticky-notes-list">
316 <?php
317 foreach ($instance_settings as $k => $sticky_note) {
318 ?>
319 <li class="vbo-sticky-note">
320 <div class="vbo-sticky-note-cmds">
321 <span class="vbo-sticky-note-cmd-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>
322 <span class="vbo-sticky-note-cmd-trash" onclick="vboWidgetStickyNoteDelete(this);"><?php VikBookingIcons::e('trash'); ?></span>
323 </div>
324 <div contenteditable="true" spellcheck="false" class="vbo-widget-sticky-canvas">
325 <?php echo $sticky_note->html; ?>
326 </div>
327 <div class="vbo-sticky-note-sign">
328 <span class="vbo-sticky-note-sign-dt"><?php echo date(str_replace("/", $this->datesep, $this->df).' H:i', $sticky_note->ts); ?></span>
329 <?php
330 if (!empty($sticky_note->user)) {
331 ?>
332 <span class="vbo-sticky-note-sign-user"><?php echo $sticky_note->user; ?></span>
333 <?php
334 }
335 ?>
336 </div>
337 </li>
338 <?php
339 }
340 ?>
341 <li class="vbo-sticky-note-add">
342 <div class="vbo-sticky-note-add-inner" onclick="vboWidgetStickyNoteAdd(this);">
343 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
344 </div>
345 </li>
346 </ul>
347 </div>
348 </div>
349
350 <script type="text/javascript">
351 // declare global variables for notes sorting
352 var vbo_stickynote_initial_pos = null;
353
354 jQuery(document).ready(function() {
355
356 // register input event listener for each sticky note
357 var stickies<?php echo $wrapper_instance; ?> = document.querySelectorAll('#<?php echo $wrapper_id; ?> .vbo-widget-sticky-canvas');
358 for (var i = 0; i < stickies<?php echo $wrapper_instance; ?>.length; i++) {
359 stickies<?php echo $wrapper_instance; ?>[i].addEventListener('input', VBOCore.debounceEvent(vboWidgetStickyNoteUpdateTxt, 750));
360 }
361
362 if (typeof jQuery.fn.sortable !== 'undefined') {
363 /**
364 * Make all sticky notes sortable. Do not use .disableSelection() or this
365 * will break all [contenteditable] elements and their focus/selection events.
366 */
367 jQuery('#<?php echo $wrapper_id; ?> .vbo-admin-widget-sticky-notes-list').sortable({
368 cursor: 'move',
369 handle: '.vbo-sticky-note-cmd-drag',
370 items: 'li.vbo-sticky-note',
371 revert: false,
372 start: function(event, ui) {
373 // update sticky note initial position
374 vbo_stickynote_initial_pos = jQuery('#<?php echo $wrapper_id; ?>').find('.vbo-sticky-note').index(jQuery(ui.item));
375 },
376 update: function(event, ui) {
377 // get sticky note new position
378 var now_note = jQuery(ui.item);
379 var new_note_index = jQuery('#<?php echo $wrapper_id; ?>').find('.vbo-sticky-note').index(now_note);
380 var widget_instance = now_note.closest('.vbo-admin-widget-sticky-notes-wrap').attr('data-instance');
381
382 if (vbo_stickynote_initial_pos === null) {
383 return;
384 }
385
386 // the widget method to call
387 var call_method = 'sortStickyNote';
388
389 // make a silent request to remove the sticky note
390 VBOCore.doAjax(
391 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
392 {
393 widget_id: "<?php echo $this->getIdentifier(); ?>",
394 call: call_method,
395 note_index_old: vbo_stickynote_initial_pos,
396 note_index_new: new_note_index,
397 note_instance: widget_instance,
398 tmpl: "component"
399 },
400 function(response) {
401 // unset global note position var
402 vbo_stickynote_initial_pos = null;
403 try {
404 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
405 if (!obj_res.hasOwnProperty(call_method)) {
406 console.error('Unexpected JSON response', obj_res);
407 }
408 } catch(err) {
409 console.error('could not parse JSON response', err, response);
410 }
411 },
412 function(error) {
413 // unset global note position var
414 vbo_stickynote_initial_pos = null;
415 console.error(error);
416 }
417 );
418 }
419 });
420 } else {
421 // hide sortable handler
422 jQuery('#<?php echo $wrapper_id; ?> .vbo-admin-widget-sticky-notes-list').find('.vbo-sticky-note-cmd-drag').hide();
423 }
424
425 });
426 </script>
427
428 <?php
429 if (static::$instance_counter === 0 || $is_ajax) {
430 ?>
431 <script type="text/javascript">
432 jQuery(document).ready(function() {
433
434 /**
435 * Add event listener to keydown for shortcuts during typing on contenteditable elements.
436 */
437 document.onkeydown = function(e) {
438 e = e || window.event;
439 var active_el = document.activeElement;
440 var exec_cmd = null;
441 var exec_val = null;
442 if ((!e.metaKey && !e.ctrlKey) || !active_el || !active_el.hasAttribute('contenteditable')) {
443 return;
444 }
445
446 if (e.keyCode == 66) {
447 // CMD + B detected
448 exec_cmd = 'bold';
449 } else if (e.keyCode == 85) {
450 // CMD + U detected
451 exec_cmd = 'underline';
452 } else if (e.keyCode == 73) {
453 // CMD + I detected
454 exec_cmd = 'italic';
455 } else if (e.keyCode == 83) {
456 // CMD + S
457 exec_cmd = 'strikeThrough';
458 } else if (e.keyCode == 72 || e.keyCode == 84) {
459 // CMD + H || CMD + T detected
460 exec_cmd = 'formatBlock';
461 exec_val = 'h2';
462 } else if (e.keyCode == 80) {
463 // CMD + P
464 exec_cmd = 'formatBlock';
465 exec_val = 'p';
466 } else if (e.keyCode == 79 || e.keyCode == 78) {
467 // CMD + O || CMD + N detected
468 exec_cmd = 'insertOrderedList';
469 } else if (e.keyCode == 76) {
470 // CMD + L
471 if (window.getSelection()) {
472 var range = window.getSelection().getRangeAt(0);
473 exec_val = range.toString();
474 if (exec_val && exec_val.length) {
475 // some text is selected
476 if (exec_val.match(/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i)) {
477 // URI selected, set command to create a link
478 exec_cmd = 'createLink';
479 } else {
480 // just some plain text was selected, ask for a custom URI
481 e.preventDefault();
482 var link_uri = prompt(Joomla.JText._('VBO_STICKYN_CUSTOMURI'), '<?php echo JUri::root(); ?>');
483 if (link_uri != null && link_uri != '' && link_uri.indexOf('http') >= 0) {
484 exec_val = '<a href="' + link_uri + '">' + exec_val + '</a>';
485 exec_cmd = 'insertHTML';
486 }
487 }
488 } else {
489 // no text selected, create an unordered list
490 exec_val = null;
491 exec_cmd = 'insertUnorderedList';
492 }
493 } else {
494 // cannot access text selection, create an unordered list also in this case
495 exec_val = null;
496 exec_cmd = 'insertUnorderedList';
497 }
498 } else if (e.keyCode == 77 && window.getSelection()) {
499 // CMD + M
500 var txtsel = window.getSelection().getRangeAt(0).toString();
501 if (txtsel && txtsel.length && txtsel.indexOf('<') === 0 && txtsel.substr(-1, 1) == '>') {
502 // HTML tag selected, convert it from plain text to HTML code
503 if (txtsel.indexOf('><') >= 0) {
504 // hack for converting icons, where empty tags are not parsed correctly
505 txtsel = txtsel.replace('><', '> <');
506 }
507 exec_val = txtsel + ' ';
508 exec_cmd = 'insertHTML';
509 }
510 }
511
512 if (exec_cmd !== null) {
513 e.preventDefault();
514 document.execCommand(exec_cmd, false, exec_val);
515 active_el.focus();
516
517 return false;
518 }
519 }
520
521 /**
522 * Listen to mousedown event for clicks on links inside the elements
523 * with contenteditable, otherwise links in sticky notes won't open.
524 */
525 jQuery(document.body).on('mousedown', '.vbo-widget-sticky-canvas[contenteditable]', function(e) {
526 var elem = jQuery(e.target);
527 if (elem.is('a')) {
528 var goto = elem.attr('href');
529 if (goto && goto.length && goto.indexOf('http') >= 0) {
530 e.preventDefault();
531 window.open(goto, '_blank');
532 return false;
533 }
534 }
535 });
536 });
537 </script>
538
539 <script type="text/javascript">
540 function vboWidgetStickyNoteAdd(elem) {
541 // display the help for the shortcuts instructions
542 jQuery(elem).closest('.vbo-admin-widget-wrapper').find('.vbo-sticky-shortcuts-help').fadeIn();
543 // sticky note default HTML placeholder
544 var sticky_placeholder = '<h2>' + Joomla.JText._('VBO_STICKYN_TITLE') + '</h2>' + "\n";
545 sticky_placeholder += '<p>' + Joomla.JText._('VBO_STICKYN_TEXT') + '</p>' + "\n";
546 sticky_placeholder += '<p>' + Joomla.JText._('VBO_STICKYN_TEXT2') + '</p>' + "\n";
547 // build new sticky note HTML
548 var html_sticky_new = '<div class="vbo-sticky-note-cmds">';
549 html_sticky_new += ' <span class="vbo-sticky-note-cmd-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
550 html_sticky_new += ' <span class="vbo-sticky-note-cmd-trash" onclick="vboWidgetStickyNoteDelete(this);"><?php VikBookingIcons::e('trash'); ?></span>';
551 html_sticky_new += '</div>';
552 html_sticky_new += '<div contenteditable="true" spellcheck="false" class="vbo-widget-sticky-canvas">';
553 html_sticky_new += sticky_placeholder;
554 html_sticky_new += '</div>';
555
556 // build new element and add HTML to it
557 var sticky_new = document.createElement('li');
558 sticky_new.setAttribute('class', 'vbo-sticky-note');
559 sticky_new.innerHTML = html_sticky_new;
560
561 // attach listener for input event
562 sticky_new.addEventListener('input', VBOCore.debounceEvent(vboWidgetStickyNoteUpdateTxt, 750));
563
564 // add new element to the document, before the button to add new sticky notes
565 var append_to = jQuery(elem).closest('.vbo-admin-widget-sticky-notes-list').find('.vbo-sticky-note-add');
566 append_to.before(jQuery(sticky_new));
567
568 /**
569 * The input event is immediately triggered so that the newly added note will be saved to avoid
570 * problems when like adding two notes before even typing some text, and then moving/removing them.
571 */
572 sticky_new.dispatchEvent(new Event('input'));
573 }
574
575 function vboWidgetStickyNoteDelete(elem) {
576 var note_elem = jQuery(elem);
577 var note_index = note_elem.closest('.vbo-admin-widget-sticky-notes-list').find('.vbo-sticky-note').index(note_elem.closest('.vbo-sticky-note'));
578 var widget_instance = note_elem.closest('.vbo-admin-widget-sticky-notes-wrap').attr('data-instance');
579
580 var confirm_lbl = Joomla.JText._('VBO_WIDGETS_CONFRMELEM');
581 confirm_lbl = confirm_lbl.length ? confirm_lbl : 'Continue?';
582 if (confirm(confirm_lbl)) {
583 // the widget method to call
584 var call_method = 'deleteStickyNote';
585
586 // make a silent request to remove the sticky note
587 VBOCore.doAjax(
588 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
589 {
590 widget_id: "<?php echo $this->getIdentifier(); ?>",
591 call: call_method,
592 note_index: note_index,
593 note_instance: widget_instance,
594 tmpl: "component"
595 },
596 function(response) {
597 try {
598 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
599 if (!obj_res.hasOwnProperty(call_method)) {
600 console.error('Unexpected JSON response', obj_res);
601 }
602 } catch(err) {
603 console.error('could not parse JSON response', err, response);
604 }
605 },
606 function(error) {
607 console.error(error);
608 }
609 );
610
611 // remove the sticky note from the document
612 note_elem.closest('li.vbo-sticky-note').remove();
613 }
614 }
615
616 function vboWidgetStickyNoteUpdateTxt(event) {
617 var note_elem = jQuery(this);
618 // display the help for the shortcuts instructions
619 note_elem.closest('.vbo-admin-widget-wrapper').find('.vbo-sticky-shortcuts-help').fadeIn();
620 // element "this" may be different depending on how the event was triggered
621 if (note_elem.find('.vbo-widget-sticky-canvas').length) {
622 var note_txt = note_elem.find('.vbo-widget-sticky-canvas').html();
623 } else {
624 var note_txt = note_elem.html();
625 }
626 var note_index = note_elem.closest('.vbo-admin-widget-sticky-notes-list').find('.vbo-sticky-note').index(note_elem.closest('.vbo-sticky-note'));
627 var widget_instance = note_elem.closest('.vbo-admin-widget-sticky-notes-wrap').attr('data-instance');
628
629 // the widget method to call
630 var call_method = 'updateStickyNote';
631
632 // make a silent request to update the sticky note details
633 VBOCore.doAjax(
634 "<?php echo $this->getExecWidgetAjaxUri(); ?>",
635 {
636 widget_id: "<?php echo $this->getIdentifier(); ?>",
637 call: call_method,
638 note_txt: note_txt,
639 note_index: note_index,
640 note_instance: widget_instance,
641 tmpl: "component"
642 },
643 function(response) {
644 try {
645 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
646 if (!obj_res.hasOwnProperty(call_method)) {
647 console.error('Unexpected JSON response', obj_res);
648 } else {
649 // response for the method updateStickyNote() may contain the new instance given to the widget
650 if (widget_instance < 0 && obj_res[call_method].indexOf('[instance=') >= 0) {
651 // extract the new instance assigned
652 var resp_left = obj_res[call_method].split('[instance=');
653 var widget_instance_new = resp_left[1].split(']')[0];
654 if (widget_instance_new && widget_instance_new.length) {
655 // update widget's instance
656 note_elem.closest('.vbo-admin-widget-sticky-notes-wrap').attr('data-instance', widget_instance_new);
657 }
658 }
659 }
660 } catch(err) {
661 console.error('could not parse JSON response', err, response);
662 }
663 },
664 function(error) {
665 console.error(error);
666 }
667 );
668 }
669 </script>
670 <?php
671 }
672 }
673
674 /**
675 * Protected method to guess if the widget being rendered via AJAX in the
676 * multitask panel should load specific settings. Should be called when
677 * settings have been loaded, and if AJAX + multitask rendering is detected.
678 * It's assumed that the AJAX rendering of a multitask widget takes place one
679 * second before the AJAX event that updates the multitask map to push the widget.
680 *
681 * @param VBOMultitaskData $data the data object injected to the widget.
682 *
683 * @return bool|int false on failure, guessed settings index otherwise.
684 */
685 protected function guessMultitaskStickyInstance(VBOMultitaskData $data = null)
686 {
687 if (!is_array($this->widgetSettings) || !count($this->widgetSettings)) {
688 // nothing to guess if this widget has got no saved settings
689 return false;
690 }
691
692 if (!is_object($data)) {
693 // multitask data object must be set
694 return false;
695 }
696
697 // the page must be set in the multitask object
698 $vbo_page = $data->getPage();
699 if (empty($vbo_page)) {
700 // nothing to guess if no current page set
701 return false;
702 }
703
704 // get the map for the current page
705 $page_map = VikBooking::getAdminWidgetsInstance()->getMultitaskingMap($vbo_page, $whole = false);
706 if (!is_array($page_map) || !count($page_map)) {
707 // the multitask panel of this page has got no widgets saved, return the first index for settings
708 return 0;
709 }
710
711 // count how many widgets of this type are already on this page
712 $guessed_index = 0;
713 foreach ($page_map as $widget_type) {
714 if ($widget_type == $this->getIdentifier()) {
715 $guessed_index++;
716 }
717 }
718
719 // return the guessed index, which will load the next hypothetical instance
720 return $guessed_index;
721 }
722 }
723