Jump to content

Saving data using formhelper, Custom Validation registration


Fidde

Recommended Posts

I've just started creating plugins for IPS and was planning some modifications to the register page. What I want is to validate the members input beyond what is already available within the profile-fields you can add.

So I downloaded this:

And I did some modifications:

Spoiler

static public function buildRegistrationForm()
	{
		try
		{
			$form = call_user_func_array( 'parent::buildRegistrationForm', func_get_args() );
			$form->add( new \IPS\Helpers\Form\Text( 'pnum', NULL, TRUE, array( 'maxLength' => 150 ), function( $val )
			{
				if (!self::check($val, $personal_only = true))
				{
					throw new \DomainException( 'pnum_wrong' );
				}
			}, NULL, NULL, 'pnum' ), 'email_address' );
	
			return $form;
		}
		catch ( \RuntimeException $e )
		{
			if ( method_exists( get_parent_class(), __FUNCTION__ ) )
			{
				return call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );
			}
			else
			{
				throw $e;
			}
		}
	}

 

(I've added my own validation class above)

Spoiler

public static function checksum($pnum) {
      $pnum = self::filter($pnum);
      $len = mb_strlen($pnum);
      if($len == 10) {
         $pnum = mb_substr($pnum, 0, 9);
      }elseif($len > 10) {
         return false;
      }
 
      $checksum = 0;
      $onetwo = 1;
      for($i = 0; $i < 9; $i++) {
         $onetwo = $onetwo==1?2:1;
         $tmp = $pnum[$i] * $onetwo;
         if($tmp > 9) {
            $tmp = $tmp - 10 + 1;
         }
         $checksum += $tmp;
      }
      $checksum %= 10;
      if($checksum != 0) {
         $checksum = 10 - $checksum;
      }
      return $checksum;
   }
 
   public static function check($pnum, $personal_only = true) {
      $pnum = self::filter($pnum);
      $len = mb_strlen($pnum);
      if($len != 10) {
         return false;
      }
 
      if($personal_only && ($pnum[2] > 1 || !self::datecheck($pnum)) ) {
         return false;
      }
 
      return self::checksum($pnum) == $pnum[$len-1];
   }
 
   public static function datecheck($pnum) {
      $pnum = self::filter($pnum);
      $date = mb_substr($pnum, 0, 6);
      $y = mb_substr($date, 0, 2);
      $m = mb_substr($date, 2, 2);
      $d = mb_substr($date, 4, 2);
      $date = "19$y-$m-$d";
      return $date == date('Y-m-d', strtotime($date));
   }
 
   public static function gender($pnum) {
      $pnum = self::filter($pnum);
      if(!self::check($pnum, true)) {
         return false;
      }
      return ($pnum[8] % 2) ? 1 : 2;
   }
 
   public static function ispersonal($pnum) {
      $pnum = self::filter($pnum);
      return self::check($pnum, true);
   }
 
   public static function iscompany($pnum) {
      $pnum = self::filter($pnum);
      return !($pnum[2] < 2 || !self::check($pnum, false));
   }
 
   public static function company($pnum) {
      $pnum = self::filter($pnum);
      if(!self::iscompany($pnum)) {
         return false;
      }
      switch($pnum[0]) {
      case 2:
         return 'OF';
      case 5:
         return 'AB';
      case 7:
         return 'EK';
      case 8:
         return 'IF';
      case 9:
         return 'HB';
      default:
         return true;
      }
   }
 
   public static function filter($pnum) {
      $pnum = preg_replace('/[^0-9]/', '', $pnum);
      if(mb_strlen($pnum) > 10 && $pnum[0] <= 2) {
         $pnum = mb_substr($pnum, 2);
      }
      return $pnum;
   }

 

And this works great :) However, I wan't to save the values from the registration form, otherwise, whats the point of the validation ;)

So, simply, how do I save what using the form-helper (is it easiest to use profile-fields, cause then I can easily edit the value in the admincp)?

Link to comment
Share on other sites

What I did for now, until I have a better solution was simply editing the register.php file (applications/core/modules/front/system/register.php)

4b57af4d77877fcb5f216d092b66b68f.png

Adding 

$profileFields[ "field_3" ] = $values['pnum'];

before the custom profile fields and of course first creating a profile field with these settings:

4f31d3cfdd979015c7ec5dd4f5b4d6d1.png

I guess there is a better way, but hey, it works for now ;)

Link to comment
Share on other sites

  • 1 month later...

We are working on improvements to custom profile fields. They probably won't be available until a major release, but I'll look to see if your need can be accomplished during the refactoring. Essentially, you just need a way to apply a custom validation function to a custom profile field it looks like.

Link to comment
Share on other sites

  • 4 weeks later...
On 2016-04-08 at 3:59 AM, bfarber said:

We are working on improvements to custom profile fields. They probably won't be available until a major release, but I'll look to see if your need can be accomplished during the refactoring. Essentially, you just need a way to apply a custom validation function to a custom profile field it looks like.

Yes, my idea would be to it work like classes in css, you can append classes to your custom fields, and then you have a single PHP file that have a list with cases and if that field matches any (or all of them) it will be checked against those "validation classes". I would also like a built in function for IPS to make sure a field is unique.

Something like this:

public function check($source, $items = array()) {
		foreach($items as $item => $rules) {
			foreach ($rules as $rule => $rule_value) {
				
				$value = trim($source[$item]);
				$item = escape($item);
				if ($rule === 'required' && empty($value)) {
					$this->addError("{$item} is required");
				} else if (!empty($value)) {
					switch ($rule) {
						case 'min':
							if (strlen($value) < $rule_value) {
								$this->addError("{$item} must be a minimum of {$rule_value} characters.");
							}
							break;
						case 'max':
						if (strlen($value) > $rule_value) {
								$this->addError("{$item} can be a maximum of {$rule_value} characters.");
							}
							break;
						case 'matches':
								
								if ($value != $source[$rule_value]) {
									$this->addError("{$rule_value} must match {$item}");
								}
							break;
						case 'pnum':
							if(!Pnum::check($value)) {
							    $this->addError("{$item} is not a valid SSN.");
							}
						break;
						case 'numeric':
						
							if (!is_numeric($value)) {
								$this->addError("{$item} can not only be numeric.");
							}
							
						break;
						case 'email':
							if(!filter_var($value, FILTER_VALIDATE_EMAIL)) {
	     						$this->addError("{$item} must be a valid email.");
	   						 }
						break;
						
						case 'notnumeric':
							
							if (is_numeric($value)){
								$this->addError("{$item} can only contain numbers.");
							}
						
						break;
						case 'unique':
								$check = $this->_db->get($rule_value, array($item, '=', $value));
								if ($check->count()) {
									$this->addError("{$item} already exists.");
								}
						break;
					}
				}
			}
		}
		if (empty($this->_errors)) {
			$this->_passed = true;
		}
		return $this;
	}

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...