Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,341
  • Joined

  • Days Won

    173

Everything posted by mac_gyver

  1. your loop should only be retrieving the data, forming the $message body with the data values, clearing any previous To: address (see the ClearAddresses() method), set the To: address from the data, and call the send() method. all the rest of the phpmailer related logic should exist only once and come before the start of your loop. you would also want to check if the send() method indicated success or failure. if it failed, log the error information and the user's email address. if it was successful, you would probably want to set a status value somewhere to indicate that the email was sent (though this is no guarantee that it was received) so that you don't repeatedly send the same reminder email.
  2. rather than to try and make your existing code 'work' (the comma separated list you are showing as a value makes no sense - the type and the meal number is known from the select name and don't belong in each option value), just define what data you have and what result you want to produce from that data. i gather that $data is an array that somehow contains the possible choices for meat, fruit, and vegs? your goal would be to produce the <option></option> list for for each type, using the $type variable to select what part of the $data to use. the value='...' attribute that you produce should be just be an identifier for the choice. the display label should indicate to the user what each choice means. if the option list is always the same for any type, all three meals each day and all 7 days of the week are the same, you would produce the option choices ONCE, store the result in a php array variable, using the type as the array index, then simply output them when needed, using the $type variable to select which one you output. so, what does the $data array look like?
  3. https://en.wikipedia.org/wiki/Web_search_engine
  4. your would queue the email messages in a database table and use a cron job/scheduled task to actually send them.
  5. as to having a huge amount of code, you should be dynamically producing the forms and dynamically processing the form data. for the form you posted above, you have a hidden field that indicates that day of the week. you will know that all the form fields correspond to that day. you don't need to include the day as part of the form field name. you have two (or more) types of items being selected - meat, fruit. the form field name should just be that type. you are doing this for three meals a day. if you use an array name for the select name, you can use the meal number as the array index, i.e. name='meat[1]', name='meat[2]', name='meat[3]', same for fruit[1], fruit[2], fruit[3] and any other types. if you have a list of the types, you would loop over that list as well, rather than hand-coding all of this out. the submit button doesn't need to be named because you have the hidden field with the name. see this example code that produces 7 days of forms, with 3 meals per day, with whatever different types you have - $days = array('Sunday','Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' ,'Saturday'); $num_meals = 3; $types = array('meat','fruit'); foreach($days as $day){ echo "<h4>$day</h4>"; echo "<form method='post' action=''>"; echo "<input type='hidden' name='dayofweek' value='$day'>"; foreach(range(1,$num_meals) as $meal_number){ echo "<h5>Meal $meal_number</h5>"; foreach($types as $type){ echo "$type: "; echo "<select name='{$type}[$meal_number]'>"; echo "<option>build your option list in a loop using the variables present - \$day, \$type, \$meal_number to select which data to use</option>"; echo "</select><br>"; } } echo "<input type='submit' value='Save'>"; echo "</form>"; } if you in fact want only ONE form around all the days, you wouldn't use the hidden field with the day in it. you would add a second dimension to the form field array names. the first dimension would hold the day name (the day number would be better). the second dimension would be the meal number.
  6. you would add a unique composite key to your database table consisting of those three columns.
  7. yes, and what if your category values have been referred/linked/bookmarked to by visitors to your site. they would expect to be able to revisit your site and have their links/bookmarks take them to the same category information if it still exists. unless you are using test data in your tables that you will completely delete and start over with real data, you wouldn't ever alter the referral values between tables after it exists.
  8. to get you going, here is your index.php code, rearranged as suggested - <?php // 1) initialization - create/define things your code needs - session_start(), require files holding configuration data/function definitions, setup an autoloader for class definitions... session_start(); $errors = array(); // holds error messages. if empty, no errors, if not empty, at least one error. $products = array(); $products['MMS-1754'] = array('name' => 'Flute', 'cost' => '149.50'); $products['MMS-6289'] = array('name' => 'Trumpet', 'cost' => '199.50'); $products['MMS-3408'] = array('name' => 'Clarinet', 'cost' => '299.50'); require_once('cart.php'); // 2) start of database dependent code - create a database connection. if you are using exceptions to handle database errors, this would be where the try block starts. // none in this example // 3) determine user state and permissions - check if the current user is logged in and retrieve any permissions the user has. the rest of the code on the page would make use of the logged in state and permissions to determine what code can be ran and what content will be produced. // if you were doing this for real, you would require that the user be logged in/authenticated at some point // 4) post method form processing - the post method form processing code, which creates/modifies/deletes data on the server, should come near the start of your file so that you aren't tempted to output anything to the browser before any data has been updated by the processing code. if your page has multiple sections of form processing code, you would have them all groped together in this section of code. if($_SERVER['REQUEST_METHOD'] == 'POST'){ $action = filter_input(INPUT_POST, 'action'); switch($action) { case 'add': $product_key = filter_input(INPUT_POST, 'productkey'); $item_qty = filter_input(INPUT_POST, 'itemqty'); add_item($product_key, $item_qty); break; case 'update': $new_qty_list = filter_input(INPUT_POST, 'newqty', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY); foreach($new_qty_list as $key => $qty) { if (true) { update_item($key, $qty); } } break; case 'empty_cart': break; } if(empty($errors)){ // after successfully (no errors) processing any post data, do a header() redirect to the exact same url that the form submitted to. this will cause a get request for your page. this will cause the browser to forget that a form was submitted and it won't try to resubmit the form data if you refresh the page or browse back to the same url. this also enforces separation of concerns. post method form processing, which modifies data on the server is a separate concern from displaying data due to a get request for your page. if you want to display a one-time 'success' message after the header() redirect, pass it in a session variable, then clear he session variable after the the message gets displayed. $host = $_SERVER['HTTP_HOST']; $uri = $_SERVER['REQUEST_URI']; header("Location: http://$host$uri"); die; } // if there are errors while processing any post data, you would not redirect, stay on the page, let the rest of the code on the page display the errors, (re)display the form, and repopulate the form fields with the previously submitted values. } // 5) get method business logic - code that produces/gets data needed for the dynamic content on the page. this code contains any database specific code that knows how to retrieve data from your database tables. the result of this code should be php variables that the code later on the page uses as its input. this code should contain NO html/css/javascript markup. // since this code is using an array to define the product information, not used in this example $action = filter_input(INPUT_GET, 'action'); // condition the get method action input switch($action) { case 'show_cart': // not used in this example break; case 'show_add_item': default: // not used in this example break; } // 6) end of database dependent code - if you are using exceptions to handle database errors, you would catch the errors at this point. you can also destroy any query result resources and the database connection at this point since you won't need them any longer. //none in this example //7) get method presentation logic - // code that knows how to take the data (database data, errors, form data...) from ALL the above code and // produce the dynamic output for the page. if the output doesn't require any 'heavy' processing/formatting, // just use the data directly in the html page/template code. the result from this code should be php variables // that the html page/template uses. this code should contain NO database specific statements. if your page // has multiple sections of get method presentation logic, you would have them all groped together in this // section of code. switch($action) { case 'show_cart': ob_start(); // capture the result of the included file include 'cart_view.php'; $main_content = ob_get_contents(); ob_end_clean(); break; case 'show_add_item': default: ob_start(); // capture the result of the included file include 'add_item_view.php'; $main_content = ob_get_contents(); ob_end_clean(); break; } // html page/template - this section starts with the <!DOCTYPE ... tag and ends with the </html> tag. it is the actual html document that the dynamic output is put into to make the complete page. only simple php conditional logic/loops, function calls (that are responsible for producing output), and echo statements should be present in this section of code. ?> <!DOCTYPE html> <html> <head> <title>My Guitar Shop</title> <link rel="stylesheet" type="text/css" href="main.css"> </head> <body> <header> <h1>My Guitar Shop</h1> </header> <main> <?php if(!empty($errors)){ echo 'The following error(s) occurred:<br>'; foreach($errors as $error){ echo "$error<br>"; } } ?> <?php echo isset($main_content) ? $main_content : ''; ?> </main> </body> </html> note: i didn't actually 'fix' anything in your code. in fact, for the places with php syntax errors due to incomplete logic, i just added a true keyword so that the code didn't throw any php syntax errors. faking/fixing up the php syntax and removing the common start/end of the html document from the two view files, lets your code run, but not necessarily do what you want, within the suggested page layout.
  9. actually, that's not specific enough for us to help you. we already know your code isn't working/broken/doesn't do what it is supposed to do because you are posting a topic on a programming help forum. if it was working/not broken/does do what it is supposed to do, you wouldn't be posting here. to get help, you must post actual errors and the code that they correspond to, symptoms (the output you actually observed, even if the output was a blank page) and at what point in the process they occurred, or specific questions.
  10. since you didn't ask any specific question, which is what we need in order to specifically help you with any problem you are having, here's a general list of things about your current code - 1) post method form processing code should be separate from any get method code. these are two separate concerns and should be completely separated in your code. post method form processing code should check if a form was submitted at all, validate any inputs, and create/update/delete the data. after you successfully (no errors) process any post method form data, you should do a header() redirect back to the exact same url of the page. this will cause a get request for your page. you can then display the result of what the form processing code altered. 2) your cart should only contain the key (item id) and the quantity. all the other information is derived data and should not be stored in the cart. 3) don't use the global keyword to bring data into a function. pass any input data into a function as a call-time parameter. 4) you should only have ONE instance of your main html document. everything that is common from the <!DOCTYPE tag through to the </html> tag should be a single 'template'. only the content section that's different should be in your view. you should store the output from processing the view code in a php variable, then just echo that php variable in the one main html/document template at the correct location. i would either put or include the main html document at the end of your index.php file. 5) in cart_view.php, to display the contents of the cart, loop over the cart data (which will be just the item keys and quantities), use the key to get the name and cost from the $products array, calculate the item total from the quantity and the cost, and sum up each item cost to get the order total. simplifying the cart to only hold the key/quantity will make a lot of your php code go away. also, i just noticed that you don't have any session_start() in the code, so none of your $_SESSION variables will work. you need to have php's error_reporting set to E_ALL and display_errors set to ON (preferably in your php.ini) to get php to help you by reporting and displaying all the errors it detects. if you layout the code in your main file like suggested at the following link, it will help organize and make your code foolproof (a session_start() would be part of the initialization section) - http://forums.phpfreaks.com/topic/297824-database-issues-and-working/?do=findComment&comment=1519095
  11. @hansford, it's usually better to state what's wrong, rather than to post 'fixed' code. by stating what the problem is, some learning will take place, rather than mimicking. the OP may not even realize everything you changed in the code.
  12. your query statements are definitely producing an error, due to the LIMIT clause being supplied string values. do you have PDO's error mode set to exception (you have to specifically do this after you make the database connection) so that any of the errors from the PDO statements will throw an exception (that you can catch in one place to handle db errors) to let you know they failed? at a minimum, the two bound parameters for the LIMIT ?, ? must use PDO::PARAM_INT for the types and you cannot pass these in the ->execute() method (it treats all values as strings) and since you are binding the parameters, you shouldn't be passing anything in the ->execute() method. also, if the two values for the LIMIT x,y are entirely produced within your code, there's no need to bind them into the query, just put them directly in the query statement.
  13. your database query would retrieve the data you want, in the order that you want it. you would store the data from the query into an array, then extract the heading information from the array of data. then just loop over the data and output it the way you want it. see the following post for an example of doing this - http://forums.phpfreaks.com/topic/298003-data-display-in-wrong-column/?do=findComment&comment=1520525
  14. if this portion of your ajax is basically just moving functionality from the server to the browser, for when javascript is enabled, you can practice DRY (Don't Repeat Yourself) programming. you already have server-side code that's producing the values, html, .... instead of outputting those values/html when the page is requested, output them as 'generic' json encoded data in the ajax response. see the following example. code on your main page - <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Generic ajax - use server output to dynamically specify and populate elements in the dom without writing out code for each different thing</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("button").click(function(){ $.ajax({ url: 'api.php', data: "", //optional data to pass to api.php dataType: 'json', success: function(data) { var vals = data.val; // text and textarea values if(vals){ $.each(vals, function(key, value){ $(key).val(value); }); } var htmls = data.html; //inner html if(htmls){ $.each(htmls, function(key, value){ $(key).html(value); }); } var styls = data.styles; //css class name if(styls){ $.each(styls, function(key, value){ $(key).attr("class", value); }); } var sels = data.sel; // select/option - selected if(sels){ $.each(sels, function(key, value){ var v = value != '' ? true : false; $(key).prop("selected", v); }); } var checks = data.che; // radio and checkbox - checked if(checks){ $.each(checks, function(key, value){ var v = value != '' ? true : false; $(key).prop("checked", v); }); } } }); }); }); </script> </head> <body> <form method='post' action='your_formaction.php'> <div id='seats'></div> <input type='submit'> </form> <button>DEMO button to Get JSON data. You can also just automatically load the data when the page is ready in the browser.</button> </body> </html> example api.php code - <?php // the first array index is the 'type' that corresponds to the val, html, styles, ... in the javascript code // the second array index is the jquery selector (typically an id selector '#id') that will be used by the javascript code // output sample data - // html example $number_value = 3; $content = "<select name='seat'>"; foreach(range(1,$number_value) as $value){ $content .= "<option value='$value'>$value</option>\n"; } $content .= "</select>"; $array['html']['#seats'] = $content; // val/value example $array['val']['input[name="course_number"]'] = $course_number; // from wherever you are getting the course number echo json_encode($array); this method can replace your existing .val(), .html() usage. i have included one .val() example that should work with your existing page.
  15. this is the whole point of variables and control structures in programming. you can set a variable to any value, from wherever you want, and use control structures, such as a loop, to test/use the value that's in the variable to determine what to do. foreach(range(1,$number_value) as $value){ echo "<option value='$value'>$value</option>\n"; }
  16. your form should submit the id and you should store the id in the second table to relate the row in the second table back to the source information in the first table. information like the sitename/username should only exist once, in the source table where it is defined/stored.
  17. here's an example - <?php session_start(); // post method form processing code if($_SERVER["REQUEST_METHOD"] == "POST") { // load if(isset($_POST['load'])){ // process the groupid input, for brevity, just save it in the session variable // you would normally validate/cast it as a positive integer and detect if one of the choices has been selected $_SESSION['groupid'] = $_POST['groupid']; // do whatever processing you want when a groupid has been selected } // dump if(isset($_POST['dump'])){ // do whatever processing you want for this condition // clear the groupid unset($_SESSION['groupid']); } // any other post method form processing code.... } ?> <?php // at the part of your code where you are producing the output for the form - ?> <form method='post'> <select name="groupid" <?php echo isset($_SESSION['groupid']) ? 'disabled':''; ?>> <option value='0'>GROUP</option> <?php foreach(range(1,10) as $group){ // you should be retrieving the group numbers from wherever you have the group information stored, not hard-coded in the code $sel = isset($_POST['groupid']) && $_POST['groupid'] == $group ? 'selected' : ''; echo "<option value='$group' $sel>$group</option>\n"; } ?> </select> <?php if(!isset($_SESSION['groupid'])){ // no groupid selected echo "<input type='submit' name='load' value='Load'>"; } else { // a groupid is selected, output the stuff for when there is a groupid echo "<input type='submit' name='dump' value='Dump'>"; // whatever else you want to output } ?> </form> if would help you greatly in creating the program logic that does what you want if you organize your code with the form processing code grouped together and the code that produces the output on your page grouped together.
  18. do the disabling of the groupid select/option menu in your php code, rather than using javascript. when you submit the groupid select/option menu and redisplay the page, use the fact that you now have a non-default/non-zero groupid value to cause the disabled attribute to be output in that select/option menu. i would also only output the 'dump' button and any other form controls that are dependent on having a valid groupid, if you actually have a non-default/non-zero groupid value. submitting the 'dump' button would clean up any data and clear the fact that you have a groupid selected. this would cause the page to be displayed without the disabled attributed in the groupid select/option menu and would prevent the output of the 'dump' button and the rest of the form controls.
  19. disabled form controls are not submitted with the form data. so, i'm guessing that is what is causing the rest of the code, that you didn't show us, from working. how is this second select/option menu being requested/produced? why are you choosing to disable the first one? would making it read-only accomplish your goal, as read-only form controls are submitted with form data.
  20. no it's not that simple. you would do this like your bank or credit-card company does it, by storing a record for each transaction that lists the date, amount (credits are +amounts, debits are -amounts), and information about the transaction (confirmation number for payments, name/reason for each debit). why would you have any code in place that would allow a user to directly affect these amounts? the user should only have 'permission', through your code, to display the amounts and cause events to occur that enter a transaction for that user. for credit (+) transactions, you would verify with the payment gateway that the user made a payment before entering a row in the database table with the amount. for debit (-) transactions, you would only enter those if you know who the user is and if this is dealing in real money, you would re-verify who the user is by having him/her re-enter their username/password.
  21. GROUP BY in the query doesn't do that. it consolidates the rows having the same group value into a single row. it's primarily used when you want to use aggregate functions (sum, count, ...) on the data in the group. to do what you are asking, you would order (use ORDER BY topic) the rows in the result set to get the rows for the same topic together, then when you are outputting the data, each time the topic value changes you would close out the previous topic section and start a new topic section.
  22. if this is a 'contact us' form and you always want to send to a specific email address, use one of the phpmail classes (phpmailer, switftmailer) and use smtp authentication against your receiving email account and send the emails directly to your remote email account. this will make your php script 'look' like an authenticated/logged-in email client connecting to your email account and eliminate the sending mail server at your web host from the process. you can also use this method to send emails through your remote email account, with whatever quantity restrictions your mail provider imposes. if you do need to send through the mail server at your web hosting, i would start by finding out from them if your emails are actually being sent. just because the mail() function is returning a true value, doesn't mean that the mail server has sent or has any intention of sending the email. some mail servers are configured to return a true value/no errors regardless of what happens to the email so as to not allow hackers to use the returned errors to find mail box names... next, the BT email server may be doing a more thorough check of the DNS records at your web hosting than what gmail is doing. the ONLY information a receiving mail server gets with any email is the ip address of the server/device the email is being sent from (from the tcp/ip data packets) and information in the email, i.e. the from address. the receiving mail server will use these two pieces of information to try and validate that the email is actually coming from where it says it is by checking the DNS records at the sending ip address and at the domain in the form address. perhaps the BT mail server is looking for a secondary piece of information that gmail isn't and something is either missing (missing values usually aren't a problem) or is set incorrectly (incorrect values will get an email discarded.) to help resolve this, there is usually a 'postmaster' web page at the major email hosts that will tell you what is required to successfully send an email to their server. there is usually a contact email where you can either find if a sending mail server has been specifically blacklisted at that email host or to request that a sending mail server be white-listed. also, you can use the various tools at a site like dnsstuff.com to check for and check for errors in the DNS records for your domain and the mail server at your web host.
  23. i'll try to answer some of the points from your last post above. sorry ahead of time for the bluntness that may ensue, because many of these things are basic/prerequisites that you should have, and may have, been shown before you were expected to use them - that's the syntax for a foreach() loop. reading the php.net documentation up to the control structure section and then reading the specific page for a foreach() loop would have given you the information you need to understand what the syntax means. no guessing is required. programming languages are one of the most heavily documented subjects on the planet because it's impossible to use them without having a good language reference. unfortunately, just being shown something and told what to type in a situation doesn't teach the meaning of it. that's mimicking/parroting. learning something technical like a programming (or a linguistic) language (which is not the same as learning how to program) is a process where you define a part of the language, then use it in an example to reinforce and internalize the meaning. you then build on what has been learned before. for example, if you haven't learned the general syntax for a php statement (what terminates a statement), learned the syntax for php strings, learned the syntax for php variables, learned the syntax for an assignment statement, and learned the definition for an echo statement, you won't know the actual meaning of every character in the following - $some_variable = 'hello'; echo $some_variable; that would let you generalize and use those same elements when writing your own code. since a foreach loop operates on an array of data (or something that's Traversable, like a PDOStatement object), you would need to get the result from the query into an array. the clearest way (that also separates the database statements from your presentation code ), would be to use the pdo ->fetchAll() method. you can find information about the pdo class in the php.net documentation. since your code is dependent on the pdo class, reading just about all of the pdo documentation at php.net would be to your advantage. the data from a post method form will be available in the php $_POST array. the form field name='some_name' attributes determine the $_POST array index names - $_POST['some_name]. at this point, the submitted data is in a php variable that you can use any way you want in your code, such as binding it with a place-holder in a prepared sql query statement. this is real basic/fundamental php information that there are probably 5,000,000 examples posted on the web to find and examine. again, the documentation for the php statements you are using defines what it all means. you don't have to guess, just make use of the documentation to learn the basics of the php language. that is the creative part of programming, which is different form learning the php language itself. see my post above about defining, then breaking the problem down into the steps that accomplish the task, to help with how to put statements together in a meaningful way.
  24. in addition to needing a basic understanding of the php language before you try to use it to do anything, the biggest thing that helps with programming is to define what you are trying to do, before you try to write the code for it. trying to write code or modify existing code (which would also apply to code snippets you find or are given) without a clear definition of what end result you are trying to produce, just wastes a lot of time. so, what are you trying to do, 1) a form with inputs for city/state, and 2) form processing code that takes the submitted city/state values, retrieves the matching information, if any, from the database table, and displays the results in a particular format. you would then break down each of those main tasks into smaller and smaller steps, until you can finally write the code that accomplishes each step. for the form processing code, those steps would be - 1) create a database connection, handling any connection errors, and as has been recommend, set the error mode to exceptions so that all the rest of the database statements will throw exceptions that you can catch and handle in one place. 2) check that a form was submitted - you were shown/given a method='post' form. however, this form is controlling what will be displayed. it should use method='get'. post method forms are for changing data on the server. 3) condition/filter/validate the submitted form data. 4) if there were no validation errors, use the submitted data in a database query. 4.1) form and run the sql statement for a SELECT query with a WHERE clause that will use the submitted city/state values, using place-holders for the input parameters. 4.2) prepare the query. 4.3) bind the input parameters to the place-holders in the sql statement. 4.4) execute the query. 5) retrieve the data that the query matched, if any. since your assignment mentions using a foreach() loop, the intent would be to fetch all the rows that the query matched into an array, then use the foreach() loop to loop over that array. 6) output the data, if any, in that particular format. if there is no matching data, output a message stating so. this list of steps that you have defined will become comments in the code that you will write. give me a couple of minutes and i may (no promises) post an example using pdo to do this.
  25. if you are not even sure that a $ starts a variable (programming is not about guessing or assuming, it is an exact science), you need to start with the basics. i would recommend that you read (so that you can internalize the information) at least the Getting Started and Language Reference (which covers variable naming) sections of the php.net documentation. php.net supplies the documentation in several forms, both on-line and down-loadable. i find the down-loadable .chm file particularly useful since it has a search-able index and in the cases where the index doesn't find what you want, you can use the search tab. next, if you have a question to post on the forum, limit yourself to just the relevant verbiage. we can only give an answer when we know of a specific question. just telling us you don't know what something means isn't specific enough. you must tell us what exactly you don't understand, because we are not providing free tutoring services. we are providing direction and sharing programming knowledge.
×
×
  • 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.