-
Posts
5,521 -
Joined
-
Days Won
187
Everything posted by mac_gyver
-
jQuery Sortable Portlet Save position to database
mac_gyver replied to MsKazza's topic in Javascript Help
is the query failing (from error handling logic that you should always have in your code) or are the php statements failing (form having php's error_reporting/display_errors turned fully on in the php.ini on your development system)? if your original posted code was using the php mysqli extension, why are you now using the php mysql extension? the mysql extension has been removed from the php since the end of last year. you should also be using a prepared query (supported by the php mysqli and pdo extensions) to supply the data values to the sql query statement and this will also make executing the query inside of a loop slightly more efficient, since you will prepare the query only once before the start of the loop. also, if you are still asking questions in this thread, you should de-select the solved post so that people will see that the thread is not actually solved and will read it to see the new questions. -
jQuery Sortable Portlet Save position to database
mac_gyver replied to MsKazza's topic in Javascript Help
what debugging have you done to find what the code IS doing? the code i posted is tested and submits and logs the data. aside from the note about the actual database statements not being used and therefore not being tested, the code works. is your data being being displayed? does your database table have an id column, that's named 'id'? what does the developer console in your browser show? is the 'log.txt' file being created on the server? -
jQuery Sortable Portlet Save position to database
mac_gyver replied to MsKazza's topic in Javascript Help
so, i went through your code to figure out what it is doing, in order (pun intended) to figure out how to make this work. starting with your html markup - 1) the id='...' attribute you have for the column div's, should start with a letter, to make them valid. i choose to use id='COL_n', where n = 1, 2, ..., 6 2) the portlet div's needs an id attribute so that the serialize/toArray functions have something to use as data. i choose to use id='ID_n', where n is the job id auto-increment column value from your database table (if you don't have a job id, you need one.) 3) to allow the php code to dynamically produce the html, for the different status values 1-6, you need a way of mapping the status value to the display label - 'New' through 'To Be Invoiced'. i choose to use an array, and since you (probably) want to output each status section, regardless of if there is any data for it, you would loop over this array to produce the sections on the page, then loop over any data for each section. the html, from the <div style="clear:both;"></div> to the end of the page should look more like the following (note: data values that you output to the browser should be passed through htmlentities(). this is not in the example code and is left up to you as a programming exercise) - <?php // define status value to label mapping $status_map = array(); $status_map[1] = 'New'; $status_map[2] = 'Artwork Rec'; $status_map[3] = 'Approved & Ordered'; $status_map[4] = 'In Production'; $status_map[5] = 'Delivered'; $status_map[6] = 'To Be Invoiced'; // query for all the data you want, in the order that you want it $query = "SELECT * FROM jobs ORDER BY status ASC, job_title DESC"; $result = mysqli_query($con,$query); $data = array(); while($row = mysqli_fetch_assoc($result)) { $data[$row['status']][] = $row; // index/pivot the data using the status value - 1..6 } // note: i used some made-up data in the $data array at this point. the above query code should work, but is untested. // loop over the data and produce the output foreach($status_map as $key=>$label) { echo "<div class='column' id='COL_$key'>\n"; echo "<h3>$label</h3>\n"; if(isset($data[$key])) // is there any data from the database for this key/status { foreach($data[$key] as $row) { echo "<div class='portlet' id='ID_{$row['id']}'>\n"; echo "<div class='portlet-header'>{$row['job_title']}</div>\n"; echo "<div class='portlet-content'><a href='pdfs/{$row['pdf_link']}' target='_blank'>View PDF</a></div>\n"; echo "</div>\n"; } } echo "</div>\n"; } ?> </body> </html> next, the jquery you have that is using an id selector - "#portlet" should be removed since this exercise is operating on a class basis, not an id. also, you would not use the update : method, since this triggers for every column that gets updated. if you move something from one column to another, it triggers two times. you need to use the stop : method. see the following javascript/jquery that i came up with - <script> $(document).ready(function(){ $( ".column" ).sortable({ connectWith: ".column", handle: ".portlet-header", cancel: ".portlet-toggle", placeholder: "portlet-placeholder ui-corner-all", stop: function() { var dat = []; var i = 0; $(".column").each(function() { dat[i++] = [this.id,$(this).sortable("toArray")]; // this.id is the column id, the 2nd element are the job id's in that column }); $.ajax({ method: "POST", url: "save_order.php", data: { data: dat } }); } }); $( ".portlet" ) .addClass( "ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" ) .find( ".portlet-header" ) .addClass( "ui-widget-header ui-corner-all" ) .prepend( "<span class='ui-icon ui-icon-minusthick portlet-toggle'></span>"); $( ".portlet-toggle" ).on( "click", function() { var icon = $( this ); icon.toggleClass( "ui-icon-minusthick ui-icon-plusthick" ); icon.closest( ".portlet" ).find( ".portlet-content" ).toggle(); }); }); </script> this will submit an array of data to the .php file, in $_POST['data']. see the following example code that extracts the column number and job id (if any), and logs the information to log.txt - <?php // for some reason, the portlet toArray 'adds' an empty element to the start of each array if(isset($_POST['data'])) { foreach($_POST['data'] as $arr) { //$arr[0] is the column id - COL_1, COL_2 (these are the status number 1-6 = New - To Be Invoiced) //$arr[1] is an array of the ids that are in the column - ID_1, ID_5 // get the status (column) number list($not_used,$status) = explode('_',$arr[0]); // get the id's in each status/column $arr[1] = array_filter($arr[1]); // remove empty elements if(empty($arr[1])) { // an empty status/column $str = "Status: $status, empty"; file_put_contents('log.txt',print_r($str,true)."\n",FILE_APPEND); } else { // non-empty status/column foreach($arr[1] as $element) { // get the id number list($not_used,$id) = explode('_',$element); $str = "Status: $status, Id: $id"; file_put_contents('log.txt',print_r($str,true)."\n",FILE_APPEND); } } } } -
jQuery Sortable Portlet Save position to database
mac_gyver replied to MsKazza's topic in Javascript Help
I was going to ask if you would post a sample of your jobs data, in a php array format (see var_export()), so that we would have something to test with, but in looking at your code, you need to first write a single sql query that gets ALL the data you want in the order that you want it, rather than having 6 queries. then fetch all the data into an array. your code would then loop over that array to produce the output. at this point, you could use var_export() on that array to supply us with some data to test with. -
why my explode and str_split code is not working?
mac_gyver replied to Michael_Baxter's topic in PHP Coding Help
you are closing the database connection inside your loop, which you would know if you spent any time looking at your code. if you had php's error_reporting/display_errors turned fully on, you would be getting an error similar to - Warning: mysqli::query(): Couldn't fetch mysqli in your_file on line x. -
it's running exactly what part of what you described 'individually' on 360 products? if you mean the switch/case statement, this is exactly where you were at a little over a year ago - https://forums.phpfreaks.com/topic/297053-switch-statement-taking-a-long-time-to-execute/ each case xyz: statement must be evaluated to find the one that matches the current value and i'm not sure how php finds the next case statement in the tokenized bytecode. if i remember correctly, at the time of that linked to thread, a switch/case statement made up of empty case xyz: break; statements, or at best just an echo or an assignment statement in each case, didn't take that long to execute for all 300 values. however, if php must scan through all the tokenized bytecode to find the token that identifies the start of each/next case : statement, for your actual code, with several statements inside each case, this would take a noticeable and progressively longer time the further down in the list of case statements php must search to find a match. converting to the rules based code that i have suggested will eliminate the switch/case statement. you will still be looping over a set of values, but you will be directly using those values in a function/method call. the time taken for the code execution for each set of values will be the same.
-
First of all, your question is about php code, don't know why you posted this in the HTML forum section. You can install all-in-one xAMP (x = W, M, L for Windows, Mac, Linux, AMP = Apache, Mysql/MariaDB, Php) development packages on any current PC and operating system. see this link - https://www.apachefriends.org/index.html
-
web servers are stateless. all the code and query(ies) you have described start over and run again for every request you are making to the server. an ajax request is still a request to the server. the only thing that may be helping in this case is if the queried for data is still in the database server's query cache, it will be returned from the cache rather than actually executing the query against any database tables. for you to cache the queried for data in the php code and eliminate touching the database server for it, would require that you store the data in a session variable. edit: also, for it to take multiple seconds for this code/query to run once indicates there is some problem, either in the db table design, the queries, or in the php code.
-
are the objects created in session variable(s)? if they are not, they are are all destroyed when the server-side code execution ends, which is at the end of each http request, and they are all re-created for every http request.
-
well, there you go. you would need to find where the Mail class is being defined at and find out why it isn't being defined for the current code. it's not a native php class, so it would be either explicitly required/included or there would be an auto-loader that requires the file containing the class definition.
-
assuming that you want to look at all the select/option menus and they all have class='qty', you would loop over each of the elements with that class - $(document).ready( function() { $('input[type="image"]').click( function() { var total = 0; $( ".qty" ).each(function() { total += Number($( this ).val()); }); if(total == 0) { alert("You have not selected a product quantity!"); return false; } }); });
-
you are probably getting a fatal run-time error at either the Mail::factory() or $smtp->send() statement. have you done the following -
-
define: "it crashes"? does the server fall out of the rack and crash to the floor or what? keep in mind that we are not sitting right next to you and only see the information you supply in your posts. what exact error or symptom do you get when the code runs that leads you to believe that something crashes? do you have php's error_reporting set to E_ALL and display_errors set to ON so that php would report and display all the errors it detects? btw - the site specific information you had to go through and edit before posting the code should be in defined constants or php variables and be defined in a required file, so that you wouldn't need to alter the code before posting or if you ever reuse the code on a different site, you only need to edit the values in the required file.
-
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
to make this general purpose (what if a different door frame material requires more or less screws), the easiest method is to simply enter the number of screws as the multiplier in the rule for each different door item id, not for the category of sliding doors. -
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
see post #2 in the thread, point #2, about how i came up with categories from your existing code. this example is for your hard-coded rules for 'ManDoors' and 'Windows', converted into general purpose, data driven code. 'ManDoors' and 'Windows' are not specific items, they are at best categories that items are organized under. in general, you would use id's. since your current code doesn't have id's for categories, only names as part of method calls, i used the only information that i had available in the example. the offset is there for when you want to offset the quantity by a value, not dependent on how may 'used on' items there are. different variations of something, insulated vs non-insulated, are/should be different items/part numbers. each different item would have their own unit rule. since ManDoors seems to be a category, you would have categories for insulated ManDoors and un-insulated ManDoors. for the example given, you would add as many rules are there are cases - for white caulking rules - $unit_rules['ManDoors'] = array('mult'=>.75,'offset'=>0); $unit_rules['Windows'] = array('mult'=>.75,'offset'=>0); $unit_rules['ManDoors-insulated'] = array('mult'=>1.2,'offset'=>0); $unit_rules['Windows-insulated'] = array('mult'=>.8,'offset'=>0); for any cases like this, i would add a line item to the BOM, 'building height adder' that the rules in the the scissor lift quantity calculation would use - $unit_rules[building_height_adder_item_id_goes_here] = array('mult'=>0,'offset'=>1);. then if the building height adder is on the BOM, the scissor lift quantity calculation would result in 1 scissors lift rental. see the commentary in post #2. the whole point of what i posted is to move the values that are hard-coded in the program logic into a data structure, making this a data-driven design. once you get the hard-coded values out of the code, you can define them in a database table and let new rules get added or existing rules get edited by providing a user interface for the database table. -
mysql query not working with drop down boxes
mac_gyver replied to lindisfarne's topic in PHP Coding Help
promised example code - // define, or get from an sql query, the choices for the select/option menus $author_data = array(); $author_data[] ="ken davies"; $author_data[] = "arthur smith"; $author_data[] ="gill rafferty"; $author_data[] ="molly brown"; $author_data[] ="gilbert riley"; // define and populate the data for the other select/option menus. left up to you as a programming exercise. $genre_data = array(); $year_data = range(2002,2008); $publisher_data = array(); // define a list/array of expected inputs for the dynamic WHERE clause $choices = array(); $choices[] = 'author'; $choices[] = 'genre'; $choices[] = 'year'; $choices[] = 'publisher'; // produce the dynamic WHERE clause $and_terms = array(); // holds each term for the WHERE clause // loop over the defining array of choices foreach($choices as $choice) { if(isset($_GET[$choice])) { // the choice is set, add it to the terms to use $and_terms[] = "`$choice` = '$_GET[$choice]'"; // you need to either - validate that the input value is exactly one of the possible choices, properly escape the value using the database escape string function, or use a prepared query to supply the value to the sql statement. left up to you as a programming exercise. } } // db connection - convert to PDO and use exceptions to handle errors. left up to you as a programming exercise. $con = mysql_connect("localhost","root",""); If (!$con){ die("Can not Connect with database" . mysql_error()); } mysql_select_db("authors",$con); $where_clause = !empty($and_terms) ? 'WHERE ' . implode(' AND ', $and_terms) : ''; // build the sql query statement $sql = "SELECT * FROM books $where_clause"; // execute the query and retrieve the data into an array $result_data = array(); $myData = mysql_query($sql,$con); while($row = mysql_fetch_assoc($myData)) { $result_data[] = $row; } // start the html document/template ?> <html> <head> <title>My Page</title> </head> <body> <br> <form> <select name="author" size="2"> <?php foreach($author_data as $value) { $sel = isset($_GET['author']) && $_GET['author'] == $value ? ' selected': ''; echo "<option value='$value'$sel>$value</option>\n"; // you need to apply htmlentities() to any data being output. left up to you as a programming exercise. } ?> </select> <input type = "submit" value = "go"> <select name="genre" size="4"> <?php // use code similar to the above to produce each set of select/option choices. left up to you as a programming exercise. ?> <option value="adventure">adventure</option> <option value="biography">biography</option> <option value="crime">crime</option><br /> <option value="romance">romance</option> <option value="thriller">thriller</option> </select> <input type = "submit" value = "go"> <select name="year" size="4"> <option value="2002">2002</option> <option value="2003">2003</option> <option value="2004">2004</option> <option value="2005">2005</option> <option value="2006">2006</option> <option value="2007">2007</option> <option value="2008">2008</option> </select> <input type = "submit" value = "go"> <select name="publisher" size="4"> <option value="blue parrot">blue parrot</option> <option value="yonkers">yonkers</option> <option value="zoot">zoot</option> </select> <input type = "submit" value = "go"> </form> <?php // you need to use css to style your table border. left up to you as a programming exercise. echo"<table border='3'> <tr> <th>id</th> <th>author</th> <th>title</th> <th>publisher</th> <th>year</th> <th>genre</th> <th>sold</th> </tr>"; foreach($result_data as $row) { echo "<tr>"; echo "<td>" . $row['id'] . "</td>"; // you need to apply htmlentities() to any data being output. left up to you as a programming exercise. echo "<td>" . $row['author'] . "</td>"; echo "<td>" . $row['title'] . "</td>"; echo "<td>" . $row['publisher'] . "</td>"; echo "<td>" . $row['year'] . "</td>"; echo "<td>" . $row['genre'] . "</td>"; echo "<td>" . $row['sold'] . "</td>"; echo "<tr />"; } echo "</table>"; ?> </body> </html> -
mysql query not working with drop down boxes
mac_gyver replied to lindisfarne's topic in PHP Coding Help
your form should use method='get' since you are determining what will be displayed on the page. also, don't use nonsense variable names like $bird, $cat, ... and in fact, if you aren't doing anything to the value in a variable, there's no good reason to copy one variable to another, just use the original variable. next, when you are doing the same processing/operation on a set of data (your series of drop-down select menus), don't write out every possible combination of values. just make a list (array) that defines the expected inputs, then loop over this list to access the input data. you would produce and store each column = 'value' and store them in an array. then, just implode the array with the ' AND ' keyword to produce the WHERE clause in the query (implode will work even if there is only one entry.) you would also want to dynamically produce the select/option menus, so that you can make the selection 'sticky' so that a user doesn't need to keep re-picking things they have already selected. you would do this by making the choices a list/array, then just loop over the list when you produce each select/option menu, outputting the 'selected' attribute in any existing selected option. you would also use these defining lists/arrays to validate the input data. if your list of possible choices are actually coming from a database table, you would query for this data to produce the select/option menu, rather than have them in a hard-coded array. lastly, you should use a prepared query, with place-holders for each data value. when you switch your code from the obsolete mysql statements to use PDO (the best choice) or msyqli, you would also convert the query to a prepared query. if i have some time, i will post an example. edit: you should also separate the concerns in your code. the majority of the php logic should come first, then at the end have your html document/template that has a minimum of php logic in it. this will help make it easier to switch from the obsolete mysql statements, since the php logic using them will be grouped together and not be interspersed in the html markup for your document. -
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 easy answer to the Sliding Tec Screws, is, to just enter the number of screws per door as the multiplier for each door entry. -
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
creating a new entry would be fairly straight forward - 1) enter the name and select the category for the new item. inserting this into the product/item table would assign an item id to it. the item id would be used in any related data and logic. 2) if the new item is used by other unit items or categories of items, you would need a way of searching/listing and selecting (checkboxes) which of the existing items/categories it goes with. the category id or item id of the selected item would become the $unit_rules key/index. you would enter any multiplier/offset or other values you determine you may need. any group rules you have define would have a way of selecting just the possible choices. if at all possible, i would avoid allowing any arbitrary logic/tests to be entered. i'll have to give some thought to the Sliding Tec Screws case. -
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
feel free to use, modify, or ignore any of these thoughts - 1) in general, if you find yourself making variables/properties/constants and functions/methods where the name is specific to the name of a data item, so that any time you change the amount of data items, you must write new/delete variables/properties, constants, functions/methods, you have an inflexible hard-coded design, that is both taking your time writing and testing, but also maintaining. your code should instead be general purpose, where the names of things indicate their purpose or function, not the name of the data they operate on. see the next item for some examples - 2) $this->getTotalQuantityManDoors(true) + $this->getTotalQuantityWindows(true)). i'm betting that the code for each of these methods is identical, except for some values being used, and you have a bunch more of these type of named methods. these are operating on categories. if your product/item table has categories, you could simply use one common getTotalQuantityByCategory(category_goes_here) method. the same is probably true for a bunch of other hard-coded functions getting quantities of items. just have a common getTotalQuantityByItem(item_id_or_name_goes_here) method. 3) customer supplied items. it sounds like you have a bunch of code/logic/parameters to handle this special case, repeated many times? i'm assuming prices are stored in a product/item table and are multiplied by the BOM table quantity to come up with the total price for each item? to handle customer supplied items, just add a price multiplier column to the BOM table. for items that are customer supplied, store a zero in this column. for items that are purchased for the project, store a one/use a one as the default value for the column. multiply the item price * bom quantity * this new column to come up with the total price for any item. no extra handling is needed. the BOM quantity can be used as is to calculate any dependent quantities. 4) i would use a data driven design, where the rules are defined in data (that can be stored/retrieved from a database table.) this will remove the values from the logic and let you have just one copy of the logic that is re-used with different sets of rules. you can have 'unit' rules, that apply to each quantity of an item/category, and group rules, that apply to the total quantity in a group (i would put rounding up/down, box quantities .. here). for each item/category, define a multiplier and an offset. as you are looping over the main items, just apply the multiplier and offset to come up with the quantity. for any group, once you have the quantity for the group, apply the group rules. here is a pseudo code example for the white caulking - case (self::whiteCaulking) : $unit_rules = array(); // note: this example is for categories, not individual items, though you could mix them easily by adding an indicator to the defining array if the $key it a category or an item and call the appropriate method to get the correct quantity $unit_rules['ManDoors'] = array('mult'=>.75,'offset'=>0); $unit_rules['Windows'] = array('mult'=>.75,'offset'=>0); $group_rules = array(); $group_rules[] = array('operation'=>'function','name'=>'ceil'); $quantity = 0; // apply any unit rules foreach($unit_rules as $key->$rule) { $quanity += ($this->getTotalQuantityByCategory($key) * $rule['mult']) + $rule['offset']; } // apply any group rules foreach($group_rules as $rule) { switch($rule['operation']) { case 'function': $quantity = $rule['name']($quantity); break; } } $quantities[] = $quantity; break; i didn't work out how this would apply to the slidingTecScrews example, but it should be possible to make this work for any case you have now. you will find that the actual php logic for each case statement is or can be made to be the same, just with different defining arrays. when you get to that point, you would just set up the two arrays of data for each case, then call a common function/method to calculate the quantity and return it to the calling code. once you get to this point, you can eliminate all the switch/case logic and just store/retrieve all the rules in a database table and loop over them in turn to calculate the bom quantities. -
Please help me understand what I am doing wrong again.
mac_gyver replied to sonnieboy's topic in PHP Coding Help
if someone tries to log in and the entered username/password combination doesn't match, that doesn't mean they haven't registered. what if they miss-typed the value for either field? you would output a generic 'The username/password didn't match' message for this case and let them try to log in again. if the current visitor is not logged in, you would provide a link to the registration page, near the login form, for them to click on if they desire to register. you would this when they register, not when they log in. -
you would only allow logged in users to post. your log-in system would store the user id in a session variable. you would both test if the session variable is set before presenting any output needed to post comments and processing any form submission and you would get the user id from the session variable when forming and running the INSERT query to save the posted comment. you would get the product id from the content you are displaying that you are allowing comments to be posted for.
-
Checking the value of a dropdowns in sql php
mac_gyver replied to sarojthapa60's topic in PHP Coding Help
<option ... ></option> tags need value='...' attributes, not id's. i recommend that you write and test one small section of code at a time and only go onto the next section when you have determined that previous section works correctly. -
it's not clear what you are asking, since we don't know what your 'business rules' are that determine which query to run or what result you expect. however, i suspect you are asking how can you form and run any arbitrary SELECT query without writing and repeating different variations of the php logic depending on what the query is? if so, you need to write a general purpose query method, that you extend the main database class with, that accepts a built up sql query statement and an optional array of bound input data that corresponds to any place-holders in the sql statement. your main application code would build the sql query statement and the array of bound input data, then just call the general purpose query method when it needs to execute a query. unfortunately, you shouldn't use msyqli to do this, since it will require dynamically binding the input and the output data, which will require either using call_user_func_array() or the reflection class, since you must supply a variable number of parameters to the mysqli bind_param() and bind_result() calls. if you instead use the PDO extension, doing this is simple, straight forward, and will run fun significantly faster than using msyqli based code.