/** * @param String $password * @param Member $member * @return ValidationResult */ public function validate($password, $member) { $valid = new ValidationResult(); if ($this->minLength) { if (strlen($password) < $this->minLength) { $valid->error(sprintf("Password is too short, it must be %s or more characters long.", $this->minLength), "TOO_SHORT"); } } if ($this->minScore) { $score = 0; $missedTests = array(); foreach ($this->testNames as $name) { if (preg_match(self::$character_strength_tests[$name], $password)) { $score++; } else { $missedTests[] = $name; } } if ($score < $this->minScore) { $valid->error("You need to increase the strength of your passwords by adding some of the following characters: " . implode(", ", $missedTests), "LOW_CHARACTER_STRENGTH"); } } if ($this->historicalPasswordCount) { $previousPasswords = DataObject::get("MemberPassword", "\"MemberID\" = {$member->ID}", "\"Created\" DESC, \"ID\" Desc", "", $this->historicalPasswordCount); if ($previousPasswords) { foreach ($previousPasswords as $previousPasswords) { if ($previousPasswords->checkPassword($password)) { $valid->error("You've already used that password in the past, please choose a new password", "PREVIOUS_PASSWORD"); break; } } } } return $valid; }
/** * Create member account from data array. * Data must contain unique identifier. * * @throws ValidationException * @param $data - map of member data * @return Member|boolean - new member (not saved to db), or false if there is an error. */ public function create($data) { $result = new ValidationResult(); if (!Checkout::member_creation_enabled()) { $result->error(_t("Checkout.MEMBERSHIPSNOTALLOWED", "Creating new memberships is not allowed")); throw new ValidationException($result); } $idfield = Config::inst()->get('Member', 'unique_identifier_field'); if (!isset($data[$idfield]) || empty($data[$idfield])) { $result->error(sprintf(_t("Checkout.IDFIELDNOTFOUND", "Required field not found: %s"), $idfield)); throw new ValidationException($result); } if (!isset($data['Password']) || empty($data['Password'])) { $result->error(_t("Checkout.PASSWORDREQUIRED", "A password is required")); throw new ValidationException($result); } $idval = $data[$idfield]; if (ShopMember::get_by_identifier($idval)) { $result->error(sprintf(_t("Checkout.MEMBEREXISTS", "A member already exists with the %s %s"), _t("Member." . $idfield, $idfield), $idval)); throw new ValidationException($result); } $member = new Member(Convert::raw2sql($data)); $validation = $member->validate(); if (!$validation->valid()) { //TODO need to handle i18n here? $result->error($validation->message()); } if (!$result->valid()) { throw new ValidationException($result); } return $member; }
/** * @param String $password * @param Member $member * @return ValidationResult */ public function validate($password, $member) { $valid = new ValidationResult(); if ($this->minLength) { if (strlen($password) < $this->minLength) { $valid->error(sprintf(_t('PasswordValidator.TOOSHORT', 'Password is too short, it must be %s or more characters long'), $this->minLength), 'TOO_SHORT'); } } if ($this->minScore) { $score = 0; $missedTests = array(); foreach ($this->testNames as $name) { if (preg_match(self::config()->character_strength_tests[$name], $password)) { $score++; } else { $missedTests[] = _t('PasswordValidator.STRENGTHTEST' . strtoupper($name), $name, 'The user needs to add this to their password for more complexity'); } } if ($score < $this->minScore) { $valid->error(sprintf(_t('PasswordValidator.LOWCHARSTRENGTH', 'Please increase password strength by adding some of the following characters: %s'), implode(', ', $missedTests)), 'LOW_CHARACTER_STRENGTH'); } } if ($this->historicalPasswordCount) { $previousPasswords = DataObject::get("MemberPassword", "\"MemberID\" = {$member->ID}", "\"Created\" DESC, \"ID\" DESC", "", $this->historicalPasswordCount); if ($previousPasswords) { foreach ($previousPasswords as $previousPasswords) { if ($previousPasswords->checkPassword($password)) { $valid->error(_t('PasswordValidator.PREVPASSWORD', 'You\'ve already used that password in the past, please choose a new password'), 'PREVIOUS_PASSWORD'); break; } } } } return $valid; }
public function validate(ValidationResult $validationResult) { $mailblockRecipients = $this->owner->getField('MailblockRecipients'); if (!$this->validateEmailAddresses($mailblockRecipients)) { $validationResult->error(_t('Mailblock.RecipientError', 'There are invalid email addresses in the Recipient(s) field.')); } $whitelist = $this->owner->getField('MailblockWhitelist'); if (!$this->validateEmailAddresses($whitelist)) { $validationResult->error(_t('Mailblock.WhitelistError', 'There are invalid email addresses in the Whitelist field.')); } }
public function validateData(Order $order, array $data) { $result = new ValidationResult(); if (!isset($data['ShippingMethodID'])) { $result->error(_t('ShippingCheckoutComponent.ShippingMethodNotProvidedMessage', "Shipping method not provided"), _t('ShippingCheckoutComponent.ShippingMethodErrorCode', "ShippingMethod")); throw new ValidationException($result); } if (!ShippingMethod::get()->byID($data['ShippingMethodID'])) { $result->error(_t('ShippingCheckoutComponent.ShippingMethodDoesNotExistMessage', "Shipping Method does not exist"), _t('ShippingCheckoutComponent.ShippingMethodErrorCode', "ShippingMethod")); throw new ValidationException($result); } }
/** * Check if the user has verified their email address. * * @param ValidationResult $result * @return ValidationResult */ function canLogIn(&$result) { if (!Permission::check('ADMIN')) { if (!$this->owner->Verified) { $result->error(_t('EmailVerifiedMember.ERRORNOTEMAILVERIFIED', 'Please verify your email address before login.')); } if (!$this->owner->Moderated && $this->owner->requiresModeration()) { $result->error(_t('EmailVerifiedMember.ERRORNOTMODERATED', 'A moderator needs to approve your account before you can log in.')); } } return $result; }
public function validateData(Order $order, array $data) { $result = new ValidationResult(); if (!isset($data['PaymentMethod'])) { $result->error("Payment method not provided", "PaymentMethod"); throw new ValidationException($result); } $methods = GatewayInfo::get_supported_gateways(); if (!isset($methods[$data['PaymentMethod']])) { $result->error("Gateway not supported", "PaymentMethod"); throw new ValidationException($result); } }
public function validate(ValidationResult $valid) { if (!$valid->valid()) { return $valid; } if (empty($this->owner->Title)) { return $valid->error('Title is empty!'); } if (intval($this->owner->ReleaseID) === 0) { return $valid->error('You must select a release'); } if (intval($this->owner->CuratorID) === 0) { return $valid->error('You must select a Curator'); } return $valid; }
/** * Validate the owner object - check for existence of infinite loops. */ function validate(ValidationResult $validationResult) { if (!$this->owner->ID) { return; } // The object is new, won't be looping. if (!$this->owner->ParentID) { return; } // The object has no parent, won't be looping. if (!$this->owner->isChanged('ParentID')) { return; } // The parent has not changed, skip the check for performance reasons. // Walk the hierarchy upwards until we reach the top, or until we reach the originating node again. $node = $this->owner; while ($node) { if ($node->ParentID == $this->owner->ID) { // Hierarchy is looping. $validationResult->error(_t('Hierarchy.InfiniteLoopNotAllowed', 'Infinite loop found within the "{type}" hierarchy. Please change the parent to resolve this', 'First argument is the class that makes up the hierarchy.', array('type' => $this->owner->class)), 'INFINITE_LOOP'); break; } $node = $node->ParentID ? $node->Parent() : null; } // At this point the $validationResult contains the response. }
public function validate() { $result = new ValidationResult(); if (!$this->Title || !$this->Currency || !$this->Rate) { $result->error('Please fill in all fields', 'ExchangeRateInvalidError'); } return $result; }
public function validate() { $result = new ValidationResult(); if (!$this->Title || !$this->Currency || !$this->Rate) { $result->error('Rate is missing a required field', 'ExchangeRateInvalidError'); } return $result; }
public function validate(\ValidationResult $validationResult) { $constraints = $this->getConstraints(); foreach ($constraints as $constraint) { if (!$constraint->holds()) { $validationResult->error($constraint->message()); } } }
public function validateData(Order $order, array $data) { $result = new ValidationResult(); //TODO: validate credit card data if (!Helper::validateLuhn($data['number'])) { $result->error('Credit card is invalid'); throw new ValidationException($result); } }
public function validateData(Order $order, array $data) { $result = new ValidationResult(); $code = $data['Code']; if ($this->validwhenblank && !$code) { return $result; } //check the coupon exists, and can be used if ($coupon = OrderCoupon::get_by_code($code)) { if (!$coupon->validateOrder($order, array("CouponCode" => $code))) { $result->error($coupon->getMessage(), "Code"); throw new ValidationException($result); } } else { $result->error(_t("OrderCouponModifier.NOTFOUND", "Coupon could not be found"), "Code"); throw new ValidationException($result); } return $result; }
/** * Check if the user has verified their email address. * * @param ValidationResult $result * @return ValidationResult */ public function canLogIn(&$result) { if (!$this->owner->Verified) { // Don't require administrators to be verified if (Permission::checkMember($this->owner, 'ADMIN')) { return $result; } $result->error(_t('MemberEmailVerification.ERROREMAILNOTVERIFIED', 'Sorry, you need to verify your email address before you can log in.')); } return $result; }
/** * Confirm that the tag has been given a title and doesn't already exist. */ public function validate(ValidationResult $result) { // Determine the field to use, based on the configuration defined tag types. $validate = 'Title'; $class = $this->owner->ClassName; foreach (Config::inst()->get('FusionService', 'custom_tag_types') as $type => $field) { if ($type === $class) { $validate = $field; } } // Confirm that the tag has been given a title and doesn't already exist. if ($result->valid() && !$this->owner->{$validate}) { $result->error("\"{$validate}\" required!"); } else { if ($result->valid() && $class::get_one($class, array('ID != ?' => $this->owner->ID, "LOWER({$validate}) = ?" => strtolower($this->owner->{$validate})))) { $result->error('Tag already exists!'); } } // Allow extension. $this->owner->extend('validateFusionExtension', $result); return $result; }
public function validateData(Order $order, array $data) { if (Member::currentUserID()) { return; } $result = new ValidationResult(); if (Checkout::membership_required() || !empty($data['Password'])) { $member = new Member($data); $idfield = Member::config()->unique_identifier_field; $idval = $data[$idfield]; if (ShopMember::get_by_identifier($idval)) { $result->error(sprintf(_t("Checkout.MEMBEREXISTS", "A member already exists with the %s %s"), $idfield, $idval), $idval); } $passwordresult = $this->passwordvalidator->validate($data['Password'], $member); if (!$passwordresult->valid()) { $result->error($passwordresult->message(), "Password"); } } if (!$result->valid()) { throw new ValidationException($result); } }
/** * @param Order $order * @param array $data * @throws ValidationException */ public function validateData(Order $order, array $data) { $result = new ValidationResult(); $existingID = !empty($data[$this->addresstype . "AddressID"]) ? (int) $data[$this->addresstype . "AddressID"] : 0; if ($existingID) { // If existing address selected, check that it exists in $member->AddressBook if (!Member::currentUserID() || !Member::currentUser()->AddressBook()->byID($existingID)) { $result->error("Invalid address supplied", $this->addresstype . "AddressID"); throw new ValidationException($result); } } else { // Otherwise, require the normal address fields $required = parent::getRequiredFields($order); foreach ($required as $fieldName) { if (empty($data[$fieldName])) { $errorMessage = _t('Form.FIELDISREQUIRED', '{name} is required', array('name' => $fieldName)); $result->error($errorMessage, $fieldName); throw new ValidationException($result); } } } }
/** * Test combining validation results together */ public function testCombineResults() { $result = new ValidationResult(); $anotherresult = new ValidationResult(); $yetanotherresult = new ValidationResult(); $anotherresult->error("Eat with your mouth closed", "EATING101"); $yetanotherresult->error("You didn't wash your hands", "BECLEAN"); $this->assertTrue($result->valid()); $this->assertFalse($anotherresult->valid()); $this->assertFalse($yetanotherresult->valid()); $result->combineAnd($anotherresult)->combineAnd($yetanotherresult); $this->assertFalse($result->valid()); $this->assertEquals(array("EATING101" => "Eat with your mouth closed", "BECLEAN" => "You didn't wash your hands"), $result->messageList()); }
/** * Validate credit card number using Luhn algorithm * * @see CreditCard::validationResult */ public function validateCardNumber() { if (strlen($this->number) < 12) { $this->validationResult->error('Card number length is invalid'); } // Luhn algorithm to check the validity of the card number $map = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 1, 3, 5, 7, 9); $sum = 0; $last = strlen($this->number) - 1; for ($i = 0; $i <= $last; $i++) { $sum += $map[$this->number[$last - $i] + ($i & 1) * 10]; } if (!($sum % 10 == 0)) { $this->validationResult->error('Card number is invalid'); } }
/** * Returns a valid {@link ValidationResult} if this member can currently log in, or an invalid * one with error messages to display if the member is locked out. * * You can hook into this with a "canLogIn" method on an attached extension. * * @return ValidationResult */ public function canLogIn() { $result = new ValidationResult(); if ($this->isLockedOut()) { $result->error(_t('Member.ERRORLOCKEDOUT', 'Your account has been temporarily disabled because of too many failed attempts at ' . 'logging in. Please try again in 20 minutes.')); } $this->extend('canLogIn', $result); return $result; }
/** * Hook to validate this record against a validation result * * @param ValidationResult $result * @param string $filename Optional filename to validate. If omitted, the current value is validated. * @return bool Valid flag */ public function validate(ValidationResult $result, $filename = null) { if (empty($filename)) { $filename = $this->getFilename(); } if (empty($filename) || $this->isValidFilename($filename)) { return true; } // Check allowed extensions $extensions = $this->getAllowedExtensions(); if (empty($extensions)) { $extensions = File::config()->allowed_extensions; } sort($extensions); $message = _t('File.INVALIDEXTENSION', 'Extension is not allowed (valid: {extensions})', 'Argument 1: Comma-separated list of valid extensions', array('extensions' => wordwrap(implode(', ', $extensions)))); $result->error($message); return false; }
/** * Returns a valid {@link ValidationResult} if this member can currently log in, or an invalid * one with error messages to display if the member is locked out. * * You can hook into this with a "canLogIn" method on an attached extension. * * @return ValidationResult */ public function canLogIn() { $result = new ValidationResult(); if ($this->isLockedOut()) { $result->error(_t('Member.ERRORLOCKEDOUT2', 'Your account has been temporarily disabled because of too many failed attempts at ' . 'logging in. Please try again in {count} minutes.', null, array('count' => $this->config()->lock_out_delay_mins))); } $this->extend('canLogIn', $result); return $result; }
/** * Validate that product exists and is published, variation exists for product if necessary * and quantity is greater than 0 * * TODO remove the check for $firstWrite when transactions are implemented * * @see DataObject::validate() * @return ValidationResult */ function validate() { $result = new ValidationResult(); $firstWrite = !$this->ID; $product = $this->Object(); $variation = $this->Variation(); $quantity = $this->Quantity; //Check that product is published and exists if (!$product || !$product->exists() || !$product->isPublished()) { $result->error('Sorry this product is no longer available', 'ProductExistsError'); } //TODO need to change checks for variation so that variation is checked properly when transactions are implemented //Check that variation exists if required, not on first write when ItemOption hasn't had a chance to be written if ($product && $product->requiresVariation() && (!$variation || !$variation->validateForCart()->valid()) && !$firstWrite) { $result->error('Sorry, these product options are no longer available', 'VariationExistsError'); } else { if ($variation && !$variation->validateForCart()->valid()) { $result->error('Sorry, these product options are no longer available', 'VariationIncorrectError'); } } //Check that quantity is correct if (!$quantity || !is_numeric($quantity) || $quantity <= 0) { $result->error('Quantity for this product needs to be greater than 0', 'QuantityError'); } return $result; }
/** * Validate that an sspak contains the correct content. * * For example, if the user uploaded an sspak containing just the db, but declared in the form * that it contained db+assets, then the archive is not valid. * * @param string|null $mode "db", "assets", or "all". This is the content we're checking for. Default to the archive setting * @return ValidationResult */ public function validateArchiveContents($mode = null) { $mode = $mode ?: $this->Mode; $result = new ValidationResult(); $file = $this->ArchiveFile()->FullPath; if (!is_readable($file)) { $result->error(sprintf('SSPak file "%s" cannot be read.', $file)); return $result; } $process = new Process(sprintf('tar -tf %s', escapeshellarg($file))); $process->setTimeout(120); $process->run(); if (!$process->isSuccessful()) { throw new RuntimeException(sprintf('Could not list files in archive: %s', $process->getErrorOutput())); } $output = explode(PHP_EOL, $process->getOutput()); $files = array_filter($output); if (in_array($mode, array('all', 'db')) && !in_array('database.sql.gz', $files)) { $result->error('The snapshot is missing the database.'); return $result; } if (in_array($mode, array('all', 'assets')) && !in_array('assets.tar.gz', $files)) { $result->error('The snapshot is missing assets.'); return $result; } return $result; }
/** * Validate writing of the Twitter Account * * @param $validation ValidationResult **/ public function validate(ValidationResult $validation) { if ($this->owner->TwitterUserID && $this->owner->TwitterScreenName && $this->owner->TwitterAccessToken && $this->owner->TwitterAccessSecret) { // Check to see if the user is already connected to an account & whether it matters. if ($this->getOverwriteExistingTwitterAccount() == false) { $changed = $this->owner->getChangedFields(); if ($this->owner->isChanged("TwitterUserID") && trim($changed['TwitterUserID']['before']) != "") { $validation->error("You already have a Twitter account connected."); } } // Check to see if there are other types of this DataObject also connected to this Twitter account (if it matters) if ($this->getAllowDuplicateTwitterAccounts() == false) { $duplicate = DataList::create($this->owner->ClassName)->filter("TwitterUserID", $this->owner->TwitterUserID); // Exclude the current user from the search. if ($this->owner->ID) { $duplicate = $duplicate->exclude("ID", $this->owner->ID); } if ($duplicate->first()) { $validation->error("Your Twitter account is already connected to another " . $this->owner->singular_name() . "."); } } } }
public function validate(ValidationResult $result) { $names = array(); if ($result->valid()) { foreach ($this->owner->FlexiFormFields() as $field) { if (empty($field->Name)) { $result->error("Field names cannot be blank. Encountered a blank {$field->Label()} field."); break; } if (in_array($field->Name, $names)) { $result->error("Field Names must be unique per form. {$field->Name} was encountered more than once."); break; } else { $names[] = $field->Name; } $default_value = $field->DefaultValue; if (!empty($default_value) && $field->Options()->exists() && !in_array($default_value, $field->Options()->column('Value'))) { $result->error("The default value of {$field->getName()} must exist as an option value"); break; } } if ($this->FlexiFormID() && ($flexi = FlexiFormUtil::GetFlexiByIdentifier($this->FlexiFormID()))) { if ($flexi->ID != $this->owner->ID) { $result->error('Form Identifier in use by another form.'); } } } }
public function validate(ValidationResult $result) { if ($this->owner->ExpirationDate && $this->owner->PublicationDate && $this->owner->ExpirationDate <= $this->owner->PublicationDate) { $result->error('Expiration date needs to be greater than the Publication date.'); } }
/** * Validate the Product before it is saved in {@link ShopAdmin}. * * @see DataObject::validate() * @return ValidationResult */ public function validate() { $result = new ValidationResult(); //If this is being published, check that enabled variations exist if they are required $request = Controller::curr()->getRequest(); $publishing = $request && $request->getVar('action_publish') ? true : false; if ($publishing && $this->requiresVariation()) { $variations = $this->Variations(); if (!in_array('Enabled', $variations->map('ID', 'Status'))) { $result->error('Cannot publish product when no variations are enabled. Please enable some product variations and try again.', 'VariationsDisabledError'); } } return $result; }
/** * Validate every component against given data. * @param array $data data to validate * @return boolean validation result * @throws ValidationException */ public function validateData($data) { $result = new ValidationResult(); foreach ($this->getComponents() as $component) { try { $component->validateData($this->order, $this->dependantData($component, $data)); } catch (ValidationException $e) { //transfer messages into a single result foreach ($e->getResult()->messageList() as $code => $message) { if (is_numeric($code)) { $code = null; } if ($this->namespaced) { $code = $component->namespaceFieldName($code); } $result->error($message, $code); } } } $this->order->extend('onValidateDataOnCheckout', $result); if (!$result->valid()) { throw new ValidationException($result); } return true; }