Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/core#2846 Towards validation of start and end dates. Forms. #21513

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions CRM/Campaign/Form/Campaign.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,22 +249,27 @@ public function buildQuickForm() {
];

$this->addButtons($buttons);

$this->addFormRule(['CRM_Campaign_Form_Campaign', 'formRule']);
}

/**
* add the rules (mainly global rules) for form.
* All local rules are added near the element
*
* @param $fields
* @param $files
* @param $errors
*
* @return bool|array
* @see valid_date
*/
public static function formRule($fields, $files, $errors) {
public static function formRule($fields) {
$errors = [];

// Validate start/end date inputs
$validateDates = \CRM_Utils_Date::validateStartEndDatepickerInputs('start_date', $fields['start_date'], 'end_date', $fields['end_date']);
if ($validateDates !== TRUE) {
$errors[$validateDates['key']] = $validateDates['message'];
}

return empty($errors) ? TRUE : $errors;
}

Expand Down
9 changes: 4 additions & 5 deletions CRM/Contribute/Form/ContributionPage/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,10 @@ public static function formRule($values, $files, $self) {
}
}

//CRM-11494
$start = CRM_Utils_Date::processDate($values['start_date']);
$end = CRM_Utils_Date::processDate($values['end_date']);
if (($end < $start) && ($end != 0)) {
$errors['end_date'] = ts('End date should be after Start date.');
// Validate start/end date inputs
$validateDates = \CRM_Utils_Date::validateStartEndDatepickerInputs('start_date', $values['start_date'], 'end_date', $values['end_date']);
if ($validateDates !== TRUE) {
$errors[$validateDates['key']] = $validateDates['message'];
}

if (!empty($self->_values['payment_processor']) && $financialType = CRM_Contribute_BAO_Contribution::validateFinancialType($values['financial_type_id'])) {
Expand Down
6 changes: 4 additions & 2 deletions CRM/Event/Form/ManageEvent/EventInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ public function buildQuickForm() {
public static function formRule($values) {
$errors = [];

if (!empty($values['end_date']) && ($values['end_date'] < $values['start_date'])) {
$errors['end_date'] = ts('End date should be after Start date.');
// Validate start/end date inputs
$validateDates = \CRM_Utils_Date::validateStartEndDatepickerInputs('start_date', $values['start_date'], 'end_date', $values['end_date']);
if ($validateDates !== TRUE) {
$errors[$validateDates['key']] = $validateDates['message'];
}

//CRM-4286
Expand Down
8 changes: 4 additions & 4 deletions CRM/Event/Form/ManageEvent/Registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -460,10 +460,10 @@ public static function formRule($values, $files, $form) {
}
}

if (isset($values['registration_start_date']) && isset($values['registration_end_date'])) {
if ($values['registration_end_date'] < $values['registration_start_date']) {
$errorMsg['registration_end_date'] = ts('Registration end date should be after Registration start date');
}
// Validate start/end date inputs
$validateDates = \CRM_Utils_Date::validateStartEndDatepickerInputs('registration_start_date', $values['registration_start_date'], 'registration_end_date', $values['registration_end_date']);
if ($validateDates !== TRUE) {
$errorMsg[$validateDates['key']] = $validateDates['message'];
}

//check that the selected profiles have either firstname+lastname or email required
Expand Down
6 changes: 6 additions & 0 deletions CRM/Price/Form/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,12 @@ public static function formRule($fields, $files, $form) {
$errors['count'] = ts('Participant Count must be greater than zero.');
}

// Validate start/end date inputs
$validateDates = \CRM_Utils_Date::validateStartEndDatepickerInputs('active_on', $fields['active_on'], 'expire_on', $fields['expire_on']);
if ($validateDates !== TRUE) {
$errors[$validateDates['key']] = $validateDates['message'];
}

if ($form->_action & CRM_Core_Action::ADD) {
if ($fields['html_type'] != 'Text') {
$countemptyrows = 0;
Expand Down
53 changes: 53 additions & 0 deletions CRM/Utils/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -2223,4 +2223,57 @@ public static function convertDateToLocalTime($dateObject, $format = 'YmdHis') {
return $dateObject->format($format);
}

/**
* Check if the value returned by a date picker has a date section (ie: includes
* a '-' character) if it includes a time section (ie: includes a ':').
*
* @param string $value
* A date/time string input from a datepicker value.
*
* @return bool
* TRUE if valid, FALSE if there is a time without a date.
*/
public static function datePickerValueWithTimeHasDate($value) {
// If there's no : (time) or a : and a - (date) then return true
return (
strpos($value, ':') === FALSE
|| strpos($value, ':') !== FALSE && strpos($value, '-') !== FALSE
);
}

/**
* Validate start and end dates entered on a form to make sure they are
* logical. Expects the form keys to be start_date and end_date.
*
* @param string $startFormKey
* The form element key of the 'start date'
* @param string $startValue
* The value of the 'start date'
* @param string $endFormKey
* The form element key of the 'end date'
* @param string $endValue
* The value of the 'end date'
*
* @return array|bool
* TRUE if valid, an array of the erroneous form key, and error message to
* use otherwise.
*/
public static function validateStartEndDatepickerInputs($startFormKey, $startValue, $endFormKey, $endValue) {

// Check date as well as time is set
if (!empty($startValue) && !self::datePickerValueWithTimeHasDate($startValue)) {
return ['key' => $startFormKey, 'message' => ts('Please enter a date as well as a time.')];
}
if (!empty($endValue) && !self::datePickerValueWithTimeHasDate($endValue)) {
return ['key' => $endFormKey, 'message' => ts('Please enter a date as well as a time.')];
}

// Check end date is after start date
if (!empty($startValue) && !empty($endValue) && $endValue < $startValue) {
return ['key' => $endFormKey, 'message' => ts('The end date should be after the start date.')];
}

return TRUE;
}

}
76 changes: 50 additions & 26 deletions tests/phpunit/CRM/Campaign/Form/CampaignTest.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

/**
* Test APIv3 civicrm_contribute_* functions
*
* @package CiviCRM_APIv3
* @subpackage API_Contribution
* @group headless
*/
class CRM_Campaign_Form_CampaignTest extends CiviUnitTestCase {

/**
* Test the submit function on the contribution page.
* Set up a correct array of form values.
*
* @return array
*/
private function getCorrectFormFields($thousandSeparator) {
return [
'goal_revenue' => '$10' . $thousandSeparator . '000',
'is_active' => 1,
'title' => 'Test Campaign',
'start_date' => date('Y-m-d'),
'includeGroups' => [],
'custom' => [],
'campaign_type_id' => 1,
];
}

/**
* Test the submit function on the campaign page.
*
* @param string $thousandSeparator
*
Expand All @@ -30,17 +31,40 @@ public function testSubmit($thousandSeparator) {
$this->createLoggedInUser();
$form = new CRM_Campaign_Form_Campaign();
$form->_action = CRM_Core_Action::ADD;
$result = CRM_Campaign_Form_Campaign::Submit([
'goal_revenue' => '$10' . $thousandSeparator . '000',
'is_active' => 1,
'title' => 'Test Campaign',
'start_date' => date('Y-m-d'),
'includeGroups' => [],
'custom' => [],
'campaign_type_id' => 1,
], $form);
$values = $this->getCorrectFormFields($thousandSeparator);
$result = CRM_Campaign_Form_Campaign::Submit($values, $form);
$campaign = $this->callAPISuccess('campaign', 'get', ['id' => $result['id']]);
$this->assertEquals('10000.00', $campaign['values'][$campaign['id']]['goal_revenue']);
}

/**
* Test end date not allowed with only 'time' part.
*
* @param string $thousandSeparator
*
* @dataProvider getThousandSeparators
*/
public function testEndDateWithoutDateNotAllowed($thousandSeparator) {
$this->setCurrencySeparators($thousandSeparator);
$values = $this->getCorrectFormFields($thousandSeparator);
$values['end_date'] = '00:01';
$validationResult = \CRM_Campaign_Form_Campaign::formRule($values);
$this->assertArrayHasKey('end_date', $validationResult);
}

/**
* Test end date must be after start date.
*
* @param string $thousandSeparator
*
* @dataProvider getThousandSeparators
*/
public function testEndDateBeforeStartDateNotAllowed($thousandSeparator) {
$this->setCurrencySeparators($thousandSeparator);
$values = $this->getCorrectFormFields($thousandSeparator);
$values['end_date'] = '1900-01-01 00:00';
$validationResult = \CRM_Campaign_Form_Campaign::formRule($values);
$this->assertArrayHasKey('end_date', $validationResult);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

class CRM_Contribute_Form_ContributionPage_SettingsTest extends CiviUnitTestCase {

/**
* Set up a correct array of form values.
*
* @return array
*/
private function getCorrectFormFields() {
return [
'title' => 'Test contribution page',
'financial_type_id' => 1,
'start_date' => date('Y-m-d'),
'end_date' => date('Y-m-d', time() + 86400),
];
}

/**
* Test correct form submission.
*/
public function testValidFormSubmission() {
$values = $this->getCorrectFormFields();
$form = new CRM_Contribute_Form_ContributionPage_Settings();
$validationResult = \CRM_Contribute_Form_ContributionPage_Settings::formRule($values, [], $form);
$this->assertEmpty($validationResult);
}

/**
* Test end date not allowed with only 'time' part.
*/
public function testEndDateWithoutDateNotAllowed() {
$values = $this->getCorrectFormFields();
$values['end_date'] = '00:01';
$form = new CRM_Contribute_Form_ContributionPage_Settings();
$validationResult = \CRM_Contribute_Form_ContributionPage_Settings::formRule($values, [], $form);
$this->assertArrayHasKey('end_date', $validationResult);
}

/**
* Test end date must be after start date.
*/
public function testEndDateBeforeStartDateNotAllowed() {
$values = $this->getCorrectFormFields();
$values['end_date'] = '1900-01-01 00:00';
$form = new CRM_Contribute_Form_ContributionPage_Settings();
$validationResult = \CRM_Contribute_Form_ContributionPage_Settings::formRule($values, [], $form);
$this->assertArrayHasKey('end_date', $validationResult);
}

}
49 changes: 49 additions & 0 deletions tests/phpunit/CRM/Event/Form/ManageEvent/EventInfoTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

class CRM_Event_Form_ManageEvent_EventInfoTest extends CiviUnitTestCase {

/**
* Set up a correct array of form values.
*
* @return array
*/
private function getCorrectFormFields() {
return [
'title' => 'A test event',
'event_type_id' => 1,
'default_role_id' => 1,
'start_date' => date('Y-m-d'),
'end_date' => date('Y-m-d', time() + 86400),
];
}

/**
* Test correct form submission.
*/
public function testValidFormSubmission() {
$values = $this->getCorrectFormFields();
$validationResult = \CRM_Event_Form_ManageEvent_EventInfo::formRule($values);
$this->assertEmpty($validationResult);
}

/**
* Test end date not allowed with only 'time' part.
*/
public function testEndDateWithoutDateNotAllowed() {
$values = $this->getCorrectFormFields();
$values['end_date'] = '00:01';
$validationResult = \CRM_Event_Form_ManageEvent_EventInfo::formRule($values);
$this->assertArrayHasKey('end_date', $validationResult);
}

/**
* Test end date must be after start date.
*/
public function testEndDateBeforeStartDateNotAllowed() {
$values = $this->getCorrectFormFields();
$values['end_date'] = '1900-01-01 00:00';
$validationResult = \CRM_Event_Form_ManageEvent_EventInfo::formRule($values);
$this->assertArrayHasKey('end_date', $validationResult);
}

}
44 changes: 44 additions & 0 deletions tests/phpunit/CRM/Event/Form/ManageEvent/RegistrationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

class CRM_Event_Form_ManageEvent_RegistrationTest extends CiviUnitTestCase {

/**
* Set up a correct array of form values.
* @todo More fields are required for formRule to return no errors
*
* @return array
*/
private function getCorrectFormFields() {
return [
'is_online_registration' => 1,
'registration_start_date' => date('Y-m-d'),
'registration_end_date' => date('Y-m-d', time() + 86400),
'is_email_confirm' => 0,
'confirm_title' => 'Confirm your registration',
'thankyou_title' => 'Thank you for your registration',
];
}

/**
* Test end date not allowed with only 'time' part.
*/
public function testEndDateWithoutDateNotAllowed() {
$values = $this->getCorrectFormFields();
$values['registration_end_date'] = '00:01';
$form = new CRM_Event_Form_ManageEvent_Registration();
$validationResult = \CRM_Event_Form_ManageEvent_Registration::formRule($values, [], $form);
$this->assertArrayHasKey('registration_end_date', $validationResult);
}

/**
* Test end date must be after start date.
*/
public function testEndDateBeforeStartDateNotAllowed() {
$values = $this->getCorrectFormFields();
$values['registration_end_date'] = '1900-01-01 00:00';
$form = new CRM_Event_Form_ManageEvent_Registration();
$validationResult = \CRM_Event_Form_ManageEvent_Registration::formRule($values, [], $form);
$this->assertArrayHasKey('registration_end_date', $validationResult);
}

}
Loading