Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,356
  • Joined

  • Days Won

    173

Everything posted by mac_gyver

  1. for your current information, the business logic to retrieve the data would be - $query = " SELECT igc.id, igc.giftCardName, igc.giftCardImage, igcc.currency, igcc.amount, igcc.pointsPrice, sum(if(igcc.status ='available',1,0)) as available, sum(if(igcc.status ='redeemed',1,0)) as redeemed FROM instant_gift_cards igc INNER JOIN instant_gift_card_codes igcc ON igc.id = igcc.giftCardId WHERE igc.status = 'Enabled' GROUP BY igc.id, igcc.amount ORDER BY igc.dateCreated DESC, igcc.amount"; $stmt = $db->query($query); $giftCard = array(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)){ $giftCard[$row['id']][] = $row; } and the presentation logic would be - print" <table style=\"width:100%\" class=\"tableList\"> <tr> <th style=\"width:35%\">Prize Name</th> <th style=\"width:12%\">Amount</th> <th style=\"width:12%\">Points</th> <th style=\"width:12%\">Available</th> <th style=\"width:12%\">Redeemed</th> <th style=\"width:17%\">Action</th> </tr>"; if(!empty($giftCard)){ // there's at least one gift card to display foreach($giftCard as $arr){ // $arr is an array of arrays, one sub-element for each amount under each gift card $rowspan = count($arr); $first = 1; // a flag to detect the first pass through the following loop foreach($arr as $row){ // row will be the database row for each amount under one gift card echo "<tr>"; // start a row if($first++ == 1){ // output the one-time information here... if($row['giftCardImage']){ $nameOrImage = '<img src="./images/giftcardrewards/'.$row['giftCardImage'].'" alt="'.$row['giftCardName'].'" title="'.$row['giftCardName'].'">'; }else{ $nameOrImage = $row['giftCardName']; } echo "<td rowspan='$rowspan'>$nameOrImage</td>"; } // output the common data for each html table row here... if($row['available'] == '0'){ $redeemAction = 'Out of Stock'; } elseif($userInfo['currentPoints'] < $row['pointsPrice']){ $needed = $row['pointsPrice'] - $userInfo['currentPoints']; $redeemAction = 'You need '.$needed.' point(s)'; } elseif($userInfo['currentPoints'] >= $row['pointsPrice']){ $redeemAction = '<input type="button" value="Redeem" onclick="if(confirm(\'Are you sure to redeem this prize?\')){location.href=\'index.php?do=instantGiftCards&action=redeem&cardId='.$row['id'].'&amount='.$row['amount'].'\';}">'; } print"<td style=\"text-align:center\">".$row['currency'].$row['amount']."</td> <td style=\"text-align:center\">".$row['pointsPrice']."</td> <td style=\"text-align:center\">".$row['available']."</td> <td style=\"text-align:center\">".$row['redeemed']."</td> <td style=\"text-align:center\">".$redeemAction."</td> </tr>"; } } }else{ print" <tr> <td colspan=\"4\" style=\"text-align:center;color:#2B1B17;padding:15px 0\">No prizes added.</td> </tr>"; } print" </table>";
  2. here's a single (one) query that gets all the data your code currently is getting - SELECT igc.id, igc.giftCardName, igc.giftCardImage, igcc.currency, igcc.amount, igcc.pointsPrice, sum(if(igcc.status ='available',1,0)) as available, sum(if(igcc.status ='redeemed',1,0)) as redeemed FROM instant_gift_cards igc INNER JOIN instant_gift_card_codes igcc ON igc.id = igcc.giftCardId WHERE igc.status = 'Enabled' group by igc.id, igcc.amount ORDER BY igc.dateCreated DESC, igcc.amount another comment about what you are currently doing - you are repeating the currency, amount, and pointsPrice in each same amount row in your instant_gift_card_codes table, for each code under any giftCardId. you should have another table that holds only one copy of the currency, amount, and pointsPrice information. your instant_gift_card_codes table would then only have an id, the id of the corresponding row in this new table, the code, and the status - available/redeemed.
  3. to do what mogosselin has suggested, you will need to pre-process the data that the query returns, making an array of arrays, where the main array index is the instant_gift_cards id. then as you are looping through the different instant_gift_cards to display them, you can use count() on the sub-array for each instant_gift_cards to find out the rowspan value. in order to do this, you must first separate the business logic that's getting the data, from the presentation logic that's displaying the data. you should be able to put a comment in your code, above which is only php and database query logic, without any html/css/javascript.. and below which there is no database specific code, just php variables, loops, echo/print statements... that produces the html/css/javascript based on the data that was retrieved by the business logic. you also need to NOT run queries inside of loops. you can write one query that gets all this information at once (time permitting, someone will probably post an example.) edit: also, for static/program produced values, like your status = 'Enabled', there's no point is using a prepared query for that. just build the query with the value in it. place-holders in queries are for data that must be escaped/cast to prevent errors or to prevent sql injection and for queries that will be executed more than once with different values. you queries will also be easier to write and read if you use alias names for the tables being referenced.
  4. we can only help you with your code after you have posted it and we also need to know exactly what output you expected and what output you did get, because telling us what did happen, even if it's a completely blank page, is as important as knowing what didn't happen when troubleshooting programming.
  5. store the data in a database. a) you can set up indexes that allow information to be found quickly, without reading through the whole set of data. b) the database engine is complied code that can find information at least 10x faster than php's interpreted code can.
  6. no matter how high you set the values, someone can and will come along and try to upload larger files than the settings allow. your code should test for upload errors and report back to the visitor when individual files (determined by the upload_max_filesize setting) and when all the form data (determined by the post_max_size setting) has been exceeded.
  7. how do you know that? what sort of symptom or error do you get? there's a dozen different things that could prevent an upload from working, starting with the form not having the needed enctype attribute all the way through to file/folder permissions preventing move_uploaded_file() from being able to move the file to the destination folder. is your code even testing if the file got uploaded without any errors, before trying to use the uploaded file information?
  8. the emails are being sent FROM your mail server at bluehost. the domain in the from address needs to correspond to the sending mail server, i.e. you have set up dns zone records under your account that the receiving mail server can use to confirm that the sending mail server where your domain is hosted at IS where the mail should have been sent from. if you want to include the sender's email address, for reply purposes, you put it into a Reply-to: mail header, not the From: header.
  9. while the purpose of your code is to produce client-side html, the issue is the php code and using smarty syntax and commends, which is all php. moving to the php help forum...
  10. your code produces a fatal php parse/syntax error due to a missing ;. i'm not going to tell you where, because your development system should have php's error_reporting set to E_ALL and display_errors set to ON in your php.ini so that all php errors will be reported and displayed. for this kind of error, php can point you to the correct area of the code (usually the actual problem causing a syntax error is immediately prior to where the syntax error is reported) and you should be able to find things like missing punctuation. edit: next you have a functional problem in getting the current autoincrement value from a table, increment it, and using it. if you have concurrent requests to your page, you will end up with wrong values. the way you would do this is, after the INSERT query runs for the aktiviteter table, use mysqli_insert_id() to get the actual id that was generated. next, you are mixing mysql_ (no i) and mysqli_ (with an i) functions. you need to use all mysqli_ (with and i) functions.
  11. you can test if your pdo driver is emulating prepared queries (for some, that's the only choice, regardless of the PDO::ATTR_EMULATE_PREPARES setting), by checking if a deliberate syntax error in your sql statement is throwing an error at the ->prepare() statement (temporarily add a die; after the prepare() to prevent the ->execute() from running) or at the ->execute() statement; if the query is actually being sent to the database server to be prepared, the syntax error will be thrown at the ->prepare() statement.
  12. in the context of a monthly calendar, what do you want to display? displaying every open time slot for even one trainer (what if you have 20 trainers) would not be piratical. your monthly calendar could at best show a clickable 'event' on the days that have available bookings (and a non-clickable, 'full' listing for days that have no open time slots), either just one event total, if any of the selected/filtered trainers have an opening, or one event for each selected/filtered trainer that has an opening on that date, with a hoover/pop-open tool or a link that gives you a view/page that consists of the booking grid with the open time slots for the clicked on date. a monthly calender could be used for the appointment confirmation. you could display an 'event' on any days that have any un-confirmed appointment(s), for the currently logged in trainer. clicking on the 'event' would take that trainer to a grid of un-confirmed appointments that can then be reviewed and approved. assuming that a trainer would have the need to cancel an appointment, you would instead display an 'event' for all days that the trainer is available. clicking on any day would take the trainer to a grid that shows un-approved and approved appointments on that day with choices to approve/cancel each appointment.
  13. a persons ip address can change at any time and all the people connecting from one nat based network will share the same ip address. using the ip for anything other than just informational purposes will result in problems of locking someone out or of allowing someone access just because the connected from the same network. you must limit access based on the logged in user's id and what content he has permission to view or change.
  14. dynamically produced web sites don't actually have folders and files for everything or for each user. they use logical folders and pages that map (using url rewriting) to one actual file that retrieves the correct content from a database and displays it in response to the url that was used to request the page. are you sure want to try to copy and then manage a bunch of actual folders and files? also, how are you going to restrict access for making changes to the proper user?
  15. the bind_parm() statement must have - i'm not making this up, this comes directly from the php.net documentation for that function - the statement you end up producing must be in the form - $stmt->bind_param ('iissssss',$var1,$var2,$var3,$var4,$var5,$var6,$var7,$var8); the only way one of the ways you can dynamically do this is to use call_user_func_array() and as stated, there are examples in the user contributed notes in the php.net documentation. edit: the user contributed notes that i have mentioned contains a method using class Reflection to do this in a more direct way. also, your $build_bind_param string isn't correct for the query you are showing. you would build the part that corresponds to the set of $arrays values and concatenate that in the correct place in the string relative to the other parameters.
  16. http://forums.phpfreaks.com/topic/281305-pagination-from-search-results/?hl=%2Bhttp_build_query&do=findComment&comment=1446040
  17. form data is only available on the page request that the form submitted to. it's up to your code to propagate the search term with the pagination links. in the search.php code, there's no need to check the $_GET['submit'] or to even have it as a named field in the form, just make sure there's a $_GET['search'], assuming you only want to display anything if a search term was entered. to build your pagination links, you should use a function like http_build_query, as it will let you take any existing $_GET parameters and combing in your page parameter. another thing http_build_query does for you, that your current code is lacking, is to urlencode all the values being put into the link, so that the link won't be broken if someone includes a search term that includes characters that must be urlencoded. http_build_query also lets you specify the separator to use between parameters, which for a link, should be &
  18. yes, and for those that have javascript enabled, you can use an onchange event to submit the filter form. for those without javascript, provide a submit button using <noscript></noscript> tags. i would reverse the order of the fields in the rewritten url. you will always have a page number, even if there's only one page. the page number should come first. the content and sort type won't necessarily exist and should come after the page number.
  19. you would make links that contain a get parameter that tells your one page how you want to sort the data, such as ?sort=date&direction=asc you would then test for and validate the get parameters and use the values to determine what sql query statement to build (don't use the values directly in a query without being fully validated to insure they are ONLY one of the permitted values in order to prevent sql injection.) you would also build the pagination links with whatever existing get parameters there (you can use http_build_query to do this) are so that they propagate between the page requests when you click on the pagination links.
  20. your testing on the development system should have found things like query errors. your code should also have logic that tests each query to see if it failed or not and take an appropriate action. if a query does fail, you should output a user message - 'Sorry, an error has prevented this page from completing the requested operation' and log the actual query and the database error message. testing is more than just checking that the code runs. it means testing if the code does what you expect for both expected values and unexpected values and making sure that the code produces the expected result for all the possible execution paths/logic branches.
  21. things which are configuration dependent (and php version dependent) will be producing either php syntax or runtime errors. if the pages all actually run at all, then at least the main pages don't contain php syntax errors and you can set php's error_reporting to E_ALL and display_errors to ON in the code to see what errors are being detected by php. you could also post the code here and someone could directly tell you the most likely things it is doing that would be configuration or version dependent.
  22. using a prepared query with the IN() comparison, will require that you dynamically supply a place-holder in the query for each value in the array - it must look like IN (?,?,?,?,?), you must dynamically build the bind_parm() statement with the correct first parameter with a type character for each place holder, and the hard part, you must dynamically supply a 2nd through nth parameter consisting of a variable (which can be an array element) for each parameter. if you look at the user contributed notes in the php.net documentation, either in the msyqli prepare or mysqli bind_parm section, you can probably find a script/class that helps do this for you. to build the place-holders and the type character string, you can just get a count of the elements in the array and use string functions to build those. to actually supply a dynamic number of parameters to a function, you must use call_user_func_array(). or if you can switch to using the PDO database library/class, all of this becomes very simple, because you can bind each parameter separately.
  23. you could of course write out a ->bind_result() statement that lists a $row['column_name'] variable for each column you have selected in the query, but that wouldn't be general purpose and would require that you do a lot of typing that the computer would be more than happy to save you from doing each time you write out or change a query. fortunately, i have done this before, and when you see how much code this takes, you will see why we recommend using the PDO database library/class. with respect to the code i posted as an example above, the following section - $stmt->execute(); ... // the above php code is the business logic, that knows what to do on the page and how to get data from the database is replaced with this - $stmt->execute(); $meta = $stmt->result_metadata(); $variables = array(); // the 'bind_result' parameters $data = array(); // array to reference to hold the actual fetched data $fields = array(); // just the field names, for building the display header while($field = $meta->fetch_field()){ $variables[] = &$data[$field->name]; // parameters to 'bind_result' are references to the data array elements $fields[] = $field->name; } call_user_func_array(array($stmt, 'bind_result'), $variables); $results = array(); $i=0; while($stmt->fetch()){ $results[$i] = array(); foreach($data as $k=>$v){ $results[$i][$k] = $v; // you must specifically access the key/value (otherwise you get a reference to the element in $data and they are all the last value fetched) } $i++; } $stmt->close(); // the above php code is the business logic, that knows what to do on the page and how to get data from the database
  24. this is covered in point #2 in my post and the php.net documentation for msyqli prepared queries. the portion of the code using ->get_result() will need to be rewritten to use the ->bind_result() and ->fetch() methods. if you continue to use mysqli statements, you will need to use a ->bind_result() statement to bind each column being selected in the query to a php variable (array entries will work), then, in your existing while(){} loop, use the ->fetch() method to get the data from the query into those variables. if you instead switch to using PDO statements, you can avoid all of this mess, because no matter how you run the query (prepared statements or not, regardless of any driver or php version differences), you can use PDOStatement methods to fetch the result form the query.
  25. the parentheses are not part of the require_once statement (it's not a function.) what using them does is cause php to evaluate the term they enclose, similar to using parentheses in a math equation to force operator precedence.
×
×
  • 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.