<?php
/**
* @package RSForm! Pro
* @copyright (C) 2007-2019 www.rsjoomla.com
* @license GPL, http://www.gnu.org/copyleft/gpl.html
*/
defined('_JEXEC') or die;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Factory;
require_once JPATH_ADMINISTRATOR.'/components/com_rsform/helpers/field.php';
require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/calendar.php';
class RSFormProFieldCalendar extends RSFormProField
{
public $customId;
// backend preview
public function getPreviewInput()
{
$layout = $this->getProperty('CALENDARLAYOUT', 'FLAT');
return RSFormProHelper::getIcon('calendar') . ' ' . Text::_('RSFP_COMP_FVALUE_' . $layout);
}
// functions used for rendering in front view
public function getFormInput() {
$calendar = RSFormProCalendar::getInstance('YUICalendar');
$value = (string) $this->getValue();
$name = $this->getName();
$id = $this->getId();
$layout = $this->getProperty('CALENDARLAYOUT', 'FLAT');
$format = $this->getProperty('DATEFORMAT');
$readonly = $this->getProperty('READONLY', 'NO');
$attr = $this->getAttributes('input');
$type = 'text';
$additional = '';
$zIndex = $this->getZIndex();
$position = $this->getPosition();
// Create a unique ID for this calendar.
$this->customId = $this->formId.'_'.$position;
$hiddenValue = '';
$hidden = Factory::getApplication()->input->get('hidden', array(), 'array');
$hiddenName = $this->formId.'_'.$this->getProperty('NAME', '');
if (!empty($hidden[$hiddenName])) {
$hiddenValue = preg_replace('#[^0-9\/]+#i', '', $hidden[$hiddenName]);
} else {
if (!empty($value)) {
// Let's allow the 'now' keyword
if (strtolower($value) == 'now')
{
$value = Factory::getDate('now')->format($format);
}
if (Factory::getLanguage()->getTag() != 'en-GB')
{
$value = RSFormProCalendar::fixValue($value, $format);
}
// Try to create a date to see if it's valid
$date = DateTime::createFromFormat($format, $value);
if ($date !== false)
{
$hiddenValue = $date->format('m/d/Y');
}
else
{
$value = '';
$hiddenValue = '';
}
}
}
// set the calendar script
$config = array(
'offset' => $this->getProperty('VALIDATIONCALENDAROFFSET', 1),
'layout' => $layout,
'dateFormat' => $format,
'value' => $hiddenValue,
'minDate' => $this->isCode($this->getProperty('MINDATE', '')),
'maxDate' => $this->isCode($this->getProperty('MAXDATE', '')),
'validationCalendar' => $this->getProperty('VALIDATIONCALENDAR', ''),
'formId' => $this->formId,
'customId' => $this->customId
);
$calendar->setCalendar($config);
// Parse Additional Attributes for the input textbox
if ($attr) {
foreach ($attr as $key => $values) {
// @new feature - Some HTML attributes (type, size, maxlength) can be overwritten
// directly from the Additional Attributes area
if ($key == 'type' && strlen($values)) {
${$key} = $values;
continue;
}
$additional .= $this->attributeToHtml($key, $values);
}
}
// This is the textbox used to display the date
$input = '<input'.
' id="txtcal'.$this->customId.'"'.
' name="'.$this->escape($name).'"'.
' type="'.$this->escape($type).'"';
// Is it read only?
if ($readonly) {
$input .= ' readonly="readonly"';
}
if ($placeholder = $this->getProperty('PLACEHOLDER', ''))
{
$input .= ' placeholder="'.$this->escape($placeholder).'"';
}
// Add the value
$input .= ' value="'.$this->escape($value).'"';
// Additional HTML
$input .= $additional;
// Close the tag
$input .= ' />';
// Flat layouts need a <br /> so that the calendar is shown below the textbox
if ($layout == 'FLAT') {
// Let's just substitute the "button" with a <br /> tag
$button = '<br />';
} elseif ($layout == 'POPUP') {
$attr = $this->getAttributes('button');
$label = $this->getProperty('POPUPLABEL', '...');
$additional = '';
// Parse Additional Attributes for the button
if ($attr) {
foreach ($attr as $key => $values) {
$additional .= $this->attributeToHtml($key, $values);
}
}
// Create the popup button
$button = $this->getButtonInput($label, $additional);
}
// This is the calendar HTML container
$hide = '';
// If this is a popup layout, hide the container so that it's only shown when the button is clicked
if ($layout == 'POPUP') {
$hide = 'clear:both;display:none;position:absolute;';
}
$container = '<div'.
' id="cal'.$this->customId.'Container"'.
' style="'.$hide.'z-index:'.$zIndex.'">'.
'</div>';
// This is the hidden field of the calendar
$hidden = '<input'.
' id="hiddencal'.$this->customId.'"'.
' type="hidden"'.
' name="hidden['.$this->formId.'_'.$id.']"'.
' data-rsfp-original-date="' . $this->escape($hiddenValue) . '"' .
' />';
$html = $this->setFieldOutput($input, $button, $container, $hidden, $layout);
return $html;
}
protected function getButtonInput($label, $additional)
{
if (!$this->getProperty('ALLOWHTML'))
{
$label = $this->escape($label);
}
return '<button id="btn' . $this->customId . '" type="button"' . $additional . '>' . $label . '</button>';
}
// set the field output - function needed for overwriting in the layout classes
protected function setFieldOutput($input, $button, $container, $hidden, $layout) {
return $input.$button.$container.$hidden;
}
// @desc Gets the position of this calendar in the current form (eg. if it's the only calendar in the form, the position is 0,
// if it's the second calendar the position is 1 and so on).
protected function getPosition() {
return RSFormProCalendar::getInstance('YUICalendar')->getPosition($this->formId, $this->componentId);
}
protected function getZIndex() {
return (9999 - (int) $this->getProperty('Order'));
}
// @desc All calendars should have a 'rsform-calendar-box' class for easy styling
// Since the calendar is composed of multiple items, we need to differentiate the attributes through the $type parameter
public function getAttributes($type='input') {
$attr = parent::getAttributes();
if (strlen($attr['class'])) {
$attr['class'] .= ' ';
}
if ($type == 'input') {
$attr['class'] .= 'rsform-calendar-box';
$layout = $this->getProperty('CALENDARLAYOUT', 'FLAT');
if ($layout == 'FLAT') {
$attr['class'] .= ' txtCal';
}
} elseif ($type == 'button') {
unset($attr['aria-required'], $attr['aria-invalid'], $attr['aria-describedby']);
$attr['class'] .= 'btnCal rsform-calendar-button';
if (!empty($attr['onclick'])) {
$attr['onclick'] .= ' ';
} else {
$attr['onclick'] = '';
}
$attr['onclick'] .= "RSFormPro.YUICalendar.showHideCalendar('cal".$this->customId."Container');";
}
return $attr;
}
public function processValidation($validationType = 'form', $submissionId = 0)
{
$validate = $this->getProperty('VALIDATIONDATE', true);
$required = $this->isRequired();
$format = $this->getProperty('DATEFORMAT');
$value = $this->getValue();
if ($required && !strlen(trim($value)))
{
return false;
}
if ($validate && strlen(trim($value)))
{
if (Factory::getLanguage()->getTag() != 'en-GB')
{
$value = RSFormProCalendar::fixValue($value, $format);
}
$validDate = DateTime::createFromFormat($format, $value);
if ($validDate)
{
$validDate = $validDate->format($format);
}
if ($validDate !== $value)
{
return false;
}
}
return true;
}
}