Refactoring form code in php - php

I get three values from a form (thread_title, thread_content and thread_tags):
This is the code to check their lengths:
$errors = array();
$thread_title = filter_input(INPUT_POST, 'thread_title');
$thread_content = filter_input(INPUT_POST, 'thread_content');
$thread_tags = filter_input(INPUT_POST, 'thread_tags');
if (strlen($thread_title) < 20 )
{
$errors['thread_title'] = 'Title is too short, minimum is 20 characters.';
}
if (strlen($thread_content) < 30 )
{
$errors['thread_content'] = 'Content is too short, minimum is 30 characters.';
}
if (strlen($thread_tags) < 3)
{
$errors['thread_tags'] = 'Tags must be atleast 3 characters.';
}
I repeat this in the reply.php file:
if (strlen($reply_content) < 20)
{
$errors['reply_content'] = 'Reply must be atleast 20 characters.';
}
.etc
If the errors array is empty I then clean the data and submit it to the database. How can this code be made cleaner, refactored?
I know I can use something like PEAR QUICK_FORM (2.0?), however that is still in alpha and the error messages appear as a JS popup in that and not next to the required field.

github is a source of lot of really good code. I did a quick search for form validation. For example:
https://github.com/bretticus/PHP-5.3-Form-Validator looks okay?
Furthermore I believe if you want to refactor your code, you should practice TDD(unit testing).

Related

Php Recursive Function Infinite loop Error

I am having a php recursive function to calculate nearest sale price. but i don't know why its run infinite time and throw error of maximum execution.
Its look like below:
function getamazonsaleper($portal)
{
$cp = floatval($this->input->post('cp')); //user provided inputs
$sp = floatval($this->input->post('sp')); //user provided input
$gst = floatval($this->input->post('gst')); //user provided input
$rfsp = floatval($this->input->post('rfsp')); //user provided input
$mcp = (int)($this->input->post('mcp')); //user provided input
$weight = floatval($this->input->post('weight')); //user provided input
$output = $this->getsalepercent($cp,$sp,$gst,$rfsp,$mcp,$weight,$portal);
return $output;
}
function getsalepercent($cp,$sp,$gst,$rfsp,$mcp,$weight,$portal) //recursive funtion
{
$spcost = ((($sp/100)*$cp));
$gstamount= (($spcost/(100+$gst))*$gst);
$rfspamount= ($spcost*($rfsp/100));
$mcpamount= ($cp*($mcp/100));
$fixedfee=$this->getfixedfee($portal,$spcost);
$weightfee=$this->getweightprice($portal,$weight);
$totalcost=$fixedfee+$weightfee+$rfspamount;
$gstinput=($totalcost*(18/100));
$remittances = $spcost-$totalcost-$gstinput;
$actualprofit= $remittances-$cp-$gstamount+$gstinput;
$actualprofitpercent = ($actualprofit/$cp)*100;
if( $actualprofitpercent >= $mcp)
{
return $sp;
}elseif($actualprofitpercent < $mcp)
{
$newsp = (int)($sp+10) ;
$this->getsalepercent($cp,$newsp,$gst,$rfsp,$mcp,$weight,$portal);
}
}
Can anybody tell me how can resolve this issue? Thanks in advance.
Edited :
Perameters
$cp=100;
$sp=200;
$mcp=20;
$weight=0.5;
$gst=28;
$rfsp=6.5;
First a couple of side notes:
- the way you use $gstinput it cancels itself out when you calculate $actualprofit (it's -$gstinput in $remittances which gets added to +$gstinput).
- $mcpamount seems to go completely unused in the code... I thought for a second you might vahe simply confused vars when doing the comparison, but of course for $cp = 100 it makes no difference.
Even so when I made a few calculations using the example values you gave for $sp = 200 (and growing by 10), I got:
Value of $actualprofit, which for $cp = 100 is also the value of $actualprofitpercent...
for $sp = 200:
43.25 - $fixedfee - $weightfee
for $sp = 210:
50.4125 - $fixedfee - $weightfee
for $sp = 220:
57.575 - $fixedfee - $weightfee
so for each $sp = $sp + 10 recursion the value of $actualprofitpercent (without taking into account $fixedfee and $weightfee) seems to grow by 7.1625.
The value of $weightfee should stay the same, but the value of $fixedfee depends on the value of $sp... Could it be that at each recursion getfixedfee() returns a value which grows faster than 7.1625?

Checking PHP Strlen of multiple strings

I have 4 fields from a previous page using an html form in the post method. Everything works fine except I am trying to check to make sure the strlens of each field are below 200. The following code always says that they are too long even though I am making sure they are way below 200.
PHP:
$hsname = trim($_POST['hsname']);
$hsstate = trim($_POST['hsstate']);
$hsemail = trim($_POST['hsemail']);
$hspassword = trim($_POST['hspassword']);
if (strlen($hsname) || strlen($hsstate) || strlen($hsemail) || strlen($hspassword) > 200){
die("Each field can only contain 200 characters"); //this is always returned even though the fields are below 200.
}
else {
echo "fields have good characters";
}
I will translate Your if condition:
if (strlen($hsname) || strlen($hsstate) || strlen($hsemail) || strlen($hspassword) > 200)
It`s like:
if(strlen($hasname)!='' || strlen($hsstate)!='' || strlen($hsemail)!='' || strlen($hspassword) > 200)
So You should know why it`s wrong now ;)
Compare every strlen or try that:
$maximumValue = max(strlen($hsname), strlen($hsstate), strlen($hsemail), strlen($hspassword));
// You got maximum value now, so:
if($maximumValue > 200){}
The reason your condition always returns true is because you're only checking if the last string has a length of greater than 200. The other strings are checked for whether they have a length of greater than 0, so your condition reads "if any of the first 4 strings are greater than 0 or the last string is greater than 200". Try this instead
foreach(array($hsname,$hsstate,$hsemail,$hspassword) as $string) {
if(strlen($string) > 200) {
die("Each field can only contain 200 characters");
}
}
You need to check that the fields are indeed there, and then check their length.
One way of doing it:
$fields = array('hsname', 'hsstate', 'hsemail', 'hspassword');
foreach ($fields as $field) {
if (!array_key_exists($field, $_POST)) {
die("Field {$field} is missing");
}
// Declare a variable whose name is in $field.
${$field} = trim($_POST[$field]);
if (strlen(${$field}) > 200) {
die("Field {$field} must be less or equal to 200 characters");
}
}
If you have international character support, you may also want to verify effective string length against database field length; a single UTF8 "character" may be more than one database field "character". The mb_* functions may help you, as well as utf8 encoding and decoding functions.
That wont work, when you evaluate
strlen($hsname)
It will satisfy the if condition when it has more than 0 characters
This is the same for the first 3 strings you check against
You need the ' > 200 ' for each of the strings you want to compare [assuming that you are passing the actual values in the post]:
$hsname = 'test';
$hsstate = 'test';
$hsemail = 'test';
$hspassword = 'test';
if (strlen($hsname) > 200 || strlen($hsstate) > 200 || strlen($hsemail) > 200 || strlen($hspassword) > 200){
die("Each field can only contain 200 characters"); //this is always returned even though the fields are below 200.
} else {
echo "fields have good characters";
}

Advanced PHP foreach() loop..(nested if/else)

I'm having a bit of a brain-fart here...lol
I was using a forloop() initially for this.. but then the conditions got a bit more advanced on things I needed to check for, as well as the output based on found/not found..
My problem is ensuring that on consecutive loops.. the 'else' on the (no access) potion only gets echo'd once... but of course on every 'loop' it will check from the top and if not a match output the 'no-access' text.. (on every iteration).. where it should only output once.
Originally there was only a few if() statement/checks in the foreach() loop.. where a simple break; took care of things fine...
but these if()'s turned into if/else.. which means the else will get 'triggered' on the next 'loop'.. how can this be prevented?
$arrwebinars = ("Name1", "Name3");
foreach($arrwebinars as $webinar) {
/* Webinar 1 */
if($webinar == 'Name1') {
if($web01_title != '') {
echo "available";
} else {
echo "not available";
}
} else {
echo "no access";
}
/* Webinar 2 */
if ($webinar == 'Name2') {
if ($web02_title != '') {
echo "available";
} else {
echo "not available";
}
} else {
echo "no access";
}
/* Webinar 3 */
if ($webinar == 'Name3') {
if($web03_title != '') {
echo "available";
} else {
echo "not available";
}
} else {
echo "no access";
}
}
is there some other sort of 'control' I can use to ensure the main if/else only gets executed once?
Sorry , I am having a hard time trying to describe this one, hopefully the code explains it all (and the problem)
thanks.
update:
Current State: reverted back to foreach() loop.
User is only authorized for 2 vids (#5 & #6 we'll say..can be any of the 6 in reality)
Upon first loop/iteration.. vids 1-4 output (no access for you!) (because they dont, only #5 & #6 as stated above)
no. 5 outputs the embed code fine (access)
no. 6 says 'No access for you'.. (even though they do/should have access)
Upon the scond iteration..vids 1-4 are duplicated, and again say "No access for you" (outside of it being a duplication..this is correct).. however, vid #5 NOW says "no access for you" (first loop it outputted fine, second loop it is looking for a new 'match' while not what I want.. in theory this is correct.. but should have a duplicate)
Vid #6 is NOW outputting the embed code (where as on first loop it did not)..
The user has only purchased access to 2 vids.. so the loop only happens twice.
but I get '12' echo's
No matter what I should only get 6 echo's with 1 out put per video (available/not available -or- no access)
I cant seem to wrap my head around this today.. :(
Goal I want achieve:
6 outputs TOTAL
each output (echo) should ONLY have:
available or not available printed (this is the nested conditional check for the blank title)
-or-
no access
there are 6 video to check against.
the user can have purchased access to 1 or up to all 6 vids
first check is: is the webinar name in their purchased array found in the total available 6 vids available
second tier conditional check:
if YES (match found == access)...then check to see if the title is missing (if there output access [video embed code]... if not there output text 'not available yet')
(going back to first conditional check) if there is NO ACCESS (match not found).. output 'no access' text.
This works if I wanted duplicates on the stage/page.. (but I dont!) LOL..
I need to be limited to ONLY 6 outputs,.. as there are only a total of 6 vids available.
I DO NOT WANT:
on loop 1 it outputs access for vid#1 and #2-#6 are no access..
on loop 2 it re-states all of these outputs, has vid#1 no-access now, vid#2 has access and vids #3-#6 are no access...
etc.etc.. and the cycle continues. I'm getting lost on this one!..
thanks!
If you wish to stop considering that "row" when you encounter a "no access" then you could simply continue; after each no-access. or do you wish to check the others even if you encounter "no access" on the first, just to fail silently in that case?
Not sure exactly what you're trying to achieve, but your code could be shortened greatly.
$webinars = array('one', 'two', 'Name3');
$web0_title = 'not empty'; // Just a demo
for ( $i = 0; $i < count($webinars); $i++ )
{
$access = FALSE;
$available = FALSE;
$name = 'Name' . $i;
$title = 'web' . $i . '_title';
if ( $webinars[$i] == $name ) {
if ( ! empty( $$title ) ) {
$available = TRUE;
}
$access = TRUE;
}
// Simple debug, not sure what you want to accomplish
echo 'Webinar: ' . $webinars[$i] . ' <br />';
echo 'Availability: ' . ( $available ? 'Available' : 'Not Available' ) . '<br />';
echo 'Access: ' . ( $access ? 'Access' : 'No Access' ) . '<br /><br />';
}
Edit: Just read your comments so I updated it.

Comparing Object Attributes to Integers in OO PHP?

I'm having a small problem. In a class called reservation that has an attribute called reserve , which in the database is a tinyint(4), and an attribute kamp, which is int(10). I'm trying to do this:
if ($this->kamp == 387 || $this->kamp == 388 || $this->kamp == 389) {
$this->reserve = 0;
} else {
$this->reserve = 1;
}
Now my problem is, the code ALWAYS jumps straight to the else bracket. Even when I'm 100% sure $this->kamp is 387, 388 or 389.
Does this have anything to do with datatypes or am I missing something? I think the problem lies within this piece of code, since in my database there are objects showing up where reserve = 1 and the kamp is one of the three numbers I mentioned.
Thanks!
i think this will work for you.
$val = intval($this->kamp);
and then print or echo for result it will giving you value or not ?
let me know if i can help you more.

Validation Opencart

i want to add php phone number validation in opencart code sample is given below
if(!filter_var($customer_email, FILTER_VALIDATE_EMAIL)) {
$errors[$pos++] = 'Email is not valid.';
}
if($customer_mobile=='') {
$errors[$pos++] = 'Please enter your Mobile.';
} /*elseif (strlen($customer_mobile) < 11 || !is_numeric($this->request->post['cell_number'])){
$errors[$pos++] = 'Mobile number should be 7 digits.';
}*/
#Tayyab Gulsher Vohra....
I am also facing this problem.I concluded myself and made it.
follow the instruction.,
The opencart is a MVC structure platform,so you need to know about Controller , Model and view ,Here Controller is first initialization telephone number in index()function
if (isset($this->request->post['telephone'])) {
$this->data['telephone'] = $this->request->post['telephone'];
} else {
$this->data['telephone'] = $this->customer->getTelephone();
}
further, telephone number must be valid using this method.,
function validate()
if( !preg_match("/^([1]-)?[0-9]{3}-[0-9]{3}-[0-9]{4}$/i", $this->request->post['telephone']) ) {
$this->error['telephone'] = $this->language->get('error_telephone');
}
then you should be initialized telephone number value in language file.
Well, you have 2 options, validate or filter.
Because phone numbers are different in length and characters, what I would suggest is that you just filter
FILTER_SANITIZE_NUMBER_INT
Remove all characters except digits, plus and minus sign.
for more info:
Filters
EXAMPLE:
<?php echo filter_var("Home: +1 (123) 456-7890 # John", FILTER_SANITIZE_NUMBER_INT); ?>
Sanitizer functions are not really ready for validation of phone numbers and I would probably use a regex leaving ( ) + - : e and numbers in as this allows for most variations of international numbers and extensions.

Categories