client and server side validation - php

Hi guys I wanted to know how to validate 3 things both server and client side.
database table product
my database looks something like this but they are over 400 data in it.
pid name size
1 grey 12 inch
2 blue 16 inch
database table category
pid category
1 vans
2 nike
database table itemised
pid price
1 30.00
2 50.00
I have some fields I need to verify. I have already done a validation to check that it is not empty.
One of the field in my table looks like this
<select id="Category" name="Category">
<?php
dbconnect();
$stmt = $conn->prepare("SELECT Name FROM Category WHERE pid=:id");
$stmt->bindParam('id',$id);
$stmt->execute();
$i = 0;
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if ($i == 0) {
echo '<option SELECTED value="'.$row['Name'].'">'.$row['Name'].'</option>
';
}
else {
echo '<option value="'.$row['Name'].'">'.$row['Name'].'</option>';
}
$i++;
}
?>
</select>
it is not in a form rather a table. If you notice the size as number and letter it in.
My question
More or less everyone familiar with developer tools to change posted value. I want to validation both client(JS) and client(php) to make sure that no one as mess up the value.
I did this to check that not of it is empty
for an example if have
normal
<option value="blue vans">blue vans</option>
not-normal
<option value="">blue vans</option> // in this one the value is `BLANKET`
The js below check this
function isEmpty(aTextField,errormessage) //null may be used for errormessage to only change the colour of matching fields
{
if (aTextField.value.length<=0)
{
if (lfield != aTextField || lfield === null) { fields[fields.length] = [aTextField,false]; } else { fields[fields.length-1] = [aTextField,false]; }
lfield = aTextField;
if (errormessage !== "")
{
if (counter < error_count || error_count == 0) { errors += errormessage+'\n'; } counter++;
}
return true;
}
else
{
if (lfield != aTextField || lfield === null) { fields[fields.length] = [aTextField,true]; }
lfield = aTextField;
return true;
}
}
in php
function notEmpty($inputname,$error_message)
{
$this->js.='if (!isEmpty(formname.'.$inputname.',"'.$error_message.'")) return false;';
if ( isset($_POST[$inputname]) && ( strlen($_POST[$inputname]) <= 0 ))
{
if ($error_message != null)
{
$this -> error_message .= $error_message.'<br>';
}
}
}
Now you see how I have validate for blanket value for all of the options in my table
How can i verify both in js and php
for the size it will be kinda simple if i didnt have inch at the end but changing over 1000 data in a database will be a pain.
Any idea how I can do this please???
I hope I have explain this clearly and if not please leave a comment and I will try and rephrase the question.
Thanks

I would use regular expressions for both Javascript and php. You can use the same pattern in both languages, so u don't have to write it twice.
php-check for the size:
<?php
if(!preg_match("/^[0-9]+ (inch|othervalue1|othervalue2)$/",$_POST[$inputname]){
$this -> error_message .= 'Wrong Value<br>';
}
?>
For JS, you can take a look at this: http://www.w3schools.com/jsref/jsref_obj_regexp.asp
This might do the trick in JS, but not tested yet:
function checkSize(value){
var patt=new RegExp("^[0-9]+ (inch|othervalue1|othervalue2)$");
return patt.test(value); //returns false for wrong value
}
Furthermore I would suggest to make 2 columns for both value and unit. It would give you several advantages.

You could use intval to convert the string size into an integer, for example intval('12 inch') will return 12.

Try preg_match("/(\d+) inch/", $input_str) or similar to test whether your desired regular expression matches.
You should also be escaping (html special entities) all variable to your HTML output. Otherwise angle-brackets will break the page.
At least you're using prepared statements on the DB side.. thank God. One out of three seems to be good for a PHP "application".

Just to provide you with an alternative way of validating.
You could also post the form via ajax so you only have to validate server-side:
$('#myForm').ajaxForm({
dataType: 'json',
success: function(response) {
if (response.error) {
alert(response.error);
} else {
$('#myForm').text(response.message);
}
}
});
(This is assuming you're using the jQuery plugin http://malsup.com/jquery/form)
Then in you're PHP you should check whether the current request is ajax:
function isAjax() {
return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
}
...
if (isAjax() {
$response = array();
if (!empty($this->error_message)) {
$response['error'] = str_replace('<br>', "\n", $this->error_message);
} else {
$response['message'] = 'Form submitted';
}
header('Content-type: application/json');
echo json_encode($response);
exit;
}

Related

Creating a simple php page that allows the user to input characters to search for names

I am trying to make a php page where we can input characters and select year of birth
After submitting it should show all the corresponding name but it doesn't work.
For example I input 'a' and the name containing 'a' having the same year as selected should appear.
This is my code:
In data.php I have like this
$person[0]=array('name'=>'Daniel','dateofbirth'=>2000);
$person[1]=array('name'=>'Gaetan','dateofbirth'=>1980);
My function.php
<?php
function comparator($word,$dateofbirth) {
include("data.php");
$p=1;
for($i=0;$i<count($person);$i++) {
$position=strpos(strtolower($person[$i]['name']),$word);
if($position === false) {
$p++;
}
else {
if($dateofbirth==$person[$i]['dateofbirth']) {
echo $person[$i]['name'] ;?><br /><?php
}
}
}
if($p==count($person)) {
echo "No results found";
}
}
?>
And the index.php, I used get method
I think my function.php is the problem but I don't know how to fix it.
I think this should solve your problem - https://3v4l.org/oQ1BC - however I feel it's necessary to say that it's inefficient and in production data are never stored that way, you should store the details of people in a database and connect to it and perform an SQL query. This only answers the original question.
function findPeople($searchString, $YoB, $listOfPeople){
$peopleFound = [];
foreach($listOfPeople as $individual){
if(strpos($individual['name'], $searchString) !== false && $individual['dateofbirth'] == $YoB){
$peopleFound[] = $individual;
}
}
return $peopleFound;
}
$listOfPeople = array();
$listOfPeople[0]=array('name'=>'Daniel','dateofbirth'=>2000);
$listOfPeople[1]=array('name'=>'Gaetan','dateofbirth'=>1980);
print_r(findPeople('a', 2000, $listOfPeople));

Comparison of words from the database and output of the result

I need to check the words received from the database with the user's entered word and if there is a match, then output its value from the database, and if not, then output what the user entered.
The code below works fine if there is a match.
function d_typeplace_morf($d_typeplace)
{
global $wpdb;
$typeplace_results = $wpdb->get_results('SELECT vozmozhnyi_variant_mesta, ego_slovoforma_v_predlozhnom_padezhe FROM dEzpra_jet_cct_tip_mest_obrabotki');
if ($typeplace_results) {
foreach ($typeplace_results as $typeplace_result) {
$d_typeplace_raw = mb_strtolower($typeplace_result->vozmozhnyi_variant_mesta);
$d_typeplace_morf = mb_strtolower($typeplace_result->ego_slovoforma_v_predlozhnom_padezhe);
$d_typeplace = mb_strtolower($d_typeplace);
if (stripos($d_typeplace, $d_typeplace_raw) !== false) {
echo $d_typeplace_morf;
}
}
}
}
I'm an amateur in PHP, just learning. And I can't figure out how to output $d_typeplace if no match is found.
I tried to add
else {
echo $d_typeplace;
}
, but I get an array of words from the user entered.
I will be grateful for any help. Also for any suggestions for improving this code.
---Addition---
I apologize for my English. This is a problem in the Russian language, I need to take into account the morphology. To do this, the database has a list of words and their analog, for example, X = Y. I get these words and compare what the user entered. If he entered X, then we output Y. If he led Z, which is not in the database, then we output Z.
Thus, we check $d_typeplace with $d_typeplace_raw and if there is a match, we output $d_typeplace_morf, which is equal to $d_typeplace_raw. And if not, then $d_typeplace (it contains the value that the user entered).
Oh, I'm sorry, I understand myself that I'm explaining stupidly)
I cannot quite understand what you are asking: you need to output the string entered by the user, but you can only print an array?
If this is the case, I think you parsed the string before, in order to therefore you need to do join again the values contained in the array.
Try with:
else {
echo implode(" ", $d_typeplace);
}
--- EDITED ---
Try with:
function d_typeplace_morf($d_typeplace)
{
global $wpdb;
$typeplace_results = $wpdb->get_results('SELECT vozmozhnyi_variant_mesta, ego_slovoforma_v_predlozhnom_padezhe FROM dEzpra_jet_cct_tip_mest_obrabotki');
if ($typeplace_results) {
$found = false;
foreach ($typeplace_results as $typeplace_result) {
$d_typeplace_raw = mb_strtolower($typeplace_result->vozmozhnyi_variant_mesta);
$d_typeplace_morf = mb_strtolower($typeplace_result->ego_slovoforma_v_predlozhnom_padezhe);
$d_typeplace = mb_strtolower($d_typeplace);
if (stripos($d_typeplace, $d_typeplace_raw) !== false) {
echo $d_typeplace_morf;
$found = true;
break;
}
}
if (!$found) {
echo $d_typeplace;
}
}
}
But I think it would be more efficient, if you implemented the second code snippet written by #Luke.T
I'm presuming you were trying to add the else like this?
function d_typeplace_morf($d_typeplace)
{
global $wpdb;
$typeplace_results = $wpdb->get_results('SELECT vozmozhnyi_variant_mesta, ego_slovoforma_v_predlozhnom_padezhe FROM dEzpra_jet_cct_tip_mest_obrabotki');
if ($typeplace_results) {
foreach ($typeplace_results as $typeplace_result) {
$d_typeplace_raw = mb_strtolower($typeplace_result->vozmozhnyi_variant_mesta);
$d_typeplace_morf = mb_strtolower($typeplace_result->ego_slovoforma_v_predlozhnom_padezhe);
$d_typeplace = mb_strtolower($d_typeplace);
if (stripos($d_typeplace, $d_typeplace_raw) !== false) {
echo $d_typeplace_morf;
} else {
echo $d_typeplace;
}
}
}
}
Which was outputting an array because the for loop was continuing, if you add a break like so...
echo $d_typeplace;
break;
It should stop outputting an array. Depending on your use case you could however perform similar functionality directly in your sql query using LIKE ...
function d_typeplace_morf($d_typeplace)
{
global $wpdb;
$typeplace_results = $wpdb->get_results('
SELECT ego_slovoforma_v_predlozhnom_padezhe
FROM dEzpra_jet_cct_tip_mest_obrabotki
WHERE vozmozhnyi_variant_mesta LIKE %' . $d_typeplace . '%');
if ($typeplace_results) {
//Echo result
} else {
echo $d_typeplace;
}
}

vTiger Event Handler to check if record exists

I am working on vTiger 6.5 and I am trying to figure a way to see if a record exists in a custom module of mine. I want to check whether the 'policynumber' is new before saving, here is my code so far. For some reason it seems to act randomly depending on my module number chosen.
class isaHandler extends VTEventHandler {
function handleEvent($eventName, $entityData) {
global $adb;
$moduleName = $entityData->getModuleName();
if($moduleName=='isa'){
if($eventName == 'vtiger.entity.beforesave.modifiable') {
$isNew = $entityData->isNew('policynumber');
if ($isNew == false) {
echo "Duplicate policy number";
exit;
}
}
if($eventName == 'vtiger.entity.beforesave') {}}
if($eventName == 'vtiger.entity.beforesave.final') {
$price = $entityData->get('currentamount');
if($price > 20000){
echo "Please go back and enter less than 20000";
exit;
}
if($eventName == 'vtiger.entity.aftersave') {}
}
}
At the moment I am currently using an echo just to see the result. But later on I will perform more than this.
isNew()
Returns true if new record is being created, false otherwise.
More info is here
you should write a custom query to check policynumber already exist or not in your function:
if($eventName == 'vtiger.entity.beforesave.modifiable') {
global $adb;
$result = $adb->pquery("SELECT your-field-name FROM table_name WHERE policynumber=?", array($policynumbervalue));
if($result && $adb->num_rows($result)) {
echo "This policy number exist";
die();
}else{
// write your overwrite code
}
} //end if($eventName == 'vtiger.entity.beforesave.modifiable')
Update:
I am assuming there is field i.e. policynumber in your form, you enter some value in this field and submit the form. so you will get entered policy number value from this:
$policynumbervalue = $entityData->get('policynumber'); //this is vtiger standard way
if this does not work, you can simply use php global variable $_REQUEST['policynumber'] but I is not a good practice.
Hope this will help.
This is the update to my answer, I simply done an if statement on the number of rows displayed.
if($eventName == 'vtiger.entity.beforesave.modifiable') {
$policynumbervalue = $entityData->get('policynumber');
$sql = $adb->pquery("SELECT policynumber FROM vtiger_isa WHERE policynumber=?",array($policynumbervalue));
$nrows = $adb->num_rows($sql);
if($nrows > 0){
echo "<script type=\"text/javascript\">window.alert('ISA policy number already exists, you will be redirected to the updata module.');
window.location.href = '/vtigercrm/index.php?module=isa&view=List';</script>";
exit;
}

Why is Apache inserting comment into some of my HTML output?

While running my code through W3C's HTML validator for HTML5, I noticed that some of my files had this comment inserted before the tag:
<!-- This file should NOT be stored in the web root directory (or any sub-directory thereof) If this is not possible, place it in the 'include' directory and restrict access via Apache's .htaccess files -->
This only seems to happen with pages that are accessed via POST requests, though I have been unable to pin down any cause, nor have searches turned up anything.
I am using mod rewrites and the HTML is generated from multiple files from webroot/views/ and webroot/includes/, but other pages that are similarly generated do not have this issue.
Anyway, I normally wouldn't worry about it, but when sending an xml request to dynamically update a price field, the xml return results, which were supposed to be just the price value as a number, were prefixed by that entire comment.
Now, I can remove it in my application code, which is what I have done, but I'd really like to know under what circumstances Apache decides to inject this comment into outputted HTML files.
For reference, here is my JS to send/handle the xml request:
<script type="text/javascript">
/**
* Updates the currently displayed price based on currently selected options
* #param category_id Id of currently selected category
*/
function updatePrice(category_id) {
if (category_id === undefined || category_id < 1) {
return false;
}
if (!document.getElementsByTagName) { return; }
var aSelect = document.getElementsByTagName("SELECT");
var data = [];
data.push("category_id=" + category_id);
for (var i = 0; i < aSelect.length; i++) {
var sid = aSelect[i].id;
if (sid !== undefined && sid.indexOf("select_") > -1) {
data.push(sid + '=' + aSelect[i].value);
}
}
data = data.join('&');
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// Hack to remove Apache's auto-generated comment/warning at top of some pages
var text = xmlhttp.responseText;
text = (text.length > 0 ? text.substring(text.lastIndexOf('>') + 1).trim() : '');
var price = document.getElementById("product-price");
if (price != null) {
price.value = (text.length < 1 ? 'N/A' : ('$' + text));
}
}
}
xmlhttp.open("POST", "rental_update_price.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(data);
}
</script>
And here is the php file that processes the request:
<?php
if (!isset($errors)) { $errors = array(); }
if (!isset($notifications)) { $notifications = array(); }
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($_POST['category_id']) || !is_numeric($_POST['category_id'])) {
die('Sorry, there has been a system error.');
}
$category_id = (int) $_POST['category_id'];
require './includes/config.inc.php';
require MYSQL;
$att_tbl = selectWithCondition($dbc, 'att_table', 'rental_categories', 'id', $category_id, 'i', 'LIMIT 1');
if ($att_tbl === FALSE) {
die('Failed to retrieve product attribute table from database.');
}
// Retrieve all 'select' keys and values to query exact product id and price
$selected = array();
foreach($_POST AS $k=>$v) {
if (strpos($k, 'select_') > -1) {
// All select fields should be foreign key references, i.e. positive integers
if (ctype_digit($v) && $v > 0) {
$selected[(str_replace('select_', '', $k) . '_id')] = (int) $v;
} else {
$errors[$k] = 'Invalid value';
}
}
}
if (empty($selected)) {
die('No columns selected.');
}
// TODO select price instead of id
$q = "SELECT p.id FROM products p";
$where = '';
foreach($selected AS $k=>$v) {
if (empty($where)) {
$where = "t.$k=$v";
} else {
$where .= " AND t.$k=$v";
}
}
$q .= " JOIN $att_tbl t ON t.product_id=p.id WHERE $where LIMIT 1";
if (($r = $dbc->query($q))) {
if ($row = $r->fetch_assoc()) {
// Generate dummy price value for testing:
echo number_format((((int) $row['id']) * 31) / 100, 2);
}
$r->close();
} else {
$notifications['error'] = 'A system error has occurred. The system administrator will be notified automatically.';
$notifications['error_log'] = 'Error No: ' . $dbc->errno . '-' . $dbc->error;
}
}
require MYSQL;
if MYSQL is a file, give it an extension .php so it doesn't bypass the PHP interpreter.
I think PHP does print the warning when you include a file which is not parsed.
Answering my own question since it was one of those where you look for days and when you finally break down and ask, it becomes glaringly obvious almost immediately.
In my MYSQL file, I had that comment at the top, even before the php tags, and in certain situations the MYSQL file is included before any other HTML output, which then results in that comment being displayed.
Moving the comment to within the php tags so that it is not considered HTML fixes the issue.
Thanks to all who commented.

How can I place text that relates to a foreach function, outside the loop?

I'm really unsure how to describe this, so please forgive me.
Basically, I'm reading from an XML, and then generating an IF statement that checks all records in the XML and if a condition matches, details about that record is displayed.
What I want to add, is a similar function but in reverse, but outside the foreach loop, so it's only displayed once.
foreach($xml as $Reader) { $items[] = $Reader; }
$items= array_filter($items, function($Reader) use ($exclude) {
if($Reader->Picture == 'None' || in_array($Reader->Pin, $exclude)) {
return false;
}
return true;
});
usort ($items, function($a, $b) {
return strcmp($a->Status,$b->Status);
});
foreach($items as $Reader) {
if($Reader->Status == 'Available' && !in_array($Reader->Pin, $exclude)) {
echo "<a href='/details?Pin=".$Reader->Pin."'>".$Reader->Name ." (".$Reader->Pin.")</a> is available! ... ";
}
}
if (!$items) { echo "Please check back in a moment when our readers will be available!"; }
So, in the XML file each Reader has a Status that can be one of three values: Available, Busy or Logged Off.
So what I'm doing, is for each record in the XML, checking if the Reader status is available.. and if so, echo the above line.
But I want to add in, that if NONE of the readers show as 'Available' to echo a single line that says 'Please check back in a moment'.
With the code above, ifthere are four readers online, but they're all busy.. nothing is displayed.
Any ideas?
Just use a simple boolean value
$noneAvailable = true;
foreach($items as $Reader) {
if($Reader->Status == 'Available' && !in_array($Reader->Pin, $exclude)) {
echo "<a href='/details?Pin=".$Reader->Pin."'>".$Reader->Name ." (".$Reader->Pin.")</a> is available! ... ";
$noneAvailable = false;
}
}
if ($noneAvailable) {
echo "Please check back in a moment";
}
I managed to take the answer given above, and combine it with XPath to just filter the records in the XML based on the status given using xPath.
include TEMPLATEPATH."/extras/get-readers.php";
$readers = $xml->xpath('/ReaderDetails/Reader[Status="Available"]');
$gotOps = false;
foreach ($readers as $Reader)
{
echo "<a href='/details?Pin=".$Reader->Pin."'>".$Reader->Name ." (".$Reader->Pin.")</a> is available! ... ";
$gotOps = true;
}
if ($gotOps!=true)
{
echo 'Please check back in a moment when our readers will be available!';
}

Categories