Jump to content

mac_gyver

Staff Alumni
  • Content Count

    4,350
  • Joined

  • Days Won

    115

Everything posted by mac_gyver

  1. if you are just starting out, i recommend that you start with a form and form processing code for just one form field. once you get to the point of being able to design, write, test, and debug the code for one field, you can deal with the code needed for the rest of the fields, which you should add one a a time. btw - your empty min/max prices are likely due to the preg_match validation failing, where you are setting the min/max prices to an empty string. there's two problems with this validation - 1) your regex pattern probably has some problem, and 2) you should leave any value that didn't pass validation as is so that it will re-populate the form field.
  2. the only user information you should store in a session variable is the user id. you should query on each page request to get any other user related data, which you would store in a general program variable/object, named as to the meaning of the data. the reason for doing this is so that any changes to the values will take place immediately (on the next page request.) by storing the values in session variables, they will only reflect any changes when someone logs in again. once you retrieve the user related data from wherever it is persistently stored, you would use it for determining both what the user can do and what the user can see on each page. what makes you think that? do you have code on your site that allows users to create or edit php program variables?
  3. Yes. It provided a better user experience, since you can directly display any validation errors when you re-display the form and you can re-populate the form fields with the previously submitted data so that the user doesn't need to keep re-entering the same values over and over. It also takes less code over doing these things on two separate pages since you don't need to pass error information and field values between pages. The only things that are needed to accomplish this are 1) put the form processing code above the start of the html document and 2) put the form processing code inside of a conditional statement that detects if a post method form has been submitted so that it only runs if the form has been submitted.
  4. does the activation link contain a run-once unique token? this would let you know if something is just submitting email addresses or actually has access to the content in the emails.
  5. if a business rule of the application is that that booking/busy times start/end on 30 minute intervals, you would need to provide a method of picking values that follow that rule and you would need to validate submitted data to insure that it meets that rule. if you have existing data that doesn't follow that rule, you can normalize the values, either where they are stored or when pre-processing the array of data, to round start times down to the previous interval time and round end times up to the next interval time.
  6. here's an outline of what the logic would look like - $interval = 30; // booking/busy interval in minutes // based on conditional logic in the code, 0 = mon through 6 = sun define('MON',0); // use defined constants to make code/data self-documenting // working hours $hours = []; $hours[MON] = ["morning_from" => "closed", "morning_to" => "closed", "afternoon_from" => "13:00", "afternoon_to" => "19:00"]; // note: if you define the above array as an array of arrays, with the from/to values, a label (Morning/Afternoon), and a 'closed' or time entry, you can just loop over this to produce the output without needing to have specific code for each possible segment in a day // busy times - the example data is for a monday $busy = []; $busy[] = ["title"=> "Test", "start_date" => "2019-11-25 13:00:00", "end_date" => "2019-11-25 14:00:00"]; // pre-process the booked/busy data $data = []; foreach($busy as $arr) { $date = $arr['start_date']; $end_date = $arr['end_date']; while (strtotime($date) <= strtotime($end_date)) { $data[$date] = $arr['title']; $date = date("Y-m-d H:i:s", strtotime("$date +$interval min")); } } // examine the pre-processed booked/busy data echo '<pre>'; print_r($data); $current_date = '2019-11-25'; // determine the current date being displayed using whatever logic the code has now $book_day_int = date('N') - 1; // get the integer day of week number - 1 $current_day = $hours[$book_day_int]; // get the from/to data for the current day // morning output (see the note above by the $hours array to simplify and make the code general-purpose) $start = $current_day['morning_from']; $end = $current_day['morning_to']; if( $start != 'closed') { echo 'Morning<br>'; $start = "$current_date $start:00"; $end = "$current_date $end:00"; $date = $start; $end_date = $end; while (strtotime($date) <= strtotime($end_date)) { echo $date; // test if this date-time is busy if(isset($data[$date])) { echo ' ' . $data[$date]; } echo '<br>'; $date = date("Y-m-d H:i:s", strtotime("$date +$interval min")); } } // afternoon output $start = $current_day['afternoon_from']; $end = $current_day['afternoon_to']; if( $start != 'closed') { echo 'Afternoon<br>'; $start = "$current_date $start:00"; $end = "$current_date $end:00"; $date = $start; $end_date = $end; while (strtotime($date) <= strtotime($end_date)) { echo $date; // test if this date-time is busy if(isset($data[$date])) { echo ' ' . $data[$date]; } echo '<br>'; $date = date("Y-m-d H:i:s", strtotime("$date +$interval min")); } }
  7. here’s how you should do this - pre-process/expand the booked/busy array of data so that it has entries for each 30 minute interval of the appointment, using the date-time value Y-m-d H:i:s as the array index. for the example data, you would end up with three entries - 2019-11-25 13:00:00, 2019-11-25 13:30:00, and 2019-11-25 14:00:00, all with the same title as the array value (if the data for each appointment is actually more than this, store it as a sub-array under each index.) get the day of week number from the current date you are displaying, then get the morning/afternoon start and end times for that day, loop over the 30 minute intervals, from the start time to the end time, produce the date-time value for each interval - Y-m-d H:i:s, then test (isset() will work) if there’s an entry in the pre-processed booked/busy data array for the current interval.
  8. chrisj, what is the overall reason you have been beating on this script (and the previous phpmotion script) for so long? is this for a collage course assignment? is this for self-learning? do you think that having a video sharing script will help you to make money? some other reason? the main reason i ask is, most of your posts seem like you just want someone else to think/write code for you, and your only involvement is to be a 'proxy typist' pushing keys on a keyboard. this is not how programming help works, doesn't result in any learning, and doesn't result in much progress. you need to be able to define for yourself what the code/data should do, then through learning enough php/sql/html/css/javascript, be able to design, write, test, and debug the code needed to produce an application or make changes to an existing application. you need to sit down with paper/pencil or an open text document, and list out the top-level work-flow (steps) that need to occur, from the point where someone first visits your site through to the point where they watch a purchased video. you would then define what the user interface (UI) looks like for each step. you would then define what input data, what processing, and what result or output is needed to accomplish each step. the part of the process where you are at in this thread is when the user has hit the submit button during the 'checkout' step. regardless of this being for physical or digital items or using real money or credits, the processing is the same/similar. you would store/convert the cart items in to a 'pending' (unpaid) order. when payment is confirmed, you would update the order status to 'paid' and either trigger the shipment of physical items or make digital items available for downloading/viewing. since you are using credits that are being managed on your site, as far as the order status, you would determine if the user has enough credits in their account, update the order status to 'paid', deduct the amount from the user's account, add the earned amount to the video owner's account, and add the reminder to the system's account. all the database queries that modify data as part of this step, must be part of the same database transaction, so that if any of them fail, they all fail and roll-back. to manage the amounts, each video (which can have its own price, resulting in a different earned amount, and a different remainder for the system) that's purchased should have a separate set of records inserted into the account table. here is the starting definition for the account table - since the time when i wrote that, i think it would be a good idea to add the video purchase id (auto-increment integer primary index from the paid_videos table) so that the account records are related to the video purchase record they correspond to. so, what would be inserted into the account table foreach(){} video that is purchased - a row with the purchaser's id (id_user), the negative of the video purchase price, a transaction type id (for a purchase), the last insert id from the row that was inserted into the paid_videos table, and the current datetime. a row with the video owner's id (user_id_uploaded), the positive earned amount for the video, a transaction type id (for an earned amount from a purchase), the last insert id from the row that was inserted into the paid_videos table, and the current datetime. a row with the system's id, the positive remainder between the video purchase price and the earned amount, a transaction type id (for a system share of a purchase), the last insert id from the row that was inserted into the paid_videos table, and the current datetime. the transaction_type_id in the above means that you need a 'transaction type' table, with an id column and a name column. to get the account total for any user id, you would just SUM() the total column, and group by the user_id column, for any single, list, or all users (depending on the WHERE clause used.) to get the account total for any/each transaction type, you would additionally group by the transaction type id column.
  9. what output do you get and if it's a blank page, what does the 'view source' of the page in your browser show? either the output is hidden in the 'view source' or the code isn't being executed. since you apparently are getting the data inserted, it's possible you are 'seeing' the result of a double page request, especially since you are using a get request to do this rather than a post method form.
  10. to do this, you need to produce an array that defines the permitted choices and also contains entries that control which tables/columns to use in the query. you would then dynamically produce the base query by having general-purpose code that makes use of the data in the array. short-answer: you are trying to produce a data driven design, rather than to hard-code logic for every possible choice. some comments about the existing code - use domain relative urls, this will eliminate the need for the $page_url value. trimming input data after you have tested if the data is empty is backwards. use http_build_query() to produce links in your code from any existing get parameters and any new values. this will eliminate the need for the preg_repalce() statement near the start of the code. put the 'get method' business logic before the start of your html document. the base query, with any table, join, where, and having clauses must be the same for both the COUNT(*) query and the data retrieval query. build this part of the query and any bound input parameters, in this part of the query, in dedicated php variables, then use these variables when building and executing the two queries. put literal, constant values directly into queries, such as the publish = 1 value. use implicate binding, by supplying an array of the input values to the execute call. don't copy variables to other variables without a good reason. just use the original variables.
  11. how much total code/files is/are there? if you post your code (less any database/api credentials) somewhere (in the forum or on github) you would get more specific help about what you do need to change. since your code works under php5.6, you don't have to deal with register_globals, and the only things to update would be those that have been removed, are backward incompatible, or are deprecated (to future-proof) in going from 5.6 to 7.x.
  12. if your code is not making any shell/system/passthru calls, it doesn't matter what operating system you use for a development system. all that matters is you have the same set of extensions and php.ini settings between the development system and the live server. you can use one of the all-in-one development packages. the mysql extension became deprecated as of PHP 5.5 (released in 2013) and would have been throwing errors in your code if not for the @ error suppressors. don't ever use @ error suppressors in any code. on a live/public server, your php error related settings should be set to log all errors. if you are faced with updating old code that uses the mysql extension, do yourself a favor and 1) jump directly to use the very simple and future-proof PDO extension, 2) use prepared queries when supplying external/unknown data to an sql query statement (this actually simplifies the sql query syntax), 3) using implicate binding (supply an array of values to the execute call) for prepared queries, and 4) use exceptions for errors and in most cases let php catch and handle the exception where it will use its error related settings to control what happens with the actual error information (database errors will 'automatically' get displayed/logged the same as php errors.) doing these four things greatly simplifies the implantation of your database specific code, which will let you eliminate, rather than convert code, shortening the task.
  13. if you use exceptions for database statement errors and in most cases let php catch and handle the exception, php will use its error related settings to control what happens with the actual error information (database errors will 'automatically' get displayed/logged the same as php errors.) you will be able eliminate the existing error handling, rather than to convert it. 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); now the bad news, it is not enough to just update statements in old code, as one of the things that was removed in php5.4, magic_quotes, eliminated some protection that php provided against sql special characters in external string data from breaking the sql query syntax (which is how sql injection is accomplished.) if your code does not have specific protection for all external/unknown data, and for all the different data types, being put into sql queries, you will need to add it. the simplest, universal way of doing this is to use prepared queries, provided that you switch to use the simpler PDO extension. the prepared query interface for the mysqli extension is overly complicated and inconsistent
  14. if you use the simple session cart definition that has been given on a different forum, using the item id as the array index, and storing the quantity as the array value under the index, doing what you are asking only takes a couple of lines of code.
  15. detect that a post method form was submitted. trim all input data at once, so that you can detect if all white-space characters were entered (this is the only alteration you should make to the input data.) if more more than one form will submit to the same page, add logic, using your favorite method, to detect a unique field/value from the form, to control which form processing code to execute. validate all input data, storing unique and helpful validation error messages in an array. this array is also an error flag. if the array is empty, there are no errors. if the array is not empty, there are errors. if there are no validation errors, use the submitted form data. afaik, the form name is not submitted, as the form tag is not an input field. the submit button may or may not be set, depending on how the form gets submitted and/or which browser is being used, so, don't bother testing it. if you need to distinguish between multiple forms on one page, add a unique key/value as a hidden form field, and detect this in your code. except for un-checked check boxes and radio buttons, once the form has been submitted, all other form field types will be set, even if they are empty, so there's no point in cluttering up code with isset() statements for these types of fields. you would want to see (during development)/log (on a live/public server) php errors if expected-set form fields are not set, as this indicates either a programming mistake or someone/something submitting their own set of fields. as an advanced programming subject, dynamically validate and process the submitted form data, by defining an array, with the field names as the array indexes, and an array of elements under each index controlling the validation steps and the type of processing for each field. none of this has anything to do with security. security is achieved by using data properly in whatever context it is being used in. if used in an sql context, use a prepared query. if used in a html context, apply htmlentities() to the data. if uploading files, store them in a location that is not directly accessible through a http request.
  16. this is due to floating point conversion errors. see this link on how to do this math using binary coded decimal numbers, i.e. like a hand-held calculator does - https://www.php.net/manual/en/book.bc.php
  17. since the code is un-setting the variable and will always output 'else test', if you are not seeing the output, ether - your code is redirecting all over or using ajax to display content and you are not actually 'on' the page where this code is at, but the refresh does 'goto' the page where this code is at. you have some conditional logic that is preventing the posted code from being executed, either explicate logic or an exit/die statement, which the refresh doesn't trigger, and so the posted code gets executed. some html is being conditionally output prior to the posted code and the output from the posted code is hidden in the 'view source' of the page, but, again, the refresh doesn't trigger the prior output, and so you see the output from the posted code. since you have repeated the unset() statement with the variations of the code, i/we assume that is actually part of this code. do you understand what the unset() statement does and what affect it will have on the conditional logic test(s) you have posted? as stated on one of the other help forums, all you are showing/describing are snippets of code and symptoms. if you just post all the relevant code for the page(s) involved with this problem, someone can probably solve this in a couple of minutes.
  18. use the PDO extension, use exceptions for errors and in most cases let php catch and handle the exception, and use prepared queries when supplying external/unknown data to the sql query. this will result in the simplest and most consistent code. if the scope of your work is limited to just getting the database code to securely work, you would write user functions that use the PDO extension internally, then search/replace the mysql_xxxx functions with the new user written pdo_xxxx functions. for the new pdo_query() function, it would have an optional call-time array parameter for the prepared query input data. if this input parameter is empty, the function code would just call the query method. if the input parameter is not empty, the function code would first call the prepare method, then supply the array of input data when it calls the execute method. for any query that has external/unknown data being put directly into it, you would need to convert it to be a prepared query by removing the variables, any quotes around the variables, any {} around the variables, and any concatenation dots, and replace each value with just a ? place-holder. the variables that got removed would be supplied as the array call-time parameter to the pdo_query() function call. if any of the queries are being dynamically built, you will need to address changing them to be prepared queries on a case by case basis. of concern are the number of files you have. this typically indicates that the code is not general purpose and could stand to be re-factored to use a content management system (CMS) and a data driven design. perhaps something to budget time for in the future?
  19. how did you arrive at this point? did this code work before? did you copy/paste the PASSWORD_BCRYPT value from somewhere or did you type it manually? if you copied it, i recommend that you delete it and manually type it. we have seen cases where 'published' code contains non-ascii or non-printing characters, which looks correct, but which php cannot recognize.
  20. if php can read it to load it, you can read it to make a copy - <?php $in_file = 'C:\xampp\php\php.ini'; // path to the php.ini, can be found in the phpinfo() output under - Loaded Configuration File $out_file = 'ini.org'; file_put_contents($out_file,file_get_contents($in_file));
  21. it takes more than just converting the database statements to update old code. due to the removal of magic_quotes, that provided some security in external string data, you must add protection against sql special characters in data from breaking the sql query syntax, which is how sql injection is accomplished. if you have a large amount of code that needs to be updated, creating user written functions that use the PDO extension internally to replace the mysql_ functions, via search/replace, then change any query with external data being put directly into it, into a prepared query, will result in the least amount of overall changes to the code. if you only have a small amount of code that needs to be updated, just directly re-writing it to use the PDO extension is the best solution. while you are making these changes, switch to use exceptions of errors and in most cases let php catch and handle the exception, where it will use its error related settings to control what happens with the actual error information (database errors will get displayed or logged the same as php errors.) this will let you eliminate, rather than convert, the existing error handling, which is only giving real visitors information they cannot do anything about, and giving hackers useful feedback that something they did caused a specific type of error.
  22. the error is because there are a different number of place-holders in an sql query statement compared with the number of values supplied when the query is executed. the solution would be to find out why that is happening and correct it. it's likely that the computer restart as part of the win update either committed or lost some unsaved change in a server setting or in a code file.
  23. probably because the code is assigning a 1 to the session variable. your code should - unconditionally start the session, in a common 'required' configuration/initialization file. first detect if there is a logged in user. if there's not a logged in user, there's no point in querying to get any user data. you should instead set up a default set of $user data. if there is a logged in user, run the query to get the user's data. you should only SELECT the columns you want, and unless this is part of a login script, you should not SELECT the password hash. if the query didn't find any matching user data, you either have a programming mistake or a user's row got deleted between the time the user logged in and when you executed this query. if the query did find matching user data, fetch it to replace the default values set in item #2.
  24. the posted code contains some problems and questionable logic that need to be corrected before you worry about making changes to what it is doing - to display a product, a commented out 'avail' value, an image, and a price are being checked in the code. this should be done in the sql query. you should only query for products that should be displayed. in the case of having an image and a price, should the product even have been INSERTed if these pieces of data weren't submitted? the html table 'cleanup' code needs to be inside the end of the if($result) logic and also needs to output a closing </tr> tag. there are several 'empty' <a> anchor/link tags being produced. why? the non-empty <a> tag that starts with the product image is never closed. should this even be a link and what portion of the product information should it include? if there's no item no and description for a product, do you really have a product to display? these two values are being put into the paypal form data. do you want empty values for them to be submitted to paypal? for your added conditional logic, if there are only two choices, a zero or a one, you only need - if(expression) { logic for a true expression } else { logic for a false expression}
  25. i reviewed one of your earlier threads and it was using an array to hold errors. what happened, why did you take a step backwards? your existing validation logic for a 'required' field is not doing what you think, so, when you copied it for a non-required field, it has no chance of working. for a required field, if the input is empty, that's an error and there's no point in running any additional validation on that input as they will fail too. only if the input is not empty, run additional validation on that input. the logic to do this would look like - if(some required field == '') // note the comparision is with an emtpy string. php's empty() treats a zero as empty, so if zero is a valid value, you don't want to use empty() to test it. { // the field is an empty string $errors['some field name'] = "This field is required."; } else { // the field is not empty, perform additional validation step(s) if(!some other validation test) // note the ! (not) in the conditional statement { // the field did not pass this validtion test $errors['some field name'] = "This field does not meet the requirements of this validtion test."; } } for a non-required field, you don't care if the field is empty, but if it is not empty, you perform the additional validation (this is basically the else logic from above) - if(some field != '') { // the field is not empty, perform additional validation step(s) if(!some other validation test) // note the ! (not) in the conditional statement { // the field did not pass this validtion test $errors['some field name'] = "This field does not meet the requirements of this validtion test."; } } if all you are doing with preg_match is finding if a value matches the pattern, there's no need for the matches parameter. just directly test the result of the preg_match statement. your original validation logic for the account field contained miss-typed variables and incorrect preg_match parameters. do you have php's error_reporting set to E_ALL and display_errors set to ON so that php would help you by reporting and displaying all the errors it detects? lastly, when you have more than about 2-3 form fields, you should dynamically process the form data, by defining an array that holds a definition of the fields and what validation tests to perform on each field. this is a level to work toward in your coding, so that you don't find yourself writing out bespoke logic for each form field for each different form.
×
×
  • 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.