implode() an array with multiple database columns, except on last entry PHP - php

I am using PHP to create an XML document from a database to import into Adobe InDesign. I want to be able to add a comma after each entry but not on the last one. I have tried using implode() but I have had no luck. Any help would be greatly appreciated. Here is the code with out any attempt at adding the comma. I can just add a comma after the closing but that will still give me one on the last entry. Any advice on how to attack this would be much appreciated. Thanks!
function getAssocXML ($company) {
$retVal = "";
// Connect to the database by creating a new mysqli object
require_once "DBconnect.php";
$staffResult = $mysql->query("
SELECT company,
fName,
lName,
title,
contact1,
contact2
FROM staff
WHERE company = '$company'
AND title
LIKE '%Associate%'
AND archive = 0
");
if ($staffResult->num_rows >= 1 && $staffResult->num_rows < 4) {
$retVal = $retVal;
for ($i = 0; $i < $staffResult->num_rows; $i++) {
// Move to row number $i in the result set.
$staffResult->data_seek($i);
// Get all the columns for the current row as an associative array -- we named it $aRow
$staffRow = $staffResult->fetch_assoc();
// Write a table row to the output containing information from the current database row.
$retVal = $retVal . "<staff>";
$retVal = $retVal . "<name>" . $staffRow['fName'] . " " . $staffRow['lName'] . "</name>";
$retVal = $retVal . "<contact>" . staffContact($staffRow['contact1'], $staffRow['contact2']) . "</contact>";
$retVal = $retVal . "</staff>";
}
$retVal = $retVal . " — Associate
";
$staffResult->free();
}
if ($staffResult->num_rows > 4) {
$retVal = $retVal;
$retVal = $retVal . "<staffHeader>Associates: </staffHeader>";
for ($i = 0; $i < $staffResult->num_rows; $i++) {
// Move to row number $i in the result set.
$staffResult->data_seek($i);
// Get all the columns for the current row as an associative array -- we named it $aRow
$staffRow = $staffResult->fetch_assoc();
// Write a table row to the output containing information from the current database row.
$retVal = $retVal . "<staff>";
$retVal = $retVal . "<name>" . $staffRow['fName'] . " " . $staffRow['lName'] . "</name>";
$retVal = $retVal . "<contact>" . staffContact($staffRow['contact1'], $staffRow['contact2']) . "</contact>";
$retVal = $retVal . "</staff>";
}
$retVal = $retVal . "
";
$staffResult->free();
}
return $retVal;
}
print getAssocXML(addslashes($aRow['company']));

You can do it with the help of this query
echo join(' and ', array_filter(array_merge(array(join(', ', array_slice($array, 0, -1))), array_slice($array, -1)), 'strlen'));
OR
$last = array_slice($array, -1);
$first = implode(', ', array_slice($array, 0, -1));
$both = array_filter(array_merge(array($first), $last), 'strlen');
echo implode(' and ', $both);

I'm afraid that I don't readily grasp your intent here. I don't see anything in your code that is using any sort of array, which is a pre-requisite for implode() (a.k.a. join())
However, here's a little trick that I've used numerous times when I am building something in a loop:
$result = "";
$comma = "";
foreach (...) {
.. calculate some $value ..
$result = $result . $comma . $value;
$comma = ",";
}
The first time through the loop, $comma isn't a comma! It's an empty string. At the end of the first iteration through the loop, it becomes a comma, for use next time. It's a simple but effective way to build an arbitrarily-long "comma-separated string" in-place.
HTH!

Related

Pass a Variable in PHP to Query Database for Deletion

I am trying to create a cron job in php that deletes disabled users found in a csv file and logs the deleted users to a txt file. Everything works except only the last user in the csv file is deleted. Here is what I have so far:
class purgeInactive extends JApplicationCli
{
public function doExecute()
{
$file = '../tmp/purge_user.csv';
$contents = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$csvRows = array_map('str_getcsv', $contents);
$log = ('../log/purged_users.txt');
$today = date('F j, Y, g:ia');
$row = 1;
if (($handle = fopen("../tmp/purge_user.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
file_put_contents($log, PHP_EOL . 'Removed Disabled User(s): ' . $data[$c] . PHP_EOL . '-' . $today . PHP_EOL, FILE_APPEND);
$disUsers = implode(',', $data);
echo ', ' . $disUsers ; // to test $disUsers output
} // end for statement
} // end while statment
} // end if statement
fclose($handle);
$db = JFactory::getDbo();
$user = JFactory::getUser();
$query = $db->getQuery(true);
$userArray = var_export($disUsers,true);
echo PHP_EOL.'This is to test the output of $userArray'.$userArray;
$query
->select($db->quoteName(array('id')))
->from($db->quoteName('#__users'))
//->delete ($db->quoteName('#__users'))
//->where(array($db->quoteName('username') . ' IN(' . $userArray) . ')');
->where(array($db->quoteName('username') . ' = ' . $userArray));
//->where($deleteReq);
$db->setQuery($query);
//$result = $db->execute();
$result = $db->query();
}
}
JApplicationCli::getInstance('purgeInactive')->execute();
Any suggestions on how to run each user in the csv file individually? I am about brain dead on this as I have been working on it too long.
Note: I am running Joomla that uses ldap and I use echo for $userArray to check results.
I think instead of ...
->where(array($db->quoteName('username') . ' = ' . $userArray));
You just want
->where(array($db->quoteName('username') . ' IN(' . $userArray) . ')');
That's assuming you want to delete all the rows whose usernames are in $userArray.
If the values in $userArray aren't necessarily SQL-safe, you might also want to do this first:
$userArray = array_map('mysql_real_escape_string', $userArray);
Each row of your csv is iterating this line: $disUsers = implode(',', $data);
This means that all usernames in that row will be saved to $disUsers, then the next iteration will overwrite the old data with the new row's usernames -- this is why only the final row of data is making it down to your delete query.
$data[$c] is what should be pushed into a $disUsers array like this: $disUsers[] = $data[$c];
In your query, you'll need to quote-wrap each array value; this will do that job:
->where($db->qn('username') . ' IN (' . implode(',', array_map(function($username)use($db) {return $db->q($username);}, $disUsers)) . ')')
Here is a post of mine where I discuss writing Joomla queries with IN: https://joomla.stackexchange.com/a/22898/12352

PHP SQL - Order By Date failing due to ","

I have a very strange issue. I am querying data and formatting it into a json. The format works great, but when i try to add a case that prevents a , from appearing in the last item of the json, the "Order By Date" of my SQL statement doesn't work, i just orders it by ID. Any thoughts why?
$sql = "SELECT * FROM events ORDER BY date";
$res = mysql_query($sql,$con);
$number = mysql_num_rows($res);
$json = 'var event_data={';
$i = 1;
while ($row = mysql_fetch_assoc($res))
{
$json .= '"'.$row['id'].'": {';
$json .= '"loc_id":"'.$row['loc_id'].'"';
$json .= ', "type":"'.$row['type'].'"';
$json .= ', "time":"'.$row['time'].'"';
$json .= ', "date":"'.$row['date'].'"}';
if ($i < $number)
{
$json .= ','; //<----- this is the problem child
}else{
$json .= '';
}
$i ++;
}
$json .= '};';
echo $json;
Please stop what you're doing now and check out: http://php.net/manual/en/function.json-encode.php
Building your own json encoder is going to be difficult to do correctly and will take quite take quite a bit of processing if you're doing it from PHP. Build up your data structure using PHP then encode the entire thing in one pass:
$o = array();
while ( $row = mysql_fetch_assoc($res) ) {
$n = array();
$n['loc_id'] = $row['loc_id'];
$n['type'] = $row['type'];
# ...
$o[ $row['id'] ] = $n;
}
echo json_encode($o);

PHP Last in array to CSV

I have been trying to get this code to work for ages now and have looked at other questions but it is not working for me. Any guidance is greatly appreciated.
In context, there is a sql query to bring back all of the results for today's entries. These are converted to a CSV file every day. To import into the software then the end of each row must return "" and a carriage return except the last row which should not add a carriage return.
The code is below:
$xo1 = "\"\"";
$xo2 = "\r\n";
while ($row = mysql_fetch_array($sql)) {
for ($i = 0; $i < $columns_total; $i++) {
$output .='"'.$row["$i"].'",';
if(++$i === $columns_total){
$xo1 = "";
$xo2 = "";}
}
$output .= $xo1;
$output .= $xo2;
}
I guess rtrim() should do the job, if I got the question right.
while ( $row = mysql_fetch_array( $sql ) ) {
foreach( $row as $column ) {
$output .= sprintf( '"%s",""' . "\r\n" , $column );
}
}
rtrim( $output, '""' . "\r\n" );
You can also use the index of the loop for this problem. When index is above zero apply the $xo1 and $xo2. For example:
for ($i = 0; $i < $columns_total; $i++) {
if ( $i > 0 ) {
$output .= $xo1 . $xo2;
}
// now apply other workings
$output .='"'.$row["$i"].'",';
}

Can't get this auto-email to work in php. Can you help me?

I'm trying to make this secret santa auto-email script, and it's really confusing me... It doesn't email properly (one person gets a TON of emails, no one else gets any...)
I tried to just change the length on the array in the for loops, did I do it right?
I use the shuffle function and the email function, which seem to work well (aside from the for loop on the email function - did I do that right?). It's the main function I need help on.
Here's the code:
<?php
function twodshuffle($array)
{
// Get array length
$count = count($array);
// Create a range of indicies
$indi = range(1,$count);
// Randomize indicies array
shuffle($indi);
// Initialize new array
$newarray = array($count);
// Holds current index
$i = 0;
// Shuffle multidimensional array
foreach ($indi as $index)
{
$newarray[$i] = $array[$index];
$i++;
}
return $newarray;
}
function email($Name, $Email, $Likes)
{
$to = $Email;
$subject = '[Secret Santa] Happy Lolidays from Santabot 2020! Your match is here!';
$message = "HEY! You are " . $Name ."'s Secret Santa. Isn't that exciting? \r\n\r\nThis is what your match filled in for likes/dislikes: \r\n----------------------------\r\n" . $Likes . "\r\n----------------------------\r\n\r\n\r\nNow get them something nice and thoughtful. We will be swapping sometime around Christmas, so you have a lot of time to put some thought in it.\r\nLet's keep gifts around the $30 mark.\r\n\r\nHappy Lolidays,\r\nDCo's Santabot 2020.\r\n\r\nPS: I have set this up so not even I know the matches nor is a list stored anywhere. DO NOT delete this email if you are at risk of forgetting your match.";
$headers = 'From: Santabot 2020 <santabot2020#mydomain.com>' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
sleep(1000);
}
$con = mysql_connect("mysql.myserver.com", "username", "password") or die(mysql_error());
mysql_select_db("lolidays_dco", $con) or die(mysql_error());
$array;
//I just changed this array size now. Is this the right syntax?
for ($i = 1; $i <= array.length() -1; $i++) {
$sql = "SELECT * FROM tbl_data WHERE Number = " . $i;
$result = mysql_query($sql);
$count=mysql_num_rows($result);
while($row = mysql_fetch_array($result))
{
$Name = $row['Name'];
$Email = $row['Email'];
$Likes = $row['Likes'];
}
$array[$i] = array("Name" => $Name, "Email" => $Email, "Likes" => $Likes);
}
$array = twodshuffle($array);
$string;
//changed this array length as well, is this the right syntax?
for ($i = 0; $i <= array.length(); $i++) {
if ($i == 2) {
$n = $array['0']["Name"];
$e = $array[$i]["Email"];
$l = $array['0']["Likes"];
email($n, $e, $l);
echo "Email Sent!<br />";
$string = $string . $array[$i]["Name"] . " => " . $array['0']["Name"] . "\r\n";
email('Matches', 'backup#email.com', $string);
}
else {
$j = $i + 1;
$n = $array[$j]["Name"];
$e = $array[$i]["Email"];
$l = $array[$j]["Likes"];
email($n, $e, $l);
echo "Email Sent!<br />";
$string = $string . $array[$i]["Name"] . " => " . $array[$j]["Name"] . "\r\n";
}
}
echo "<strong>Done!</strong>";
?>
You've hard-coded the recipient:
$n = $array['0']["Name"]; <---should be $i, not '0'
$e = $array[$i]["Email"];
$l = $array['0']["Likes"]; <---should be $i, not '0'

implode() MySql Query not working

I am trying to implode some variables and insert them into a MySql database, but for some reason it is not working. I have been trying for hours and I''m just not sure what I'm doing wrong.
If you can help it would be much appreciated.
$AddressString = "address1,address2,address3,address5,postcode";
$AddressSplit = explode( ",", $AddressString ); //split the address string
$StringLength = count( $AddressSplit ) - 1;
$s = 0; //trim any white spaces from the address string
while ( $s < count( $AddressSplit ) ) {
$AddressSplit[$s] = trim( $AddressSplit[$s] );
$s++;
}
//Create the Values to insert into DB
$MysqlValues = implode( "','", $AddressSplit );
$MysqlValues = "'$MysqlValues'";
$NumberVals = count( $AddressSplit );
$t = 1;
while ( $t < $NumberVals ) {
$ad[$i] = "add$i";
$t++;
}
$TableNames = implode( ", ", $ad );
mysql_query( "INSERT INTO pstc_add_main (" . $TableNames . ",add10,date)
VALUES (" . $MysqlValues . ",'$cdate')" );
}
Because you start making the field names 1 based, your are one field short!
In the end you must end with a equal number of fields and values.
Try this:
$t = 0;
while ( $t < $NumberVals ) {
$ad[$i] = "add$i";
$t++;
}
Or, if you do not want the first field to be "add", change it like this:
$t = 1;
while ( $t <= $NumberVals ) {
$ad[$i] = "add$i";
$t++;
}
Of course, it would have been a easy test to do:
$sql = "INSERT INTO pstc_add_main (" . $TableNames . ",add10,date)
VALUES (" . $MysqlValues . ",'$cdate')";
var_dump($sql);
mysql_query($sql);
Not tested,
I doubt you change,
$MysqlValues = implode("','", $AddressSplit);
to
$MysqlValues = implode(",", $AddressSplit);
Just use
$MysqlValues = implode( ",", $AddressSplit );
and try to edit the code like
mysql_query( "INSERT INTO pstc_add_main (".$TableNames." ,add10,date)
VALUES (" . $MysqlValues . ",$cdate)" );

Categories