-
Posts
5,451 -
Joined
-
Days Won
175
Everything posted by mac_gyver
-
How can I allow the end user to add products used in a BOM?
mac_gyver replied to DeX's topic in PHP Coding Help
^^^ 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. -
How can I allow the end user to add products used in a BOM?
mac_gyver replied to DeX's topic in PHP Coding Help
the id in the $unit_rules[...] would be the item id of a direct item. since i don't know how you are entering/specifying what would trigger the scissor lift due to the building height, i suggested a general purpose way of having a "building height adder" item, which would be a direct item that a person can pick and add to the direct bom. if you already have an item that will always be present on a bom that does this, you would use it's id in the rule. not sure if i follow, but for at least the direct bom, these are items that are selected by a human. they should only be stored in the database bom table if they have been selected for a project/building. if you are initially inserting ALL available items into the bom table, this is creating more work, increasing data storage requirements, probably takes more code, and may be where some of your performance problems are at. -
How can I allow the end user to add products used in a BOM?
mac_gyver replied to DeX's topic in PHP Coding Help
re: post #13. i would say the answer is yes. but you should work out how you are going to do this for each case. some example cases - 1) adding a new direct item that uses no indirect items - enter the information about the new direct item and save it, ignoring anything else that might be present on the page to support example cases #2 - #4. for example, an entry floor mat that will just be laid on the floor. 2) adding a new direct item that uses an existing indirect item - enter and save the new direct item information per example #1, but make use of a search/select interface on the page to choose from existing indirect items. for example, an entry floor mat that will use double-sided sticky tape to hold it in place. after entering and saving the new floor mat information, display any existing indirect items that reference the chosen direct item (there will be none since this direct item has just been inserted/created) and use the search/select interface to display existing tapes/adhesives (whatever you are using to categorize items.) and select (checkboxes or perhaps just by entering the unit multiplier/offset data) which indirect item(s) are to be used with this direct item. after entering any multiplier values, save the new rules for this indirect item to the existing rules that may already exist for it. 3) adding or editing indirect items for an existing direct item. same as the second part for example case #2. rather than entering and saving the information for a new direct item, just select an existing direct item. the edit page would display the direct item that has been selected, any existing indirect items that reference the chosen direct item (so you can edit the rules, including deleting rules) and the search/select interface to let you add more indirect items for the chosen direct item. 4) adding a new indirect item. near the search/select interface, if there isn't a suitable existing indirect item, have entry form fields to add a new indirect item, that once added can be selected for the current chosen direct item. -
most of the time, when it appears like you have multiple sessions that change depending on the method used to reach a page, it's because the host-name/sub-domain (the www. in the address) is changing depending on how you reach the page. are the url's in the links and in the redirects constant and always have the www. as part of them? as to any other problems in the code, you have far too much logic, due to an overly complicated data design. if you use the product id as the cart's array index and only store the quantity as the value in the array element, all the logic to manipulate the cart contents will be simplified. for example, here is what the add to cart logic would look like - // if the cart doesn't exist, create an empty one - you should put this logic in a common location above any code that references the cart if(!isset($_SESSION['cart_array'])) { $_SESSION['cart_array'] = array(); } // add a new item to cart with quantity 1, if already in cart add 1 to the quantity if (isset($_POST['pid'])) { // pid is the product/item id $pid = (int)$_POST['pid']; // cast, or better yet validate, the value to php integer (will be limited to the operating system's maximum integer value) if(!isset($_SESSION['cart_array'][$pid])) { // if the item isn't in the cart, add it with quantity 0 (the quantity will be incremented to one in the next statement) $_SESSION['cart_array'][$pid] = 0; } // add 1 to the quantity $_SESSION['cart_array'][$pid]++; header("location: http://www._______.c...om/cart.php"); // you need to either set up a defined constant, a php variable, or use $_SERVER['HTTP_HOST'] to supply the hostname/domain for url's so that you don't need to type them in each instance throughout the code exit(); } all other code will be equally simplified. next, you should not run an sql query inside of a loop. to display the cart contents, just retrieve all the product id's (see array_keys() ), which will be either cast/validated as integers by your add to cart logic, form a comma separated list (see implode() ), and run one sql query with - WHERE id IN(the_comma_separated_list_goes_here) to get all the product data at one time. you can loop through the data from the query to display the cart, using the product id from each row to access the quantity value in the cart. lastly, the php mysql extension is obsolete and was removed from php almost one year ago. you need to be learning current information or updating your code to use either the php PDO or msyqli extension. the PDO extension is more consistent and simpler to use over the mysqli extension.
-
How can I allow the end user to add products used in a BOM?
mac_gyver replied to DeX's topic in PHP Coding Help
the data-driven rule based logic is only to replace the hard-coded logic you have now, for determining the derived quantity of dependent items, based on the primary/direct entered item. if you don't have any hard-coded logic calculating the quantity now, there would not be any rules needed. you probably don't have the item in your switch/case statement either. you have a direct bom, of the items that are selected by people and an indirect/derived bom, of items that this thread is trying to calculate. it's only the indirect/derived items that will have rules defined for them. -
if…else if…PHP SQL Insert into tbl based on conditions
mac_gyver replied to elliottdan's topic in PHP Coding Help
sorry to confirm this, but yes, this is not a correct database design, making it almost impossible to insert, find, or retrieve data. your database tables are laid out like a multi-sheet spreadsheet. you need to do some research on 'database normalization.' basically, one data item will be stored per row in whatever a table is designed for and all the same meaning data will be in the same table. once you store the raw data with any relevant - who, what, when, where, and why information about the data item, it will be simple to write queries to find and retrieve the data the way you want. -
php only knows the information that it receives from the http(s) request. your php 'page control' logic would determine what page is being produced for any request. the navigation logic would use that value, in a php variable, to determine what to produce in the markup.
-
care to share any information on what symptom or error you got when you try your code. we are not sitting there with you and don't know what you saw in front of you. we also don't have the ability to run your code on your server. i do however have a recommendation, before you can use AJAX to accomplice a task, you must be able to write, test, and debug a html form and php form processing code. then, adding AJAX is as simple as adding an event listener that gets all the form data, makes the http request to the php form processing code, and prevents the default action of the browser submitting the form.
-
while it's slightly more verbose, it has eliminated an entire line of code - $DisplayName = $row['DisplayName']; for each discrete variable. it has also 'encapsulated' all the data for this item under one name, $stream_data. this will eliminate any conflict with the data for other items your application may be creating, such as user data. a user could easily have a piece of data called DisplayName. do you want to spend your time trying to keep track of and debug problems with multiple variables called $DisplayName? it IS a variable. your code assigned the result of mysqli fetch statement to it. you are referencing elements of it on the right-hand side of an assignment statement when you are creating and assigning values to the $DIsplayName, .... variables. an array is just a variable with more than one dimension. i recommend that you read the introductory sections of the php.net documentation so that you can learn what php variables are. anything that starts with a $ is a php variable. we understand what you are doing and what you are saying/writing. we are trying to show you a method that eliminates all kinds of time and problems when writing code and makes the data retrieval code simple and general purpose so that you don't have to spend your time beating out line after line of code and can instead concentrate on getting the program logic do what you want it to do. if you want to display/dump the entire contents of $stream_data for debugging purposes, this is all you need - print_r($stream_data); lastly, by having the data for any particular item in an array, you are set up for the next step that will further simplify your web coding, of using a template to produce the output from that data. a template system will take an associative array of data as input and populate the corresponding tags/place-holders with the correct data.
-
there already IS a variable assigned to the data from the fields, the variable you fetched the data into, $row. the code you have been trying/posting is already using elements of the array variable here -> $DisplayName = $row["DisplayName"];. just use $row["DisplayName"] everywhere and forget amount $DisplayName.
-
yes, see the reply posted above your's that the ipb forum programmers Chimps couldn't figure out how to reliably notify you of while you were posting your reply. the code you posted implements some of the things i mentioned, but still has some issues - 1) by testing $result after you have tried to fetch data from the query, that code will throw a php error at the fetch statement any time the query fails due to an error. you would need to test $result before you try to fetch any data. however, if you enable exceptions like suggested, you don't need to have any logic in your code testing $result. if there is a query error, an exception will be thrown and the code trying to fetch data will never be executed. 2) by hard-coding the echoing of $mysqli->errno and $mysqli->error in the code, you will expose information in the errors to a visitor. if you use the suggested exception method, what happens with the error information is controlled by php settings, so that on a live server, you would log the information, rather than to display it, simply by changing a couple of php settings. 3) the first code has this - $row = $result->fetch_assoc() for the fetch statement. you now have this - $row=mysqli_fetch_array($result,MYSQLI_ASSOC). while both are functionally equivalent, why are you making unnecessary changes and going from simpler to more verbose syntax? Keep It Simple. 4) see what i wrote above about not creating discrete variables. your current method has you typing things in the SELECT list, two times in each $some_var = $row['some_column']; assignment statement, and then where you use the data. using the suggested method eliminates all the assignment statements. you would typically fetch the data into a variable named to indicate what the data means. so, rather than $row, you would use something like $stream_data. 5) lastly, i didn't write it above, but php closes the database connection for you when the php script ends. unless your code is taking a large amount of time to run after fetching the data from the database, there's no good reason to close the database connection yourself. so, for the last posted code, this is all you would really need - $sql = "SELECT gpsStatus, DisplayName, ChaserLocation, StreamStatus, CurrentViewers, TimeStamp FROM streamdb WHERE id = 1"; $result = $mysqli->query($sql); $stream_data = $result->fetch_assoc(); // just use the elements in $stream_data in the rest of the code
-
your current code is missing a opening { for the while() loop. this would be producing a php syntax error if you had php's error_reporting set to E_ALL and display_errors set to ON in the php.ini on your development system. if you put these settings into your code, they won't help with php syntax errors in the same file, because your code never runs to cause the settings to be in effect. speaking of (writing about) the while() loop, if you are running a query that you expect to match a single row, don't loop to fetch the results. this is just cluttering up your code. just fetch the row as an array into a variable. speaking of (writing about) variables, what's wrong with an array variable? by creating discrete variables from each element of an array, all you are doing is spending time typing, fixing typo errors, and changing the code every time you change what gets SELECTEd by a query or reuse the code for a different query and also make the same changes to the code that uses the data. you should just fetch the data from the query into one php array variable, then use that array variable everywhere in the rest of your code. Keep It Simple. Programming is already a tedious task. Don't make more work for yourself by typing out line after line after line of code that you must keep editing any time something changes. next, what is this - if (!$sql) { ? the $sql variable is a php string that represents the sql query statement you have built. unless it's an empty string, it will never be false. i suspect this usage is trying to handle errors? if so, you need to use exceptions to handle errors. this will eliminate the need to write logic around every database statement that can fail. your main code will only have to deal with error free database statement execution. if you enable exceptions for the mysqli extension, any error will throw an exception. if you let php handle the uncaught exception, it will use the php error_reporting/display_errors/log_errors settings to determine what happens with the actual error information. for the mysqli extension, if you enable exceptions before you try to make the database connection, any connection error will also throw an exception. to enable exceptions for the mysqli extension, add the following before your connection code - $driver = new mysqli_driver(); $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
-
Allow ability to NOT attach file in PHP mail form
mac_gyver replied to spastickyle's topic in PHP Coding Help
it requires nothing. it's just a dang example and this stuff is called software for a reason. if it doesn't do what you want, you can change it so that it does. -
Allow ability to NOT attach file in PHP mail form
mac_gyver replied to spastickyle's topic in PHP Coding Help
you should use an array name for the form field, with the array index being a unique name if you need to identify which field a file was selected for. if you leave the index value out, you will get integer indexes, starting at 0. next, you MUST test if a file was successfully uploaded before you can reference any of the file information. if a file wasn't selected, the ['error'] element of the uploaded file information will be - the ['error'] element will be - UPLOAD_ERR_OK if the file was successfully uploaded. see example #3 at this link - http://php.net/manual/en/features.file-upload.post-method.php for how you can define the form field and loop over the file information. -
i recommend that you tell or show us what symptom or error you are getting that leads you to believe that something doesn't work. we are not sitting there with you and don't know what it is you are seeing in front of you. why are you using both the msyql and mysqli extensions in one script? do you even have a connection using the mysql extension? there would be php error's if you don't. 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? your code should ALWAYS detect and handle errors with database statements, so that it doesn't try to run logic that's dependent on database statements working when they haven't and test to make sure that a query matched a row of data before using the data. why are you using a multi_query() statement for a single query? this opens the door for sql injection to run ANY type of query, especially since you are not doing anything to protect against sql injection. even if you currently trust the data source, someone at some point can get nefarious data onto the site you are getting your data from. you must ALWAYS protect against sql injection. btw - the php mysql extension has been removed from php for almost a year. you should not be using it at all at this point in time.
-
your $_POST data isn't the problem. your code is most likely being executed. why you are getting a symptom that makes it appear like your code isn't being executed is due to either php's output_buffering (hides output from your code and php errors if there is a header() redirect) and/or php's error reporting/display_errors (php errors are not being reported/displayed) settings that are set on your server. you should be getting an error like this - you need to have the following set in the php.ini on your development system - error_reporting = E_ALL display_errors = ON output_buffering = OFF make sure these are set as shown, restart your web server to get any changes made to the php.ini to take effect, and confirm that the settings actually got changed by checking the values with a phpinfo() statement in a .php script. this will get your development system set up so that it will help you by showing any output from your code and from php errors. once you are getting that particular Notice: ... error, it should be easy to find and fix the problem in your code. next, you need to use prepared queries, with place-holders in the sql query statement for data values and use exceptions to handle database errors. this will actually simplify both your sql query and php program logic. unfortunately, the php mysqli extension is not the best choice. if you can, switch to use the php PDO extension. it is more consistent and easier to use than the mysqli extension.
-
to cause all php detected errors to be reported and displayed, you need to set php's error_reporting to E_ALL (it should always be set to this) and set display_errors to ON. these should be set in the php.ini on your development system, so that ALL php errors will be reported (setting them in your code won't help with php syntax errors) and so that you don't need to remember to set them to get php to help you or forget to remove them form your code when you put it onto a live server (you should log all php errors on a live server, not display them to the visitor.) you still have some problems in the posted code - 1) htmlentities() is an OUTPUT function. it is used when you output data to the browser. it is not used on input data and it has nothing to do with data used with an sql query. 2) $mysqli. if you have switched to using the PDO extension, name the variable holding the instance of the PDO class something helpful like $pdo. 3) the first parameter in your bindParam() statement isn't correct. it's either the place-holder number (starting at 1), when using ? place-holders, or its the named place-holder. basic information like this can always be found in the php.net documentation. 4) your sql query is only SELECT'ing the username. therefor, $row['password'] won't exist. this would be throwing an undefined index error once you have php's error_reporting/display_errors set as suggested. 5) you also need to fetch the row and test if the query matched a row, all at the same time. the current code will throw php errors at the $row['password'] if the query doesn't match any row. you can do this - if($row = $query->fetch(PDO::FETCH_ASSOC)) { // the query matched a row, use password_verify() here... }
-
you would start by going through the examples in the documentation. mpdf expects you to either capture the html you want to convert or to add each line of html as you are producing it. the easiest way of coding this would be to do it on the page where you are producing the html output, so that you don't need to duplicate the code that's responsible for searching the database and producing the html. you would also want to do it completely on the server-side, since accepting the html input from the browser would leave the application open to inserting 'any' content into the pdf document, not just the output from your report code.
-
your form doesn't have any field named 'id', so, $_POST['id'] doesn't exist. this would be throwing php errors if you had php's error_reporting set to E_ALL and display_errors set to ON (preferably in the php.ini on your development system.) with no id value, the WHERE clause in the query is false, so the affected rows will always be zero.
-
Select dropdown list search and date picker seach type
mac_gyver replied to aquilina's topic in PHP Coding Help
yes, but have you been looking at what your code is doing? you have added a completely separate sql query for the company name, instead of modifying the existing sql query so that it would match the data you want. in programming (and for any goal), you must define what you want the code to do, before you can write any code to do it. otherwise, you can end up spending an infinite amount of time working on something without accomplishing anything useful. just ask the programmer's who wrote this forum software. so, first define what you want to the WHERE clause in the sql query to be for the four possibilities of date range and company name selection - 1) no date range (empty date form fields) and no company name (the ALL default choice) - you want the query to match all data, i.e. a query with a WHERE clause without any terms in it for the date and company name. if these are the only things being used in the WHERE clause, you can leave the entire WHERE clause out of the query. 2) a date range and no company name - you want the query to match data - WHERE sl_iv.DOCDATE BETWEEN 'the_start_date' AND 'the_end_date' 3) no date range and a company name - you want the query to match data - WHERE COMPANYNAME = 'the_selected_company_name' 4) both a date range and a company name - you probably want the query to match data with both conditions - WHERE sl_iv.DOCDATE BETWEEN 'the_start_date' AND 'the_end_date' AND COMPANYNAME = 'the_selected_company_name' given that the original code has this - $queryCondition = "";, your task would be to build the correct WHERE clause in that variable, it's already being put into the sql query statement. a general purpose way of doing this, that will support any number of different terms/filters, is to add each term as an element to an array. you can then just implode() the array using the " AND " keyword to produce a WHERE clause containing all of the terms. this will work regardless of the number of terms you add to the array (provided you define an empty array first.) you also need to do something that i suggested at the top of this thread and use a get method form. you would also want to re-populate the form fields with any previous selection so that the form is 'sticky' and retains the values and you need to display the data from the query someplace beside inside the search form. lastly, you need to protect against sql special characters in the data from breaking the sql syntax (which is how sql injection is done) and causing errors. the best way of doing this is to use a prepared query with place-holders in the sql statement for data values, then supply the data when the query is executed. unfortunately, doing this for a dynamic sql statement, which what you have with different possible filters, isn't very straight-forward using the php mysqli extension. the php PDO extension is an all around better choice to use over the mysqli extension and you should switch to it if you can. -
How to Loop the following question and answer?
mac_gyver replied to FooKelvin's topic in PHP Coding Help
what do you mean, 'you hope.' that's why you test code, to confirm if it produces the correct result. that would tell you if the code is correct or if you must go back and find what it is doing wrong. -
How to Loop the following question and answer?
mac_gyver replied to FooKelvin's topic in PHP Coding Help
change this - $ques[] = $row['q_text']; to this - $ques[$row['question_id']] = $row['q_text']; -
Select dropdown list search and date picker seach type
mac_gyver replied to aquilina's topic in PHP Coding Help
when the submitted value is the ALL choice, you would leave the corresponding term out of the WHERE clause. -
How to Loop the following question and answer?
mac_gyver replied to FooKelvin's topic in PHP Coding Help
it's not entirely clear, since there's no context or explanation in the attached spread-sheet, what the data is and which of it is even relevant. i'll venture some guesses - 1) The data is the result set/rows from an sql query? if so, if you store that data into an array in your code and use var_export() on that array, you can paste valid php code that we could use as test data. 2) Expr2 is the user/employee id and the Expr3 is the text answer you want to display? if so, here's a way of producing the output - 1) query for and retrieve the question id and question text, in the order that you want to display them (in case they are not to be displayed by the id ordering), separately from the main data retrieval query. store the question id/text into an array, using the question_id as the array index and the question text as the array value. you would leave out the question text in the main data retrieval query. 2) when you retrieve the main data, loop over it and pre-process/pivot it and store it into a multi-dimensional array. the first array dimension/index would be the employee_id. the second array dimension/index would be question_id - $data[employee_id][question_id][] = 'text answer to display'; // the last [] is to accommodate multiple replies to any question. 3) to produce the output, produce the table header by outputting the first column, then loop over the array from item #1 above. to produce the data section, loop over the pre-processed data. this will give you the employee_id and the array of replies for that employee id, with the reply array index being the question_id. loop over the array question id's, from item #1, to get the question_id's in the order that you are displaying the questions/replies. use the question_id to reference the correct reply for the current employee id. this will give you an array of replies for that question_id. loop over or implode() this array to output the text in each table cell. see the following simplified example - // some made up questions $q = array(); $q[1] = 'q1'; $q['2A'] = 'q2 a'; $q['2B'] = 'q2 b'; $q[3] = 'q3'; $q[4] = 'q4 mult'; // some made up data $data = array(); $data[1][1][] = 'e1 q1'; $data[1]['2A'][] = 'e1 q2 a'; $data[1]['2B'][] = 'e1 q2 b'; $data[1][3][] = 'e1 q3'; $data[1][4][] = 'e1 q4 1'; $data[1][4][] = 'e1 q4 2'; $data[2][1][] = 'e2 q1'; $data[2]['2A'][] = 'e2 q2 a'; $data[2]['2B'][] = 'e2 q2 b'; $data[2][3][] = 'e2 q3'; $data[2][4][] = 'e2 q4 1'; $data[2][4][] = 'e2 q4 2'; // produce table header echo "<table>\n"; echo "<tr><th>Employee ID</th>"; // loop over array of questions for the header foreach($q as $question) { echo "<th>$question</th>"; } echo "</tr>\n"; // produce table data foreach($data as $employee_id=>$replies) { // $replies is an array with the question_id as the array index echo "<tr><td>$employee_id</td>"; // loop over the question id's in the order they are being displayed foreach(array_keys($q) as $q_id) { // is there a reply for this quesiton_id if(isset($replies[$q_id])) { // there is a reply for this question // there can be multiple replies to a question - separate them with a <hr> in the table cell echo "<td>"; echo implode('<hr>',$replies[$q_id]); // note: this works correctly if there is a single reply, the result is just the single array element by itself echo "</td>"; } else { // no reply, output whatever you want for this case echo "<td>n/a</td>"; } } echo "</tr>\n"; } echo "</table>\n"; -
Select dropdown list search and date picker seach type
mac_gyver replied to aquilina's topic in PHP Coding Help
we can only help you with problems in your code when you post your code. post your attempt with both filters in it. btw - you should be using a method='get' form for controlling what will be displaying on the page.