Jump to content

Psycho

Moderators
  • Posts

    12,161
  • Joined

  • Last visited

  • Days Won

    130

Everything posted by Psycho

  1. Ch0cu3r meant to say "storing whether each member is subscribed or not in separate text files is very inefficient."
  2. Well, you are using an INNER JOIN (or just JOIN) in a way by including both tables and using this in your WHERE clause WHERE o.orders_resellers_id = r.resellers_id Personally, I never use that type of construct to get data from associated tables. I would always use a proper JOIN for many reasons. For one it makes the criteria for associating the records much more apparent. Plus there are many features you can't use without a proper JOIN. Your original query would work the same as this FROM orders AS o JOIN r.resellers AS r ON o.orders_resellers_id = r.resellers_id The normal JOIN will return a result set for all records where a JOIN can be made. In this case, if there are any records in orders that does not have at least one corresponding record in resellers OR if there are any records in resellers that do not have a corresponding record in orders they will not be returned. In this case, you want ALL the records from the orders table even if there are no records in the resellers table. Based on the current query structure you would use a LEFT JOIN. That means return ALL matching records from the LEFT table (i.e. first table - orders) and JOIN any matching records from the right table (resellers). $sql = "SELECT o.orders_id, o.cust_order_id, o.cust_company, o.due_date, o.product, o.quantity, o.price, o.requirements, o.cust_order_total, o.order_status, o.reseller_earnings, o.orders_resellers_id, r.reseller_name, r.reseller_surname FROM orders AS o LEFT JOIN resellers as r ON o.orders_resellers_id = r.resellers_id ORDER BY due_date DESC";​ Take a look at this page for some examples of JOIN types: http://www.sitepoint.com/understanding-sql-joins-mysql-database/ Also, I see you named the foreign key in the orders table as "o.orders_resellers_id". I would suggest naming it "o.resellers_id" - exactly the same as it is in the resellers table. That makes it explicit that it is a primary/foreign key in those two tables. Plus, as stated previously, there are some features where using the same name simplifies the logic: e.g. USING(). You could use this for example FROM orders AS o LEFT JOIN resellers as r USING(resellers_id)
  3. I would create an index.php file that is used for all the requests. That file would have something like this at the top session_start(); //Check if family data is already set in session if(!isset($_SESSION['family'])) { //Set the default data include('setDefaultData.php'); } The setDefaultData.php page would have the initial data to set in the session. Something like this $family = array( //Include all the associative array data to set for the default ); $_SESSION['family'] = $family; As for how I would do it, I am the wrong person to ask. I don't have a formal education in programming and your instructor is looking for the use of specific design patterns.
  4. Regarding the data, it doesn't state if the data needs to persist across sessions. You could just create an associative array (or arrays) with the starting state of all the data. Then on the first page load check to see if that data exists in the session. If not, load the initial data. Then on each subsequent page load use the session data. Then, whatever functionality you have will manipulate the session data. If you closed your browser and go back, you would start with the initial seed data. This is a good approach for an activity such as this for several reasons. You can create specific use cases that start with the initial data. As you test, if a problem is found you can modify the code and start the user cases over from the beginning. If you were to use a database you would likely need to reset it to default data anyway. As for the classes to you - that is up to you. How it should ideally be set up for this exercise would likely be predicated on any lessons you've already had in the class as lessons are typically designed to build upon the previous lessons.
  5. When you say "on click" that typically means using the onClick event in JavaScript. But, based on your explanation, it could just as easily be accomplished with a normal HTML form. But, those are just two methods to initiate the action (i.e. make a call to the server). So, you can either use a traditional HTML form or use an onClick event to make an AJAX call. I would suggest starting with an HTML form to get a working solution, then you can add an onClick event to initiate if you need to perform it without a page refresh. I assume you would have a form with all the relevant files listed and perhaps checkboxes to indicate which files to be moved. You would submit that form to the processing page (PHP) which would take the form data with the list of files and perform a move operation on them. However, allowing user input to be used to perform low level file operations can be risky. You will need to ensure that all input is validated and ensure no malicious references are sent from the user. That is a very high level generalization. If you want more specific help, you will need to provide the specific part that you are stuck on.
  6. Just to add to cyberRobot's response. If you reference the values in the result set in an associative array, there can only be 'one' value for any specific key in the array. So, you either need to alias different fields that use the same name or you can reference the data with a numerically based index. I would go with the former as cyberRobot suggests. Also, if you have such a problem, that might be an indication that you need to use more unique names (e.g. order_id & resellers_id). This way, you can use the same field name as the primary key in one table and the foreign key in another. It may seem more "wordy" and superfluous, but your queries will be much easier to read when you have many JOINs. Also, there are some MySQL functions that you can't use otherwise, such as USING()
  7. AJAX makes sense in this situation because the other solution would require duplicate logic to be crated in JavaScript. That only makes things more difficult and error prone. Since you already have to create server-side code to do the calculation, you can just use AJAX (JavaScript that would call the server-side code) to get the same results. That way you only need to write the logic one-time and then re-purpose it for multiple uses (one to provide immediate feedback to the user and two to do the official calculation when processing the order). But, if the problem was about validating that a required field had a value it might be easier to write separate logic for server-side and client-side. As for how to implement AJAX, that is beyond the scope of a forum post. but, JQuery makes it very simple. Here is how I would implement it: 1. Create a file with a function to perform the calculations based on data passed to it. Typically this would be a list of products and quantities. The logic would look up the prices from the DB and do the multiplication and addition to get the subtotal. Then there might be additional logic around shipping or, in this case, comissions. The function would return the results. 2. The page that receives the form POST will process the data into the format expected by the function and then get the total for use in creating the order records. 3. Create another page to receive the AJAX request. That page would only need to format the POST data to send to the function and get the total. Then that page would return the total to the calling AJAX function 4. Create a trigger on the page to get the total (without the user actually submitting the order). The trigger would call a JavaScript function to send the relevant form field data to the page on #3 above.
  8. You should NEVER rely on JavaScript (or anything client-side) for any business logic as it is very simple for a user to circumvent and pass whatever data they want. For example, if you have a select list of valid values for a particular field, you cannot assume that other values will not be passed. A malicious user can easily inject any value they want - regardless of what is in the select list. As to the above, if you were to rely on calculations made on the client-side to be used for the actual billing/charging of the customer, a malicious user could manipulate the values to anything they want. That is not to say that you can't add business logic to client-side code to provide the user a better experience. You just can't rely upon it. So, you would first want to ensure you have all business logic implemented on the server-side. Then, you can add logic on the client-side where it makes sense. For example, let's say you have a field for an email address and you want to validate that the format of the value matches what an email address should look like. You would add logic on the server to check the format and throw an appropriate error if found to be invalid. But, maybe you don't want to have the user POST the page before finding out such an error exists. You could then add additional client-side logic to check the email address when the user exist the field or when they attempt to POST. So, going back to the calculation. As stated above, you absolutely want to have server-side logic to do the calculations when it comes to billing/charging. If you want to give the user some immediate feedback, you could ad​d client-side logic to do the same calculation. But, that can be a problem as you would have to ensure the two processes are in sync. Otherwise, you risk the displayed (client-side) value not matching what the user is ultimately charged. A better approach would be to write the logic one-time on the server-side. That process could be used for both the final calculation when the order is submitted and you could use it within an AJAX call to provide the user a total without having to POST the page. Just don't get that total to display in the client and populate a field for the purpose of using it when the user submits the page as they can change it (even if it is a read-only field). You will want to call the same logic to calculate the price when the order is submitted.
  9. Wow. You must have a very interesting interview process.
  10. You do order calculations on the client-side? Let me know what you are selling and I'll go buy mass quantities and 'hack' the price to be $0.01 I'm not sure what 'earnings' have to do with an order. But, if there are properties of the reseller (which can change) that affect the order, then that is data that is order specific and should be copied to the order as you say you are. Or, you can keep a historical record of those properties of the seller and reference the correct dataset when an order is placed. But, I don't know where this discussion started. If this is a response to my third point - my comments still stand. You are grouping the records to get the total which would prevent the data for those fields to be worthless. Then you can change the LEFT JOIN to a normal JOIN and those resellers without any matching records in the orders table will not be in the result set Then you don't need to SELECT the fields from the order table nor do you need to do the SUM() function (unless it is possible for orders to have a zero value for the reseller earning. If that is the case, then you would need the sum and the WHERE clause could exclude the records with a zero SUM value. And with respect to Barand's last post. If you are wanting all orders rom a specific date to today, then why not just use WHERE orders.due_date >= '2014-01-01' As he said, there shouldn't be any orders in the future.
  11. One other note. The BETWEEN operator may not be working as you intend. When you have this due_date BETWEEN '2014-08-14' AND '2015-08-14' It will match all records starting at midnight (00:00:00) on 2014-08-14 to midnight (00:00:00) on 2015-08-14. In other words, anything on 2015-08-14 from 00:00:01 to 23:59:59 will NOT be included. Never mind. The due date is a DATE type and not a TIMESTAMP. So it will be inclusive.
  12. A few thoughts. I create my queries in a logical order based on how you want the data. In this case you are gathering data about resellers with the earnings being secondary. So, I would select from the resellers table first. It would work with what you have, but it makes more sense to me to switch it. Second, what if there are not records in the orders table for a particular reseller. Using a normal JOIN, as you have above, that reseller would not be included in the results. If you want ALL the resellers to be displayed (even if there are no order records to JOIN on), then you need to use a LEFT/RIGHT join. You would use a RIGHT JOIN with the order you have above, but it would be a LEFT JOIN if done in the reverse order (which makes more logical sense to me). Third, you are including other fields in the order table (besides the earnings field). But, you are grouping the records from that table to get the total. I would assume each order has a unique ID, status and earning value. So, including those fields and doing a GROUP BY will retain only one value from one of the fields that were group. This makes no sense. Either leave those fields out or include them and leave out the GROUP BY to get the total - you can get the total by adding the earnings field when processing the records. But, I'm guessing you really don't need those fields. Fourth, ideally you would not be using a textual value for Order Status and instead use a numeric identifier (which could map to another table with the textual values). Using a LIKE clause to filter the records is very inefficient. Lastly, the SELECT list contains the field r.reseller_id, which does not exist. Based on the table schema provided it would be r.id Try this: SELECT r.id, r.reseller_name, r.reseller_surname, r.reseller_email, r.reseller_phone, r.reseller_commission, r.reseller_vat_number, -- o.id, o.reseller_earnings, o.order_status, SUM(o.reseller_earnings) as total FROM resellers as r LEFT JOIN orders as o ON r.id = o.resellers_id WHERE o.due_date BETWEEN '2014-08-14' AND '2015-08-14' AND o.order_status LIKE '%Order Completed%' GROUP BY r.id ORDER BY total DESC
  13. What do you mean by "Is it possible to see the result of left join of two tables(without on clause)?" What do you expect to get without an ON clause for a LEFT/RIGHT JOIN? Why don't you explain what you are trying to achieve?
  14. Well, scootstah's 'creative' solution aside, both mine and Barands's solutions would work. If you review those two you would answer your question above.
  15. The following solution protects against an item not existing in the list, but does not contain logic to prevent an infinite loop if the values were to contain such a problem <?php $paths = array( 'A' => 'B', 'B' => 'C', 'C' => 'D', 'D' => 'A' ); function getPaths($fullStart, $fullEnd, $paths) { $pathListAry = array(); //Return array $pathStart = $fullStart; //function var $pathEnd = false; //function var while($fullEnd != $pathEnd) //Run loop until full end is found { if(!isset($paths[$pathStart])) { echo "Error: No path starting with $pathStart"; return false; } $pathEnd = $paths[$pathStart]; $pathListAry[$pathStart] = $pathEnd; //Set start to current path end point $pathStart = $pathEnd; } return $pathListAry; } //Run solution $start = 'A'; $end = 'D'; $thePaths = getPaths($start, $end, $paths); //Output results echo "Starting from $start and ending at $end : <br><br>\n"; echo "<pre>" . print_r($thePaths, true) . "</pre>"; ?>
  16. I've never used getElementByID() recursively like this var mname = document.getElementById('addform').getElementById('machine_name'); Is there a reason why you are referencing the form using getElementById() then trying to reference the 'machine_name' elements using getElementById() from that? Why not just directly reference the 'machine_name' element using var mname = document.getElementById('machine_name'); Also, the function doesn't make sense. You are getting the value for Target, but then simply returning returnVal - which is false. I'm guessing this is not complete. And, there will also be a failure on this line since 'f' is not defined var target = f.getElementById('target').value;
  17. The answer is it depends. I know a good bit about VBScript as opposed to Visual Basic, but it is mostly transferable. If you only need to know if the body contains the word "cash" you would still need to account for variations such as "Cash", "CASH", etc. So, I would do the following: Convert the body to all lower or upper case characters. Then check for the target word. That is the simplest solution, but has one downfall. If 'cash' is contained in another word as opposed to being its own word it would still provide a match. To work around that you would need to use Regular Expression which is more complicated. Based on your actual need you may need to go that route. Note that if this is for some type of spam detection process you will likely get a lot of emails falling through the cracks since they will use other characters to get around detection, e.g. "ca$h". So, you could use the LCase function to convert the body to all lower case and then the InStr function to see if your target word is contained in the content. Here is some mock code: VAR bodyText = LCase(mail.body.text) IF InStr (bodyText, "cash", vbTextCompare) Then ' "cash" does exist in the body Else ' "cash" does not' exist in the body End If
  18. Psycho

    No word wrap?

    Yep, I was right. The HTML is invalid. On every row in your results you have an opening FORM tag and a a radio button input. But, you don't close the form! instead there is a single closing form tag after all the records (and multiple opening forms) are created. However, something else is wrong as well. Even on a page with just one record (where there would only be one FORM opening tag, it still doesn't work. But, there are so many other problems it's not worth my time to try and troubleshoot. The HTML output is a mess. Many problems should not have any functional implications, but it all adds up. Here's one tip for you: In the code to produce each row of verses, you are defining the width for each column in the TD element. It would be much simpler to just define the width ONE TIME when creating the header row. Less code to clutter the logic and less output to send to the browser.
  19. Psycho

    No word wrap?

    You misinterpreted my comment. I didn't say there was no closing TD tag. I said there was no closing bracket for the opening tag. Line 133 above is this: It should be this: As for your new problem, I doubt it is a CSS issue. It is likely an HTML. When I ran your page through an HTML validator, there were plenty of errors. I recall there was one or more about the FORM tags.
  20. Psycho

    No word wrap?

    I believe this is your problem: ol,ul,li,h1,h2,h3,h4,h5,h6,p,span,td,div { margin:0px; padding:0px; line-height:0px; <== REMOVE THIS list-style:none; } It makes no sense to my why you would globally apply those style properties to all those elements anyway. For example, what does list_style have to do with header tags?
  21. Your problem is that the variables used to identify the index contain values that do not exist as indexes in those two arrays. Either the indexes in one or both of those arrays are not sequential or the max limit ($Counter3) is higher than the indexes in those two arrays. When dealing with arrays, you should almost always be using the foreach() loops to iterate through the values, as Ch0cu3r shows, rather than trying to programatically determine the indexes to use. I'll add some more suggestions: Give your variables meaningful names that give an indication as to what they contain. Otherwise, you spend too much time trying to figure out what is what - especially when you have to go back to some code in the future. Separate your logic (PHP) from your presentation (HTML). This makes your code much more maintainable and flexible. In this case, rather than stick PHP code to create the options between the <select> tags you could put the PHP code at the top of the page and store the output for the options in a variable. Then just include an echo statement in the HTML where the <select> tags are. Also, with all due respect to Ch0cu3r, I would suggest including line breaks (and even spacing) in the HTML output using \n and \t. It makes it much easier to debug issues in the HTML code. Example: <?php //Array of menun groups and options $menuOptionsAry = array( 'Drinks' => array( 'Tea', 'Coffee', 'Orange Juice', 'Apple Juice' ), 'Food' => array( 'Toast', 'Ham Sandwich', 'Chicken Soup', ), 'Desert' => array( 'Ice Cream', 'Chocolate Moose', 'Jelly' ), ); //Create the default value for the menu options list $menuOptions = "\t<option value='None'>No Component</option>\n"; //Create the dynamic values for the menu options list foreach($menuOptionsAry as $menuGroupLabel => $menuGroupValues) { $menuOptions .= "\t<optgroup label='{$menuGroupLabel}'>\n"; foreach($menuGroupValues as $menuValue) { $menuOptions .= "\t\t<option value='{$menuValue}'>{$menuValue}</option>'; } $menuOptions .= "\t</optgroup>\n"; } ?> <html> <head> <title>Sample Page</title> </head> <body> Select a menu item: <form> <select name="menu"> <?php echo $menuOptions; ?> </select> </form> </body> </html>
  22. Psycho

    No word wrap?

    This would not be a PHP or MySQL problem. It would be a problem in the HTML/CSS. Posting the server-side code only complicates our ability to help you. Please provide the output that is causing the problem. If you provide a link to a page with the problem, it would be helpful to work with the CSS code to debug. But, right off the bat I see invalid HTML code. On line 133 there is no closing greater than symbol for the TD tag. Also, the value for the input on line 137 should be enclosed in quotes. Also, why all the lines of code to clear the mysql results before you close the table? It's not invalid, just not logical in my opinion.
  23. You are trying to use ORDER BY in two different ways - one to get the last three records that have been added and another one to sort them for display purposes - you can't do both concurrently. You can use a subquery to get the last three records and an outer query to sort them for display purposes SELECT * FROM ( SELECT Id, zone, xtime, xdate, temp, status FROM temp_log WHERE zone LIKE 'Unit%' ORDER BY Id DESC LIMIT 3 ) unitResults ORDER BY zone
  24. @obodo, I'm not sure what the purpose of your code is, but it does not match reality. I'm sure there are some exceptions out there, but how you are calculating the pay periods is not what is done in the real world. Companies that pay once a month, don't set the pay periods up to be 30 days apart. They set up the payday to be on the same numerical date each month. For example, payday would be on the 5th of each month. However, they would also have rules to account for when the 5th lands on a weekend or a holiday. For paydays that are every every week, or every two weeks, those would be on the same day of the week every week (or two) with adjustments for holidays. Note that with this type of pay periods, there will be months with five paydays (for weekly) or three paydays (for bi-weekly) For paydays that are twice a month, they are set up the same as the monthly pay period. They will be on two specific dates each month (e.g. the 1st and the 15th). The logic you are using is not accurate and is more complicated than reality, IMHO.
  25. Except Barand hasn't posted in this thread . . . so I assume you are talking about the code I posted. Vapor, you posted a problem and we took the time to provide solutions. Now you are asking us to analyze some other code to determine what is better and "clean & secure". Sorry, but I'm not going to take the time to do that. The code I posted works with the content on the page provided at the time I wrote it. If that content changes (specifically the format), I can make no guarantees. As to how you should display the output, that I leave to you. That is where you definitely need to worry about ensuring the code will not create security problems (e.g. XSS). That can be resolved using htmlentities() as one solution. But, how you create the output (CSS tables, etc.) is up to you. This forum is about helping people with code they have written. It would be nice to see you at least make an attempt as opposed to just writing everything for you.
×
×
  • 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.