Psycho
-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Community Answers
-
Psycho's post in Not all quieries from form checkboxes are not being executed was marked as the answer
As @dodgeitorelse3 asks, please show your form code. It is impossible for a single variable (e.g. $_POST['vote']) to have multiple values. I am assuming you have nine checkboxes all with the same name, but different values. That won't work. You need to either create them with different names OR create them as an array. Also, checkboxes are unique in that if they are not checked they are not included in the POST data, so you would want to check that they are set and not just check for the values.
If you name each checkbox differently (the value would be unnecessary in this context)
<input type="checkbox" name="Juste" value="1"> Juste <input type="checkbox" name="Chavez-Gris" value="1"> Chavez-Gris Then your processing code might look like this
if (isset($_POST['Juste'])) { $result = mysqli_query($db,"UPDATE NewBoard SET votes=votes+'1' WHERE lname = 'Juste'")or die ("Fatal Query Error: " . mysqli_error($db)); } if (isset($_POST['Chavez-Gris'])) { $result = mysqli_query($db,"UPDATE NewBoard SET votes=votes+'1' WHERE lname = 'Chavez-Gris'")or die ("Fatal Query Error: " . mysqli_error($db)); } Or you could create your checkboxes as an array (this would be my approach)
<input type="checkbox" name="votes[]" value="Juste"> Juste <input type="checkbox" name="votes[]" value="Chavez-Gris"> Chavez-Gris In which case the processing code might look like this
//Set variable based on POST value or empty array if none selected $votesArray = isset($_POST['votes']) ? $_POST['votes'] : array(); //Check for each value in the $votesArray if (in_array('Juste', $votesArray)) { $result = mysqli_query($db,"UPDATE NewBoard SET votes=votes+'1' WHERE lname = 'Juste'")or die ("Fatal Query Error: " . mysqli_error($db)); } if (in_array('Chavez-Gris', $votesArray)) { $result = mysqli_query($db,"UPDATE NewBoard SET votes=votes+'1' WHERE lname = 'Chavez-Gris'")or die ("Fatal Query Error: " . mysqli_error($db)); }
-
Psycho's post in Help with directory loop was marked as the answer
A couple things. First please put code into code tags using the forum editor. I have fixed your initial post.
Second, you say that you get a "blank screen", but you have provided no content of what debugging you have performed. You state you are looking for another way to iterate over the files - but you have already confirmed that the files do load and you can iterate over them - you just aren't getting results. So, rather than finding a different way to get the files (which you have already accomplished), you need to figure out why it is not working.
I suspect the issue may be your variable names are causing confusion and you aren't passing what you think you are to the processing code. In example you post with a single file you have this:
$file = file('myfile.xml'); In that case $file is an array of the contents of the file. Then you state that you tried thing such as
$file = glob("directory/*"); foreach ($file as $line) { or
$directory = 'directory'; $files = scandir($directory); foreach ($files as $file) { In the first case $line is a $file (not a line) and in the second case $file (in the foreach loop) is a reference to the file NOT an array of the contents of the file. I'm assuming you are not calling file() on the file reference within your loop. If you had called that first variable $linesAry, which is more accurate to what it is, I think you would have seen this yourself.
This should work. Note I don't have a an environment to test on at the moment. So there could be some minor typos\errors.
<?php //Make the DB connection $servername = "localhost"; $username = "dbuser"; $password = "dbpass"; $db = "dbdb"; $conn = new mysqli($servername, $username, $password, $db); if ($conn->connect_error){ die("Connection failed: ". $conn->connect_error); } //Get the contents of the directory $directoryStr = "directory/*"; echo "Processing directory: {$directoryStr}<br>\n"; $filesAry = glob($directoryStr); echo "Found: " . count($filesAry) . " files<br><br>\n"; //Iterate over each file foreach ($filesAry as $fileStr) { //Reset the variables for the data being searched $ip = ''; $hostname = ''; $port = ''; $portArray = array(); $portList = ''; $timestamp = ''; //Get content of the file into an array echo "Processing file: {$fileStr}<br>\n"; $linesAry = file($fileStr); //Iterate over each line of text in the file foreach($linesAry as $lineStr) { //Get IP Address if (strpos($lineStr, 'addrtype="ipv4"') == TRUE) { preg_match('/addr=".* addrtype/', $lineStr, $results); $ip = implode(" ",$results); $ip = ltrim($ip, 'addr="'); $ip = rtrim($ip, '" addrtype'); echo "<br><strong><u>Device</u></strong><br>"; echo "IP Address: $ip<br>"; } //Get Hostname if (strpos($lineStr, 'type="PTR"') == TRUE) { preg_match('/name=".*" type/',$lineStr,$results); $hostname = implode(" ",$results); $hostname = ltrim($hostname,'name="'); $hostname = rtrim($hostname, ' type'); $hostname = rtrim($hostname, '"'); echo "Hostname: $hostname<br>"; } //Get Ports if (strpos($lineStr, 'portid="') == TRUE) { preg_match('/portid=".*><state/',$lineStr,$results); $port = implode(" ",$results); $port = ltrim($port,'portid="'); $port = rtrim($port, '"><state'); echo "Port: $port<br>"; array_push($portArray, $port); } //Add Values to Database if (strpos($lineStr, '/host>') == TRUE) { $timestamp = time(); $mytime = new \DateTimeImmutable('@'.$timestamp); $portList = implode(", ",$portArray); $sql = "insert into _____ (ip,hostname,ports,timestamp) values ('$ip', '$hostname', '$portList', '$timestamp')"; if ($conn->query($sql) === TRUE) { echo "Data Added: $ip - $hostname - $portList - $timestamp <br>"; } else { echo "Error: ".$sql."<br>".$conn->error; } } } } //Close the DB connection $conn->close(); ?>
-
Psycho's post in please help - don't know how to sequence call-ups was marked as the answer
No. It is a lot to go through. But, I can tell that there is a lot of unneeded code. For example the big sections where you are echoing out "<? echo $data["BFG002"] ?>" should be put in a function and called, when needed. And it makes no sense to go in and out of PHP code between those values.
For example, you can reduce all of this:
[quote]<? echo $data["BFG001"] ?> <? echo $data["BFG002"] ?> <? echo $data["BFG003"] ?> <? echo $data["BFG004"] ?> <? echo $data["BFG005"] ?> <? echo $data["BFG006"] ?> <? echo $data["BFG007"] ?> <? echo $data["BFG008"] ?> <? echo $data["BFG009"] ?> <? echo $data["BFG010"] ?> <? echo $data["BFG011"] ?> <? echo $data["BFG012"] ?> <? echo $data["BFG013"] ?> <? echo $data["BFG014"] ?> <? echo $data["BFG015"] ?> <? echo $data["BFG016"] ?> <? echo $data["BFG017"] ?> <? echo $data["BFG018"] ?> <? echo $data["BFG019"] ?> <? echo $data["BFG020"] ?> <? echo $data["BFG021"] ?> <? echo $data["BFG022"] ?> <? echo $data["BFG023"] ?> <? echo $data["BFG024"] ?> <? echo $data["BFG025"] ?> <? echo $data["BFG026"] ?> <? echo $data["BFG027"] ?> <? echo $data["BFG028"] ?> <? echo $data["BFG029"] ?> <? echo $data["BFG030"] ?> <? echo $data["BFG031"] ?> <? echo $data["BFG032"] ?> <? echo $data["BFG033"] ?> <? echo $data["BFG034"] ?> <? echo $data["BFG035"] ?> <? echo $data["BFG036"] ?> <? echo $data["BFG037"] ?> <? echo $data["BFG038"] ?> <? echo $data["BFG039"] ?> <? echo $data["BFG040"] ?> <? echo $data["BFG041"] ?> <? echo $data["BFG042"] ?> <? echo $data["BFG043"] ?> <? echo $data["BFG044"] ?> <? echo $data["BFG045"] ?> <? echo $data["BFG046"] ?> <? echo $data["BFG047"] ?> <? echo $data["BFG048"] ?> <? echo $data["BFG049"] ?> <? echo $data["BFG050"] ?> <? echo $data["BFG051"] ?> <? echo $data["BFG052"] ?> <? echo $data["BFG053"] ?> <? echo $data["BFG054"] ?> <? echo $data["BFG055"] ?> <? echo $data["BFG056"] ?> <? echo $data["BFG057"] ?> <? echo $data["BFG058"] ?> <? echo $data["BFG059"] ?> <? echo $data["BFG060"] ?> <? echo $data["BFG061"] ?> <? echo $data["BFG062"] ?> <? echo $data["BFG063"] ?> <? echo $data["BFG064"] ?> <? echo $data["BFG065"] ?> <? echo $data["BFG066"] ?> <? echo $data["BFG067"] ?> <? echo $data["BFG068"] ?> <? echo $data["BFG069"] ?> <? echo $data["BFG070"] ?> <? echo $data["BFG071"] ?> <? echo $data["BFG072"] ?> <? echo $data["BFG073"] ?> <? echo $data["BFG074"] ?> <? echo $data["BFG075"] ?> <? echo $data["BFG076"] ?> <? echo $data["BFG077"] ?> <? echo $data["BFG078"] ?> <? echo $data["BFG079"] ?> <? echo $data["BFG080"] ?> <? echo $data["BFG081"] ?> <? echo $data["BFG082"] ?> <? echo $data["BFG083"] ?> <? echo $data["BFG084"] ?> <? echo $data["BFG085"] ?> <? echo $data["BFG086"] ?> <? echo $data["BFG087"] ?> <? echo $data["BFG088"] ?> <? echo $data["BFG089"] ?> <? echo $data["BFG090"] ?> <? echo $data["BFG091"] ?> <? echo $data["BFG092"] ?> <? echo $data["BFG093"] ?> <? echo $data["BFG094"] ?> <? echo $data["BFG095"] ?> <? echo $data["BFG096"] ?> <? echo $data["BFG097"] ?> <? echo $data["BFG098"] ?> <? echo $data["BFG099"] ?> <? echo $data["BFG100"] ?> <? echo $data["BFG101"] ?> <? echo $data["BFG102"] ?> <? echo $data["BFG103"] ?> <? echo $data["BFG104"] ?>[/quote]
To this:
[code]<?php
for ($i=1; $i<103; $i++) {
$aryIdx = "BFG" . str_pad($i, 3, '0', STR_PAD_LEFT);
echo " " . $data[$aryIdx];
}
?>[/code]
-
Psycho's post in Loop through line items (Stripe) pulled from database was marked as the answer
Unless there are additional fields in the query result set, you don't have all the corresponding fields shown in the example data. The example data has a "name" and "description". Your data has a description, but no name. You could use the SKU in place of the name. Also, I assume "unit_amount" is the price. Here is some (untested) code which should do what you need
//Create the line items array $lineItems = array(); foreach ($resultID as $row) { $lineItems[] = array( "price_data" => array( "currency" =>"usd", "product_data" => array( "name"=> $row['sku'], "description" => $row['description'] ), "unit_amount" => $row['price'] ), "quantity" => $row['qty'] ) ); //Create full payment array $paymentArray = array( "success_url" => "https://www.domain.com/stripesuccess.php?sid={CHECKOUT_SESSION_ID}", "cancel_url" => "https://www.domain.com/cart.php", "mode" => 'payment', "line_items" => $lineItems ); //Set session for payment call $session = \Stripe\Checkout\Session::create($paymentArray);
-
Psycho's post in Simplify code was marked as the answer
Here 0is how I would handle that
function columninfo($table, $col = NULL) { //State the error condition check if(!$this->CheckTable($table)){ return false; } //State the error condition check if($col!=NULL && !$this->Checkfield($table, $col)){ return false; } //No errors $stmt = $this->db->prepare('SELECT * FROM '.$table); $stmt->execute(); $numCol = $stmt->columnCount(); $colAry = array(); for ($i = 0; $i < $numCol; $i++) { if($stmt->getColumnMeta($i)['name'] == $col) { //Return type for selected column return $stmt->getColumnMeta($i)[0]; } else { //Append current column to return arrray $colAry[] = $stmt->getColumnMeta($i); } } //Return array for all columns return $colAry; }
-
Psycho's post in I have AND operator in Where statement of query, how can i know which statement did not returned was marked as the answer
You can give this a try. I think it's probably a little more verbose than it needs to be, but should do what you are asking. Not going to guarantee it is what you want, so run it through some tests first
<?php //Var to hold result $result = false; //Query for an exact match on both gpw and ewt $query = "SELECT gpm, ewt, totCool from {$uniluxModel} where gpm = :uniluxGpm AND ewt = :uniluxEwt"; $stmt = $dbConn->prepare($queryStr); $stmt->execute(array(':uniluxGpm' => $uniluxGpm, ':uniluxEwt' => $uniluxEwt)); if($stmt->rowCount() > 0) { //There was an exact match $result = $stmt->fetchColumn() } //If no result try getting the two closest records matching gpm and high/low for ewt if (!$result) { $query = "( SELECT gpm, ewt, totCool FROM wxyz WHERE gpm = :uniluxGpm1 AND ewt < :uniluxEwt1 ORDER BY gpm DESC LIMIT 1 ) UNION ( SELECT gpm, ewt, totCool FROM wxyz WHERE gpm = :uniluxGpm2 AND ewt > :uniluxEwt2 ORDER BY gpm ASC LIMIT 1 )"; $stmt = $dbConn->prepare($queryStr); $stmt->execute(array(':uniluxGpm1' => $uniluxGpm, ':uniluxEwt1' => $uniluxEwt, ':uniluxGpm2' => $uniluxGpm, ':uniluxEwt2' => $uniluxEwt)); if($stmt->rowCount() > 0) { //There was a result $result = $stmt->fetchColumn() } } //If no result try getting the two closes records matching ewt and high/low for gpm if (!$result) { $query = "( SELECT gpm, ewt, totCool FROM wxyz WHERE gpm < :uniluxGpm1 AND ewt = :uniluxEwt1 ORDER BY gpm DESC LIMIT 1 ) UNION ( SELECT gpm, ewt, totCool FROM wxyz WHERE gpm > :uniluxGpm2 AND ewt = :uniluxEwt2 ORDER BY gpm ASC LIMIT 1 )"; $stmt = $dbConn->prepare($queryStr); $stmt->execute(array(':uniluxGpm1' => $uniluxGpm, ':uniluxEwt1' => $uniluxEwt, ':uniluxGpm2' => $uniluxGpm, ':uniluxEwt2' => $uniluxEwt)); if($stmt->rowCount() > 0) { //There was a result $result = $stmt->fetchColumn() } } //If no result get the two closest records that are both above gpm and ewt and both below gpm and ewt if (!$result) { $query = "( SELECT gpm, ewt, totCool FROM wxyz WHERE gpm < :uniluxGpm1 AND ewt < :uniluxEwt1 ORDER BY gpm DESC, ewt DESC LIMIT 1 ) UNION ( SELECT gpm, ewt, totCool FROM wxyz WHERE gpm > :uniluxGpm2 AND ewt > :uniluxEwt2 ORDER BY gpm ASC, ewt ASC LIMIT 1 )"; $stmt = $dbConn->prepare($queryStr); $stmt->execute(array(':uniluxGpm1' => $uniluxGpm, ':uniluxEwt1' => $uniluxEwt, ':uniluxGpm2' => $uniluxGpm, ':uniluxEwt2' => $uniluxEwt)); if($stmt->rowCount() > 0) { //There was a result $result = $stmt->fetchColumn() } } if(!$result) { //No records that match either value echo "Not enough data to compute"; } else { //Do something with the data } ?>
-
Psycho's post in associative array and foreach was marked as the answer
I am pretty certain that your source array is not constructed how the instructor intended. You are simply assigning an array of values to each associative key. I would think the source array should have an element for each employee with each value assigned to an associative key. Something like this:
$employees = array ( array('name' => 'Employee-1', 'department' -> 'IT', 'salary' => '5000'), array('name' => 'Employee-2', 'department' -> 'HR', 'salary' => '4000'), array('name' => 'Employee-3', 'department' -> 'Marketing', 'salary' => '3000'), array('name' => 'Employee-4', 'department' -> 'Sales', 'salary' => '1500'), // etc. . . . ); The loop over each record in the $employees array
foreach($employees as $employee) { echo "Name: {$employee['name']}<br>"; echo "Department: {$employee['department']}<br>"; echo "Salary: {$employee['salary']}<br>"; }
-
Psycho's post in How to detect if a user is online? was marked as the answer
With a web application, you can certainly record when a user logs in, but even if you have a logout function a user can simply close the browser window. So, you do need a way to track that they are still there. Since this is a game where two people are playing each other, I think you need to do more than just track when they hit a new page. Here is what I would do:
Create a last active field in the user table. Every time you see activity from the user, update the timestamp.
Determine "how long" of a time period that you would consider someone as still active: 5 minutes, 10 minutes, ??? Then use that time period to query for active players based on those whose last active timestamp is within the last X minutes. This can also be used for two players already in a game to notify one that the other has dropped off.
Once two users start a game use AJAX to both continually update their last active value AND to proactively notify them of anything relevant. E.g. when it is their turn, if the other user drops off, etc. AJAX is simply javascript that makes a server call and returns back data to the user which you can then implement additional logic to act on that returned data. You can update the content in their browser window based on the move the other player made, make a notification, whatever. In this case, I would have the AJAX make a call every X seconds (10, 20, 30 ???). That call would do several things: Update the last active timestamp for the user Check if the other user is still active. Since the other player will also have AJAX running, their last active timestamp should never be greater than the time you set for the AJAX calls to be made. So, if the other players last active timestamp is more than double that time period, I would let the user know that the other user has dropped Check if the other user has made a move (if it was their turn). If so, alert the user that the other user has made their move, show the results of that move, and tell the player it is now their turn. I'm sure there are some things I am leaving out, but the core of it is to use regular calls via AJAX to determine when users have completed a turn and to ensure they are still online. Be sure to use a JavaScript framework to do this (such as JQuery) instead of trying to build the AJAX code with native JavaScript.
-
Psycho's post in JavaScript not working in IE11 was marked as the answer
To my knowledge, <output> tags do not have a "value" attribute.
In your form there are fields like this:
<output class="loan-amount" name="principal" id="principal" onChange="calculate();"></output> Then, in the calculate function there is logic like this:
var principal = document.getElementById("principal").value; Typically I see IE making 'assumptions' in how it interprets code, but this seems to be one instance where IE is doing the right thing and not assuming the field has a property which it does not.
I would write all of that much differently, but to make it work correctly move the name/id parameters from the <output> tags to the corresponding <input> tags. That way the code is referencing the value of the input fields.
-
Psycho's post in Get Image from CSS was marked as the answer
@Barand,
I see a potential problem with that logic. It assumes that if '#header-cover-image' is defined in the file then the next occurrence of url is necessarily for that element. If that class is defined but it has no url() parameter defined, but a later one does, it would erroneously pick up the url() parameter for the later element. You could use strpos to get the contents between the following {}, but this is where RegEx is very useful. Also, I think the search for '#header-cover-image' should include a space or '{' after the text - otherwise it would also find '#header-cover-image-something'.
While I know this can be accomplished with a single RegEx, I wasn't able to figure out the correct syntax. It would need to ensure that the url() was within the curly braces immediately following the class name being searched. I tried using a backreference, but my RegEx skills while good are not great. Perhaps someone else can create a single RegEx solution
<?php $match = false; //Get the contents of file $text = file_get_contents('style.css'); //Find the contents of the css class definition $CssContentRegEx = "~#header-cover-image[\ ]?\{([^\}]*)~s"; if(preg_match($CssContentRegEx, $text, $cssMatch)) { //find the url definition $imageUrlRegEx = "~url[\ ]?\(([^\)]*)~s"; if(preg_match($imageUrlRegEx, $cssMatch[1], $urlMatch)) { $match = $urlMatch[1]; } } if($match) { echo "Match: {$match}"; } else { echo "No match"; } ?> -
Psycho's post in Multi Dimensional Array Into Table was marked as the answer
Can you not run "real" queries instead of that funky WP framework? At the very least you need to find out how to use JOINs in the WP framework - all those looping queries are performance hogs. If you can provide the table structure I can provide a query that makes this very simple. Barring that - here is a complicated solution:
<?php $cars = array( array("Volvo",1994,18), array("BMW",2010,13), array("Saab",2015,2), array("Land Rover",2015,20), array("Land Rover",2017,15) ); //Create an array of unique years $years = array(); foreach($cars as $record) { //Add to years if not already there if(!in_array($record[1], $years)) { $years[] = $record[1]; } } //Sort years sort($years); //Loop through records to create structured array $outputData = array(); foreach($cars as $record) { //See if this vehicle has been added previously if(!isset($outputData[$record[0]])) { //Create an initial empty array for all years $outputData[$record[0]] = array_fill_keys($years, ''); } //Add the current record quantity for the specified year $outputData[$record[0]][$record[1]] = $record[2]; } //Create headers for table $headers = "<th>Model</th>\n"; foreach($years as $year) { $headers .= "<th>{$year}</th>\n"; } //Create the content for output $output = ''; foreach($outputData as $model => $years) { $output .= "<tr>\n"; $output .= "<td>{$model}</td>\n"; foreach($years as $year => $quantity) { $output .= "<td>{$quantity}</td>\n"; } $output .= "</tr>\n"; } ?> <html> <body> <table border='1'> <tr> <?php echo $headers; ?> </tr> <?php echo $output; ?> </table> </body> </html> -
Psycho's post in How to SUM action from all users one by one? was marked as the answer
1. You are only SELECTing the amount, but you also need the receiver in your data. So, that needs to be in the SELECT condition
2. The SUM() function requires a GROUP BY - this determine which records get summed. Since you want all the 'actions' added for each receiver, you need to GROUP BY receiver
3. I would highly suggest creating your queries as a variable and including the variable in the query functions instead of writing the queries directly in the query function. It makes management and debugging much, much easier. And format the query to help in reading it.
$query = "SELECT receiver, SUM(action) as value_sum FROM transactions WHERE comment = 'tax' GROUP BY receiver ORDER BY receiver"; $result = mysqli_query($con, $query); -
Psycho's post in String comparisons using xpath was marked as the answer
This seems to work:
$x = $xml->xpath("//image[number(translate(substring-before(@lastUpdate, 'T'), '-', '')) > 20180307]"); The substring-before(@lastUpdate, 'T') returns the date string that comes before the 'T'.
Then, that value is used within translate([VALUE], '-', '') to remove the dashes in the date string.
Then, that value is used within number([VALUE]) to convert the resulting string 'YYYYMMDD' into a number value and is compared against the numeric value for your specified date.
You can compare on date and time if you use '+' in the substring-before() function and use '-T:' in the second parameter for the translate() function.
-
Psycho's post in Array in for or foreach from database was marked as the answer
Agree with mac_gyver!
As to your code. It is running a DB query and then looping over each record (which is an array). Then for each record you are appending the record to the previous list of records as a multidimensional array. Then, finally, you are (within that loop) iterating over each record in the array to add the record to an output variable.
There are several problems here:
A) Because you are adding each record to the multi-dimensional array AND outputting the array within the loop, if it was working, you would get results like this: 1, 1, 2, 1, 2, 3, 1, 2,3 ,4 . . .
B) When tryign to output a record, you are referencing the array (that was retrieved via mysqli_fetch_array). You need to reference a value in the result set.
C) You are redefining the value of the output variable on each loop. You should be appending the new record output to the existing output.
D) While it does work, there is no need to do a for() loop on an array with a random variable - use a foreach() loop.
Building upon mac_gyver's post:
<?php // Query the database for the needed records // - suggest putting SQL commands in CAPS $sql = "SHOW TABLES FROM XXXX"; $result = mysqli_query($GaryDB, $sql); //Dump database results into array $table_result = []; while($row = mysqli_fetch_array($result)) { // Add the table NAME to the array: $row[0] // - Not the array $table_result[] = $row[0]; } // Examine the data print_r($table_result); // Iterate over the results to create the output $table_options = ''; foreach($table_result as $table) { //Append this record ot the output variable $table_options .= "<option value='{$table}'>{$table}</option>\n"; } // Output the content within the presentation (HTML) // The above code should exist at the top of the page or in a separate file ?> <html> <body> Tables: <select name="tables"> <?php echo $table_options; ?> </select> </body> </html> -
Psycho's post in Looping so that each record is inserted a number of times equal to a column value was marked as the answer
You only need to prepare a query ONCE - then run it multiple times as needed (with different data). You are preparing the same query multiple times.
$order_ids = []; while ($row = $ordStat->fetch(PDO::FETCH_ASSOC)) { $order_ids[] = $row['order_id']; } if (count($order_ids) > 0) { $placeholders = implode(',', array_fill(0, count($order_ids), '?')); $detailStatCheck = " SELECT invnoc as INVOICE, fstatc as STATUS, cstnoc AS DEALER, framec AS FRAME, covr1c AS COVER, colr1c AS COLOR , extd2d AS SHIPDATE, orqtyc AS QUANTITY FROM GPORPCFL WHERE invnoc IN ($placeholders) "; try { $detailCheck = $DB2conn->prepare($detailStatCheck); $detailRslt = $detailCheck->execute($order_ids); $count2 = $detailCheck->fetch(); print_r($order_ids); print_r($count2); } catch(PDOException $ex) { echo "QUERY FAILED!: " .$ex->getMessage(); } //Create prepared INSERT query $insertPlacement = " INSERT INTO placements_new (sku_id, group_id, dealer_id, start_date, expire_date, locations, order_num) SELECT id, sku_group_id, :DEALER, DATE_ADD(DATE_FORMAT(CONVERT(:SHIPDATE, CHAR(20)), '%Y-%m-%d'),INTERVAL 7 DAY) as start_date, DATE_ADD(DATE_FORMAT(CONVERT(:SHIPDATE, CHAR(20)), '%Y-%m-%d'),INTERVAL 127 DAY) as expire_date, :QUANTITY, :INVOICE FROM skus s WHERE s.frame=:FRAME AND s.cover1=:COVER AND s.color1=:COLOR "; while ($row2 = $detailCheck->fetch(PDO::FETCH_ASSOC)) { //IF exists and today is before expire date //update records = quantity, or insert //ELSEIF exists and today is past expire_date, just insert number for each quantity //ELSE doesn't exist at all, perform below $values = [ ":DEALER" => $row2["DEALER"], ":SHIPDATE" => $row2["SHIPDATE"], ":QUANTITY" => $row2["QUANTITY"], ":INVOICE" => $row2["INVOICE"], ":FRAME" => $row2["FRAME"], ":COVER" => $row2["COVER"], ":COLOR" => $row2["COLOR"], ]; for($i=0; $i<$row2["QUANTITY"]; $i++) { try{ $insert = $MysqlConn->prepare($insertPlacement); $insertRslt = $insert->execute($values); }catch(PDOException $ex){ echo "QUERY FAILED!!!: " . $ex->getMessage(); } } } } -
Psycho's post in Printing multiple arrays or array subsets was marked as the answer
The output problem is due to this:
You create an array and APPEND each record to the array in the loop
$Db2ShipArr[] = $db2ShipRow; Then you output that array
print_r($Db2ShipArr); So, on the first iteration of the loop, that array contains the first record and outputs just that one record. Ont eh second iteration of the loop it contains the first and second records (and outputs both records). On the third iteration it would output records 1, 2, & 3.
Also, you don't need to (and shouldn't) run that other query within a loop. Run ONE query to get all the data.
<?php $query = "SELECT order_id FROM order_status WHERE order_status = 'S'"; $result = mysqli_query($mysqlConn, $query); $order_ids = array(); //loop results to gather order IDs and store them while ($row = mysqli_fetch_assoc($result)){ $order_ids[] = $row['order_id']; } //Get the order details for ALL the orders in ONE query $orderIdsStr = "'" . implode("', '", $order_ids) . "'"; //SELECT FROM DB2 WITH THE ORDER NUMBERS FIRST $query = "SELECT invnoc as INVOICE, cstnoc AS DEALER, framec AS FRAME, covr1c AS COVER, colr1c AS COLOR , extd2d AS SHIPDATE, orqtyc AS QUANTITY FROM GPORPCFL WHERE invnoc IN ({$orderIdsStr}) GROUP BY invnoc,cstnoc, slsnoc, orqtyc, framec, covr1c,colr1c, extd2d ORDER BY invnoc asc"; $Db2ShipRslt = odbc_exec($DB2Conn, $query); if ( $Db2ShipRslt === false ) { exit (odbc_errormsg($DB2Conn)); } //Process the results $Db2ShipArr = array(); while($db2ShipRow = odbc_fetch_array($Db2ShipRslt)){ { //Output the record print_r($db2ShipRow); //Append record to results array $Db2ShipArr[] = $db2ShipRow; } ?> -
Psycho's post in Document upload security? was marked as the answer
Word doc and pdf files are definitely problematic because they can (by intention) have embedded code and/or links to external resources. I don't think any of the above measures would protect against any malicious such data. I suppose some virus scanners may catch some, but definitely not all. For example, a virus scanner is not going to check every hyperlink in a document to see if it is pointing to a malicious site.
One "possible" option to be 100% certain, would be to use a plug-in or COM object (or even something you can call from a command line) to "create" PDF files. When someone uploads a doc or pdf file, send the document to the process to create a PDF with the appropriate parameters to ensure it creates a non-interactive PDF (no links, no fillable forms, etc.). You should be left with a simple, flat PDF that has no code. The only problem might be licensing. Many years ago I was involved with a web application where we used a server-side component to generate PDF files from PostScript code. It was quite expensive. If this is for non-commercial purposes you may be able to find something free or cheap.
-
Psycho's post in Latest Conversations was marked as the answer
There is a particular aspect of your request that I feel needs to be clarified.
Let's say there are messages between Mike & Bob. So, some message are From: Mike -> To: Bob and others are From: Bob -. To: Mike. It would be simple® to group all of those into two different groups. But, if I understand you correctly, you want to group all of the conversations together where the two people in the From and To columns are the same two people - regardless of who was in the From and who was in the To.
I'm sure there are more efficient ways to do this, but here is how I would approach it. First, we need a way to have a unique identifier for the two people in a message regardless of who is in the From/To columns. I would concatenate the two user IDs ensuring the lower number comes before the higher number. E.g.
CONCAT(LEAST(uid_to, uid_from), '-', GREATEST(uid_to, uid_from)) as users_key You can then GROUP BY that to get the most recent ID for conversations with unique participants. Then you need to use that to get the records for those conversations.
SELECT * FROM tbl WHERE id IN ( SELECT MAX(id) FROM tbl GROUP BY CONCAT(LEAST(uid_to, uid_from), '-', GREATEST(uid_to, uid_from)) ) Note: I used a dash '-' between the IDs in the CONCAT() because there would be erroneous associations otherwise. E.g. records (1 and 122) would create the same key as (11 and 22): 1122. Using the dash, I instead get 1-122 vs. 11-22.
-
Psycho's post in I'm going crazy, a md5 comparison fools me. was marked as the answer
Hard for me not to be condescending. How do you think these two values would be the same?
The cookie value
The reference hash
Two problems:
1. You are trimming and using strip_tags() on the $_GET value in one case and not the other
2. At the end of the first value you are also including "OID" . $reference but not on the other.
If you need to 'create a code' or some other p[rocess that should be repeatable, you should create a function to do it rather than creating the process multiple times.
-
Psycho's post in How to create php form like this?! was marked as the answer
The only "form" I see on that site is a group of radio buttons. The only thing special I see is that the radio buttons possibly have custom CSS applied to change their appearance. See this example: https://www.w3schools.com/howto/howto_css_custom_checkbox.asp
Or, it could be that they are "plain" radio buttons at all. They also look similar to JQueryUI radio buttons: https://jqueryui.com/checkboxradio/#radiogroup
Except that the example above has the button and label within a "button" that changes background color based on the selected state of the radio button.
Or, if there is more to the form than the radio buttons, you will need to point it out. That was the only thing I saw as field input on that page.
-
Psycho's post in MOdifying existing loop for spreadsheet record was marked as the answer
You know, it is best if you were to identify your requirements up front! If I had known you were needing these other calculated values, I would have taken a different approach. In this case I would add all the values for each "ID" entity to an array. Then use that array of values to do the calculations of Subtotal, Average, etc. That way, if there is no existing function to get the value I can just create a function and pass the array.
None of this is tested
function array_mean($array) { return array_sum($array) / count($array); } function array_median($array) { //Sort the array sort($array); //Get the count $count = count($array); //Check if odd/even number if($count%2) { //Odd number - get middle value $medianIndex = ($count-1) / 2; $median = $array[$medianIndex]; } else { //Even number number - get avg of middle two values $startIndex = ($count/2) - 1; //Get index of first of two middle items //Calculate the average of the middle pair $median = ($array[$startIndex]+$array[$startIndex+1]) / 2; } //Return median return $median; } function array_mode($array) { //Get the count of all values in the array $valuesAry = array_count_values($array); //Sort by occurance rate sort($valuesAry); //Return the first key (value with highest frequency) return key($valuesAry); } foreach($resultData as $idRecords) { //Set arrays to hold values to calculate $talktimeValues = array(); $outboundValues = array(); $inboundValues = array(); $dealersValues = array(); //Iterate over the records for this ID foreach($idRecords as $record) { //Increment row number $rowNo++; //Add record row to spreadsheet $sheet->setCellValue("A{$rowNo}", $record['Name']); $sheet->setCellValue("B{$rowNo}", $record['ID']); $sheet->setCellValue("C{$rowNo}", $record['TalkTime']); $sheet->setCellValue("F{$rowNo}", $record['Outbound']); $sheet->setCellValue("I{$rowNo}", $record['Inbound']); $sheet->setCellValue("L{$rowNo}", $record['Dealers']); $sheet->setCellValue("O{$rowNo}", $record['Date']); $sheet->setCellValue("P{$rowNo}", $record['Day']); } //Add subtotals $rowNo++; $sheet->setCellValue("B{$rowNo}", "Subtotals"); $sheet->setCellValue("C{$rowNo}", array_sum($talktimeValues)); $sheet->setCellValue("F{$rowNo}", array_sum($outboundValues)); $sheet->setCellValue("I{$rowNo}", array_sum($inboundValues)); $sheet->setCellValue("L{$rowNo}", array_sum($dealersValues)); //Add mean $rowNo++; $sheet->setCellValue("B{$rowNo}", "Means"); $sheet->setCellValue("C{$rowNo}", array_mean($talktimeValues)); $sheet->setCellValue("F{$rowNo}", array_mean($outboundValues)); $sheet->setCellValue("I{$rowNo}", array_mean($inboundValues)); $sheet->setCellValue("L{$rowNo}", array_mean($dealersValues)); //Add Median $rowNo++; $sheet->setCellValue("B{$rowNo}", "Medians"); $sheet->setCellValue("C{$rowNo}", array_median($talktimeValues)); $sheet->setCellValue("F{$rowNo}", array_median($outboundValues)); $sheet->setCellValue("I{$rowNo}", array_median($inboundValues)); $sheet->setCellValue("L{$rowNo}", array_median($dealersValues)); //Add Mode $rowNo++; $sheet->setCellValue("B{$rowNo}", "Modes"); $sheet->setCellValue("C{$rowNo}", array_mode($talktimeValues)); $sheet->setCellValue("F{$rowNo}", array_mode($outboundValues)); $sheet->setCellValue("I{$rowNo}", array_mode($inboundValues)); $sheet->setCellValue("L{$rowNo}", array_mode($dealersValues)); } -
Psycho's post in Trying to loop an array and group by user for totals, phpspreadsheet was marked as the answer
Including subtotals in such a report is a pretty standard report format.
Before I provide a solution, a couple notes:
1. When defining the string for the query, why do you have an "or die()". Are you afraid PHP won't be able to define the variable? I assume you meant that to go after the line that actually executes the query. But, that is not a good implementation. Lear to check for errors and handle them gracefully.
2. Use Comments! They make your job (and those that help you) easier.
3. I'm not liking how you are setting the column to 'A' and then incrementing it using '++'. I'm actually surprised it works. But, I think it makes more sense to be explicit and it will make the job of creating the subtotals a little easier.
4. You should order the records by ID
This isn't tested, so it may have a typo or two
//Create and run query $sql = " SELECT CONCAT(u.first_name, ' ', u.last_name) as Name, t.ext_id as ID, t.total_talk_time_minutes as TalkTime, t.total_outbound as Outbound, t.total_inbound as Inbound, t.dealers_contacted as Dealers, t.date_of_report as Date FROM ambition.ambition_totals t INNER JOIN ambition.ambition_users u ON t.extension = u.extension WHERE date_of_report between curdate() - interval 5 day and curdate() ORDER BY ID"; $result = mysqli_query($conn,$sql); //Start the spreadsheet $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); //Create header row $sheet->setCellValue('A1', 'Name'); $sheet->setCellValue('B1', 'User ID'); $sheet->setCellValue('C1', 'Talk Time Per Call'); $sheet->setCellValue('D1', 'Outbound Calls'); $sheet->setCellValue('E1', 'Inbound Calls'); $sheet->setCellValue('F1', 'Dealer Contacts'); $sheet->setCellValue('G1', 'Date'); //Preprocess the data into a multi-dimensional array // with the id as the parent index $resultData = array(); while($row = mysqli_fetch_assoc($result)) { $resultData[$row['ID']][] = $row; } //Set starting row number $rowNo = 1; //Iterate over the results for each unique id foreach($resultData as $idRecords) { //Set subtotal variables to 0 $subtotalTalktime = 0; $subtotalOutbound = 0; $subtotalInbound = 0; $subtotalDealers = 0; //Iterate over the records for this ID foreach($idRecords as $record) { //Increment row number $rowNo++; //Add record row to spreadsheet $sheet->setCellValue("A{$rowNo}", $row['Name']); $sheet->setCellValue("B{$rowNo}", $row['ID']); $sheet->setCellValue("C{$rowNo}", $row['TalkTime']); $sheet->setCellValue("D{$rowNo}", $row['Outbound']); $sheet->setCellValue("E{$rowNo}", $row['Inbound']); $sheet->setCellValue("F{$rowNo}", $row['Dealers']); $sheet->setCellValue("G{$rowNo}", $row['Date']); //Update the subtotals $subtotalTalktime += $row['TalkTime']; $subtotalOutbound += $row['Outbound']; $subtotalInbound += $row['Inbound']; $subtotalDealers += $row['Date']; } //Increment row number $rowNo++; //Add subtotal row to spreadsheet $sheet->setCellValue("C{$rowNo}", $subtotalTalktime); $sheet->setCellValue("D{$rowNo}", $subtotalOutbound); $sheet->setCellValue("E{$rowNo}", $subtotalInbound); $sheet->setCellValue("F{$rowNo}", $subtotalDealers); } -
Psycho's post in an exact string match only was marked as the answer
I'm really not following your request. Are you only wanting to return a match if the match starts at the very beginning of the string? If so, then you just need to add the start of line anchor: '^'
/^([A-z0-9])\w+\.\w{3,4}/ -
Psycho's post in scandir - iterate over 2 directories was marked as the answer
I think you need to slow down a bit. You are make things harder than they need to be. Plus, when you add a third, fourth, fifth directory you need to modify several lines of code. Write the code so all you have to do is add a directory and not modify the logic. Also, use comments! And, please read documentation for the functions you are using. They have features you are not taking advantage of.
The glob() function has a flag to only return directories. Since that is all you are using, you should use it.
Don't duplicate logic. E.g.
if (is_file($dir[$i]."/".$app."_schema.php")) { require ($dir[$i]."/".$app."_schema.php"); } Creating the string for the full path to the file is a bad idea. If you ever have to change it you run the risk on modifying one and not the other. It probably does not seem like a big deal, but trust me - things like this do happen and debugging them is a pain. Define the full path as a variable and then use that variable in the logic.
Using your basic logic, here is a rewrite that is much more flexible and maintainable
<?php ## Begin user defined values $dirAry = array( '/home/pi/path/path/', '/home/pi/path/path1/' ); ## End user defined values //Creat array of all sub-directories $subDirAry = array(); foreach($dirAry as $dir) { //Get all items in the directory $items = glob("{$dir}*"); //Remove '.' and '..' $items = array_slice($items, 2); //Append to the subdirectories array $subDirAry = array_merge($subDirAry, $items); } //Create the schema array $schemaFiles = array(); foreach($subDirAry as $subDir) { //Create full path for schema file $app = basename($subDir); $schemaFile = "{$subDir}/{$app}_schema.php"; //Verify that file exists if(file_exists($schemaFile)) { $schemaFiles[] = $schemaFile; require($schemaFile); } } print_r($schema); -
Psycho's post in Counting files in a directory was marked as the answer
They are basically the same thing:
FileSystemIterator, on it's own, will return all items in a directory (with the exception of being able to exclude the '.' and '..'). GlobIterator extends the function so you can have it only return specific items matching a pattern. Look at your own example. The GlobIterator will only count files (or directors) ending with '.xml'.
So, if you simple want to count all elements in a directory use FileSystemIterator. Else, if you are only looking for specific folders/files matching a pattern use GlobIterator.