Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
How does the database store that automatically without adding it in the insert? As Barand stated you simply define its default value to be set to the current time. And, for future reference, you can also set up a timestamp field to automatically update to the current time when the record is modified. So no need to pass a time to the UPDATE queries to maintain a last updated value! Here is something like what your table structure should look like CREATE TABLE `views` ( `view_id` int(11) NOT NULL auto_increment, `viewer_id` int(11) NOT NULL, `location_id` int(11) NOT NULL, `location_type` int(11) NOT NULL, `time` timestamp NOT NULL default CURRENT_TIMESTAMP, PRIMARY KEY (`view_id`) )
-
So, you are sending the unix timestamp from JS? Did you see what I posted twice previously that if you use a MySQL timestamp field you don't even need to pass the timestamp with the INSERT queries - it will be handled automatically by the database.
-
As Barand stated you should absolutely be using the database timestamp field type. Right now you must be explicitly populating that value when a new view record is added to the table. By using the MySQL timestamp field you can let the database do that automatically. So, to do this properly you will need to look at any operations that retrieve the date value for those records and change them as needed. It all depends on how you use the date in those scenarios.
-
EDIT: Just saw your last response. I tested my queries using a timestamp field - so I don't know why you are not getting the correct results. EDIT#2: Ok, I just reread your last response. Are you storing PHP timestamps or using the MySQL timestamps. You should definitely be using the MySQL timestamps so you can use the date operations in MySQL. In fact, you can set up the field to auto-populate with the current timestamp when creating records in the views table. So, you would not need to include that field when doing INSERTs. Can you provide the table format for the views table? OK, after a little googling, this will work for getting the correct count of 'views_since_yesterday' for all views that occurred since midnight at the beginning of the previous day SELECT `location_id`, `location_type`, COUNT(`view_id`) as `total_views`, SUM(`view_date` > DATE_SUB(CONCAT(CURDATE(), ' 00:00:00'), INTERVAL 1 DAY)) as `last_day_views` FROM `views` GROUP BY `location_id`, `location_type`
-
Yeah, it is a lot simpler than you guys are trying: SELECT `location_id`, `location_type`, COUNT(`view_id`) as `total_views`, SUM(`view_date` > DATE_SUB(NOW(), INTERVAL 7 DAY)) as `last_week_views` FROM `views` GROUP BY `location_id`, `location_type` You can modify the condition in the SUM() as needed for different periods. So, if you want views since yesterday you need to create the date object for midnight for the prior day instead of just DATE_SUB -1 days.
-
I prefer usort() to array_multisort() array_multisort() requires you to create new arrays before you even sort the array - creating more overhead. usort() may take a little more lines of code, but it's probably more efficient and it is easier to understand. The function below is written out to be easy to read and could be condensed. Also, the $a and $b within the return lines may need to be swapped to sort in the order you are looking for - I didn't test it. function sortTotals($a, $B) { //Do initial sort on 'ttl_points' if($a['ttl_points'] != $b['ttl_points']) { return $a['ttl_points'] - $b['ttl_points']; } //Do secondary sort on 'brd_points' if($a['brd_points'] != $b['brd_points']) { return $a['brd_points'] - $b['brd_points']; } //Both fields are the same values return 0; } //Usage usort($totals, "sortTotals");
-
There are some easy solutions, but the problem is what logic would you use to determine what a "word" is. The easiest solution would be to explode() the string using spaces, then use array_chunk() to create elements with 1,000 elements each and implode those back with spaces. $words = explode(' ', $originalString); $wordChunks = array_chunk($words, 1000); foreach($wordChunks as &$words) { $words = implode(' ', $words); } // $wordChunks is an array of 1000 word strings But, as stated above - it depends what you consider a word. This could create some differences from what you expect.
-
Because you are not defining any JOIN condition so it is doing a dross-join - joining EVERY record from the first table on EVERY record from the 2nd. You wouldn't need to have the location_id listed twice anyway (if it is done correctly). That query is also a little more complicated than I think it needs to be. I think there's a good solution, but I need to verify it first. Can you provide a more detailed description of exactly what data you are wanting? The queries you have don't quite make sense to me.
-
I gave you a number of things to try. At least try those and report what results you get. As for Christian's suggestion you should absolutely do that. Otherwise you are only creating more work for yourself. Just change the name of the original inboxview.php file to something like viewmessage.php. Then call that file when trying to view messages from either the inbox or the outbox. That way you only have one file to maintain. If you find a bug when viewing inbox messages you would be inclined to only fix the issue in the viewinbox.php file and would likely forget that the same problem must also exist in the viewoutbox.php file. That will lead to fractured code.
-
Right. What I was getting at is that if the order is "random" there is no logical way to handle adds/deletions to the source data as you navigate from page to page. So, if using the seed method, a record was deleted from page 2, then all the records on page 3, 4, etc. would change. You could build some custom functionality such as getting a random list and storing it is session/cookie data. Then, if a record is deleted, all the records after that record would move up in position. And, if records are added, the only logical thing to do would be to add them to the end of the list (which really isn't random). If you are going to create some fixed list to start such as this, you definitely need to account for add/deletes otherwise you may get less records than intended on a page and new records won't display in the data. Believe me, I have had to deal with many different issues regarding pagination. I've had product managers and designers come up with plenty of ideas that sound good on paper but cannot logically be implemented (e.g. subtotals). When these issues are identified the typical response is to add more complexity to handle those issues - which leads to more bugs. Some may argue that add/deletes while a user is paginating through the records is an edge case scenario and does not need to have a lot of additional work to make it "perfect". However, my position is that whatever feature is being implemented should "just work". A randomized pagination doesn't "just work". And, personally, as a user, my first instinct would be to sort the grid in some logical order - but that my be due to the fact that I have a slight OCD tendency.
-
I'd agree. But, I would also modify the permission check (if you've implemented one) to only display the message if the message is FROM or TO the current user.
-
It's very disappointing to try and help someone out when they don't appear to be even trying. You say that you are just being redirected to the outbox, correct? Are you saying you don't see anything in that code that would perform that redirect??? $messageID = (isset($_GET['messageID'])) ? intval($_GET['messageID']) : 0; if(!$messageID) { header('location: outbox.php'); exit(); } So, you know there is a condition check that (if true) will redirect to the outbox. That condition is predicated on $_GET['messageID'] Have you tried echoing $_GET['messageID'] to the page to verify what it contains or, better yet, do a print_r($_GET)? Did you look at the HTML source code on the outbox.php page to verify that the links are created with the correct URL parameter for 'messageID'? Did you look at the PHP code on that page to see how that parameter is being created? In short, have you done anything to actually figure out the problem on your own rather than just trying it, seeing it doesn't work, and then posting here? You do not need to be a programmer to do simple debugging.
-
To start, look at the code that creates links in your inbox. They *should* have a parameter on them for the "messageID" and they apparently do not. Without that you cannot get the message to display. That will resolve the "Notice" message above which will also resolve part of the problem with the query. But, here are some other issues: $messageID = $_GET['messageID']; if(!isset($messageID)) { You SET $messageID and then do a check if it is set. Kind of pointless since it would always be set. It may be set as null if $_GET['messageID'] is not set - but $messageID would always be set in that logic. else if(isset($messageID)) If the if() condition is checking if something is not set, just use else. No need to use elseif() with a condition to see if it is set. $getmessage = mysql_query("SELECT * FROM 'gn_messages' WHERE 'messageTo' = '$messageTo' AND 'messageID' = '$messageID'"); 1. Don't create your queries directly in the mysql_query() function call. Create the query as a string variable so if something goes wrong you can echo it to the page for debugging. 2. Where is $messageTo defined? Do you really need it since you are specifying the message ID? I could see where you might want to use it to restrict people from seeing messages not intended for them, but that's not how I'd do it. 3. NEVER EVER user user submitted values (POST, GET, COOKIE) in your queries without properly escaping/sanitizing them 4. If you are only getting one record - don't use a while() loop Sample code. This is not meant to be a copy/paste solution. only an idea of how the logic might look <?php session_start(); include 'gradnetconn.php'; $currentUser = $_SESSION['user']; $messageID = (isset($_GET['messageID'])) ? intval($_GET['messageID']) : 0; if(!$messageID) { header('location: inbox.php'); exit(); } $query = "SELECT * FROM 'gn_messages' WHERE 'messageID' = '$messageID'" $result = mysql_query($query) or die(mysql_error()); $message = mysql_fetch_object($result); if($message->messageTo != $currentUser) { echo "You are not allowed to view this message"; } else { echo "<h2>$message->messageSubject</h2>"; echo "<p>$message->messageBody</p>"; echo "<p>From: $message->messageFrom On: $message->messageDate</p>"; } ?>
-
I have no insight into your application - and am not willing to take the time to do so. If the status and expiration date make sense for those associated tables then keep that data there. I really don't care. But, I don't really understand what you are trying to accomplish with the query in this thread. If you are wanting to use that query for login purposes I don't think you should try and use the active and expiration dates to exclude records in the query search. Have the query simply find the record in the login table based on username and password AND grab the associative data from the other tables. If no match, then you know that the username/password is not valid. But, if you get a record THEN check the other fields to see if the user is active and not past the expiration period. That way you can give the user a useful message as to why they cannot log in. I would suggest using this query SELECT l.login_id, l.username, l.login_type, IF( (l.login_type = 'tutor' AND t.date_expires < NOW()) OR (l.login_type = 'institute' AND i.date_expires < NOW()), false, true) AS expired, IF( (l.login_type = 'tutor' AND t.active <> 1) OR (l.login_type = 'institute' AND i.active <> 1), true, false) AS active FROM login AS l LEFT JOIN tutors AS t ON l.login_id = t.login_id LEFT JOIN institutes AS i ON l.login_id = i.login_id This will return login_id, username, login_type and two dynamically generated variables: expired and active. - If the user is a student OR if the user is a tutor/institute and the corresponding expiration is in the future the value of expiration will be false (else it is true). - If the user is a student OR if the user is a tutor/institute and the corresponding active value is true, the value of active will be true (else it is false) After running that query you could have some logic such as this: $query = "SELECT l.login_id, l.username, l.login_type, IF( (l.login_type = 'tutor' AND t.date_expires < NOW()) OR (l.login_type = 'institute' AND i.date_expires < NOW()), false, true) AS expired IF( (l.login_type = 'tutor' AND t.active <> 1) OR (l.login_type = 'institute' AND i.active <> 1), true, false) AS active FROM login AS l LEFT JOIN tutors AS t ON l.login_id = t.login_id LEFT JOIN institutes AS i ON l.login_id = i.login_id WHERE username='$username' AND password='$passwordhash'"; $result = mysql_quer($query) or die(mysql_error()); if(!mysql_num_rows($result)) { echo "Your credentials are incorrect."; } else { $user = mysql_fetch_assoc($result); if($user['expired']) { echo "Your account has expired."; } elseif(!$user['active']) { echo "Your account is inactive."; } else { //Everything checks out - complete login process } }
-
Impossible to know from what you have provided. But, I see some things that look "off". <select name="messageTo" id="messageTo" /> <option value = <?php $sql = "SELECT * FROM gn_users"; $queryresult = mysql_query($sql) or die (mysql_error()); while($row = mysql_fetch_assoc($queryresult)){ $userFirstName= $row['userFirstName']; $userSurname = $row['userSurname']; echo "<option value = $userFirstName > $userSurname</option>\n"; } mysql_free_result($queryresult); ?></option> 1. You start an opening option tag, then run your query and create the options, and then having a closing option tag. The HTML markup would be messed up. basically you are putting all the options inside a parent set of options. makes no sense. 2. The value of an option tag should be enclosed in quotes. 3. There is no closing SELECT Tag 4. Are you really wanting the first name as the value? you should be using the ID of the record So, whatever the value of the options are, they will be passed in the post data. You should verify that by doing a print_r(%_POST) on the page that receives the form data. If the values are passed and not getting saved, then you need to look at the code for saving the records. This is what I think your code should look like for creating the select list. <?php //Put this section at the top of the script $query = "SELECT userID, userFirstName, userSurname FROM gn_users"; $result = mysql_query($query) or die (mysql_error()); $toOptions = ''; while($row = mysql_fetch_assoc($queryresult)) { $toOptions .= "<option value=\"{$row['userID']}\">{$row['userFirstName']} {$row['userSurname']}</option>\n"; } ?> <!-- this goes in the body of the HTML --> <select name="messageTo" id="messageTo" /> <?php echo $toOptions; ?> </select>
-
I still think you need to put the expiration and status in the login table. Since that information is used as part of the login process it makes sense. Just leave empty for those users to which the values do not apply. But, since you seem hell bent on approaching it in this manner - the below should work. You don't state what values are used in the active fields - so I guessed. SELECT l.login_id, l.username, l.login_type, IF( (l.login_type = 'student') OR (l.login_type = 'tutor' AND t.date_expires >= NOW() AND t.active = 1) OR (l.login_type = 'institute' AND i.date_expires >= NOW() AND i.active = 1), true, false) AS login_status FROM login AS l LEFT JOIN tutors AS t ON l.login_id = t.login_id LEFT JOIN institutes AS i ON l.login_id = i.login_id WHERE username='$username' AND password='$passwordhash'
-
How to convert number in String to Value, then calculate Markup?
Psycho replied to mahogan's topic in PHP Coding Help
OK, I missed putting the empty string replacement in those lines. Try $price_per_item = preg_replace("#[^\d\.]#", '', $html->find('#price-per-item')); $total_price = preg_replace("#[^\d\.]#", '', $html->find('#total-price')); -
How to convert number in String to Value, then calculate Markup?
Psycho replied to mahogan's topic in PHP Coding Help
Did you event try the code I provided??? I don't see it listed as any of your attempts. $price_per_item = preg_replace("#[^\d\.]#", $html->find('#price-per-item')); $total_price = preg_replace("#[^\d\.]#",$html->find('#total-price')); -
This is really more complicated than you think. If the pagination order is supposed to be random how would it handle new/removed records? So, I'm on page 2 and someone removes a record that would have been on page 3. What happens when I navigate to Page 3? Depending on the method chosen above, the result could be all over the place. Page 3 has 1 less record than it should, the entire record set could be completely re-randomized (even with a seed value), empty row int he grid, etc. etc. And the same problems could arise if someone adds a record.
-
You should NOT use a do . . . while() loop when processing your database results. That is why you get a NULL value at the beginning of the array. do{ $arr1[] = $row['tagname']; }while($row = mysql_fetch_assoc($getq)); On the first iteration of that loop $row is not defined. Use a while() loop instead while($row = mysql_fetch_assoc($getq)) { $arr1[] = $row['tagname']; }
-
I'm having issues with possibly md5 encryption
Psycho replied to coaster27's topic in PHP Coding Help
Well, there's also the fact that the way you hash the password before inserting was not the same as how you hashed when doing the SELECT md5(md5('$password'), '$email') md5(md5($checkpassword)) -
I would redefine the login table such that the Login/Status information is in that table. If Students don't have an expiration or active/inactive status - then just leave those values blank for those records. Makes things so much easier. But, the reason your query is not working is because of the INNER JOINs. An INNER JOIN only pulls results where there are records from both tables that meet the matching condition. In your case there are NO records from the login table that have matching records in both the institutes and tutors tables. You want ALL the records from the first table (login) even when there are no records to JOIN to in the 2nd or 3rd tables. So, you need to use LEFT JOINS. But, I'm not sure how that would work for the date_expires field since you want that from two different tables. I'd just put all the pertinent login information in the, well, login table.
-
design a system to integrate with 3rd parties
Psycho replied to CaptainChainsaw's topic in Application Design
You should not be hard-coding data that is variable. If you design your database and logic appropriately the performance should be minimal. You would only need one or two tables. To be truly normalized you would want two tables: one for the card types and an associative table for the vendor names of each card type. But, if performance is a problem and you do not foresee having to add many vendors over time you could have one table with a record for each card type and a column for each vendor. To add a new vendor you would only need to add a column and enter the value that the vendor uses for each card. You would doing a query against a table that only contains a dozen or so records.- 3 replies
-
- design
- objected oriented
-
(and 1 more)
Tagged with:
-
design a system to integrate with 3rd parties
Psycho replied to CaptainChainsaw's topic in Application Design
Why would you hard code these values rather than putting them into a database which would be infinitely easier to maintain and manage? You can then define the different cards and the "names" that each third party product uses.- 3 replies
-
- design
- objected oriented
-
(and 1 more)
Tagged with:
-
How to convert number in String to Value, then calculate Markup?
Psycho replied to mahogan's topic in PHP Coding Help
PHP is a loosely typed language. Part of that means that the PHP parsing engine can dynamically juggle different types of variables for different needs. So, it can do math on the number value of 5 or the string of "5". $product = 5 * 5; echo $product; //Output: 25 $product = "5" * "5"; echo $product; //Output: 25 However, if the parser cannot interpret a string as a number that process would obviously fail. Based upon the image you provided I will make the assumption that the string you are getting from your supplier's site is something such as "$11.55". It is the dollar sign that would be causing the problem. Therefore, you could solve the problem by stripping out all non-numeric and non periods from the string. You will then have a string that can be interpreted as a number by PHP $price_per_item = preg_replace("#[^\d\.]#", $html->find('#price-per-item')); $total_price = preg_replace("#[^\d\.]#",$html->find('#total-price')); NOTE: If there are more than 1 periods in a value it will not be a valid number after that conversion.