Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,450
  • Joined

  • Days Won

    175

Everything posted by mac_gyver

  1. i would add to the above, those two database tables are required even in the case of a session based cart. at the point where the cart is finalized and converted to an order, you have to move the data from the session into the database tables so that you have a record of the order.
  2. you need to decide if you are going to use a session or a database table for the cart. there are advantages and disadvantages to both, the main ones being - session based cart - 1) simpler sql queries - easier for someone just starting out 2) if the cart gets 'abandoned' it is deleted when the browser is closed database based cart - 1) requires more knowledge of sql queries, but uses overall less code and queries 2) if the cart gets 'abandoned' you must periodically clean up the entries in the database table. for a first time project, using a session to hold the cart will be the easiest to understand, design, and write code for. and once you simplify the data being stored in the cart (my item #2), the code to add/delete items in the cart is very simple. the code you have posted for payment.php is very badly written and either came directly or indirectly from code at w3schools. this code can be greatly simplified, just by using an array to hold the errors. it is a huge security risk to input and store credit card numbers on your site. if you are doing this for real, and you have a merchant account that you process credit cards through, they will have a list of security requirements you must meet for them to allow you to keep your account with them if you want to input and store credit card numbers. instead, you would transfer the visitor to the merchant's online payment gateway and the only place the credit card information would be input and used is on the merchant's site. the merchant's site would send your site payment confirmation information. no. this refers to the code with the - "SELECT MAX(paymentID) as paymentIDVal FROM usercheckout" query. actually, the PDO extension is simpler and more consistent then the mysqli extension. the reason for recommending that you store the user's id in the session variable is so the code is general purpose and any queries are slightly faster. you don't have to do this, but if you ever allow a user to change his username, you will have to also change the value in the session variable to avoid logging the user out. on any page that you want to display user information, you would query for it using the user_id, rather than the username that you are doing now. the most straight forward implementation would be to have two tables - 1) orders - order_id (auto-increment) - assigns an id to the order/cart user_id - the user's id date_time_created - the data/time the order/cart was created - also used when cleaning up abandoned carts. status - the order status. initially, the status value would indicate this is a pending order, i.e. just a cart with items in it. when the cart is converted to an actual order, the status would be updated with a value that indicates this. when the payment is verified, the status would be updated to again. other columns unique to each order 2) order_items - id (auto-increment) - assigns an id to the items in the order/cart order_id - from the orders table - identifies all the items that are part of the same order item_id - the item id from your product/item table (note: if you will have different types of items, they should all be in the same table with a category column.) quantity - quantity of the item status - status of the item (this would be things like back-ordered, shipped) when the visitor adds an item to the cart, if there isn't a record for the user's id with a status = cart in the orders table, a new one is inserted, the last insert id would be retrieved and stored in a session variable. this assigns an order_id for this cart. you would use this order_id when inserting rows in the order_items table. if you update the quantity or delete the item from the cart, you would runs queries on the order_items table.
  3. your query is failing, because you are listing the wrong number of inputs in the type string for the bind_param() statement. this would either be throwing a (php?) error at the bind_param() statement or a mysql error at the execute() statement. you need to ALWAYS detect and handle statement errors. the easiest way of detecting and handling database statement errors is to use exceptions. to enable exceptions for the php msyqli extension, add the following two lines before you make the database connection - $driver = new mysqli_driver(); // note the $driver variable name used here is separate from and not related to any variable your code may be using $driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT; // MYSQLI_REPORT_ALL <-- w/index checking; w/o index checking --> MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT; then, php will catch the exception when there is an error and if you have php's error_reporting set to E_ALL and display_errors set to ON, php will display the actual cause of the error and some back-trace information.
  4. from your statement, it's not entirely clear what sort of problem you need help with. however, in looking at the code, what you have now isn't going to work. you have a session based cart at one point and a database based cart at another. programming requires that you have a clear definition of what you are trying to accomplish and what the data is going to be, before you write any code. some overall suggestions - 1) any action that modifies data should use a post method form. your 'delete from cart' should use a post method form. 2) simplify your cart definition. if you use the item id as the cart's array index and the quantity as the value, all the code will be simplified. you should pass the minimum of information through a form, since you must validate all the submitted form data. the item name and price is known on the server. passing it through the form and storing it in the cart is just more work and more code you have to write and test. 3) if the cart is empty, you should output a message stating so. at the point where you are trying to display the cart or inputting the customer information during checkout, if the cart is empty, display a message stating so. don't leave the visitor guessing why the page isn't doing anything. 4) you have a <form></form> that you have put href/links into. that makes no sense, just output the navigation links. 5) aside from your payment.php code using a database based cart, which is not where the myorder.php code is storing the cart, this code looks like a w3schools copy/paste fail. all those variables you wrote out is not how to do this. you would use an array to hold the validation errors and also serve as the error flag. if the array is empty, there are no errors. if it's not empty, there are errors. 6) you should also not input or store the credit card number, even if this is just a programming class exercise. 7) you cannot (successfully) retrieve the MAX() column value from a database table and use it. multiple rows could have been inserted due to concurrent visitors and you can get the wrong value. to get the correct auto-increment id value following an INSERT query, use the last insert id property/method for the php database extension you are using. for the mysqli extension, it would be the mysqli::$insert_id property. this test_input() function is nonsense from the web. please DON'T copy code you find on the web. actually learn how to validate input data and safely supply it as input to sql query statements. to safely supply data as input to sql query statements, you should use a prepared query, which the php mysqli extension doesn't do very well. if you can, witch to use the php PDO extension. 9) since the visitor must be logged in to display the cart, your code should require the visitor to be logged in to add or delete items to/from the cart. the add to cart and delete from cart form processing code should only be executed if the visitor is logged in. i would store the user's id, not the user's first name, in the session variable to indicate who the visitor is.
  5. here's a much easier way of doing this. get the main table's last insert id, like you are doing now, and as you loop over the uploaded files, for each successful one (your code isn't actually testing the ['error'] element to know if the file uploaded without any error), simply insert a new row containing the main table's last insert id into whatever $table3 is. get the last insert id from this table and use that as the destination file name for the move_uploaded_file() statement. this assigns a unique id (filename) for each image. if you are storing information about each image, such as original file name, description, ... you would store it in the correct row in this table. to 'edit' the file information, you need to handle each possibility - 1) no change, i.e. keep the existing image. you would display the existing file (thumbnail), original name, description, and use the image id (filename) as the type='file' form field name's array index value, which will become the $key value in the php code. i would use a different form field name for existing images (such as 'existing_files'), from the form field name for new images (currently it's 'files'). if no new file is uploaded (there's a specific error value, which is where checking the ['error'] element comes in), you would do nothing for the particular image. 2) replace an existing image. in this case you would select a new image in the browser and upload it. the ['error'] element would indicate a successful uploaded image. you would get the existing id (filename) from the $key value, and after making sure it corresponds to the current main table data being edited, you would simply use the id (filename) in the move_uploaded_file() statement to replace the image, leaving everything else as is. 3) delete an existing image. you would have a checkbox as you have theorized. the checkbox name would be an array with the array index value being the id (filename). for any checkboxes that are checked, you would get the array index value and after making sure it corresponds to the current main table data being edited, delete the corresponding image file and the row in $table3. 4) add image(s). this would use your existing code. by using a different form field name for existing files and for new files, the 'edit' code and the 'insert' code would operate on their own set of form fields. this will simplify your existing database code, making it easier to update it to current best practices and standards.
  6. the primary id column should be an auto-increment integer. it should not be a character data type.
  7. an auto-increment column needs to be an integer data type.
  8. you can either add that term as an entry in the $and_terms array or create and use a 'view' on your database table.
  9. there is a limit to the amount of data in one row. for what you have described, you would store each data item in its own row, with phone_id, config_id, and value columns. to retrieve the set of data for any phone, you would just query for the rows having that phone's id value. the phones and configuration names would be defined in other tables, giving the phone_id and config_id to use in the configuration storage table.
  10. you would produce the correct ALTER TABLE or CREATE TABLE query and execute it, provided that you can even create a database user on your hosting that has permission to alter/create a database table. however, everything you are asking points to a bad design. you shouldn't be dynamically creating tables/adding columns. 400 fields/columns in one table would be highly unusual and in it self indicates the data isn't being properly normalized (databases are not spreadsheets and trying to use them as one results in a lot of complicated code and queries to accomplish even simple tasks.) care to share some relevant information about what you are doing and a sample of the columns/fields you intend to dynamically add to a table?
  11. ^^^ then you should have posted the original code that didn't have the include statement commented out. by posting adulterated code, you wasted everyone's time making off topic attempts at helping you. the help you get is only as good as the information you supply.
  12. if you would post those exact errors w/line numbers, someone COULD help you with what's causing them, because the magic 8 ball we resort to using when someone doesn't think it's necessary to share specific information they have about a problem doesn't show us what you are seeing in front of you.. it's likely they are not exactly the same errors/line numbers as what you posted at the top of this thread.
  13. what sort of error or problem are you having with this query? if you remove all the (), which don't appear to be doing anything, it looks like it should work.
  14. this code is not good and it's not safe. afaik, the XMLHttpRequest() object is not universal between browsers. if you are going to use ajax, you must either take into account all the likely browsers or you need to use a library like jquery to do this for you. before you can ajax, you must be able to html. your form and your form processing code must work properly before you can add ajax to it. your page should also work of someone has javascript disabled. once you get your form and form processing code to work, adding ajax is as simple as adding an event listener tied to an id or class in the form tag, prevent the default form action, serialize the form data (which takes a single statement to operate on all the successful form fields), submit the data, and handle the response. next, because anyone or anything can submit data to your form processing code, it must enforce security. your form processing code needs to detect that a post method form has been submitted, validate the input data, safely produce the message body, and any email address you put into a mail header must be validated to insure it contains only one properly formatted email address to prevent mail header injection. lastly, emails being sent from a form submission on a web site are NOT being sent from the email address that someone entered in the form. the emails are being sent from the web hosting mail server or a third-party mail server. the From: email address must either be hosted at the sending mail server or there must be an SPF record at the domain in the From: email address that says the sending mail server is authorized to send email for that domain.
  15. this error has probably been occurring for some time, but because your code/site isn't using the imagick extension, and you haven't had the php error_reporting/display_errors setting set to report all errors, it hasn't been shown. this error, while it should be fixed, isn't relevant to the immediate problem. if the form field names and values are showing up in the browser address bar, it's because the JavaScript isn't submitting the form and the browser is (the <form tag doesn't have a method attribute, so the default get method is being used.) if the code worked before, what exactly have you changed in it?
  16. Nooooooooo...... this code is logically incorrect and if you are using this same basic code for the email version, it is not secure. the point of a captcha is to prevent non-human submissions from working or unnecessarily using server resources. the current code, if there is no captcha field in the submitted data sets $validQuery = true; and merrily runs the rest of the code. only if there is a captcha field in the submitted data and its value matches the expected value should the rest of the the form processing code run. you should not have any other statements before you have verified the captcha. your form processing code, regardless of what it finally does with the submitted form data, must first test if a post method form was submitted. next, only checkbox and radiobuttons in a form are 'optional' and may not exist in the submitted form data. by using an isset() test for a field that is 'required' makes that field 'optional'. if you need (that still hasn't been determined, since you should find and fix what's causing the slow email operation) to convert from sending an email to recording the submitted data, all you should do is take the same information you have now that's going into the email and (securely) insert that into the database table, along with recording the date/time of the submission, perhaps other things like the visitor's ip address..., and a status field, that would be used to control if the record has been send in the summery email. there's no need for all the rest of logic you have shown. all you are doing is changing what happens with the submitted form data. next, to implement the cron based sending of a summery email, you would just find the records in the table that have a status that says they have not been sent, retrieve the data, produce the summery email, and if sending is successful, change the status to indicate they have been sent. you could also have a field in the table that you update with the send date/time.
  17. wouldn't that mean exactly what your comment in the code states - where is the 'id' in the URL coming from? wouldn't the edit link that you are producing on one page and code using a value from that link on another page need to use the same name for the GET parameter? after you get (pun not intended) the names to match, is there actually an id value in the link? and this is the problem with you just wanting the code to work and wanting someone else to tell you why it doesn't, you are not involved with, looking at, following, and getting what the relationship is between the different pieces of code in the process.
  18. you would need to use php's output buffering statements.
  19. that''s not what he stated. you are the only person here that can investigate what your code and your data are doing. in order to fix a problem, you must find what is causing it. otherwise, all you are doing is trying to make symptoms disappear, which will just mess up the code and leave the problem intact. in programming, except for very overt problems, there is not a 'one symptom' is always caused by exactly 'one thing' relationship, because there are multiple different methods of accomplishing any task. a dozen different people could have written a questionnaire application, that produces the same exact symptom you are getting, and the cause could be different in each application. the error and line of code you posted is only the tail-ass-end of the problem, it's a symptom. without knowing fully how your code got to that execution point and what processing it is doing on the data up to that point, we cannot even suggest what to do to narrow down the problem. had the code been written with validation and error checking/reporting logic in it, the code would be helping you by telling you the first point where something wasn't as expected, rather than continuing to execute and giving you a php error at the tail-end of the problem. fundamentally, if the code is well written, it will tell you when, where, and why it is failing. no one is suggesting rewriting all the code, but if it doesn't have useful validation and error checking/reporting logic in it now, it was never actually finished to begin with and still needs some work done on it. the only hints i can give are general purpose debugging - 1) do you have php's error_reporting set to E_ALL? you are likely getting related Notice errors earlier in the code that could help pin down the problem. you may in fact be getting an undefined index Notice error at the same line code you have posted. 2) is php's output_buffering turned OFF, so that messages your code echos and php error messages won't be hidden if the code is doing header() redirects. 3) because it's random, it's due to either a race (timing/request) condition, an initial (initialization) condition, or assumption that the code and data are making. beyond those, you have got an application that doesn't work. you would need to post enough of the code that reproduces the problem for us to even be able to give specific suggestions on what to check.
  20. what debugging have you done to find out WHAT the code IS doing? do you have php's error_reporting set to E_ALL and display_errors set to ON (in the php.ini on your development system) so that php would help you by reporting and displaying all the errors it detects? are you sure the elseif() statement being shown is true and that no prior related if() or elseif() statement was true so that the shown elseif() will even be executed? do you have the PDO error mode set to exceptions so that database errors will throw an exception, combined with the suggested php error_reporting/display_errors settings, so you will see any database errors? is there a header() redirect later in the code that could be redirecting back to the same page, combined with php's output_buffering being on, that would hide any php errors or any output from echo statements in your code?
  21. yes, $type is one variable, it's an array variable. it has more than one dimension. each array index references a different element of the array variable. there is a posted example showing how to use the $type array, for one of the stated purposes, of replacing the switch/case statement. that example would be this code - $alertID = ''; $alertClass = ''; if(isset($type[$event])) { list($alertID,$alertClass) = $type[$event]; } i'm guessing you don't understand what that is doing? $type is the array that has been defined and has had four elements assigned to it. the 'Tornado Warning', 'Severe Thunderstorm Warning', 'Flash Flood Warning', and 'Flood Warning' are the array indexes. supplying a literal array index name - $type['Flash Flood Warning'] in some code would reference the id and class values that are stored/assigned for the flash flood warning array index value. supplying a variable array index name - $type[$event] (assuming that $event is a string, rather than an simplexmlelement object) in some code would use the value in $event as the array index and would reference the id and class values that are stored/assigned for whatever is in $event. using isset($type[$event]) is testing if the element in the array $type, given by the array index name in $event is set. using list($alertID,$alertClass) = $type[$event]; is referencing the element in the array $type, given by the array index name in $event, and assigning the id and class values that are stored for that array index name to the $alertID and $alertClass variables. note: once your code has parsed and filtered the xml data so that only data having those four types is being processed and displayed, there's no need for the if(...){...} conditional logic or initializing the $alertID and $alertClass to empty strings. the event types in the data being looped over will be in the $type array and you only need the - list($alertID,$alertClass) = $type[$event]; line of code.
  22. don't know what that is referring to, since nothing posted is doing that. you can require the defining array and the couple of lines of logic anywhere you want. if you do the other things that are needed to accomplish the stated goals of only keeping data of those types and ordering the data in the output by those types, the defining array will need to be required before the point where it is first referenced. the errors you are getting, which you didn't post, but i'll guess anyway, are either due to this - $type = array($event);, which isn't what i posted, that's creating an array with $event as the value in it, or they are due to the fact that the various child values you are getting are SimpleXMLElement objects, not strings, and for the case of using $event as an array index, needs to be cast to a string either implicitly, by adding double-quotes around it where it is used, or explicitly by using (string) when the value is first assigned to $event.
  23. to do this will require changing how your code works, by separating the different 'concerns'. you need to separate the parsing of the data from the display of the data. in the parsing code, you would store the data into an array of sub-arrays, using the event type as the main array index and only store the types that you went to keep. you would only store the raw data values, without any formatting. you can use print_r() or var_dump() to verify that the data you have stored is what you expect, before going onto the next step of producing the output. in the display code, you would loop over the main array indexes in the order that you want to display them. this will give you any sub-arrays of data for each event type. you would loop over the sub-array and produce the output from the data. all the formatting code would be in this section. lastly, i'm sure in one or more of your threads, it has been suggested (by me) to not write out php logic just to map one value to another. you should use a simple mapping array. see the following - // define a map of the event type string, to any other values. the two entries are the alertID and the alertClass // this defining array is also used in the parsing code to control what event types are kept - if $type[$event] isset(), keep the data // is it also used when displaying the data. the order of the entries here controls the output order, by looping over the keys (see array_keys() ) from this array to access the parsed data in the same order $type = array(); $type['Tornado Warning'] = array('Tornado', 'AlertTornado'); $type['Severe Thunderstorm Warning'] = array('SevereThunderstorm','AlertSevereThunderstorm'); $type['Flash Flood Warning'] = array('FlashFlood','AlertFlood'); $type['Flood Warning'] = array('FlashFlood','AlertFlood'); besides the uses listed in the comments, this converts your design into a general purpose 'data driven' design, where any specific data values are pulled out of the program logic, leaving the program logic simplified and general purpose, and by putting the data values all in one place, you eliminate repetition in the code and make it easy to add, remove, or alter any of the data values. edit: by switch'ing (coding pun intended) to a data driven design, all that switch/case logic can be replaced with this - $alertID = ''; $alertClass = ''; if(isset($type[$event])) { list($alertID,$alertClass) = $type[$event]; }
  24. actually, naming form fields (variables, db column names, or anything else) with an incremental number is a bad design that takes more code to produce the markup and process the data. you should use an array name for the form fields. - name="School[]", name="Student[]", and name="Class[]". this will submit the data as a php array for those field names, that you can simply loop over and access the values from each set of form fields within the group.
  25. ^^^ i'll have to digest that before replying fully. direct (parent) items are the things that are specifically and intentionally picked by the sales engineer, i.e. quantity 3, steel man door, quantity 10, 3 x 5 sash window.... picking these results in a direct bom that consists mainly of the item id and its quantity, that's stored with respect to a project/building id. the indirect/derived/calculated (child) items are the incidental items, fasteners, sealants, lift rental, labor (i'm assuming you are handling time/labor using this same system) ... that are the result of each direct item. currently, any time you change something on the direct bom, your code is looping over all the possible indirect items (in a bottom up fashion, in your original thread some time ago, it was mentioned to use a top down method, so that only things that change get recalculated) and is using values and equations hard-coded in the logic (hopefully to be converted to this data-driven rules based method) to calculate the quantity of each indirect item id. this produces an indirect bom that mainly consists of the indirect item id and its quantity. entering new items, of either direct or indirect type, can be done en-mass without regard to any association. the page where you define new or edit existing rules could be with respect to either the direct item or the indirect item, and you may want to do both. what i described above is with respect to the direct item. for any selected direct item, you would be able to see what existing rules there are and can edit, delete, or add new indirect items. so, for something like a window, you would see and edit any fasteners, flashing, sealant, ... for an edit page with respect to the indirect items, such as white caulk, when you select that item, it would show you all the rules defined for it and what direct items it is used with and if you are using categories, like in an example earlier in this thread, you can either just list the category name(s) or retrieve and display all the actual direct items that are under any category based rule. this indirect item edit page may be more useful for reporting purposes, rather than being the primary method where you define/edit the rules. lastly, i'm assuming that you have the direct bom stored in a database table. once you have these rules stored in a database table, for at least the unit_rules, you can produce the indirect bom entirely in one sql query (join the bom table with the rules table using the direct item id, sum the - bom quantity times the multiplier plus the offset, and group by the indirect item id). you may be able to also apply the group_rules in the same query, but that's more thinking than i want to do on this subject.
×
×
  • 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.