Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Community Answers

  1. 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; }  
  2. 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 } ?>  
  3. 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>"; }  
  4. 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.
  5. 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.
  6. Psycho's post in Get Image from CSS was marked as the answer   
    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"; }   ?>
  7. 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>
  8. 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);
  9. 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.
  10. 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>
  11. 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();             }           }     } }
  12. 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; }   ?>
  13. 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.
  14. 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.
  15. 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.
  16. 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.
  17. 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));   }
  18. 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); }
  19. 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: '^'
  20. 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);
  21. 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.
  22. Psycho's post in Date inserts 00 was marked as the answer   
    This 'array' makes no sense. At least I have never seen assignments used within an array like that. Since you would be overriding the assignments on each iteration of the loop it makes even less sense why you would have assignments (since they are not used).
    $stmt->execute(array(        $pastorname   =       $_POST['pastorsname'][$i],        $ministryname =       $_POST['ministriesname'][$i],        $startdate =    "'".date('Y-m-d H:i:s', strtotime(str_replace('-', '/', $_POST['xstartdate'][$i])))."'",        $clientsname =     $_POST['clientname'][$i],        $video_url =     $_POST['url'][$i],           )); But, part of your problem is that you are appending a single quote mark to the beginning and end of the date string. You don't quote the values that will be used in prepared statements. Try this:
    for ($i = 0; $i < count($_POST['pastorsname']); $i++) {     //Create date string     $startdate = date('Y-m-d H:i:s', strtotime(str_replace('-', '/', $_POST['xstartdate'][$i])));     echo "Input: {$_POST['xstartdate'][$i]}, Start date: {$startdate}<br>\n"; //For debugging     //Create values array     $values = array(         $_POST['pastorsname'][$i],         $_POST['ministriesname'][$i],         $startdate,         $_POST['clientname'][$i],         $_POST['url'][$i]     );     //Execute statement     $stmt->execute($values); } Does it work (without the extra quotes)? If not, what does the output show?
    By the way, you should create your fields something like this
    name="record[1][pastorsname]" Then, in your code you would just do
    foreach($_POST['record'] as $record) {   //Fields are then referenced like this   //$record['pastorsname']   //$record['ministriesname'] }
  23. Psycho's post in complex php project was marked as the answer   
    Um, 'complex' is a subjective term. When I think 'complex', I am thinking about projects that require a team developers, DBAs, QA analysts, business analysts, etc. etc. I'm guessing that is not the type of 'complex' project you are wanting to do.
    My best advice is find something to do in an area that you enjoy. If you do that, it will help you stay motivated. If you pick something you have no interest in, you aren't going to be too interested in writing the code for it either. Some examples:
    If you are into computer gaming, build a site that gathers data from servers that run a particular game to show metrics, player standings, or other data of interest to people that play that game. Or perhaps, allow players to sign up with the game id so they can show metrics between the players.
    Do you like photography? Build a site that allows a person to upload their geotagged photos and provide a world map (using Google's APIs) with markers where the different photo's were taken. User can click a location and see the photos the person took. Actually, this would be cool for people that travel a lot.
    Are you into sports? Find a feed with data for a particular sport and present the data in different ways that users would like or maybe add some prediction logic. E.g. probability of a player hitting a home run based on results of his last x games.
    Etc. Etc.
  24. Psycho's post in Prepare statement query not executing was marked as the answer   
    Running loops and doing a select statement each time [especially with rand()] is a bad idea. here is what I think is a better approach.
    1. Run ONE SELECT query to get all of the vtext values from the rsample table for the groupname
    2. Populate those results into an array
    3. User array_shuffle() to randomize the results of the array
    4. Run the loops for $i & $j like you have now, but create a simple INSERT statement  like this
    INSERT INTO decks     (id, dnumber, vtext)  VALUES (:id, :dnumber, :vtext) 5. Define the vtext value on each loop using array_shift() which will remove and return the first value in the array
    $stmt -> bindValue(':vtext', array_shit($vtextValuesAry));
  25. Psycho's post in Display an image a certain number of times depending on a value in database was marked as the answer   
    Instead of creating a loop, a more elegant approach might be to use the str_repeat() function.
    Create a variable to hold the content for a star image element and then just use str_repeat() with that variable and the rating number to create the correct output.
    So, somewhere before the loop to create the output for the records define the image
    $starImg = "<img src='images/star.jpg'>"; Then within the loop for the records, use a single line to create the correct number of images using the rating number from the query results
    echo str_repeat($starImg, $game_rs['rating_number']);
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.