Skip to content

Instantly share code, notes, and snippets.

@chdemko
Created February 5, 2012 17:00
Show Gist options
  • Save chdemko/1746576 to your computer and use it in GitHub Desktop.
Save chdemko/1746576 to your computer and use it in GitHub Desktop.
#787
<?php
/**
* @package Joomla.Platform
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Form Field class for the Joomla Platform.
*
* Provides a pop up date picker linked to a button.
* Optionally may be filtered to use user's or server's time zone.
*
* @package Joomla.Platform
* @subpackage Form
* @since 11.1
*/
class JFormFieldCalendar extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 11.1
*/
public $type = 'Calendar';
/**
* Method to get the field input markup.
*
* The format attribute must be compatible with format described there http://www.php.net/manual/en/datetime.formats.php
*
* @return string The field input markup.
*
* @since 11.1
*/
protected function getInput()
{
// Initialize some field attributes.
$format = $this->element['format'] ? (string) $this->element['format'] : '%Y-%m-%d';
$filter = isset($this->element['filter']) ? strtoupper($this->element['filter']) : '';
// Build the attributes array.
$attributes = array();
if ($this->element['size'])
{
$attributes['size'] = (int) $this->element['size'];
}
if ($this->element['maxlength'])
{
$attributes['maxlength'] = (int) $this->element['maxlength'];
}
if ($this->element['class'])
{
$attributes['class'] = (string) $this->element['class'];
}
if ((string) $this->element['readonly'] == 'true')
{
$attributes['readonly'] = 'readonly';
}
if ((string) $this->element['disabled'] == 'true')
{
$attributes['disabled'] = 'disabled';
}
if ($this->element['onchange'])
{
$attributes['onchange'] = (string) $this->element['onchange'];
}
// If a known filter is given use it.
if ($filter == 'SERVER_UTC')
{
// Use the server timezone.
$timezone = JFactory::getConfig()->get('offset');
}
elseif ($filter == 'USER_UTC')
{
// Use the user timezone.
$timezone = JFactory::getUser()->getParam('timezone', JFactory::getConfig()->get('offset'));
}
else
{
// Use the default timezone
$timezone = date_default_timezone_get();
}
// If the value is an instance of JDate, use it
if ($this->value instanceof JDate)
{
$time = $this->value->format('U', true, false);
}
// Else if it is now, use current time
elseif (strtoupper($this->value) == 'NOW')
{
$time = time();
}
// Else if it's not a null value, use that time
elseif (intval($this->value))
{
$time = JFactory::getDate($this->value)->format('U', true, false);
}
else
{
$value = $this->value;
}
if (isset($time))
{
// Get the old timezone
$old_time_zone = date_default_timezone_get();
// Set the timezone
date_default_timezone_set($timezone);
// Get the value
$value = strftime($format, $time);
// Set the old timezone
date_default_timezone_set($old_time_zone);
}
return JHtml::_('calendar', $value, $this->name, $this->id, $format, $attributes);
}
}
<?php
/**
* @package Joomla.UnitTest
* @subpackage Form
*
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
/**
* Test class for JForm.
*
* @package Joomla.UnitTest
* @subpackage Form
*/
class JFormFieldCalendarTest extends JoomlaTestCase
{
/**
* Sets up dependancies for the test.
*/
protected function setUp()
{
require_once JPATH_PLATFORM.'/joomla/form/fields/calendar.php';
require_once JPATH_PLATFORM.'/joomla/utilities/date.php';
include_once dirname(__DIR__).'/inspectors.php';
$this->saveFactoryState();
}
protected function tearDown()
{
$this->restoreFactoryState();
}
public function attributeData()
{
return array(
/*
* Test normal parameters
*/
'normal' => array(
'myCalendarElement',
'myCalendarId',
'myValue',
array(
'format' => '%m-%Y-%d',
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
'filter' => ''
),
array(
'myValue',
'myCalendarElement',
'myCalendarId',
'%m-%Y-%d',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly',
)
)
),
/*
* Non integer size
*/
'nonintsize' => array(
'myCalendarElement',
'myCalendarId',
'myValue',
array(
'format' => '%m-%Y-%d',
'size' => '25est',
'maxlength' => 'forty five',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
'filter' => ''
),
array(
'myValue',
'myCalendarElement',
'myCalendarId',
'%m-%Y-%d',
array(
'size' => '25',
'maxlength' => '0',
'class' => 'myClass',
'readonly' => 'readonly',
)
)
),
/*
* No format provided
*/
'noformat' => array(
'myCalendarElement',
'myCalendarId',
'myValue',
array(
'format' => '',
'size' => '25est',
'maxlength' => 'forty five',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
'filter' => ''
),
array(
'myValue',
'myCalendarElement',
'myCalendarId',
'%Y-%m-%d',
array(
'size' => '25',
'maxlength' => '0',
'class' => 'myClass',
'readonly' => 'readonly',
)
)
),
/*
* With an onchange value
*/
'onchange' => array(
'myCalendarElement',
'myCalendarId',
'myValue',
array(
'format' => '',
'size' => '25est',
'maxlength' => 'forty five',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => 'This is my onchange value',
'filter' => ''
),
array(
'myValue',
'myCalendarElement',
'myCalendarId',
'%Y-%m-%d',
array(
'size' => '25',
'maxlength' => '0',
'class' => 'myClass',
'onchange' => 'This is my onchange value',
'readonly' => 'readonly',
)
)
),
/*
* With bad readonly value
*/
'bad_readonly' => array(
'myCalendarElement',
'myCalendarId',
'myValue',
array(
'format' => '',
'size' => '25est',
'maxlength' => 'forty five',
'class' => 'myClass',
'readonly' => '1',
'disabled' => 'false',
'onchange' => 'This is my onchange value',
'filter' => ''
),
array(
'myValue',
'myCalendarElement',
'myCalendarId',
'%Y-%m-%d',
array(
'size' => '25',
'maxlength' => '0',
'class' => 'myClass',
'onchange' => 'This is my onchange value',
)
)
),
/*
* disabled is true, no class
*/
'disabled_no_class' => array(
'myCalendarElement',
'myCalendarId',
'myValue',
array(
'format' => '',
'size' => '25est',
'maxlength' => 'forty five',
'class' => '',
'readonly' => '1',
'disabled' => 'true',
'onchange' => 'This is my onchange value',
'filter' => ''
),
array(
'myValue',
'myCalendarElement',
'myCalendarId',
'%Y-%m-%d',
array(
'size' => '25',
'maxlength' => '0',
'disabled' => 'disabled',
'onchange' => 'This is my onchange value',
)
)
),
/*
* value = 'NOW'
*/
'value_is_now' => array(
'myCalendarElement',
'myCalendarId',
'NOW',
array(
'format' => '',
'size' => '25est',
'maxlength' => 'forty five',
'class' => '',
'readonly' => '1',
'disabled' => 'true',
'onchange' => 'This is my onchange value',
'filter' => ''
),
array(
'strftime(\'%Y-%m-%d\')',
'myCalendarElement',
'myCalendarId',
'%Y-%m-%d',
array(
'size' => '25',
'maxlength' => '0',
'disabled' => 'disabled',
'onchange' => 'This is my onchange value',
)
)
)
);
}
/**
* Tests various attribute methods - this method does not handle filters
* @dataProvider attributeData
*/
public function testGetInputAttributes($name, $id, $value, $element, $expectedParameters)
{
// we create stubs for config and session/user objects
$config = new stdClass;
JFactory::$config = $config; // put the stub in place
$sessionMock = $this->getMock('sessionMock', array('get'));
require_once JPATH_PLATFORM.'/joomla/user/user.php';
$userObject = new JUser;
JFactory::$session = $sessionMock; // put the stub in place
// include our inspector which will allow us to manipulate and call protected methods and attributes
require_once __DIR__.'/inspectors/JFormFieldCalendar.php';
$calendar = new JFormFieldCalendarInspector;
if ($expectedParameters[0] == 'strftime(\'%Y-%m-%d\')') {
date_default_timezone_set('UTC');
$expectedParameters[0] = strftime('%Y-%m-%d');
}
// setup our values from our data set
$calendar->setProtectedProperty('element', $element);
$calendar->setProtectedProperty('name', $name);
$calendar->setProtectedProperty('id', $id);
$calendar->setProtectedProperty('value', $value);
// create the mock to implant into JHtml so that we can check our values
$mock = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock->expects($this->once())
->method('calendar')
->with($expectedParameters[0], $expectedParameters[1], $expectedParameters[2], $expectedParameters[3], $expectedParameters[4]);
JHtml::register('calendar', array($mock, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
}
public function testGetInputServer_UTC()
{
// we create stubs for config and session/user objects
$config = new JObject;
JFactory::$config = $config; // put the stub in place
$sessionMock = $this->getMock('sessionMock', array('get'));
require_once JPATH_PLATFORM.'/joomla/user/user.php';
$userObject = new JUser;
JFactory::$session = $sessionMock; // put the stub in place
$languageMock = $this->getMock('languageMock', array('getTag'));
$languageMock->expects($this->any())
->method('getTag')
->will($this->returnValue('en-GB'));
JFactory::$language = $languageMock; // put the stub in place
// include our inspector which will allow us to manipulate and call protected methods and attributes
require_once __DIR__.'/inspectors/JFormFieldCalendar.php';
$calendar = new JFormFieldCalendarInspector;
// setup our values from our data set
$calendar->setProtectedProperty('element',
array(
'format' => '%m-%Y-%d %H:%M:%S',
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
'filter' => 'SERVER_UTC'
)
);
$calendar->setProtectedProperty('name', 'myElementName');
$calendar->setProtectedProperty('id', 'myElementId');
$calendar->setProtectedProperty('value', 1269442718); // 2010-03-24 14:58:38
$config->set('offset', 'US/Eastern'); // -5
$userObject->setParam('timezone', 'America/Buenos_Aires'); // -3
// create the mock to implant into JHtml so that we can check our values
$mock = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock->expects($this->once())
->method('calendar')
->with('03-2010-24 10:58:38', 'myElementName', 'myElementId', '%m-%Y-%d %H:%M:%S',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly'
)
);
JHtml::register('calendar', array($mock, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
}
public function testGetInputUser_UTC()
{
// we create stubs for config and session/user objects
$config = new JObject;
JFactory::$config = $config; // put the stub in place
$sessionMock = $this->getMock('sessionMock', array('get'));
require_once JPATH_PLATFORM.'/joomla/user/user.php';
$userObject = new JUser;
$sessionMock->expects($this->any())
->method('get')
->with('user')
->will($this->returnValue($userObject));
JFactory::$session = $sessionMock; // put the stub in place
$languageMock = $this->getMock('languageMock', array('getTag'));
$languageMock->expects($this->any())
->method('getTag')
->will($this->returnValue('en-GB'));
JFactory::$language = $languageMock; // put the stub in place
// include our inspector which will allow us to manipulate and call protected methods and attributes
require_once __DIR__.'/inspectors/JFormFieldCalendar.php';
$calendar = new JFormFieldCalendarInspector;
// setup our values from our data set
$calendar->setProtectedProperty('element',
array(
'format' => '%m-%Y-%d %H:%M:%S',
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
'filter' => 'USER_UTC'
)
);
$calendar->setProtectedProperty('name', 'myElementName');
$calendar->setProtectedProperty('id', 'myElementId');
$calendar->setProtectedProperty('value', new JDate('2012-01-01 12:34:56'));
$config->set('offset', 'Asia/Muscat'); // +4
// we don't set the user param to see if it properly falls back to the server time (as it should)
// create the mock to implant into JHtml so that we can check our values
$mock = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock->expects($this->once())
->method('calendar')
->with('01-2012-01 16:34:56', 'myElementName', 'myElementId', '%m-%Y-%d %H:%M:%S',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly'
)
);
JHtml::register('calendar', array($mock, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
// create the mock to implant into JHtml so that we can check our values
$mock2 = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock2->expects($this->once())
->method('calendar')
->with('01-2012-01 16:34:56', 'myElementName', 'myElementId', '%m-%Y-%d %H:%M:%S',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly'
)
);
$config->set('offset', 'US/Eastern'); // -5
$userObject->setParam('timezone', 'Asia/Muscat'); // +4 // now we set the user param to test it out.
JHtml::register('calendar', array($mock2, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
$calendar->setProtectedProperty('value', '');
// create the mock to implant into JHtml so that we can check our values
$mock3 = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock3->expects($this->once())
->method('calendar')
->with('', 'myElementName', 'myElementId', '%m-%Y-%d %H:%M:%S',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly'
)
);
JHtml::register('calendar', array($mock3, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
$calendar->setProtectedProperty('element',
array(
'format' => '%m-%Y-%d',
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
'filter' => 'USER_UTC'
)
);
$calendar->setProtectedProperty('value', 'now');
// create the mock to implant into JHtml so that we can check our values
$mock4 = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock4->expects($this->once())
->method('calendar')
->with(strftime('%m-%Y-%d'), 'myElementName', 'myElementId', '%m-%Y-%d',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly'
)
);
JHtml::register('calendar', array($mock4, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
}
public function testGetInputJDate()
{
// we create stubs for config and session/user objects
$config = new JObject;
JFactory::$config = $config; // put the stub in place
$sessionMock = $this->getMock('sessionMock', array('get'));
JFactory::$session = $sessionMock; // put the stub in place
// we create stubs for config and session/user objects
$languageMock = $this->getMock('languageMock', array('getTag'));
$languageMock->expects($this->any())
->method('getTag')
->will($this->returnValue('en-GB'));
JFactory::$language = $languageMock; // put the stub in place
// include our inspector which will allow us to manipulate and call protected methods and attributes
require_once __DIR__.'/inspectors/JFormFieldCalendar.php';
$calendar = new JFormFieldCalendarInspector;
// setup our values from our data set
$calendar->setProtectedProperty('element',
array(
'format' => '%m-%Y-%d',
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'true',
'disabled' => 'false',
'onchange' => '',
)
);
$calendar->setProtectedProperty('name', 'myElementName');
$calendar->setProtectedProperty('id', 'myElementId');
$calendar->setProtectedProperty('value', new JDate('2012-01-01 12:34:56')); // 1269442718
// we don't set the user param to see if it properly falls back to the server time (as it should)
// create the mock to implant into JHtml so that we can check our values
$mock = $this->getMock('calendarHandler', array('calendar'));
// setup the expectation with the values from the dataset
$mock->expects($this->once())
->method('calendar')
->with('01-2012-01', 'myElementName', 'myElementId', '%m-%Y-%d',
array(
'size' => '25',
'maxlength' => '45',
'class' => 'myClass',
'readonly' => 'readonly'
)
);
JHtml::register('calendar', array($mock, 'calendar')); // register our mock with JHtml
$calendar->getInput(); // invoke our method
JHtml::unregister('jhtml..calendar'); // unregister the mock
}
/**
* Test the getInput method.
*/
public function testGetInput()
{
$applicationMock = $this->getMock('applicationMock', array('getTemplate'));
JFactory::$application = $applicationMock; // put the stub in place
$applicationMock->expects($this->any())
->method('getTemplate')
->will($this->returnValue('system'));
$form = new JFormInspector('form1');
$this->assertThat(
$form->load('<form><field name="calendar" type="calendar" /></form>'),
$this->isTrue(),
'Line:'.__LINE__.' XML string should load successfully.'
);
$field = new JFormFieldCalendar($form);
$this->assertThat(
$field->setup($form->getXml()->field, 'value'),
$this->isTrue(),
'Line:'.__LINE__.' The setup method should return true.'
);
$this->assertThat(
strlen($field->input),
$this->greaterThan(0),
'Line:'.__LINE__.' The getInput method should return something without error.'
);
// TODO: Should check all the attributes have come in properly.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment