If value exists in array, end, and restart with next array value - php

All day I've been trying to achieve the following with PHP:
Update: This is the code I'm using, please read the message in between
<?php
include ('acs_params.php');
$acs_value_based = array(25, 30, 35, 40, 45, 50, 60, 70);
$acs_types = array("$add_total","$done_total");
print_r($acs_id);
foreach ( $acs_value_based as &$value ) {
foreach ( $acs_types as &$counters) {
if ($counters >= $value) {
if ($acs_types[0] == $counters) {$acs_types1 = '1'; $acs_name = 'Tasker'; $acs_action = 'adding';}
if ($acs_types[1] == $counters) {$acs_types1 = '2'; $acs_name = 'Completer'; $acs_action = 'completing';}
if ($value == '25') { $acs_lvl = '1'; $acs_id = '25';}
if ($value == '30') { $acs_lvl = '2'; $acs_id = '30';}
if ($value == '35') { $acs_lvl = '3'; $acs_id = '35';}
$acs_exists = $acs_types1 . $acs_id;
Over here it should check if this array print_r($acs_id); contains the value of
$acs_exists. if the value already exists the following code should not be executed,
instead, the script should start again at the beginning but then with the second value of
the array print_r($acs_id);. It the value is not existing yet, then continue with the queries. (I hope my goal is clear).
mysql_query("INSERT INTO users_log(id, log, userid, date, points, action) VALUES
(id, 'achievement 1', '$username', '$currenttime', '0', '8') ");
mysql_query("INSERT INTO users_achievements(id, userid, acs_id, date) VALUES
(id, '$username', '$acs_types1$acs_id', '$currenttime') ");
?>

foreach ($acs_id as $item) {
if ($item == $acs_exist) continue;
// continue with the script (query etc)
}
Is that what you're after?

This sounds to simple, but I'll give it a shot:
// if $acs_exist is not in the array $acs_id, execute script, otherwise do nothing
if(!in_array($acs_exist, $acs_id)) {
// do whatever you want
}
I'm still poking in the dark here …
foreach($acs_id => $id) {
if($acs_id == $acs_exist) { // already exists
} else { // does not exist yet, insert into db
// your code: INSERT INTO table (column, …) VALUES(:acs_id, …)
}
}

Related

Multiple tinyint when insert data into MySql database

I have a php code which insert questions and answers for a quiz into a mysql database and for each answer a specifically tinyint number. With this method I can choose which one is the correct answer by allocating the number 1 to it and 0 to the rest of them. What I want is to can allocate to the wrong answers the numbers 2, 3 and 4, not 0 to all. I hope you understood. My English is not so good. Thank you very much !
My code:
// Question query
$query = "INSERT INTO `questions`(question_number, text)
VALUES('$question_number', '$question_text')";
// Run query
$insert_row = $mysqli->query($query) or die($mysqli->error.__LINE__);
// Validate insert
if ($insert_row) {
foreach ($choices as $choice => $choice_text) {
if($choice_text != '') {
if($correct_choice == $choice) {
$is_correct = 1;
} else{
$is_correct = 0;
}
Why don't you specify the wrong answer when it's not correct?
if($choice_text != '') {
if($correct_choice == $choice) {
$is_correct = 1;
} else{
$is_correct = $choice;
}

Import from CSV, record already exist else successful, else failed

I have a script that imports records to multiple database tables, all relation to one parent entity (address).
If the address already exist, extra columns should just be updated according to the csv. The same counts for all other entities. A counter ($exist++) should increase or an array ($existingRecords) should be filled with already existing records.
If mandatory fields are empty in the record, that record should be added to another array ($failedRecords) or another counter ($failed++) should increase.
If the address doesn't yet exist and should be created with all fields just a counter ($successful++) should increase.
In the end I have an array $result that give the number of failed, successful, and already existing (but updated) records, for user feedback.
How can I implement this in a nice clean manner without messing my current script too much up? Because what is happening right now, if a record already exist the $exist counter increase but the $successful counter as well, and I only want the $exist counter to increase if a record already already exists, and only the $successful counter should increase if a record still has to be added and was added successfully. Same goes for the $failed counter.
Here is my script (with what I tried):
public function import(CsvFile $csv) {
$root = __DIR__.'/../../../../../';
$file = $root.'var/data/'.$csv->getCsvName();
$fp = fopen($file, "r");
$batchSize = 25;
$header = null;
$successful = 0;
$failed = 0;
$exist = 0;
$results = [];
while ($row = fgetcsv($fp, null, ";")) {
if ($header === null) {
$header = $row;
continue;
}
$record = array_combine($header, $row);
// cast all values to correct data types
foreach ($record as $key => &$value) {
if (strpos($key, 'datum') !== false ||
strpos($key, 'tijdstip') !== false &&
strlen($value) == 8 &&
is_numeric($value)
) {
$value = \DateTime::createFromFormat('Ymd', $value);
}
if ($value === "") {
$value = null;
}
if (is_numeric($value)) {
intval($value) == $value ? $value = (int)$value : $value = (float)$value;
}
}
// required fields
if (!$record['name'] ||
!$record['surname'] ||
!$record['email'] ||
!$record['phone'] ||
!$record['street'] ||
!$record['houseNo'] ||
!$record['town'] ||
!$record['postcode'] ||
!$record['location'] ||
!$record['lecture'] ||
!$record['session'] ||
) {
$failed++;
continue;
}
$student = $this->em->getRepository(Student::class)->findStudent(
$record['name'], $record['surname'],
$record['email'], $record['phone']
);
if (!$student) {
$student = new Student();
$student->setName($record['name']);
$student->setSurname($record['surname']);
$student->setEmail($record['email']);
$student->setPhone($record['phone']);
} else {
$exist++;
}
$student->setAge($record['age']);
$student->setLength($record['length']);
$address = $this->em->getRepository(Address::class)->findOneBy([
'street' => $record['street'],
'houseNo' => $record['houseNo'],
'town' => $record['town'],
'postcode' => $record['postcode'],
);
if (!$address) {
$address = new Address();
$address->setStreet($record['street']);
$address->setHouseNo($record['houseNo']);
$address->setPostcode($record['postcode']);
$address->setTown($record['town']);
}
$student->setAddress($address);
$lecture = $this->em->getRepository(Lecture::class)->findOneBy([
'location' => $record['location'],
'lecture' => $record['lecture'],
'session' => $record['session'],
]);
if (!$lecture) {
$lecture = new Lecture();
$lecture->setLocation($record['location']);
$lecture->setLecture($record['lecture']);
$lecture->setSession($record['session']);
}
$lecture->setTime($record['time']);
$lecture->setSubject($record['subject']);
$student->setLecture($lecture);
$validationErrors = $this->validator->validate($student);
if (!count($validationErrors)) {
$this->em->persist($student);
$successful++;
}
if (($successful % $batchSize) == 0) {
$this->em->flush();
}
}
fclose($fp);
$csv->setImported(true);
$this->em->persist($csv);
$this->em->flush(); // Also persist objects that did not make up an entire batch
$results['successful'] = $successful;
$results['failed'] = $failed;
$results['exist'] = $exist;
return $results;
}
You can replace the existing records counter with a flag that is set to TRUE only if the current record is an existing one, and use it at the end before persisting the record.
You can set the flag to FALSE on the beginning of each loop:
while ($row = fgetcsv($fp, null, ";")) {
$existingRecordFlag = FALSE; // initialize the flag for the current record
then update it instead of the counter :
if (!$student) {
$student = new Student();
$student->setName($record['name']);
$student->setSurname($record['surname']);
$student->setEmail($record['email']);
$student->setPhone($record['phone']);
} else {
$existingRecordFlag = TRUE; //update the flag
}
then before persisting user check the value for the flag and according to it update the counter:
$validationErrors = $this->validator->validate($student);
if (!count($validationErrors)) {
$this->em->persist($student);
if ( !$existingRecordFlag){
$successful++; //new record
}else{
$exist++; //existing user
}
}else{
$failed++; //failed as the validations has errors
continue;
}
also you can add the existing records to the batch counter as they might be updated, they can also be persisted with the successful ones
if ((($successful+$exist) % $batchSize) == 0) {
$this->em->flush();
}
In your block handling the addresses you could an existing/failed counter quite easily:
$exist++;
if (!$address) {
$exist--;
$successful++;
//...
}
This will always increase the exist-counter, but jump back if address is empty and increase the new address-counter instead. Alternatively you could work with array_push($record) and array_pop($record) to add/remove the current record from a list. This might cause memory issues, since you keep your records in multiple arrays and you might run into out of memory errors.
For missing mandatory fields you'd have to do a check on the $address afterwards to see if it's not empty/containing invalid data and then increase the counter/update the field.
If you want

Display static message for empty values

i tried below code to fetch results of column dpaid_status from mysql database & its working fine:
Database
site
$i = 0;
foreach($order as $orderData)
{
$k = 0;
$orderitems = $orderData['dproduct_id'];
$orderitemsarray = explode(",", $orderitems);
while ($k < count($orderitemsarray))
{
if ($orderitemsarray[$k] != '0')
{
$stmtorders = $user_home->runQuery("SELECT * FROM order_details");
$stmtorders->execute(array(":dorder_id" => $orderData['entity_id']));
$roworders = $stmtorders->fetch(PDO::FETCH_ASSOC);
$dorderStatus = $roworders['dpaid_status'];
$productdetail = Mage::getModel('catalog/product')->load($orderitemsarray[$k]);
$designer_id = $productdetail->getDesignerID() ;
if($accountType == "admin")
{
$designerName = getDesignerName($productdetail->getDesignerID()) . " -(" . $productdetail->getDesignerID() . ")";
$stmt1 = $user_home->runQuery("SELECT * FROM order_details WHERE dproduct_id=:pid and designerorder_id=:doid");
$stmt1->execute(array(
":doid" => $orderData->getIncrementId(),
":pid" => $orderitemsarray[$k],
));
$paid_status='';
while($datas = $stmt1->fetch())
{
$paid_status=$datas['dpaid_status'];
}
$responce[] = array(
$paid_status
);
return json_encode($responce);
But for some columns there is no value for dpaid_status, so i wanted to display none for those in page. so instead of $paid_status=$datas['dpaid_status']; i tried below code ,
if ($roworders['dorder_id'] == '')
{
$paid_status='unpaid';
}
else
{
$paid_status=$datas['dpaid_status'];
}
ex : in above image there is no row for "15585" in database , so it should display unpaid for that.... but now its displaying blank....
You should check your $paid_status variable right before returning/using it. This way you will catch all cases when the value is empty (either empty value in the table or missing row in the database table).
I have added the new lines to your code, below:
$stmt1 = $user_home->runQuery("SELECT * FROM order_details WHERE dproduct_id=:pid and designerorder_id=:doid");
$stmt1->execute(array(
":doid" => $orderData->getIncrementId(),
":pid" => $orderitemsarray[$k],
));
$paid_status='';
while($datas = $stmt1->fetch())
{
$paid_status=$datas['dpaid_status'];
}
//added new lines of code here - START
if ( $paid_status == ''){
$paid_status='unpaid';
}
//added new lines of code here - END
$responce[] = array(
$paid_status
);
You can solve the problem also at SQL level, just using a query like:
SELECT [field_list], IFNULL(dpaid_status, 'unpaid') as paid_status FROM order_details
which return the dpaid_status value if the field is not null, else return 'unpaid'
You just need to use PHP empty().
Determine whether a variable is considered to be empty. A variable is
considered empty if it does not exist or if its value equals FALSE.
empty() does not generate a warning if the variable does not exist.
The following things are considered to be empty:
"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)
so your if statement can be written
if (empty($roworders['dpaid_status']))
{
$paid_status='unpaid';
}
else
{
$paid_status=$datas['dpaid_status'];
}
if ($roworders['dpaid_status'] != '')
{
$paid_status=$datas['dpaid_status'];
}
else
{
$paid_status='unpaid';
}

How to send "null" or empty value to database through PHP?

I have a jqgrid that with date columns that post in format 0/0/0000 or if empty send "null" to my php file to then insert to MYsql column. It posts "null" but does not send "null" command to database column. What I'm I missing? Firephp says that at this point my date column inputs are all '"1969-12-31"'. What can I do to post "null" correctly to these columns?
****UPDATE: Here is the var dumb for $_REQUEST:****
array(12) {
["name"]=>string(24) "FABTECH B2B Presentation"
["id_continent"]=>string(6) " Ramon"
["lastvisit"]=>string(10) "12/31/2104"
["cdate"]=>string(9) "8/22/2014"
["ddate"]=>string(9) "9/14/2014"
["notes"]=>string(69) "B2B machines are C1 AJ and HG ATC. Waiting for part data from Yoshi."
["hello"]=>string(2) "No"
["mydate"]=>string(4) "null"
["oper"]=>string(4) "edit"
["id"]=>string(3) "184"
["PHPSESSID"]=>string(32) "93de884f9e02d507ff3662f63149f9f3"
["SQLiteManager_currentLangue"]=>string(2) "10"
}
My code:
$crudColumns = array(
'id' =>'id'
,'name'=>'name'
,'id_continent'=>'id_continent'
,'lastvisit'=>'lastvisit'
,'cdate'=>'cdate'
,'ddate'=>'ddate'
,'notes'=>'notes'
,'hello'=>'hello'
,'mydate'=>'mydate'
);
function fnCleanInputVar($string){
//$string = mysql_real_escape_string($string);
return $string;
}
/*----====|| GET and CLEAN THE POST VARIABLES ||====----*/
foreach ($postConfig as $key => $value){
if(isset($_REQUEST[$value])){
$postConfig[$key] = fnCleanInputVar($_REQUEST[$value]);
}
}
foreach ($crudColumns as $key => $value){
if(isset($_REQUEST[$key])){
if ($key == 'lastvisit' || $key == 'cdate' || $key == 'ddate' || $key == 'mydate' ) {
$crudColumnValues[$key] = '"'.date('Y-m-d', strtotime($_REQUEST[$key])).'"';
} else {
$crudColumnValues[$key] = '"'.fnCleanInputVar($_REQUEST[$key]).'"';
}
}
}
FB::info($crudColumnValues, "Dates");
/*----====|| INPUT VARIABLES ARE CLEAN AND CAN BE USED IN QUERIES||====----*/
Mysql query
case $crudConfig['update']:
/* ----====|| ACTION = UPDATE ||====----*/
if($DEBUGMODE == 1){$firephp->info('UPDATE','action');}
$sql = 'update '.$crudTableName.' set ';
/* create all of the update statements */
foreach($crudColumns as $key => $value){ $updateArray[$key] = $value.'='.$crudColumnValues[$key]; };
$sql .= implode(',',$updateArray);
/* add any additonal update statements here */
$sql .= ' where id = '.$crudColumnValues['id'];
if($DEBUGMODE == 1){$firephp->info($sql,'query');}
mysql_query( $sql )
or die($firephp->error('Couldn t execute query.'.mysql_error()));
break;
Check whether the parameter from the grid is null, and put NULL into the database instead of the date.
foreach ($crudColumns as $key => $value){
if(isset($_REQUEST[$key])){
if ($key == 'lastvisit' || $key == 'cdate' || $key == 'ddate' || $key == 'mydate' ) {
if ($_REQUEST[$key] == 'null') {
$crudColumnValues[$key] = 'NULL';
} else {
$crudColumnValues[$key] = '"'.date('Y-m-d', strtotime($_REQUEST[$key])).'"';
}
} else {
$crudColumnValues[$key] = '"'.fnCleanInputVar($_REQUEST[$key]).'"';
}
}
}
Seems that you may be confusing empty with null. An empty string will be interpreted as "" whereas null will be interpreted as "null", big difference. Try this.
EDIT:
After looking at the PHP manual it seems that if you try to add a null value to an array key it is changed to "".
First of all, create your array like this
['mydate'] => ''
Change your date formatting.
foreach ($crudColumns as $key => $value){
if(isset($_REQUEST[$key])){
if ($key == 'lastvisit' || $key == 'cdate' || $key == 'ddate' || $key == 'mydate' ) {
if (strtotime($value)) {
$value = '"'.date('Y-m-d', $value).'"';
} else {
$value = "";
}
} else {
$crudColumnValues[$key] = fnCleanInputVar($_REQUEST[$key]);
}
Also, part of the issue is that you are specifying the keys but you need to be changing the value.

Merging PHP IF statements to a single statement or function

So I have some code that it seems that I have to repeat over and over again for $round == P,1,2 and A. Is there any I can achieve this without producing redundant code?
I'm thinking of writing a function that simply swaps through through all 3 possible $round variables that can be available and echoing the relevant information. Any idea on how to achieve this?
The other information will remain the same - its only $round that will change,
// determine previous round
if($round == "P") echo "";
// if we are in round 1, look up round P bookings
if($round == "1")
{
$sql = "SELECT
*
FROM ts_request
INNER JOIN ts_day
ON ts_request.day_id = ts_day.id
INNER JOIN ts_period
ON ts_request.period_id = ts_period.id
INNER JOIN ts_allocation
ON ts_request.id = ts_allocation.request_id
WHERE ts_request.round=:round
AND ts_request.dept_id=:dept
ORDER BY ts_request.module_id ASC";
$stm = $pdo->prepare( $sql );
$stm->execute( array( ':round' => 'P', ':dept' => $loggedin_id ) );
$rows = $stm->fetchAll();
foreach ($rows as $row)
{
echo '<tr align="center">';
echo '<td>'.$row['module_id'].'</td>';
echo '<td>'.$row['day'].'</td>';
echo '<td>'.$row['period'].'</td>';
echo '<td>';
$sql = "SELECT * FROM ts_roompref
WHERE request_id=:id";
$stm = $pdo->prepare( $sql );
$stm->execute( array( ':id' => $row['request_id']) );
$rows2 = $stm->fetchAll();
foreach ($rows2 as $row2)
{
if ($row2['room_id']=="0")
{
echo "Any<br>";
}
else
{
echo $row2['room_id'].'<br>';
}
}
echo '</td>';
echo '<td>'.$row['status'].'</td>';
echo '</tr>';
}
}
// if we are in round 2, look up round 1 bookings
if($round == "2")
{
$sql .= "";
}
foreach ($rows as $row)
{
// echo results here
};
// if we are in round A, look up round 2 bookings
if($round == "A")
{
$sql .= "";
}
foreach ($rows as $row)
{
// echo results here
};
This may help.
$roundsInOrder = array('P', '1', '2', 'A');
$roundKey = array_search($incomingRoundLetter, $roundsInOrder);
if ($roundKey !== false || $roundKey != 0) {
$roundToQuery = $roundsInOrder[$roundKey - 1];
// your other code snipped
$stm->execute( array( ':round' => $roundToQuery, ':dept' => $loggedin_id ) );
//more code here
}
What this code does:
It sets up the rounds in order. Then, it searches the rounds for the incoming round. We really want the key. Then, the if statement checks to a) make sure we have actually found the round and b) the round is not the first one (0 = P) because we don't want to do any query then. Finally, the $roundToQuery gets the value out of the rounds that is directly before the current key.
I think what you are searching for is the switch() function in php.
Here is a nice and simple tutorial on how to use it:
http://www.tizag.com/phpT/switch.php
Hope this helps.
"Swapping" already exists, it's called "switch statement". In your case it should look like this:
switch($round) {
case "P":
//code
break;
case "1":
//code
break;
case "2":
//code
break;
case "A":
//code
break;
default:
//code, when value of $round doesn't match any case
break;
}

Categories