Jump to content

maxxd

Gurus
  • Posts

    1,655
  • Joined

  • Last visited

  • Days Won

    51

Posts posted by maxxd

  1. If the project is still early in it's development, I'd highly recommend switching to PDO (my choice) or MySQLi, because (as already pointed out), the mysql_* functions are deprecated and removed in version 7, coming out sometime in the near-ish future. You'll find plenty of documentation on both classes in the manual, including come ideas about best practices.

  2. The problem with that is that you said all the database connection details are in header.php, so you're not going to be able to run the query before you include the header, which is where you define the database connection. You're going to need to do some refactoring. What does the file header.php look like?

  3. scootstah's right - there's no need to use sessions here. In fact, if the session value is going to be set when the user selects an option from the drop-down, using a session is going to make it more difficult on you. Simply change

    while ($row = mysql_fetch_assoc($result)) {
        $dropdown .= "\r\n<option value='{$row['type']}'>{$row['type']}</option>";
    }
    

    to

    while ($row = mysql_fetch_assoc($result)) {
        $dropdown .= "\r\n<option value='{$row['type']}'>{$row['name']} :: {$row['address']}</option>";
    }
    

    Then, on page report.php, use

    $selectedID = $_POST['items']
    

    as suggested.

     

    Note that this ($selectedID) will then contain the 'value' attribute of the option item (in this case, your desired 'id' from the database), not what the user sees in the drop-down itself.

     

    It goes without saying that you need to sanitize any data before doing anything with it in relation to a database, and that you are going to have to move to PDO or MySQLi soon - the msql_* functions are deprecated and will be removed in the next version of php.

  4. I would agree that if you have the order_item_id then you do not need order id. However, in the case of toppings it could be that item X has a choice of toppings and you want the choice applicable to the particular ordered item. Though I am guessing here about the actual relationship, without knowing the full schema.

     

    Good point. Even then, wouldn't you need an intermediary table for multiple toppings per item, which would negate the need to have the field in the toppings table, right?

  5. This is untested, but you should get the idea. Basically, you have to join each table individually on the foreign keys.

    $sql = "
    SELECT	o.id,
    	o.grand_total,
    	o.cust_name,
    	o.cust_surname,
    	o.cust_address,
    	o_i.name,
    	o_i.quantity,
    	o_i.unit_price,
    	o_i.total,
    	i.name,
    	i.price,
    	i.description,
    	i_t.topping_name,
    	i_t,topping_price
    FROM order AS o
    LEFT JOIN order_items as o_i
    	ON o.id = o_i.order_id
    LEFT JOIN items as i
    	ON o_i.items_id = i.id
    LEFT JOIN items_toppings as i_t
    	ON i_t.items_id = i.id
    ORDER BY o.id DESC $limit
    ";
    

    I don't think it's necessary to include the order id or order items id in your toppings table, because the toppings aren't related to the order, but the item. The item is related to the order through order_items, so you've got your through-line there.

  6. First and foremost, are you trying to display the database data in an HTML table, or do you actually have a string that comprises an HTML table and you're trying to extract data from the string? Looking at your attachments, it looks like you've got everything in a database, but it's good to be sure.

     

    Let us see the code you've come up with so far and let us know what results you're getting and I'm sure you'll get pointed in the correct direction.

  7. I haven't tried is_super_admin() because the preview window loads the page from a front-facing perspective, so I assume that would fail the same way that is_admin() does. I'll give it a shot, though.

     

    The remove_action() idea is intriguing - I wonder if I can flat out remove the widget section from the customizer panel entirely, and whether or not that would have any effect at all... hmmm...

     

    Thanks for the ideas!

  8. What you've got should actually work just fine.

     

    You'll want to do some more safety checks on the intended class, but that's the general idea. Something along the lines of this, for instance:

    $class = isset($_GET['url']) ? $_GET['url'] : 'notAFile';
    //check to make sure the value of $_GET['url'] isn't mainpulating the file path to allow the user
    //	to hijack system files, etc...
    if(file_exists("{$this->_pathToIncludes}/{$class}.php")){
    	$this->_inst = new $class();
    }
    $this->_inst->method();
    

    Of course, this is assuming you're using an autoloader and the file containing the class is named the same as the class itself; otherwise you'll need to include the target file before instantiating the class. You can google autloader implementations that help with namespaces and the corresponding pathing structure - I don't have an example handy, but it's not too terribly tough.

  9. Hey y'all. This is (hopefully) a dumb question and something I'm just overlooking.

     

    I've created a very simple widget that includes a separate php file. The separate .php file is actually just a large but simple HTML form consisting mostly of checkboxes. That's it. So, everything works great in the front-end and the widgets page of the back-end. I run into trouble, however, on the Customizer page. Including the template file like so:

    private function renderTemplate($template){
    	ob_start();
    	require_once($template);
    	$form = ob_get_clean();
    	print($form);
    }
    

    will cause the entire page to load multiple times in the preview window. It's clearly in a loop, though the require_once() should prevent this (note that the method is private because I'm calling it from the public widget() method after a check to make sure the file actually exists and is what I expect it to be).

     

    If I comment out the lines of the method (so the functionality is gone but the call doesn't throw an undefined function error), everything works as expected.

     

    Has anyone else seen this type of behavior or know of a way to simply not render the widget in the preview window?

     

    I can't use is_admin() because the preview window forces a front-end perspective and is_admin() always returns false. I even tried a conditional on the value of the global $pagenow, but the value of $pagenow resets itself to index.php before the previewer loads the index page, so it's exactly like calling the method from the front-end. Which needs to happen, obviously, or the user wouldn't see the widget at all.

     

    I also tried to just use file_get_content() instead of require_once() on the template file, but ran into the same issue.

     

    Anyway, any ideas or experiences are very much appreciated.

  10. Not quite sure what you're asking, but passwords should only be stored in a database after encryption. You pull the password from the database, compare it to the password provided by the user, then let it go. Don't store it in $_SESSION or $_COOKIE or anywhere else.

  11. $_GET['event'] and $_GET['mood'] are simply examples. You wanted to know how to select an option of the DOM SELECT element. You'll have to get the current value and pass it into the function in place of the $_GET variables that are there now. I can only see the code that you posted, so I don't know where those values are coming from. Basically, I used $_GET as a stub for this section of my original reply:

     

     

    As for how to achieve the goal of the actual question, you'll need to pass a current value parameter to the buildSelectOptions function (once you're refactored it into one function, not two), compare that value to the value of $id in the while loop, and if it matches, add the string ' selected' to the option row.

     

    Probably could've explained that better earlier - sorry about the confusion.

  12. I don't know the setup of your database, so I just used stub table names. Obviously update the field and table names to match your current setup. And sorry about the $conn thing - you'll have to pass that into the getMoods() and getEvents() functions, like so:

    echo buildSelectOptions('event', getEvents($conn), $_GET['event']);
    echo buildSelectOptions('mood', getMoods($conn), $_GET['mood']);
    

    Like I said, I hadn't had my required amount of caffeine...

  13. I see you create a common function and then run that function for each of the queries!

     

    Yes. That way, you only have to make a change to one part of the code when things change, and it greatly improves readability. It'll make life easier, I promise.

     

    Do you mean mysqli_close()?

     

    No, I mean that - given the code posted above - the HTML select elements are never closed. Let's look at the code you posted:

    function buildSelectOptions($options){
    	$optionsHTML = "<select name=\"Event\">\r\n";
    	 
    	foreach($options as $id => $label){
    		$optionsHTML .= "<option value='{$id}'>{$label}</option>\n";
    	}
    	return $optionsHTML;
    }
    

    Given this, the HTML output will look like this:

    <select name="Event">
        <option value='value'>This is an option</option>
        <option value='value2'>This is also an option</option>
    
    <!-- more html content -->
    

    Note that there's no '</select>' tag to close the select element. Modern browsers will (probably - honestly, I'm not sure) compensate for this, but the page won't validate properly and you're unnecessarily taxing the browser by making it figure out where you meant to end the element instead of specifically telling it. It's not much of a page load increase, but they do add up.

     

     

    The original code has run succesfully for the past year on my website, without any errors.

     

    I will try your suggested code and see what happens!

     

    While there's nothing technically wrong with the code you posted (it'll parse and run, and you won't get any errors or warnings), as you're finding out first-hand right now, it's a nightmare to maintain. And it's going to continue to be a nightmare to maintain unless you actually do some refactoring. I'm not saying you have to (or even should, quite honestly) adopt an OO style to the code, but a good code clean up will go a long, long way for you. There's some massive code smell coming off even the small snippet you posted.

     

    Like I said, the code that I posted is completely untested so it may not work without modification. But compare the readability of your posted code to the sample code I posted. Add some comments into the sample code and it'll actually be useful to you when you have to come back to the code in a year or two to make updates - you won't have to scroll up and down the page looking for where a variable was set, which specific version of buildSelectOption() you're using at which specific point, etc.

  14. This is entirely untested, and I'm only on my second cup of coffee after a long-ish night, but this should make a bit more sense.

    function buildSelectOptions($name, array $options, $current=null){
    	$htmlString  = "<select name='{$name}' id='{$name}'>\n";
    	$htmlString .= "\t<option value='-1'> -- Please select -- </option>\n";
    	foreach($options as $value=>$option){
    		$htmlString .= "\t<option value='{$value}'";
    		if($value == $current){
    			$htmlString .= " selected";
    		}
    		$htmlString .= ">{$option}</option>\n";
    	}
    	$htmlString .= "</select>\n";
    	return $htmlString;
    }
    
    function getEvents(){
    	$qry = "SELECT	 id
    			,Event_Type
    		FROM Events
    		ORDER BY id";
    	$sql = mysqli_query($conn, $qry);
    	if(mysqli_num_rows($sql) < 1){
    		return array();
    	}
    	while($res = mysqli_fetch_array($sql)){
    		$ret[$res['id']] = $res['Event_Type'];
    	}
    	return $ret;
    }
    
    function getMoods(){
    	$qry = "SELECT	 id
    			,Event_Sub_Type
    		FROM Moods
    		ORDER BY id";
    	$sql = mysqli_query($conn, $qry);
    	if(mysqli_num_rows($sql) < 1){
    		return array();
    	}
    	while($res = mysqli_fetch_array($sql)){
    		$ret[$res['id']] = $res['Event_Sub_Type'];
    	}
    	return $ret;
    }
    
    echo buildSelectOptions('event', getEvents(), $_GET['event']);
    echo buildSelectOptions('mood', getMoods(), $_GET['mood']);
    
  15. No offense, but the fact that the first line is empty really isn't the only trouble with this code.

     

    Where does $Events_info get set? Or $Mood_info? Why do you have 2 identical functions doing identical things, named and called separately? And none of the SELECT elements are ever closed, so your resulting markup has to be a complete mess.

     

    As for how to achieve the goal of the actual question, you'll need to pass a current value parameter to the buildSelectOptions function (once you're refactored it into one function, not two), compare that value to the value of $id in the while loop, and if it matches, add the string ' selected' to the option row.

  16. What does the data in table 'dtop' look like?

     

    It is weird that it's outputting all the php after the error - as scootstah suggested, you are using .php as your file extension, right? Also, if it's running on the live server and not on your local, that sounds like a configuration error - what version of PHP are you using locally? Compare the PHP and MySQL versions between the two systems, then update the local server to be at least equal to the live server.

     

    The select query you're running simply pulls all the rows from the table 'dtop', so as long as there is any data at all in that table, mysqli_num_rows() will be greater than 0, meaning that the error block should never run. The only other thing that I can think of is that the query is failing somehow. Try switching

    if (mysqli_num_rows($menu_res) < 1) {
    	//this URL does not exist << What URL? There's no WHERE clause in the query...
    	echo "<p><em>Menu error.</em></p>";
    }
    

    to

    if (mysqli_num_rows($menu_res) === false) {
    	echo "<p>".mysqli_error($menu_res)."</p>";
    }
    

    and see what that has to say.

     

    @QOC - Unless I'm misunderstanding what you're saying, I disagree. How can you have an extensible, flexible site without storing the navigation in the database? Caching will take care of any egregious database calls, and I can't remember the last time I didn't use - or see used - dynamic navigation in a site.

×
×
  • 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.