Jump to content

Adam

Moderators
  • Posts

    5,717
  • Joined

  • Last visited

  • Days Won

    6

Everything posted by Adam

  1. Sounds odd, but Windows does still have SO files, not DLL. Apache must have some kind of adapter for them..
  2. The 'headers already sent' error tells you where the output is started:
  3. Shouldn't it be..? C:\Apache2.2\php5apache2_2.dll
  4. Keywords in the URL will give you a small advantage in terms of indexing, but these days they're not by any means required to be successful. Your number one concern should be your content. Keep it rich, fresh, clean, semantic, etc. That's where you'll reap the biggest reward. I'm not saying don't add them, as they can have cosmetic benefits as well. Don't expect them to shoot you up the rankings of all of a sudden though. Google have said themselves they don't pay that level of attention to keywords in the URL, it's all about the content. Yes, but who cares about them? Exactly.
  5. Do you have an example we can use to reproduce the problem? Saying "sometimes it doesn't work" is about as ambiguous as saying there's a security hole in IE6.
  6. Good stuff. Yeah the join onto itself isn't pretty, but required to be able to get a row for each permutation. Should have mentioned that s1/s2/usr1/usr2 are just aliases.
  7. I would add some sanitisation too if I were you!
  8. Have a read through some tutorials and have a bash yourself first. If you get stuck then post your code and we'll be happy to help you fix it, but we're not here to write it for you. http://www.google.co.uk/search?q=php+send+email+attachments
  9. We can't give you a decent answer without knowing more about the two systems - are they well known? Most PHP software out there isn't particularly well written unfortunately, so extending or merging them can be quite tedious.
  10. Sure, no worries.
  11. Ha.. I'm all over the place today! Only the first was wrong - had the order bys the wrong way round: select shift1, shift2, total from ( select s1.id as shift1, s2.id as shift2, (select count(usr1.users_id) as total from usersShiftsRank usr1 join usersShiftsRank usr2 on (usr1.users_id = usr2.users_id and usr1.shifts_id != usr2.shifts_id) where usr1.rank <= 3 and usr2.rank <= 3 and usr1.shifts_id = s1.id and usr2.shifts_id = s2.id ) as total from shifts s1 join shifts s2 on (s1.id != s2.id) where s2.id > s1.id order by shift1, shift2 ) as data order by total desc;
  12. Wait a minute, ignore that. I'll get back to you later, those aren't quite right!
  13. Ahh, I had it in my head that table was rank across the x axis and shift down the y axis. Sorry, I follow you now. Although that's a very odd way to structure this data, given you have repetitions and invalid comparisons all over the place. You can still compare permutations, but I would recommend just having a three column table; shift1, shift2, total (sorted by total). That will be a lot easier to read. If you do want to go down the three-column route, you can use this query to return the data exactly as you will need it in the view: select shift1, shift2, total from ( select s1.id as shift1, s2.id as shift2, (select count(usr1.users_id) as total from usersShiftsRank usr1 join usersShiftsRank usr2 on (usr1.users_id = usr2.users_id and usr1.shifts_id != usr2.shifts_id) where usr1.rank <= 3 and usr2.rank <= 3 and usr1.shifts_id = s1.id and usr2.shifts_id = s2.id ) as total from shifts s1 join shifts s2 on (s1.id != s2.id) where s2.id > s1.id order by total desc ) as data order by shift1, shift2; If you want to still create the table you showed before though, you'll need to use this query: select s1.id as shift1, s2.id as shift2, (select count(usr1.users_id) as total from usersShiftsRank usr1 join usersShiftsRank usr2 on (usr1.users_id = usr2.users_id and usr1.shifts_id != usr2.shifts_id) where usr1.rank <= 3 and usr2.rank <= 3 and usr1.shifts_id = s1.id and usr2.shifts_id = s2.id ) as total from shifts s1 join shifts s2 on (s1.id != s2.id) order by shift1, shift2; You'll notice that the first query is oddly more complicated, given it's for a simpler table, but in order to omit repetitive permutations where the shifts have switched position, we have to order the results by shift1 and then shift2, so we can only return shifts where shift2 > shift1. Because though we've then used the order by, we have to wrap the results in a sub-query, and order them by the total in the parent. For the second query though, we actually want repetitive permutations so we can leave all that out. However when you come to display the table, you're going to need to add in the logic that will detect when the shifts are the same, as the dataset doesn't contain them. Both tables in essence though just join the shifts table onto itself (to give every permutation), then uses a sub-query to select the total number of users from usersShiftsRank that have ranked both <= 3. We have to do a similar join in the sub-query as well, so we don't count where shift1 is in the left table and shift2 is in the right table, and then when shift1 is in the right table and shift2 is in the left table separately. That was quite a head fuck to work out!
  14. As I alluded to, the data won't be very usable when it's first selected. It's a two step process. What you have is a separate row for each shift ID and rank combination, where data actually exists. For example you'll have one row for the total number of rank 1 votes for shift 1. You'll have another row for the total number of rank 2 votes for shift 1. Then another for rank 3, and another possible three rows for shift 2 ranks, etc. Using PHP you can restructure the data into a multi-dimensional array, indexed by the shift ID. Each item (each shift) in the array will then store a sub-array of ranks for that shift. If there's no index for a rank then you know nobody voted for it. See the previous code I posted. The way you're trying to do it - a column in the results for each shift - over time as you add more shifts or even from the start if you have 19, would become difficult to maintain and would be inefficient. The power behind relational tables is in rows, not columns.
  15. You could always just define some macros..?
  16. JavaScript behaves that way. Could be what's throwing you off?
  17. Sorry, missed "adapt this" - $titleurl = preg_replace('/[^a-zA-Z0-9_ -%]/', '-', $d); $titleurl = preg_replace('/-+/', '-', $titleurl); $titleurl = trim($titleurl, '-');
  18. You can have a simple pattern match one or more hyphens and replace with a single hyphen: $str = preg_replace('/-+/', '-', $str); Then to remove any leading or trailing hyphens, just run it through trim: $str = trim($str, '-');
  19. As dannyb785 quite rightly pointed out though, you're mixing HTML with JS. I mean it depends how much JS you actually have, but besides it being bad practise, you're bloating the mark-up and reducing your code:text ratio, which can be quite damaging to SEO. Of course you're unable to cache the file either, so it wastes bandwidth as well.
  20. Right I see. In that case then, you want to group the query by the shift ID and the rank, then select the count() of that grouped rank. An example will probably explain it better: select shifts_id as shiftId, rank, count(rank) as rankCount from usersShiftsRank where rank <= 3 group by shiftId, rank order by shiftId, rank; If you wanted to return the user and/or shift data as well (thinking for the second table you mentioned), you just need to join them like I showed in the last example. Also you could easily return all 6 ranks by removing the where condition. You'll notice that the data returned is a bit arbitrary and wouldn't be much use right away, so you need to loop through (generally done as you return it from the database) and restructure it for later use. The best method would be to create a new array, indexed by the shift ID with a sub-array of ranks and their totals. Like this: $rankedShifts = array(); while ($row = mysql_fetch_object($result)) { if (!isset($rankedShifts[$row->shiftId])) { $rankedShifts[$row->shiftId] = array(); } $rankedShifts[$row->shiftId][$row->rank] = $row->rankCount; } Within your view you can then cleanly loop through and display the table, displaying a 0 if no rank for a shift is specified: <table> <tr> <td></td> <td>1</td> <td>2</td> <td>3</td> </tr> <?php foreach ($rankedShifts as $shift => $ranks): ?> <tr> <td><?php echo $shift ?></td> <?php for ($i = 1; $i <= 3; $i++): ?> <td> <?php echo (isset($ranks[$i])) ? $ranks[$i] : 0 ?> </td> <?php endfor; ?> </tr> <?php endforeach; ?> </table> Obviously the first row and first column in each subsequent row would need a right border or different background colour to distinguish them from the main data. I haven't tested this by the way so I can't guarantee there isn't a syntax error or two, but the logic is right.
  21. If you're referring to the examples, that's done simply to make them more portable; it's not recommended.
  22. That makes sense, except selecting pairs. Surely if the user ranks each of them 1-6, they've selected them all? Do you mean find which users selected shift patterns 1-3 as rank 1 or 2? Also you won't need 190 queries, you'll just need one. I'm on a train at the moment but when I get to a computer I'll put together a quick example.
  23. After rereading your original post, I think I completely went in the wrong direction with "shifts" - sorry I'm quite hungover Hopefully though, it should still give you a good idea about relational tables, and what approach to take to your own application.
  24. The example table you provided is basically the output that you're after, not the data. You don't store the total number of times a user was on a particular shift, you store a row that says the user was on that shift on this particular date. You then calculate the totals as you query data, with date boundaries and/or additional conditions to select the relevant data. So you would have a shifts table, but in order to define the user and the shift itself without repeating it for every row, you would use two additional tables. Let's assume they're called "shifts" (which defines the shifts), "users" (which obviously defines the users) and "history" (which defines when a user was on a shift). We'll keep the tables minimal to keep it clear: users id | name ---------------- 1 | Adam 2 | Cheeseslice shifts id | time_start | time_end -------------------------- 1 | 00:00 | 06:00 2 | 06:00 | 12:00 3 | 12:00 | 18:00 4 | 18:00 | 00:00 history id | user_id | shift_id | date ------------------------------------ 1 | 1 | 1 | 2012-03-03 2 | 2 | 2 | 2012-03-03 3 | 1 | 1 | 2012-03-04 4 | 2 | 2 | 2012-03-04 As you can see, the history table doesn't store much data, but just links other tables together. These are known as "relational tables", and we can use JOINs within a query to join together the data as we select it. For example, to select all the user and shift data where the user had worked a morning shift on the 3rd March, we could use: select users.name from history join users on (history.user_id = users.id) join shits on (history.shift_id = shifts.id) where history.date = '2012-03-03' and shifts.time_start >= '00:00' and shifts.time_end <= '12:00' (I haven't actually tested that, but it should work.) All you need to do from here, is modify the where conditions to select the data you need, and use the MySQL count() function and group by to get the totals, grouped by each user. Don't worry about putting too much stress on the database either, MySQL can handle a lot more than what you're probably thinking. Just make sure you write the queries as efficiently as possible (post a thread to get it reviewed here if you want a second opinion), and if necessary you can use caching and other techniques to scale the application. Also for generating the graphs you can use PHP, or JavaScript, it's up to you. There's plenty of free libraries out there you can use to generate them though, so you'll probably find that the easiest bit.
  25. getElementsByClassName() is not supported in IE before version 9, so you need to define a manual implementation when it doesn't exist as a back-up.
×
×
  • 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.