Help with String Manipulation Please!

Hi everyone,

I’m new here but have been trying to find some help with some PHP.

This topic kinda spans PHP and Wordpress but the actual question is pure PHP so I hope I’ve put this in the right place.

Basically I’m developing a Wordpress website that uses the Gravity Forms User Registration plugin to handle sign ups, and due to the nature of the site I want the user names to be predefined by the site using the postcode the user entered on the first page of the form. The logic is as follows:

Get postcode from form page 1
Make sure postcode is capitalized and remove spaces
Add -001 number to the end of the postcode
Check if this complete username has been used
If it has increase to 002 and try again
If it has not been used continue
Send authorized username back to the form

Final format = AB12CD-001

I can get the postcode and format it correctly and send it back to the form fine so interfacing with GForms isn’t the issue here, but it’s the adding number section that I’m struggling with. Here’s what I’ve done so far:


add_filter("gform_pre_render_1", "populate_previous_page_data");
function populate_previous_page_data($form){

    $page_number = rgpost("gform_target_page_number_{$form["id"]}");  //Set $page_number to the form id ??
    $page_number = !is_numeric($page_number) ? 1 : $page_number;	//Make the form id a usable number ??

    foreach($form['fields'] as &$field) {	//Loop through each form field in the variable $field

        if($field['id'] != 9) // If field is not equal to 9 (or target for dynamically populating)

        $field_page = rgar($field, 'pageNumber');	//$field_page equals the form page the currently looked at field is on

        if($page_number > $field_page)	//If $page_number is greater than $field_page then
            continue;	//Exit loop and restart

        //$field['defaultValue'] = rgpost('input_2_5');	//If conditions are met, ie. the currently field in the loop is the target, set the value to the contents of input_2_5 (or the source required)
		
		$user_id = rgpost('input_2_5');
		$user_id = preg_replace('/\\s+/', '', $user_id);
		$user_id = strtoupper($user_id);
		
		$count = 1;
		$user_id_no = 001;
		$field['defaultValue'] = $user_id;

    }

    return $form;
}

I’m really struggling, I know it has to loop but I can’t seem to get it right, any help will be greatly received guys!

Welcome to the SitePoint forums :slight_smile:

So seven steps:

  1. Get postcode from form page 1
  2. Make sure postcode is capitalized and remove spaces
  3. Add -001 number to the end of the postcode
  4. Check if this complete username has been used
  5. If it has increase to 002 and try again
  6. If it has not been used continue
  7. Send authorized username back to the form

You’ve got all the right steps isolated. So lets turn them into code…

Step 1: You’re on your own here, I assume your code is validly retrieving the value, however it has to do so.
Step 2: strtoupper takes care of the capitalization. a preg_replace on ~[^A-Z0-9]~ with “” will take care of any extraneous characters.
Step 2a: You might want to validate the postcode after it’s been sanitized.
Step 3: Easy.
Step 4: This check should be the test condition of a WHILE loop.
Step 5: This should be the internal command of the while loop. Take the number, +1, [FPHP]strpad[/FPHP] the number, and slap it onto the postcode to check again.
Step 6: ENDWHILE.
Step 7: Return.

Thanks for your reply (I know it’s been a week but I’m stupidly busy).

I’m sorry if I’m being really think but I’m struggling with steps 3 - 6 still. All my attempts concatenation end up returning weird results, I’m sure part of it is Gravity Forms but this is confusing the hell out of me. I’d really appreciate some sample code to dissect if anyone could muster it would really help me.

Thanks again.

Well concatenating -001 (Step 3) should be simple. $string.“anotherstring”

Step 4 - what logic test have you come up with for testing if the full string (ABCDEF-001) already exists?

Step 5 - Keep an integer (initialized to 1 before the loop) which determines what it is you’re currently testing. If you reach this step of the code, Increment it by 1, [FPHP]str_pad[/FPHP] it (using the STR_PAD_LEFT flag and string “0”), and then replace your combined postcode with the one combining the new string and the old postcode.

Step 6 - this would be a “}”. Nothing more, nothing less.

Ok, I’ve made progress and basically some of the problems are a combination of me being dumb and Gravity Forms.

I’ve managed step 3 and formed a full user id AB12CD-001.

Now as for checking it, Wordpress has a function for this pre-built so I’m intending to use that but I just can’t seem to form the loop properly.

The function is username_exists($username) - see here: http://codex.wordpress.org/Function_Reference/username_exists.

I want a loop to use this to check but it returns either the username or NULL and all I can only seem to think of it in terms of IF statements which I know will handle the check but not the increment.

I think I need a do, while loop but don’t know how to structure it, here’s the latest code:


add_filter("gform_pre_render_1", "populate_previous_page_data");
function populate_previous_page_data($form){

    $page_number = rgpost("gform_target_page_number_{$form["id"]}");  //Set $page_number to the form id ??
    $page_number = !is_numeric($page_number) ? 1 : $page_number;	//Make the form id a usable number ??

    foreach($form['fields'] as &$field) {	//Loop through each form field in the variable $field

        if($field['id'] != 9) // If field is not equal to 9 (or target for dynamically populating)

        $field_page = rgar($field, 'pageNumber');	//$field_page equals the form page the currently looked at field is on

        if($page_number > $field_page)	//If $page_number is greater than $field_page then
            continue;	//Exit loop and restart

        //$field['defaultValue'] = rgpost('input_2_5');	//If conditions are met, ie. the currently field in the loop is the target, set the value to the contents of input_2_5 (or the source required)
		
		$user_id = rgpost('input_2_5');
		$user_id = preg_replace('/\\s+/', '', $user_id);
		$user_id = strtoupper($user_id);
		$user_count_id_no = 001;
		
		$field['defaultValue'] = build_id($user_id, $user_count_id_no);

    }

    return $form;
}

function build_id ($pcode_id, $assigned_id_no) {
	
		$cmplt_id = $pcode_id . "-" . number_pad($assigned_id_no, 3);
		
		return $cmplt_id;
}

function number_pad($number,$n) {
return str_pad((int) $number,$n,"0",STR_PAD_LEFT);
}

NULL is a defined entity in PHP that you can check against.

while(username_exists($username) !== null) {
//Username exists already. Choose another
} //Return to top of loop.
//As of this point $username is new and unique.

Cool, I’ll have a try with that, just out of interest I’ve included what I was trying here:



function build_id ($pcode_id, $assigned_id_no) {	//Builds complete user id
	
		do {
			if($assigned_id_no != 1) $assigned_id_no = 1;
			else $cmplt_id = $pcode_id . "-" . number_pad($assigned_id_no, 3);  //Puts postcode string and calls the number padding function to add the leading 0's
		}
		while(username_exists($cmplt_id));
		
		return $cmplt_id;
}

Was that even on the right lines?

It’s…very close. your IF is doing something funky that’ll end in a infinite loop. You might have wanted to do this instead:


function build_id ($pcode_id, $assigned_id_no = 1) {	//NOTE: default value for assigned_id_no given.	
		do {
			$cmplt_id = $pcode_id . "-" . number_pad($assigned_id_no, 3);  //Puts postcode string and calls the number padding function to add the leading 0's
                        $assigned_id_no++;
		}
		while(username_exists($cmplt_id));		
		return $cmplt_id;
}

You’ve been great bud, thanks. But unfortunately I’m going to have to ask something else.

Both the solution you suggested and my one you corrected and not passing the complete id (all I’m getting in the boxes is -001) and even this may be GForms playing up so its possible nothing is being passed at all so there’s still something wrong in the loop.

Any ideas?

Make sure you’re actually getting something in $user_id.

	$user_id = rgpost('input_2_5'); //What is this?
	$user_id = preg_replace('/\\s+/', '', $user_id); //If previous line was blank, this does nothing.
	$user_id = strtoupper($user_id); //Ditto

            echo "UserID:".$user_id;

Crap, it was working before and now even without the loop it isn’t!

$user_id = rgpost(‘input_2_5’); //this tells the hook where to pull the postcode from
$user_id = preg_replace(‘/\s+/’, ‘’, $user_id); //the postcode field is compulsory so will always be filled in and thus never blank
$user_id = strtoupper($user_id); //Ditto

For some reason the postcode part isn’t getting there now! So it’s not the loop it’s something else, sigh.

Edit!

Right I’ve traced some of the problem, basically I can go through the whole thing step by step until I try concatenating with this line:

$cmplt_id = $pcode_id . “-” . number_pad($assigned_id_no, 3);

(not this is without the loop in place)

as soon as I add the -001 it works fine until you clear and reload the form, after that it just put’s -001 in all boxes and nothing else, leading me back to Gravity Forms as the problem, and I’m waiting to hear back from their help desk.

For the time being there’s nothing else we can do here, thank you so much for your help and I’ll post back and let you know if I solve it once I hear back from GForms.

Cheers :slight_smile: