wordpress.php
1513 lines
| 1 | <?php |
| 2 | /** |
| 3 | * @package VikAppointments |
| 4 | * @subpackage core |
| 5 | * @author E4J s.r.l. |
| 6 | * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved. |
| 7 | * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL |
| 8 | * @link https://vikwp.com |
| 9 | */ |
| 10 | |
| 11 | // No direct access |
| 12 | defined('ABSPATH') or die('No script kiddies please!'); |
| 13 | |
| 14 | // this should be already loaded from autoload.php |
| 15 | VAPLoader::import('libraries.adapter.version.listener'); |
| 16 | |
| 17 | /** |
| 18 | * Helper class used to adapt the application to the requirements |
| 19 | * of the installed WordPress version. |
| 20 | * |
| 21 | * @see VersionListener Used to evaluate the current WordPress version. |
| 22 | * |
| 23 | * @since 1.6.3 |
| 24 | * @since 1.7 Renamed from UIApplicationWordpress |
| 25 | */ |
| 26 | class VAPApplicationWordpress extends VAPApplication |
| 27 | { |
| 28 | /** |
| 29 | * Backward compatibility for WordPress admin list <table> class. |
| 30 | * |
| 31 | * @return string The class selector to use. |
| 32 | */ |
| 33 | public function getAdminTableClass() |
| 34 | { |
| 35 | return 'wp-list-table widefat striped'; |
| 36 | } |
| 37 | |
| 38 | /** |
| 39 | * Backward compatibility for WordPress admin list <table> head opening. |
| 40 | * |
| 41 | * @return string The <thead> tag to use. |
| 42 | */ |
| 43 | public function openTableHead() |
| 44 | { |
| 45 | return '<thead>'; |
| 46 | } |
| 47 | |
| 48 | /** |
| 49 | * Backward compatibility for WordPress admin list <table> head closing. |
| 50 | * |
| 51 | * @return string The </thead> tag to use. |
| 52 | */ |
| 53 | public function closeTableHead() |
| 54 | { |
| 55 | return '</thead>'; |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Backward compatibility for WordPress admin list <th> class. |
| 60 | * |
| 61 | * @param string $align The additional class to use for horizontal alignment. |
| 62 | * Accepted rules should be: left, center or right. |
| 63 | * |
| 64 | * @return string The class selector to use. |
| 65 | */ |
| 66 | public function getAdminThClass($align = 'center') |
| 67 | { |
| 68 | return 'manage-column ' . $align; |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * Backward compatibility for WordPress admin list checkAll JS event. |
| 73 | * |
| 74 | * @param integer The total count of rows in the table. |
| 75 | * |
| 76 | * @return string The check all checkbox input to use. |
| 77 | */ |
| 78 | public function getAdminToggle($count) |
| 79 | { |
| 80 | return '<input type="checkbox" onclick="Joomla.checkAll(this)" value="" name="checkall-toggle" />'; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Backward compatibility for WordPress admin list isChecked JS event. |
| 85 | * |
| 86 | * @return string The JS function to use. |
| 87 | */ |
| 88 | public function checkboxOnClick() |
| 89 | { |
| 90 | return 'Joomla.isChecked(this.checked);'; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Helper method to send e-mails. |
| 95 | * |
| 96 | * @param string $from_address The e-mail address of the sender. |
| 97 | * @param string $from_name The name of the sender. |
| 98 | * @param string $to The e-mail address of the receiver. |
| 99 | * @param string $reply_address The reply to e-mail address. |
| 100 | * @param string $subject The subject of the e-mail. |
| 101 | * @param string $hmess The body of the e-mail (HTML is supported). |
| 102 | * @param array $attachments The list of the attachments to include. |
| 103 | * @param boolean $is_html True to support HTML body, otherwise false for plain text. |
| 104 | * @param string $encoding The encoding to use. |
| 105 | * |
| 106 | * @return boolean True if the e-mail was sent successfully, otherwise false. |
| 107 | */ |
| 108 | public function sendMail($from_address, $from_name, $to, $reply_address, $subject, $hmess, $attachments = null, $is_html = true, $encoding = 'base64') |
| 109 | { |
| 110 | $mailer = JFactory::getMailer(); |
| 111 | |
| 112 | if ($is_html) |
| 113 | { |
| 114 | $hmess = "<html>\n<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"></head>\n<body>$hmess</body>\n</html>"; |
| 115 | } |
| 116 | |
| 117 | $sender = array($from_address, $from_name); |
| 118 | $mailer->setSender($sender); |
| 119 | $mailer->addRecipient($to); |
| 120 | |
| 121 | if ($reply_address) |
| 122 | { |
| 123 | $mailer->addReplyTo($reply_address); |
| 124 | } |
| 125 | |
| 126 | $mailer->setSubject($subject); |
| 127 | $mailer->setBody($hmess); |
| 128 | $mailer->isHTML($is_html); |
| 129 | |
| 130 | $mailer->Encoding = $encoding; |
| 131 | |
| 132 | if ($attachments !== null && is_array($attachments)) |
| 133 | { |
| 134 | foreach ($attachments as $attach) |
| 135 | { |
| 136 | if (!empty($attach) && file_exists($attach)) |
| 137 | { |
| 138 | $mailer->addAttachment($attach); |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | return $mailer->Send(); |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Backward compatibility for WordPress framework loading. |
| 148 | * |
| 149 | * @param string $fw The framework to load. |
| 150 | */ |
| 151 | public function loadFramework($fw = '') |
| 152 | { |
| 153 | JHtml::fetch($fw); |
| 154 | } |
| 155 | |
| 156 | /** |
| 157 | * Backward compatibility for Joomla add stylesheet. |
| 158 | * |
| 159 | * @param string $url URL to the linked style sheet. |
| 160 | * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9'). |
| 161 | * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1). |
| 162 | * |
| 163 | * @return void |
| 164 | * |
| 165 | * @since 1.7 |
| 166 | */ |
| 167 | public function addStyleSheet($url = '', $options = array(), $attribs = array()) |
| 168 | { |
| 169 | if (empty($url)) |
| 170 | { |
| 171 | return; |
| 172 | } |
| 173 | |
| 174 | /** |
| 175 | * Add versioning to options array in order |
| 176 | * to reset the cache every time a new update is released. |
| 177 | * Versioning is used only in case it wasn't specified. |
| 178 | */ |
| 179 | if (!isset($options['version'])) |
| 180 | { |
| 181 | // make sure the constant is defined |
| 182 | if (defined('VIKAPPOINTMENTS_SOFTWARE_VERSION')) |
| 183 | { |
| 184 | $options['version'] = VIKAPPOINTMENTS_SOFTWARE_VERSION; |
| 185 | } |
| 186 | } |
| 187 | else if (empty($options['version']) || $options['version'] == 'auto') |
| 188 | { |
| 189 | // unset versioning |
| 190 | unset($options['version']); |
| 191 | } |
| 192 | |
| 193 | // use JHtml to load native dependencies when needed |
| 194 | JHtml::fetch('stylesheet', $url, $options, $attribs); |
| 195 | } |
| 196 | |
| 197 | /** |
| 198 | * Backward compatibility for WordPress add script. |
| 199 | * |
| 200 | * @param string $file Path to file. |
| 201 | * @param array $options Array of options. Example: array('version' => 'auto', 'conditional' => 'lt IE 9'). |
| 202 | * @param array $attribs Array of attributes. Example: array('id' => 'scriptid', 'async' => 'async', 'data-test' => 1). |
| 203 | * |
| 204 | * @return void |
| 205 | */ |
| 206 | public function addScript($file = '', $options = array(), $attribs = array()) |
| 207 | { |
| 208 | if (empty($file)) |
| 209 | { |
| 210 | return; |
| 211 | } |
| 212 | |
| 213 | /** |
| 214 | * Add versioning to options array in order |
| 215 | * to reset the cache every time a new update is released. |
| 216 | * Versioning is used only in case it wasn't specified. |
| 217 | * |
| 218 | * @since 1.7 |
| 219 | */ |
| 220 | if (!isset($options['version'])) |
| 221 | { |
| 222 | // make sure the constant is defined |
| 223 | if (defined('VIKAPPOINTMENTS_SOFTWARE_VERSION')) |
| 224 | { |
| 225 | $options['version'] = VIKAPPOINTMENTS_SOFTWARE_VERSION; |
| 226 | } |
| 227 | } |
| 228 | else if (empty($options['version']) || $options['version'] == 'auto') |
| 229 | { |
| 230 | // unset versioning |
| 231 | unset($options['version']); |
| 232 | } |
| 233 | |
| 234 | // use JHtml to load native dependencies when needed |
| 235 | JHtml::fetch('script', $file, $options, $attribs); |
| 236 | } |
| 237 | |
| 238 | /** |
| 239 | * Backward compatibility for card/row opening. |
| 240 | * |
| 241 | * @param string $class The class attribute for the fieldset. |
| 242 | * @param string $id The ID attribute for the fieldset. |
| 243 | * |
| 244 | * @return string The html to display. |
| 245 | * |
| 246 | * @since 1.7 |
| 247 | */ |
| 248 | public function openCard($class = '', $id = '') |
| 249 | { |
| 250 | return '<div class="row-fluid' . ($class ? ' ' . $class : '') . '"' . ($id ? ' id="' . $id . '' : '') . '>'; |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * Backward compatibility for card/row closing. |
| 255 | * |
| 256 | * @return string The html to display. |
| 257 | * |
| 258 | * @since 1.7 |
| 259 | */ |
| 260 | public function closeCard() |
| 261 | { |
| 262 | return '</div>'; |
| 263 | } |
| 264 | |
| 265 | /** |
| 266 | * Backward compatibility for WordPress fieldset opening. |
| 267 | * |
| 268 | * @param string $legend The title of the fieldset. |
| 269 | * @param string $class The class attribute for the fieldset. |
| 270 | * @param string $id The ID attribute for the fieldset. |
| 271 | * |
| 272 | * @return string The html to display. |
| 273 | * |
| 274 | * @since 1.3 |
| 275 | */ |
| 276 | public function openFieldset($legend, $class = '', $id = '') |
| 277 | { |
| 278 | static $incrementalId = 0; |
| 279 | static $useScript = true; |
| 280 | |
| 281 | if (!$id) |
| 282 | { |
| 283 | // generate a unique ID if not supplied |
| 284 | $id = 'vap-postbox-' . (++$incrementalId); |
| 285 | } |
| 286 | |
| 287 | $input = JFactory::getApplication()->input; |
| 288 | |
| 289 | $data = array(); |
| 290 | $data['name'] = $legend; |
| 291 | $data['class'] = $class; |
| 292 | $data['id'] = $id; |
| 293 | $data['tag'] = preg_replace("/[^a-z0-9_]+/i", '_', implode('.', [$input->get('option'), $input->get('view'), $id])); |
| 294 | $data['visible'] = $input->cookie->getBool($data['tag'], true); |
| 295 | |
| 296 | if ($useScript) |
| 297 | { |
| 298 | // use script only once |
| 299 | $useScript = false; |
| 300 | |
| 301 | // include script from layout |
| 302 | $script = JLayoutHelper::render('html.form.fieldset.script'); |
| 303 | } |
| 304 | else |
| 305 | { |
| 306 | $script = ''; |
| 307 | } |
| 308 | |
| 309 | return JLayoutHelper::render('html.form.fieldset.open', $data) . $script; |
| 310 | } |
| 311 | |
| 312 | /** |
| 313 | * Backward compatibility for WordPress fieldset closing. |
| 314 | * |
| 315 | * @return string The html to display. |
| 316 | * |
| 317 | * @since 1.3 |
| 318 | */ |
| 319 | public function closeFieldset() |
| 320 | { |
| 321 | return JLayoutHelper::render('html.form.fieldset.close'); |
| 322 | } |
| 323 | |
| 324 | /** |
| 325 | * Backward compatibility for WordPress empty fieldset opening. |
| 326 | * |
| 327 | * @param string $class An additional class to use for the fieldset. |
| 328 | * @param string $id The ID attribute for the fieldset. |
| 329 | * |
| 330 | * @return string The html to display. |
| 331 | * |
| 332 | * @since 1.3 |
| 333 | */ |
| 334 | public function openEmptyFieldset($class = '', $id = '') |
| 335 | { |
| 336 | return $this->openFieldset('', $class, $id); |
| 337 | } |
| 338 | |
| 339 | /** |
| 340 | * Backward compatibility for WordPress empty fieldset opening. |
| 341 | * |
| 342 | * @return string The html to display. |
| 343 | * |
| 344 | * @since 1.3 |
| 345 | */ |
| 346 | public function closeEmptyFieldset() |
| 347 | { |
| 348 | return $this->closeFieldset(); |
| 349 | } |
| 350 | |
| 351 | /** |
| 352 | * Backward compatibility for WordPress control opening. |
| 353 | * |
| 354 | * @param string $label The label of the control field. |
| 355 | * @param string $class The class of the control field. |
| 356 | * @param mixed $attr The additional attributes to add (string or array). |
| 357 | * |
| 358 | * @return string The html to display. |
| 359 | * |
| 360 | * @since 1.3 |
| 361 | */ |
| 362 | public function openControl($label, $class = '', $attr = array()) |
| 363 | { |
| 364 | $data = array(); |
| 365 | |
| 366 | if (is_string($attr)) |
| 367 | { |
| 368 | // string is not supported on WordPress platform |
| 369 | trigger_error(sprintf('%s() expects parameter 3 to be array, %s given', __METHOD__, gettype($attr)), E_USER_NOTICE); |
| 370 | |
| 371 | // use empty attributes |
| 372 | $attr = array(); |
| 373 | } |
| 374 | |
| 375 | foreach ($attr as $k => $v) |
| 376 | { |
| 377 | $data[$k] = $v; |
| 378 | } |
| 379 | |
| 380 | $data['label'] = $label; |
| 381 | $data['class'] = $class; |
| 382 | |
| 383 | return JLayoutHelper::render('html.form.control.open', $data); |
| 384 | } |
| 385 | |
| 386 | /** |
| 387 | * Backward compatibility for WordPress control closing. |
| 388 | * |
| 389 | * @return string The html to display. |
| 390 | * |
| 391 | * @since 1.3 |
| 392 | */ |
| 393 | public function closeControl() |
| 394 | { |
| 395 | return JLayoutHelper::render('html.form.control.close'); |
| 396 | } |
| 397 | |
| 398 | /** |
| 399 | * Prepares the editor scripts for being used. |
| 400 | * Useful in case the editor is initialized via JavaScript/AJAX. |
| 401 | * |
| 402 | * @param string $name The name of the editor. |
| 403 | * |
| 404 | * @return void |
| 405 | * |
| 406 | * @since 1.6.3 |
| 407 | */ |
| 408 | public function prepareEditor($name) |
| 409 | { |
| 410 | switch (strtolower($name)) |
| 411 | { |
| 412 | case 'tinymce': |
| 413 | JHtml::fetch('behavior.tinyMCE'); |
| 414 | break; |
| 415 | |
| 416 | case 'codemirror': |
| 417 | JHtml::fetch('behavior.codeMirror'); |
| 418 | break; |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | /** |
| 423 | * Returns the specified editor. |
| 424 | * |
| 425 | * @param mixed $editor The editor to load. |
| 426 | * The default one if not specified. |
| 427 | * |
| 428 | * @return JEditor The editor instance. |
| 429 | * |
| 430 | * @since 1.7 |
| 431 | */ |
| 432 | public function getEditor($editor = null) |
| 433 | { |
| 434 | return JFactory::getEditor($editor); |
| 435 | } |
| 436 | |
| 437 | /** |
| 438 | * Returns the codemirror editor in WordPress 4.9+, otherwise a simple textarea. |
| 439 | * |
| 440 | * @param string $name The name of the textarea. |
| 441 | * @param string $value The value of the textarea. |
| 442 | * @param array $params An array of options (@since 1.7). |
| 443 | * |
| 444 | * @return string The html to display. |
| 445 | * |
| 446 | * @since 1.4 |
| 447 | */ |
| 448 | public function getCodeMirror($name, $value, array $params = array()) |
| 449 | { |
| 450 | if (VersionListener::isLowerThan('4.9')) |
| 451 | { |
| 452 | // CodeMirror is not supported on WP lower than 4.9, use a plain textarea |
| 453 | $editorName = 'none'; |
| 454 | } |
| 455 | else |
| 456 | { |
| 457 | // use CoreMirror editor |
| 458 | $editorName = 'codemirror'; |
| 459 | } |
| 460 | |
| 461 | // display editor |
| 462 | return JEditor::getInstance($editorName)->display($name, $value, '100%', 600, 30, 30, $buttons = false, $id = null, $params); |
| 463 | } |
| 464 | |
| 465 | /** |
| 466 | * Backward compatibility for WordPress Bootstrap tabset opening. |
| 467 | * |
| 468 | * @param string $group The group of the tabset. |
| 469 | * @param string $attr The attributes to use. |
| 470 | * |
| 471 | * @return string The html to display. |
| 472 | * |
| 473 | * @since 1.4 |
| 474 | */ |
| 475 | public function bootStartTabSet($group, $attr = array()) |
| 476 | { |
| 477 | /** |
| 478 | * In case the cookie attribute was included within the, |
| 479 | * array, we can register the script that will be used to |
| 480 | * handle the tab changes. The last selected tab will |
| 481 | * be stored in a cookie in order to be pre-selected |
| 482 | * when refreshing the page. |
| 483 | * |
| 484 | * @since 1.7 |
| 485 | */ |
| 486 | if (isset($attr['cookie'])) |
| 487 | { |
| 488 | $this->bootstrapTabSetCookie = '<script>' . JHtml::fetch('vaphtml.scripts.tabhandler', $group, $attr['cookie']) . '</script>'; |
| 489 | } |
| 490 | else |
| 491 | { |
| 492 | $this->bootstrapTabSetCookie = ''; |
| 493 | } |
| 494 | |
| 495 | return JHtml::fetch('bootstrap.startTabSet', $group, $attr); |
| 496 | } |
| 497 | |
| 498 | /** |
| 499 | * Backward compatibility for WordPress Bootstrap tabset closing. |
| 500 | * |
| 501 | * @return string The html to display. |
| 502 | * |
| 503 | * @since 1.4 |
| 504 | */ |
| 505 | public function bootEndTabSet() |
| 506 | { |
| 507 | /** |
| 508 | * Append the 'cookie' script after creating the tabset. |
| 509 | * |
| 510 | * @since 1.7 |
| 511 | */ |
| 512 | |
| 513 | return JHtml::fetch('bootstrap.endTabSet') . $this->bootstrapTabSetCookie; |
| 514 | } |
| 515 | |
| 516 | /** |
| 517 | * Backward compatibility for WordPress Bootstrap add tab. |
| 518 | * |
| 519 | * @param string $group The tabset parent group. |
| 520 | * @param string $id The id of the tab. |
| 521 | * @param string $label The title of the tab. |
| 522 | * @param array $options A list of options. |
| 523 | * |
| 524 | * @return string The html to display. |
| 525 | * |
| 526 | * @since 1.4 |
| 527 | */ |
| 528 | public function bootAddTab($group, $id, $label, array $options = array()) |
| 529 | { |
| 530 | /** |
| 531 | * In case the badge option is specified, append a badge |
| 532 | * to the tab label, displaying the count of records. |
| 533 | * |
| 534 | * @since 1.7 |
| 535 | */ |
| 536 | if (isset($options['badge'])) |
| 537 | { |
| 538 | $badge_class = isset($options['badge']['class']) ? $options['badge']['class'] : 'badge-info'; |
| 539 | $badge_id = isset($options['badge']['id']) ? $options['badge']['id'] : $id . '_tab_badge'; |
| 540 | $badge_count = isset($options['badge']['count']) ? $options['badge']['count'] : (int) $options['badge']; |
| 541 | |
| 542 | $label .= "<span class=\"badge {$badge_class} tab-badge-count\" id=\"{$badge_id}\" data-count=\"{$badge_count}\"> </span>"; |
| 543 | } |
| 544 | |
| 545 | return JHtml::fetch('bootstrap.addTab', $group, $id, $label); |
| 546 | } |
| 547 | |
| 548 | /** |
| 549 | * Backward compatibility for WordPress Bootstrap end tab. |
| 550 | * |
| 551 | * @return string The html to display. |
| 552 | * |
| 553 | * @since 1.4 |
| 554 | */ |
| 555 | public function bootEndTab() |
| 556 | { |
| 557 | return JHtml::fetch('bootstrap.endTab'); |
| 558 | } |
| 559 | |
| 560 | /** |
| 561 | * Backward compatibility for WordPress Bootstrap open modal JS event. |
| 562 | * |
| 563 | * @param string $onclose The javascript function to call on close event. |
| 564 | * |
| 565 | * @return string The javascript function. |
| 566 | * |
| 567 | * @since 1.5 |
| 568 | */ |
| 569 | public function bootOpenModalJS($onclose = '') |
| 570 | { |
| 571 | if ($onclose) |
| 572 | { |
| 573 | $onclose .= '();'; |
| 574 | } |
| 575 | |
| 576 | return |
| 577 | <<<JS |
| 578 | var on_hide = null; |
| 579 | |
| 580 | if ("$onclose") { |
| 581 | on_hide = function() { |
| 582 | $onclose |
| 583 | } |
| 584 | } |
| 585 | |
| 586 | wpOpenJModal(id, url, null, on_hide); |
| 587 | |
| 588 | return false; |
| 589 | JS |
| 590 | ; |
| 591 | } |
| 592 | |
| 593 | /** |
| 594 | * Backward compatibility for WordPress Bootstrap dismiss modal JS event. |
| 595 | * |
| 596 | * @param string $selector The selector to identify the modal box. |
| 597 | * |
| 598 | * @return string The javascript function. |
| 599 | * |
| 600 | * @since 1.5 |
| 601 | */ |
| 602 | public function bootDismissModalJS($selector = null) |
| 603 | { |
| 604 | if (!is_null($selector)) |
| 605 | { |
| 606 | /** |
| 607 | * The static selector is no more supported due |
| 608 | * to the possibility of conflicts between 2 or more |
| 609 | * modals loaded within the same page. |
| 610 | * |
| 611 | * @deprecated 1.8 |
| 612 | */ |
| 613 | JFactory::getDocument()->addScriptDeclaration('console.warn("The selector is deprecated in ' . __METHOD__ . '()");'); |
| 614 | } |
| 615 | |
| 616 | return |
| 617 | <<<JS |
| 618 | if ('$selector') { |
| 619 | id = '$selector'; |
| 620 | } |
| 621 | |
| 622 | wpCloseJModal(id); |
| 623 | JS |
| 624 | ; |
| 625 | |
| 626 | return |
| 627 | <<<JS |
| 628 | wpCloseJModal('$selector'); |
| 629 | JS |
| 630 | ; |
| 631 | } |
| 632 | |
| 633 | /** |
| 634 | * Adds javascript support for Bootstrap popovers. |
| 635 | * |
| 636 | * @param string $selector Selector for the popover. |
| 637 | * @param array $options An array of options for the popover. |
| 638 | * Options for the popover can be: |
| 639 | * animation boolean apply a css fade transition to the popover |
| 640 | * html boolean Insert HTML into the popover. If false, jQuery's text method will be used to insert |
| 641 | * content into the dom. |
| 642 | * placement string|function how to position the popover - top | bottom | left | right |
| 643 | * selector string If a selector is provided, popover objects will be delegated to the specified targets. |
| 644 | * trigger string how popover is triggered - hover | focus | manual |
| 645 | * title string|function default title value if `title` tag isn't present |
| 646 | * content string|function default content value if `data-content` attribute isn't present |
| 647 | * delay number|object delay showing and hiding the popover (ms) - does not apply to manual trigger type |
| 648 | * If a number is supplied, delay is applied to both hide/show |
| 649 | * Object structure is: delay: { show: 500, hide: 100 } |
| 650 | * container string|boolean Appends the popover to a specific element: { container: 'body' } |
| 651 | */ |
| 652 | public function attachPopover($selector = '.wpPopover', array $options = array()) |
| 653 | { |
| 654 | static $loaded = array(); |
| 655 | |
| 656 | $sign = serialize(array($selector, $options)); |
| 657 | |
| 658 | if (!isset($loaded[$sign])) |
| 659 | { |
| 660 | // do not sanitize HTML contents |
| 661 | $options['sanitize'] = false; |
| 662 | |
| 663 | /** |
| 664 | * In case the "container" attribute is not set, |
| 665 | * always place the popover within the body. |
| 666 | * |
| 667 | * @since 1.6.5 |
| 668 | */ |
| 669 | if (!isset($options['container'])) |
| 670 | { |
| 671 | $options['container'] = 'body'; |
| 672 | } |
| 673 | |
| 674 | $data = $options ? json_encode($options) : '{}'; |
| 675 | JFactory::getDocument()->addScriptDeclaration( |
| 676 | <<<JS |
| 677 | jQuery(function() { |
| 678 | jQuery('$selector').popover($data); |
| 679 | }); |
| 680 | JS |
| 681 | ); |
| 682 | |
| 683 | $loaded[$sign] = 1; |
| 684 | } |
| 685 | } |
| 686 | |
| 687 | /** |
| 688 | * Create a standard tag and attach a popover event. |
| 689 | * NOTE. FontAwesome framework MUST be loaded in order to work. |
| 690 | * |
| 691 | * @param array $options An array of options for the popover. |
| 692 | * |
| 693 | * @see VAPApplication::attachPopover() for further details about options keys. |
| 694 | * |
| 695 | * @since 1.6 |
| 696 | */ |
| 697 | public function createPopover(array $options = array()) |
| 698 | { |
| 699 | $icon = isset($options['icon_class']) ? $options['icon_class'] : 'fas fa-question-circle'; |
| 700 | |
| 701 | $icon = isset($options['icon']) ? 'fas fa-' . $options['icon'] : $icon; |
| 702 | |
| 703 | $template = "<i class=\"{$icon} vap-quest-popover\" {popover}></i>"; |
| 704 | |
| 705 | return $this->_popover($template, $options); |
| 706 | } |
| 707 | |
| 708 | /** |
| 709 | * Create a text span and attach a popover event. |
| 710 | * |
| 711 | * @param array $options An array of options for the popover. |
| 712 | * |
| 713 | * @see VAPApplication::attachPopover() for further details about options keys. |
| 714 | * |
| 715 | * @since 1.6 |
| 716 | */ |
| 717 | public function textPopover(array $options = array()) |
| 718 | { |
| 719 | $title = isset($options['title']) ? $options['title'] : '[MISSING TITLE]'; |
| 720 | $template = "<span class=\"inline-popover vap-quest-popover\" {popover}>{$title}</span>"; |
| 721 | |
| 722 | return $this->_popover($template, $options); |
| 723 | } |
| 724 | |
| 725 | /** |
| 726 | * Creates a popover using the provided template. |
| 727 | * |
| 728 | * @param string $template The popover template. |
| 729 | * @param array $options An array of options for the popover. |
| 730 | * |
| 731 | * @return string The popover HTML. |
| 732 | * |
| 733 | * @see VAPApplication::attachPopover() for further details about options keys. |
| 734 | */ |
| 735 | protected function _popover($template, array $options) |
| 736 | { |
| 737 | $layout = new JLayoutFile('html.plugins.popover', null, array('component' => 'com_vikappointments')); |
| 738 | |
| 739 | $options['html'] = true; |
| 740 | $options['title'] = isset($options['title']) ? $options['title'] : ''; |
| 741 | $options['content'] = isset($options['content']) ? $options['content'] : ''; |
| 742 | $options['trigger'] = isset($options['trigger']) ? $options['trigger'] : 'hover focus'; |
| 743 | $options['placement'] = isset($options['placement']) ? $options['placement'] : 'right'; |
| 744 | $options['template'] = isset($options['template']) ? $options['template'] : $layout->render(); |
| 745 | |
| 746 | // attach an empty array option so that the data will be recovered |
| 747 | // directly from the tag during the runtime |
| 748 | $this->attachPopover(".vap-quest-popover", array()); |
| 749 | |
| 750 | $attr = ''; |
| 751 | foreach ($options as $k => $v) |
| 752 | { |
| 753 | $attr .= "data-{$k}=\"" . esc_attr($v) . "\" "; |
| 754 | } |
| 755 | |
| 756 | return str_replace('{popover}', $attr, $template); |
| 757 | } |
| 758 | |
| 759 | /** |
| 760 | * Return the WordPress date format specs. |
| 761 | * |
| 762 | * @param string $format The format to use. |
| 763 | * @param array &$attributes Some attributes to use. |
| 764 | * |
| 765 | * @return string The adapted date format. |
| 766 | * |
| 767 | * @since 1.6 |
| 768 | */ |
| 769 | public function jdateFormat($format = null, array &$attributes = array()) |
| 770 | { |
| 771 | if ($format === null) |
| 772 | { |
| 773 | $format = VAPFactory::getConfig()->getString('dateformat'); |
| 774 | |
| 775 | if (!empty($attributes['showTime'])) |
| 776 | { |
| 777 | // concat the time format (24 hours format only) |
| 778 | $format .= ' H:i'; |
| 779 | } |
| 780 | } |
| 781 | |
| 782 | // strip % from date format string, which was required in Joomla |
| 783 | return str_replace('%', '', $format); |
| 784 | } |
| 785 | |
| 786 | /** |
| 787 | * Provides support to handle the WordPress calendar across different frameworks. |
| 788 | * |
| 789 | * @param mixed $value The date or the timestamp to fill. |
| 790 | * @param string $name The input name. |
| 791 | * @param string $id The input id attribute. |
| 792 | * @param string $format The date format. |
| 793 | * @param array $attributes Some attributes to use. |
| 794 | * |
| 795 | * @return string The calendar field. |
| 796 | * |
| 797 | * @since 1.6 |
| 798 | */ |
| 799 | public function calendar($value, $name, $id = null, $format = null, array $attributes = array()) |
| 800 | { |
| 801 | $format = $this->jdateFormat($format, $attributes); |
| 802 | |
| 803 | JHtml::fetch('behavior.calendar'); |
| 804 | |
| 805 | return JHtml::fetch('calendar', $value, $name, $id, $format, $attributes); |
| 806 | } |
| 807 | |
| 808 | /** |
| 809 | * Method used to obtain a WordPress media form field. |
| 810 | * |
| 811 | * @return string The media in HTML. |
| 812 | * |
| 813 | * @since 1.6 |
| 814 | */ |
| 815 | public function getMediaField($name, $value = null, array $data = array()) |
| 816 | { |
| 817 | // import form field class |
| 818 | JLoader::import('adapter.form.field'); |
| 819 | |
| 820 | // create XML field manifest |
| 821 | $xml = "<field name=\"$name\" type=\"media\" />"; |
| 822 | |
| 823 | // instantiate field |
| 824 | $field = JFormField::getInstance(simplexml_load_string($xml)); |
| 825 | |
| 826 | // overwrite name and value within data |
| 827 | $data['name'] = $name; |
| 828 | $data['value'] = $value; |
| 829 | |
| 830 | // inject display data within field instance |
| 831 | foreach ($data as $k => $v) |
| 832 | { |
| 833 | $field->bind($v, $k); |
| 834 | } |
| 835 | |
| 836 | // render field |
| 837 | return $field->render(); |
| 838 | } |
| 839 | |
| 840 | /** |
| 841 | * Method used to handle the reCAPTCHA events. |
| 842 | * |
| 843 | * @param string $event The reCAPTCHA event to trigger. |
| 844 | * Here's the list of the accepted events: |
| 845 | * - display Returns the HTML used to display the ReCAPTCHA input; |
| 846 | * - check Validates the POST data to make sure the ReCAPTCHA input was checked. |
| 847 | * @param array $options A configuration array. |
| 848 | * |
| 849 | * @return mixed The event response. |
| 850 | * |
| 851 | * @since 1.6 |
| 852 | * @deprecated 1.8 Use captcha() instead. |
| 853 | */ |
| 854 | public function reCaptcha($event = 'display', array $options = array()) |
| 855 | { |
| 856 | return $this->captcha($event, $options); |
| 857 | } |
| 858 | |
| 859 | /** |
| 860 | * Method used to handle the CAPTCHA events. |
| 861 | * |
| 862 | * @param string $event The CAPTCHA event to trigger. |
| 863 | * Here's the list of the accepted events: |
| 864 | * - display Returns the HTML used to |
| 865 | * display the CAPTCHA input. |
| 866 | * - check Validates the POST data to make sure |
| 867 | * the CAPTCHA input was checked. |
| 868 | * @param array $options A configuration array. |
| 869 | * |
| 870 | * @return mixed The event response. |
| 871 | * |
| 872 | * @since 1.7.10 |
| 873 | */ |
| 874 | public function captcha($event = 'display', array $options = []) |
| 875 | { |
| 876 | $response = null; |
| 877 | |
| 878 | /** |
| 879 | * Trigger action to perform the specified ReCAPTCHA event. |
| 880 | * |
| 881 | * @param mixed $response The response to return. |
| 882 | * @param array $options A configuration array. |
| 883 | * |
| 884 | * @since 1.0 |
| 885 | */ |
| 886 | do_action_ref_array('vik_recaptcha_' . strtolower($event), array(&$response, $options)); |
| 887 | |
| 888 | return $response; |
| 889 | } |
| 890 | |
| 891 | /** |
| 892 | * Checks if the com_user captcha is configured. |
| 893 | * In case the parameter is set to global, the default one |
| 894 | * will be retrieved. |
| 895 | * |
| 896 | * @param string $plugin The plugin name to check. Leave empty |
| 897 | * to use any type of captcha. |
| 898 | * |
| 899 | * @return boolean True if configured, otherwise false. |
| 900 | * |
| 901 | * @since 1.6 |
| 902 | * @deprecated 1.8 Use getUserCaptcha() instead. |
| 903 | */ |
| 904 | public function isCaptcha($plugin = null) |
| 905 | { |
| 906 | return $this->isGlobalCaptcha(); |
| 907 | } |
| 908 | |
| 909 | |
| 910 | /** |
| 911 | * Returns the configured captcha plugin for com_users component. |
| 912 | * In case the parameter is set to global, the default one will be retrieved. |
| 913 | * |
| 914 | * @return string|null The configured captcha, NULL otherwise. |
| 915 | * |
| 916 | * @since 1.7.10 |
| 917 | */ |
| 918 | public function getUserCaptcha() |
| 919 | { |
| 920 | return $this->getGlobalCaptcha(); |
| 921 | } |
| 922 | |
| 923 | /** |
| 924 | * Checks if the global captcha is configured. |
| 925 | * |
| 926 | * @param string $plugin The plugin name to check. Leave empty |
| 927 | * to use any type of captcha. |
| 928 | * |
| 929 | * @return boolean True if configured, otherwise false. |
| 930 | * |
| 931 | * @since 1.6 |
| 932 | * @deprecated 1.8 Use getGlobalCaptcha() instead. |
| 933 | */ |
| 934 | public function isGlobalCaptcha($plugin = null) |
| 935 | { |
| 936 | return (bool) $this->getGlobalCaptcha(); |
| 937 | } |
| 938 | |
| 939 | /** |
| 940 | * Returns the configured captcha plugin for global use. |
| 941 | * |
| 942 | * @return string|null The configured captcha, NULL otherwise. |
| 943 | * |
| 944 | * @since 1.7.10 |
| 945 | */ |
| 946 | public function getGlobalCaptcha() |
| 947 | { |
| 948 | /** |
| 949 | * Trigger action to check whether the ReCAPTCHA plugin is supported. |
| 950 | * |
| 951 | * @param boolean $active True if active, false otherwise. |
| 952 | * @param mixed $plugin The requested plugin, if specified. |
| 953 | * |
| 954 | * @since 1.0 |
| 955 | */ |
| 956 | return apply_filters('vik_recaptcha_on', false, null) ? 'recaptcha' : null; |
| 957 | } |
| 958 | |
| 959 | /** |
| 960 | * Rewrites an internal URI that needs to be used outside of the website. |
| 961 | * This means that the routed URI MUST start with the base path of the site. |
| 962 | * |
| 963 | * @param mixed $query The query string or an associative array of data. |
| 964 | * @param boolean $xhtml Replace & by & for XML compliance. |
| 965 | * @param mixed $itemid The itemid to use. If null, the current one will be used. |
| 966 | * |
| 967 | * @return string The complete routed URI. |
| 968 | * |
| 969 | * @since 1.6 |
| 970 | */ |
| 971 | public function routeForExternalUse($query = '', $xhtml = true, $itemid = null) |
| 972 | { |
| 973 | // check if the query already specifies the Itemid |
| 974 | if (!preg_match("/&Itemid=[\d]*/", $query)) |
| 975 | { |
| 976 | // try to extract view from query |
| 977 | if (preg_match("/&view=([a-z0-9_]+)(?:&|$)/", $query, $match)) |
| 978 | { |
| 979 | $view = end($match); |
| 980 | } |
| 981 | else |
| 982 | { |
| 983 | $view = null; |
| 984 | } |
| 985 | |
| 986 | // import shortcodes model |
| 987 | $model = JModel::getInstance('vikappointments', 'shortcodes', 'admin'); |
| 988 | $itemid = $model->best($view); |
| 989 | |
| 990 | if ($itemid) |
| 991 | { |
| 992 | // update query with Itemid found |
| 993 | $query .= (strpos($query, '?') === false ? '?' : '&') . 'Itemid=' . $itemid; |
| 994 | } |
| 995 | } |
| 996 | |
| 997 | // route URL |
| 998 | return JRoute::rewrite($query, false); |
| 999 | } |
| 1000 | |
| 1001 | /** |
| 1002 | * Routes an admin URL for being used outside from the website (complete URI). |
| 1003 | * |
| 1004 | * @param mixed $query The query string or an associative array of data. |
| 1005 | * @param boolean $xhtml Replace & by & for XML compliance. |
| 1006 | * |
| 1007 | * @return string The complete routed URI. |
| 1008 | * |
| 1009 | * @since 1.6.3 |
| 1010 | */ |
| 1011 | public function adminUrl($query = '', $xhtml = true) |
| 1012 | { |
| 1013 | $app = JFactory::getApplication(); |
| 1014 | |
| 1015 | if (is_array($query)) |
| 1016 | { |
| 1017 | // make sure the array is not empty |
| 1018 | if ($query) |
| 1019 | { |
| 1020 | $query = '?' . http_build_query($query); |
| 1021 | } |
| 1022 | else |
| 1023 | { |
| 1024 | $query = ''; |
| 1025 | } |
| 1026 | |
| 1027 | // the query is an array, build the query string |
| 1028 | $query = 'index.php' . $query; |
| 1029 | } |
| 1030 | |
| 1031 | // replace initial index.php with admin.php |
| 1032 | $query = preg_replace("/^index\.php/", 'admin.php', $query); |
| 1033 | // replace option=com_vikappointments with page=vikappointments |
| 1034 | $query = preg_replace("/(&|\?)option=com_vikappointments/", '$1page=vikappointments', $query); |
| 1035 | |
| 1036 | // finalise admin URI |
| 1037 | $uri = JUri::root() . 'wp-admin/' . $query; |
| 1038 | |
| 1039 | if ($xhtml) |
| 1040 | { |
| 1041 | $uri = str_replace('&', '&', $uri); |
| 1042 | } |
| 1043 | |
| 1044 | return $uri; |
| 1045 | } |
| 1046 | |
| 1047 | /** |
| 1048 | * Prepares a plain/routed URL to be used for an AJAX request. |
| 1049 | * |
| 1050 | * @param mixed $query The query string or a routed URL. |
| 1051 | * @param boolean $xhtml Replace & by & for XML compliance. |
| 1052 | * |
| 1053 | * @return string The AJAX end-point URI. |
| 1054 | * |
| 1055 | * @since 1.7 |
| 1056 | */ |
| 1057 | public function ajaxUrl($query = '', $xhtml = false) |
| 1058 | { |
| 1059 | // instantiate path based on specified query |
| 1060 | $path = new JUri($query); |
| 1061 | |
| 1062 | // delete option var from query |
| 1063 | $path->delVar('option'); |
| 1064 | |
| 1065 | // force action in query |
| 1066 | $path->setVar('action', 'vikappointments'); |
| 1067 | |
| 1068 | // force application client in case of front-end |
| 1069 | if (JFactory::getApplication()->isClient('site')) |
| 1070 | { |
| 1071 | $path->setVar('vik_ajax_client', 'site'); |
| 1072 | } |
| 1073 | |
| 1074 | // create AJAX URI |
| 1075 | $uri = admin_url('admin-ajax.php') . '?' . $path->getQuery(); |
| 1076 | |
| 1077 | if ($xhtml) |
| 1078 | { |
| 1079 | // try to make "&" XML safe |
| 1080 | $uri = preg_replace("/&(?!amp;)/", '&', $uri); |
| 1081 | } |
| 1082 | |
| 1083 | return $uri; |
| 1084 | } |
| 1085 | |
| 1086 | /** |
| 1087 | * Includes the CSRF-proof token within the specified query string/URL. |
| 1088 | * |
| 1089 | * @param mixed $query The query string or a routed URL. |
| 1090 | * @param boolean $xhtml Replace & by & for XML compliance. |
| 1091 | * |
| 1092 | * @return string The resulting path. |
| 1093 | * |
| 1094 | * @since 1.7 |
| 1095 | */ |
| 1096 | public function addUrlCSRF($query = '', $xhtml = false) |
| 1097 | { |
| 1098 | JLoader::import('adapter.session.session'); |
| 1099 | |
| 1100 | // safely append the CSRF token within the query string |
| 1101 | $uri = JUri::getInstance($query); |
| 1102 | $uri->setVar(JSession::getFormTokenName(), JSession::getFormToken()); |
| 1103 | |
| 1104 | if ($xhtml) |
| 1105 | { |
| 1106 | // try to make "&" XML safe |
| 1107 | $uri = preg_replace("/&(?!amp;)/", '&', (string) $uri); |
| 1108 | } |
| 1109 | |
| 1110 | return (string) $uri; |
| 1111 | } |
| 1112 | |
| 1113 | /** |
| 1114 | * Returns the platform base path. |
| 1115 | * |
| 1116 | * @return string |
| 1117 | * |
| 1118 | * @since 1.7.1 |
| 1119 | */ |
| 1120 | public function getAbsolutePath() |
| 1121 | { |
| 1122 | return ABSPATH; |
| 1123 | } |
| 1124 | |
| 1125 | /** |
| 1126 | * Helper method to pre-load the assets needed for the Employee Area. |
| 1127 | * |
| 1128 | * @return void |
| 1129 | * |
| 1130 | * @since 1.6 |
| 1131 | */ |
| 1132 | public function loadEmployeeAreaAssets() |
| 1133 | { |
| 1134 | parent::loadEmployeeAreaAssets(); |
| 1135 | |
| 1136 | // load bootstrap too |
| 1137 | $doc = JFactory::getDocument(); |
| 1138 | |
| 1139 | $internalFilesOptions = array('version' => VIKAPPOINTMENTS_SOFTWARE_VERSION); |
| 1140 | |
| 1141 | $doc->addStyleSheet(VIKAPPOINTMENTS_CORE_MEDIA_URI . 'css/bootstrap.lite.css', $internalFilesOptions, array('id' => 'bootstrap-lite-style')); |
| 1142 | $doc->addScript(VIKAPPOINTMENTS_CORE_MEDIA_URI . 'js/bootstrap.min.js', $internalFilesOptions, array('id' => 'bootstrap-script')); |
| 1143 | } |
| 1144 | |
| 1145 | /** |
| 1146 | * Returns a list of users that are currently logged-in. |
| 1147 | * |
| 1148 | * @param mixed $limit The query limit, if specified. |
| 1149 | * @param integer $offset The query offset, if specified. |
| 1150 | * |
| 1151 | * @return array A list of users. |
| 1152 | * |
| 1153 | * @since 1.6.3 |
| 1154 | */ |
| 1155 | public function getLoggedUsers($limit = null, $offset = 0) |
| 1156 | { |
| 1157 | // get record of currently logged-in users (get_users() returns always an array) |
| 1158 | $users = get_users([ |
| 1159 | 'meta_key' => 'session_tokens', |
| 1160 | 'meta_compare' => 'EXISTS', |
| 1161 | ]); |
| 1162 | |
| 1163 | // splice the users list following the specified limits |
| 1164 | $users = array_splice($users, $offset, $limit); |
| 1165 | |
| 1166 | if (!$users) |
| 1167 | { |
| 1168 | // do not proceed in case of no users |
| 1169 | return array(); |
| 1170 | } |
| 1171 | |
| 1172 | $dbo = JFactory::getDbo(); |
| 1173 | |
| 1174 | $query = $dbo->getQuery(true) |
| 1175 | ->select($dbo->qn(array('id', 'country_code'))) |
| 1176 | ->from($dbo->qn('#__vikappointments_users', 'c')); |
| 1177 | |
| 1178 | /** |
| 1179 | * Here's a list of columns that have to be supported: |
| 1180 | * |
| 1181 | * @property string session_time The session last time. |
| 1182 | * @property integer jid The user ID. |
| 1183 | * @property integer id The customer ID. |
| 1184 | * @property string billing_name The user nominative. |
| 1185 | * @property string billing_mail The user e-mail address. |
| 1186 | * @property string country_code The user 2-letters country code. |
| 1187 | */ |
| 1188 | |
| 1189 | // map array to extract a valid response |
| 1190 | return array_map(function($user) use ($query, $dbo) |
| 1191 | { |
| 1192 | $sessions = get_user_meta($user->ID, 'session_tokens', true); |
| 1193 | |
| 1194 | if (is_array($sessions) && $sessions) |
| 1195 | { |
| 1196 | // extract last session token |
| 1197 | $session = end($sessions); |
| 1198 | $last_login = $session['login']; |
| 1199 | } |
| 1200 | else |
| 1201 | { |
| 1202 | // impossible to fetch last login |
| 1203 | $last_login = null; |
| 1204 | } |
| 1205 | |
| 1206 | $tmp = array(); |
| 1207 | $tmp['jid'] = $user->ID; |
| 1208 | $tmp['session_time'] = $last_login; |
| 1209 | $tmp['billing_name'] = $user->display_name; |
| 1210 | $tmp['billing_mail'] = $user->user_email; |
| 1211 | $tmp['country_code'] = null; |
| 1212 | $tmp['id'] = null; |
| 1213 | |
| 1214 | // complete query |
| 1215 | $query->clear('where')->where(array( |
| 1216 | $dbo->qn('c.jid') . ' = ' . (int) $user->ID, |
| 1217 | $dbo->qn('c.billing_mail') . ' = ' . $dbo->q($user->user_email), |
| 1218 | ), 'OR'); |
| 1219 | |
| 1220 | $dbo->setQuery($query, 0, 1); |
| 1221 | |
| 1222 | // merge columns found |
| 1223 | $tmp = array_merge($tmp, (array) $dbo->loadAssoc()); |
| 1224 | |
| 1225 | return $tmp; |
| 1226 | }, $users); |
| 1227 | } |
| 1228 | |
| 1229 | /** |
| 1230 | * Prepares the specified content before being displayed. |
| 1231 | * |
| 1232 | * @param mixed &$content The table content instance or a string to fetch. |
| 1233 | * @param mixed $params True to apply the full description, false to apply |
| 1234 | * the short description, if any. Any other non scalar |
| 1235 | * value to pass a configuration for plugins. |
| 1236 | * |
| 1237 | * @return void |
| 1238 | * |
| 1239 | * @since 1.6.3 |
| 1240 | */ |
| 1241 | public function onContentPrepare(&$content, $params = array()) |
| 1242 | { |
| 1243 | $pattern = "/(?:<p>)?<!--\s*more\s*-->(?:<\/p>)?/i"; |
| 1244 | |
| 1245 | if (is_null($content)) |
| 1246 | { |
| 1247 | $content = ''; |
| 1248 | } |
| 1249 | |
| 1250 | // create Content table in case a string was passed |
| 1251 | if (is_string($content)) |
| 1252 | { |
| 1253 | $text = $content; |
| 1254 | |
| 1255 | $content = JTable::getInstance('content'); |
| 1256 | $content->text = $text; |
| 1257 | } |
| 1258 | |
| 1259 | if (is_bool($params)) |
| 1260 | { |
| 1261 | // BC: take the specified type of text (full or short) |
| 1262 | $full = $params; |
| 1263 | |
| 1264 | // use an empty array |
| 1265 | $params = array(); |
| 1266 | } |
| 1267 | else |
| 1268 | { |
| 1269 | /** |
| 1270 | * Extract type of text from parameters. |
| 1271 | * If not specified, the full text will be used. |
| 1272 | * |
| 1273 | * @since 1.7 |
| 1274 | */ |
| 1275 | $full = isset($params['fulltext']) ? (bool) $params['fulltext'] : true; |
| 1276 | } |
| 1277 | |
| 1278 | // always replaces double line-breaks with paragraph elements |
| 1279 | $content->text = wpautop($content->text); |
| 1280 | |
| 1281 | /** |
| 1282 | * Interprets shortcodes contained within the full text. |
| 1283 | * |
| 1284 | * @since 1.7 |
| 1285 | */ |
| 1286 | $content->text = do_shortcode($content->text); |
| 1287 | |
| 1288 | // check if the description owns a readmore separator |
| 1289 | if (preg_match($pattern, $content->text)) |
| 1290 | { |
| 1291 | // split the description in 2 chunks |
| 1292 | $chunks = preg_split($pattern, $content->text, 2); |
| 1293 | |
| 1294 | // overwrite text with short (0) or full (1) description |
| 1295 | $content->text = $chunks[$full ? 1 : 0]; |
| 1296 | |
| 1297 | /** |
| 1298 | * Register intro and full texts too. |
| 1299 | * |
| 1300 | * @since 1.7 |
| 1301 | */ |
| 1302 | $content->introtext = $chunks[0]; |
| 1303 | $content->fulltext = $chunks[1]; |
| 1304 | } |
| 1305 | } |
| 1306 | |
| 1307 | /** |
| 1308 | * Returns a list of supported payment gateways. |
| 1309 | * |
| 1310 | * @return array A list of paths. |
| 1311 | * |
| 1312 | * @since 1.6.3 |
| 1313 | */ |
| 1314 | public function getPaymentDrivers() |
| 1315 | { |
| 1316 | // import payment dispatcher |
| 1317 | JLoader::import('adapter.payment.dispatcher'); |
| 1318 | |
| 1319 | // get paths list of supported drivers |
| 1320 | return JPaymentDispatcher::getSupportedDrivers('vikappointments'); |
| 1321 | } |
| 1322 | |
| 1323 | /** |
| 1324 | * Returns the configuration form of a payment. |
| 1325 | * |
| 1326 | * @param string $payment The name of the payment. |
| 1327 | * |
| 1328 | * @return mixed The configuration array/object. |
| 1329 | * |
| 1330 | * @since 1.6.3 |
| 1331 | * |
| 1332 | * @uses getPaymentInstance() |
| 1333 | */ |
| 1334 | public function getPaymentConfig($payment) |
| 1335 | { |
| 1336 | // instantiate payment and access its configuration form |
| 1337 | return $this->getPaymentInstance($payment)->getAdminParameters(); |
| 1338 | } |
| 1339 | |
| 1340 | /** |
| 1341 | * Provides a new payment instance for the specified arguments. |
| 1342 | * |
| 1343 | * @param string $payment The name of the payment that should be instantiated. |
| 1344 | * @param mixed $order The details of the order that has to be paid. |
| 1345 | * @param mixed $config The payment configuration array or a JSON string. |
| 1346 | * |
| 1347 | * @return mixed The payment instance. |
| 1348 | * |
| 1349 | * @throws RuntimeException |
| 1350 | * |
| 1351 | * @since 1.6.3 |
| 1352 | */ |
| 1353 | public function getPaymentInstance($payment, $order = array(), $config = array()) |
| 1354 | { |
| 1355 | // import payment dispatcher |
| 1356 | JLoader::import('adapter.payment.dispatcher'); |
| 1357 | |
| 1358 | // instantiate payment |
| 1359 | return JPaymentDispatcher::getInstance('vikappointments', $payment, $order, $config); |
| 1360 | } |
| 1361 | |
| 1362 | /** |
| 1363 | * Returns the component manufacturer name or link. |
| 1364 | * |
| 1365 | * @param array $options An array of options: |
| 1366 | * - link (boolean) True to return a link, false to return the |
| 1367 | * name only (false by default); |
| 1368 | * - short (boolean) True to display the short manufacturer name, |
| 1369 | * false otherwise (false by default); |
| 1370 | * - long (boolean) True to display the long manufacturer name, |
| 1371 | * false otherwise (true by default); |
| 1372 | * - separator (string) A separator string to insert between the |
| 1373 | * names fetched ('-' by default). |
| 1374 | * |
| 1375 | * @return string The manufacturer name or link. |
| 1376 | * |
| 1377 | * @since 1.6.3 |
| 1378 | */ |
| 1379 | public function getManufacturer(array $options = array()) |
| 1380 | { |
| 1381 | // add support for manufacturer default options |
| 1382 | $options['manufacturer'] = array( |
| 1383 | // specify a default URI |
| 1384 | 'link' => 'https://vikwp.com', |
| 1385 | // specify the manufacturer short name |
| 1386 | 'short' => 'VikWP', |
| 1387 | // specify the manufacturer long name |
| 1388 | 'long' => 'vikwp.com', |
| 1389 | ); |
| 1390 | |
| 1391 | // invoke parent to complete name building |
| 1392 | return parent::getManufacturer($options); |
| 1393 | } |
| 1394 | |
| 1395 | /** |
| 1396 | * Checks whether the reservation can be completed. |
| 1397 | * |
| 1398 | * @return boolean |
| 1399 | * |
| 1400 | * @since 1.6.3 |
| 1401 | */ |
| 1402 | public function checkAvailability() |
| 1403 | { |
| 1404 | // always return true in WordPress |
| 1405 | return true; |
| 1406 | } |
| 1407 | |
| 1408 | /** |
| 1409 | * Displays the platform alert. |
| 1410 | * |
| 1411 | * @param array $options The alert display data. |
| 1412 | * |
| 1413 | * @return string The HTML of the alert. |
| 1414 | * |
| 1415 | * @see alert() |
| 1416 | * |
| 1417 | * @since 1.7 |
| 1418 | */ |
| 1419 | protected function displayAlert(array $data) |
| 1420 | { |
| 1421 | // register script to handle cookie alert |
| 1422 | JHtml::fetch('vaphtml.scripts.cookiealert'); |
| 1423 | |
| 1424 | // include INLINE class to keep the notice stuck on its position |
| 1425 | if (empty($data['attrs']['class'])) |
| 1426 | { |
| 1427 | $data['attrs']['class'] = 'inline'; |
| 1428 | } |
| 1429 | else |
| 1430 | { |
| 1431 | $data['attrs']['class'] .= ' inline'; |
| 1432 | } |
| 1433 | |
| 1434 | // instantiate layout file |
| 1435 | $layout = new JLayoutFile('html.system.notice'); |
| 1436 | |
| 1437 | // display layout |
| 1438 | return $layout->render($data); |
| 1439 | } |
| 1440 | |
| 1441 | /** |
| 1442 | * Returns a list of supported SMS providers. |
| 1443 | * |
| 1444 | * @return array A list of paths. |
| 1445 | * |
| 1446 | * @since 1.7 |
| 1447 | */ |
| 1448 | public function getSmsDrivers() |
| 1449 | { |
| 1450 | // import sms dispatcher |
| 1451 | JLoader::import('adapter.sms.dispatcher'); |
| 1452 | |
| 1453 | // get paths list of supported drivers |
| 1454 | return JSmsDispatcher::getSupportedDrivers('vikappointments'); |
| 1455 | } |
| 1456 | |
| 1457 | /** |
| 1458 | * Returns the configuration form of a SMS provider. |
| 1459 | * |
| 1460 | * @param string $driver The name of the driver. |
| 1461 | * |
| 1462 | * @return mixed The configuration array/object. |
| 1463 | * |
| 1464 | * @since 1.7 |
| 1465 | */ |
| 1466 | public function getSmsConfig($driver) |
| 1467 | { |
| 1468 | // instantiate driver and access its configuration form |
| 1469 | return $this->getSmsInstance($driver)->getAdminParameters(); |
| 1470 | } |
| 1471 | |
| 1472 | /** |
| 1473 | * Provides a new SMS driver instance for the specified arguments. |
| 1474 | * |
| 1475 | * @param string $driver The name of the provider that should be instantiated. |
| 1476 | * If not specified, the default one will be used. |
| 1477 | * @param mixed $config The SMS configuration array or a JSON string. |
| 1478 | * @param mixed $order The details of the order that has to be notified. |
| 1479 | * |
| 1480 | * @return mixed The driver instance. |
| 1481 | * |
| 1482 | * @throws RuntimeException |
| 1483 | * |
| 1484 | * @since 1.7 |
| 1485 | */ |
| 1486 | public function getSmsInstance($driver = null, $config = null, $order = array()) |
| 1487 | { |
| 1488 | if (is_null($driver)) |
| 1489 | { |
| 1490 | // get default driver if not specified |
| 1491 | $driver = VAPFactory::getConfig()->get('smsapi'); |
| 1492 | } |
| 1493 | |
| 1494 | if (empty($driver)) |
| 1495 | { |
| 1496 | // SMS API not configured |
| 1497 | throw new RuntimeException('SMS API framework not configured', 500); |
| 1498 | } |
| 1499 | |
| 1500 | if (is_null($config)) |
| 1501 | { |
| 1502 | // get default configuration if not specified |
| 1503 | $config = VAPFactory::getConfig()->get('smsapifields'); |
| 1504 | } |
| 1505 | |
| 1506 | // import sms dispatcher |
| 1507 | JLoader::import('adapter.sms.dispatcher'); |
| 1508 | |
| 1509 | // instantiate sms |
| 1510 | return JSmsDispatcher::getInstance('vikappointments', $driver, $order, $config); |
| 1511 | } |
| 1512 | } |
| 1513 |