Jump to content

mac_gyver

Staff Alumni
  • Posts

    5,536
  • Joined

  • Days Won

    192

Everything posted by mac_gyver

  1. i/we would assume that's the id, auto-increment primary index for an existing record in the database table, passed in a hidden form field, not one of the user entered fields. you would then use the existence or absence of the id to control if you are editing/updating existing data or inserting new data.
  2. yes. just name it $item, because that is what it is in the code that's calling that function. then reference elements in item, e.g. $item['quantity'] inside the function code. this actually would have prevented the initial error at the top of this thread, because there would be no need to match up all the different parameters. it will also allow you to add more values, such as the lineNotes, simply by selecting that data where you are querying for it, then using that data inside the function. you won't have to edit the list of call-time parameters every time you change the data being passed.
  3. another issue with the posted code. when you are building the 'selected' option choices, in both the quantity and the item menus, you are outputting the option with the selected attribute when the existing value is the same as the value being output AND you are repeating the same option choice without the selected attribute. e.g. if the selected quantity is 3, you are outputting an option choice for 3 that is selected, followed by another option choice for 3 that is not selected. i doubt this is the intended result. the only conditional logic should be to determine what the selected attribute should be, the option markup should only be output once per value, that is either selected or not. note: you can simply put the 'selected' attribute in or leave it out. you don't have to put it in AND set it to a (true, i.e. any non-empty string) value to cause the option to be selected. if by some chance this is the intended result, in the case of the item select/option menu, the data-... attribute(s) are used in the lineTotal/line-total calculation, so they must be output in every option choice. the current code is not outputting them in the 'selected' option choice, which will prevent the calculation code from producing the total.
  4. the intended purpose of having the database name as a call-time parameter is so that you can make multiple connections, each with their own selected database. for this to work, $DBName must be removed from the global ... ; line of code, so that the call-time parameter will be the value that gets used. if there's ever a case of directly making an instance of the DBSQL class, yes. the line $this->DBSQL($DBName); would need to be changed to parent::__construct($DBName); as well.
  5. an additional point about the function implementation. the purpose of the markup being built inside of getItemsForQuote is to edit the existing item row values. to do so, you need to supply all those initial existing values to the code, which actually changes to become the submitted form data, when you redisplay the form upon a validation error. do NOT add a discrete call-time parameter for each of these values. simply pass an array of values as one call-time parameter. when you initially produce the form, the array of data would be that which you query for and fetch from the database. when you redisplay the form upon a validation error, the array of data would be the submitted form data.
  6. this code is killing your database server with connections. a database connection is one of the slowest, resource consuming operations you can do. your main application code should make one database connection. you would then pass it as a call-time parameter to any function that needs it. the getItemsForQuote function has the wrong responsibility. it is mixing the database specific code with the presentation code, it should only get the data, like its name indicates and my not actually be needed to get the data one item at a time. see the next point. this code is executing a select query within a loop (getting all the items for the item_type of the current item), which is also inefficient. even if there's only one item per item_type in a quote, and even worse if there is more than one, you should get all this data in one query, index it by the item_type when you fetch it, then access it when building each itemSelected select/option menu.
  7. see the 4th item under 'Other incompatible Changes' at this link - https://www.php.net/manual/en/migration80.incompatible.php also see the 'Old-style constructors' at this link - https://www.php.net/manual/en/language.oop5.decon.php
  8. i just tried the code, and there is one php version difference. a method named the same as the class is no longer automatically called when an instance of the class is created. you must specifically name the method __construct. change function PicSQL($DBName = ""){ to function __construct($DBName = ""){
  9. there is no password parameter in the pg_connect() call. does the database have a password set for the connection? is this the exact code that has previously worked? note: because you are passing the database name as a call time parameter and also using the global keyword to get the database name into the function, i'm not sure which takes precedence or if the call time parameter value sets the global variable. the only reason why this would have previously worked, is because the same value is being used in both cases. if you have any DBSQL(...) calls that are using a different value than $DBName, this probably won't work the way you think it should. you can try to use echo pg_last_error(); to see if it provides some information (doubtful.) for the error logging, do other types of php errors get logged? if so, use a phpinfo() statement and check if error_reporting is set to E_ALL, so that ALL php errors will get logged. putting the error_log(...); statement right before the pg_connect(...) call would let you know what values are actually being used inside the function. short-version: there's nothing apparent in the code that is php version specific. the connection is failing and is probably returning a false value. you can use var_dump($conn); right after the connection statement to check. therefore, you need to determine why the connection is failing.
  10. the version of your query with quotes around the place-holders should have been producing php/sql errors, about the number of bound parameters not matching the query... do you have php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your system, and have you set the PDO error mode to use exceptions? also, the error response you get can change depending on an emulated vs true prepared query. have you set the PDO emulated prepared setting to false? edit: which was mentioned in the replies in your previous PDO based thread - https://forums.phpfreaks.com/topic/314929-pdo-uncaught-error-call-to-a-member-function/
  11. moving data is also not the correct way of doing this. it's a lot of work for nothing. the record that was (should be) inserted for each sale is still correct. it defines all the who, what, when, where, and why information about the sale that was made. if something is returned, that's a different transaction that affects the quantity and it is defined by the who, what, when, where, and why information in the void/return record that gets inserted.
  12. this is a common activity, i.e. getting the row of data in each group matching a specific condition. see - https://dev.mysql.com/doc/refman/8.0/en/example-maximum-column-group-row.html not listed in that information is adding a term to the WHERE clause with id IN(a sub-query that gets the max(id) per group) (essentially what your query would be if it was just getting the max quote id per job_id group.) i cannot vouch for the efficiency of this method, but it is fairly easy to understand when you write/read it.
  13. the issue of any external, unknown, dynamic value being output on a web page, possibly containing html special characters that would break the html syntax, should be handled by applying htmlentities, with the ENT_QUOTES flag, to value when it is output. this will allow any single-quote, double-quote, <, >, or & in the actual value to work. they will be converted, by the browser, back to the actual literal character when the value is submitted.
  14. when you fetch the data from the query, you would index/pivot it using the maincat as the main array index. this will give you a sub-array of rows for each maincat value. when you loop to display the result, you can use php’s count() function to get the number of rows for each maincat value and use this as a rowspan attribute in the column where you are displaying the maincat value.
  15. LOL, i see that the same/similar information as above was given in one of your previous threads.
  16. no. do not update quantities or delete data to accomplish this. databases are for recording information. by updating/deleting data, you lose an audit trail that would let you know if a programming mistake, an accidental key was pressed, or nefarious activity changed a value. you would INSERT data for every order/transaction that affects a value. a sale would insert a row into an order/transaction table with a 'type' indicating it is for a sale, then insert row(s) into an order_item table for each item that was sold with the order_id, item_id, and quantity. to void a sale, you would insert another row into the order/transaction table with a 'type' indicating it is for a void/return, with a reference to the original order_id, then insert row(s) into the order_item table, with a negative quantity for the items that are returned and will be restocked (some of the items might have been kept, some might have been damaged, and won't be restocked.) to get the total quantity you would just SUM() the quantities per item_id.
  17. data driven example - <?php // file to save output in // note: when storing data in a file, you must use file locking to make this concurrent safe (a database automatically does this for you) $file_name = "file.txt"; // define fields - the array index is the field name, since these must be unique $fields = []; $fields['firstName'] = ['label'=>'First Name', 'type'=>'text', 'placeholder'=>'First Name', 'required'=>true, 'choices'=>[],]; $fields['lastName'] = ['label'=>'Last Name', 'type'=>'text', 'placeholder'=>'Last Name', 'required'=>true, 'choices'=>[],]; $fields['sex'] = ['label'=>'Sex', 'type'=>'radio', 'placeholder'=>'', 'required'=>false, 'choices'=>['male'=>'Male','female'=>'Female'],]; $fields['fruit'] = ['label'=>'Fav Fruit', 'type'=>'checkbox', 'placeholder'=>'', 'required'=>false, 'choices'=>['apple'=>'Apple','orange'=>'Orange','berry'=>'Berry'],]; // examine form data // echo '<pre>'; print_r($_POST); echo '</pre>'; // post method form processing if($_SERVER['REQUEST_METHOD'] == 'POST') { // array to hold output lines $output = []; foreach($fields as $field=>$arr) { switch($arr['type']) { case "text": // add validation logic as needed $output[] = "{$arr['label']}: $_POST[$field]\n"; break; case "radio": // add validation logic as needed $val = $_POST[$field] ?? 'not selected'; $output[] = "{$arr['label']}: $val\n"; break; case "checkbox": // add validation logic as needed $val = $_POST[$field] ?? 'not selected'; $val = is_array($val) ? implode(', ',$val) : $val; $output[] = "{$arr['label']}: $val\n"; break; } } // add separator $output[] = "------------------\n"; file_put_contents($file_name,$output,FILE_APPEND); } ?> <form method="post"> <?php foreach($fields as $field=>$arr) { switch($arr['type']) { case "text": $req = ($arr['required'] ?? false) ? ' required' : ''; echo "{$arr['label']}: <input type='{$arr['type']}' name='$field' placeholder='{$arr['placeholder']}'$req autocomplete='off'><br>\n"; break; case "radio": echo "{$arr['label']}:"; foreach($arr['choices'] as $value=>$label) { echo "<input type='radio' name='$field' value='$value'>$label "; } echo "<br>\n"; break; case "checkbox": echo "{$arr['label']}:"; foreach($arr['choices'] as $value=>$label) { echo "<input type='checkbox' name='{$field}[]' value='$value'>$label "; } echo "<br>\n"; break; } } ?> <input type="submit" name="submit" value="Submit"> </form>
  18. you should use a data driven design, where you have an array that defines the label, field type, placeholder text, choices (for checkbox/radio fields), and any other unique data per field. you would then loop over this defining data structure to dynamically produce the form, also use this when validating the submitted data, and use it when storing the data to a file/database, so that you can have some general-purpose code do the work, rather than writing out bespoke code for every field.
  19. of course you can do this, by supplying an array of the column names as an input to the function, then dynamically building the select list (see php's implode() function).
  20. you should be learning and developing on a localhost development system. it is a waste of time and a security risk trying to learn and develop code/query(ies) on a live/public server. your posted code IS using the mysqli database extension. the line of code i posted IS a mysqli statement. all you have to do is add that line in your code before the point where you make the database connection. if your statement means that the web host has disabled that particular function/statement, this is all the more reason to be doing this on a localhost development system.
  21. if you add the line of code that i gave to use exceptions for errors for the mysqli extension, you will get an sql error telling you why the query is failing, assuming that you have php's error_reporting set to E_ALL and display_errors set to ON. having error handling like this is a fundamental troubleshooting step, i.e. trying to teach you how to fish, rather than giving you a fish to eat every time you are hungry. please take the time to learn and use the fundamentals for this task.
  22. it's not. you don't have a clear definition of what the work-flow/steps are, so you haven't been successful at writing code that does what you want. the work-flow/steps are - a user sits down at a computer/device and logs in. this stores the logged in user id in a session variable. a logged in user can now see and do things that requires a logged in user. this tests/uses the user id in the session variable. one of the things they can see and do is see/navigate to the formulaire form, fill it in, and submit it. this also tests/uses the user id in the session variable. the form processing code for each form should be on the same page as the form. this results in the simplest code and the best user experience (you can repopulate the form field values upon an error so that the user doesn't need to keep reentering data over and over.) the way to get the form to submit to the same page it is on is to lever the entire action='...' attribute out of the form tag.
  23. your code is filled with unnecessary logic (copying variables to other variables, cryptic error handling), that doesn't help you, and you are missing needed logic, such as trimming and validate input data before using it. the current error is because you have a syntax error in the sql query statement, but the current error handling would only tell a hacker when they managed to trigger a query error. it doesn't help you when learning, developing, and debugging. when you are learning, developing, and debugging code/query(ies), you want to display all php errors and display the actual raw database statement errors. when you put your application onto a live/public server, you want to log this same information. the simple way of doing this, without adding or editing code at each database statement that can fail - connection, query, prepare, and execute, is to use exceptions for database statements and in most cases simply let php catch and handle the exception, where php will use its error related settings to control what happens with the actual error information (database statement errors will 'automatically' get displayed/logged the same as php errors.) you would then remove all the existing database statement error handling since it will no longer get executed upon an error, simplifying the code. to enable exceptions for errors for the mysqli extension, add the following line of code before the point where you make the database connection - mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  24. it's pretty apparent that your url rewriting is not working (is probably a redirect) and there's no $_POST data for the code to use. No. the end result of the login process is to remember who the logged in user is, by storing the user id in a session variable. you would then use the existence of a remembered, logged in user to display any logged in specific navigation links, form, and enable the form processing code on a page.
  25. have you checked in formulaire.php if there's $_POST data at all? add var_dump($_POST); next, why do you have a form in the login.php page that's going to another page with more form fields? you are creating a bad user experience, requiring the user to push more buttons and fill in fields, then if the username/password is not valid, you will need to go back to the login form, then go to the formulaire form to reenter the data again. also, the php code is dealing with the user/username. you have now stated this field in the second form is for a password value. please clarify? in short, what is the overall stated purpose of doing this? it looks like the formulaire data is profile information, that would be requested when a user registers, not when a user logs in.
×
×
  • 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.