02. september 2006 - 02:51Der er
9 kommentarer og 1 løsning
Send en påmindelse
Hej,
Jeg har brug for lidt hjælp og ideer til hvordan nedenstående kan forbedres.
Det skal bruges til at sende en påmindelse til en bruger hvis hun/han ikke har været logget ind på sin profil endnu.
Brugeren har 14 dage til at logge ind og derefter skal hun/han modtage 3 påmindelser med 14 dages mellemrum. Har hun/han endnu ikke logget ind, slettes vedkommende.
Jeg tror at nedenstående virker - Jeg vil bare gerne vide om det kan gøres bedre og evt. hjælpes lidt på vej.
$query = mysql_query("SELECT id, name, email FROM profiles WHERE (TO_DAYS(now()) - TO_DAYS(inserted)) > 14") or die(mysql_error());
if(mysql_num_rows($query) > 0) { while($row = mysql_fetch_assoc($query)) { $output .= "Der er en profil der ikke har brugt sin profil.<br>\n";
$queryInner = mysql_query("SELECT COUNT(id) AS total FROM profiles_reminders WHERE profiles = '" . $row["id"] . "'");
if($total > 0) { if($total <= 3) { $output .= "Profil har modtaget 3 eller mindre påmindelser.<br>\n";
$queryInnerInner = mysql_query("SELECT UNIX_TIMESTAMP(inserted) FROM profiles_reminders WHERE profiles = '" . $row["id"] . "' ORDER BY id DESC LIMIT 0, 1");
if((time() - $inserted) >= 1209600) { $output .= "Det er mere end 14 dage siden profilen sidst fik en påmindelse.</br>\n"; } }
mysql_free_result($queryInnerInner); } else { $output .= "Profilen har modtaget 3 påmindelser og skal derfor slettes.<br>\n"; } } else { $output .= "Profilen har endnu ikke modtaget en påmindelse.<br>\n"; } }
De outputs jeg har lavet er for at finde ud af hvor i koden vedkommende bruger hører til. Outputs er selvfølgelig noget der er i stedet for nogle aktioner, der skal udføres. Aktionerne har jeg ikke brug for hjælp til. :)
De 2 tabeller ser sådan ud:
CREATE TABLE `profiles` ( `id` int(11) NOT NULL auto_increment, `inserted` datetime NOT NULL, `last_login` datetime NOT NULL default '0000-00-00 00:00:00', `ip` varchar(255) collate latin1_danish_ci NOT NULL, `username` varbinary(255) NOT NULL, `email` varchar(255) collate latin1_danish_ci NOT NULL, `password` varbinary(255) NOT NULL, `name` varchar(255) collate latin1_danish_ci NOT NULL, `birthday` date NOT NULL default '0000-00-00', `children` int(11) default NULL, `region` enum('Bornholms Regionskommune','Frederiksborg Amt','Fyns Amt','Københavns Amt','Nordjyllands Amt','Ribe Amt','Ringkjøbing Amt','Roskilde Amt','Storstrøms Amt','Sønderjyllands Amt','Vejle Amt','Vestsjællands Amt','Viborg Amt','Århus Amt') collate latin1_danish_ci NOT NULL, `signature` varchar(255) collate latin1_danish_ci default NULL, `profile` text collate latin1_danish_ci, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_danish_ci;
CREATE TABLE `profiles_reminders` ( `id` int(11) NOT NULL auto_increment, `profiles` int(11) NOT NULL, `inserted` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_danish_ci;
1) Din indledende SELECT udtrækker alle profiler ... også selv om de har været logget ind. Dette betyder at samtlige brugere vil få remindere uanset om de har være logget på eller ej:
Ret til:
$query = mysql_query("SELECT id, name, email FROM profiles WHERE TO_DAYS(now())-TO_DAYS(inserted)>14 AND last_login = '0000-00-00 00:00:00'") or die(mysql_error());
(Bør der forresten ikke være en tilsvarende mekanisme som rydder op i profiler som ikke har været aktive i lang tid ... f.eks. i et års tid?)
2) Så vidt jeg kan bedømme, kan du slå dine to SQL-sætninger sammen til en:
SELECT p.id, p.name, p.email, count(pr.profiles) AS antalReminders, max(pr.inserted) AS lastReminder FROM profiles AS p LEFT JOIN profiles_reminders AS pr ON p.id=pr.profiles WHERE TO_DAYS(now())-TO_DAYS(p.inserted)>14 AND p.last_login = '0000-00-00 00:00:00' GROUP BY pr.profiles
3) Du skal nok overveje om der helt automatisk skal udsendes mails og slettes profiler indtil at det er 100% gennemtestet at din kode virker som den skal.
4) Din:
if(mysql_num_rows($query) > 0)
- tjener intet reelt formål. Den kan fjernes.
5) Når du søger på talfelter skal der ikke '-tegn rundt om værdierne:
$queryInner = mysql_query("SELECT COUNT(id) AS total FROM profiles_reminders WHERE profiles = '" . $row["id"]) . "'";
- ændres til:
$queryInner = mysql_query("SELECT COUNT(id) AS total FROM profiles_reminders WHERE profiles = " . $row["id"]);
Mange tak for din hjælp - Fedt at du gad tage dig tid. :)
1: Jeg fandt selv frem til dette efter jeg havde postet indlæggene. :) Jeg har også tænkt på at brugeren skal modtage en påmindelse hvis han har været inaktiv, men nu ville jeg lige ha' gjort det her færdig.
2: Jeg havde selv tænkt på at slå det sammen, men det blev for uoverskueligt for mig.
3: Rigtig god ide. Måske jeg skulle nøjes med at indsætte i profiles_reminders tabellen til at starte med.
4: Jeg fjerner if sætningen.
5: Jeg har gjort det til en vane at sætte apostrofer om, da jeg jo også behandler brugerinputs og derfor gerne vil undgå at forespørgslerne ødelægges. Men jeg fjerner apostroferne. :)
Jeg takker for din ros og beder dig om at smide et svar.
Ad 2) Afprøv den først i en testdatabase, men nogle passende testdata. F.eks. med phpmyadmin hvis du har adgang til dette.
Ad 5) Det er SQL-standarden at talfelter er uden '-tegn, og tekst-felter er med. MySQL kan vist godt selv finde ud af det, hvis man alligevel bruger '-tegn i et talfelt.
Imidlertid har det ikke rigtigt noget at gøre med at det er brugerinput og at det kan blive ødelagt uden. Det sikre det i hvert fald ikke i mod. Men det er jo heller ikke brugerinput i dette tilfælde :^)
2: Jeg tester på min lokale server for ikke at generer online brugere. :)
5: Så lærte jeg også noget i dag.
Jeg har forresten lidt problemer:
$query = mysql_query("SELECT a.id, a.name, a.email, count(b.profiles) AS total_reminders FROM profiles AS a LEFT JOIN profiles_reminders AS b ON a.id = b.profiles WHERE TO_DAYS(now()) - TO_DAYS(a.inserted) > 14 AND TO_DAYS(now()) - TO_DAYS(b.inserted) > 14 AND a.last_login = '0000-00-00 00:00:00' GROUP BY b.profiles") or die(mysql_error());
while($row = mysql_fetch_assoc($query)) { ##### PROFILE HAS RECEIVED LESS THAN 3 REMINDERS #####
if($row["total_reminders"] < 3) { mysql_query("INSERT INTO profiles_reminders (profiles, inserted) VALUES (" . $row["id"] . ", now())") or die(mysql_error()); } }
mysql_free_result($query);
Tager denne query ikke alle de brugere med id'et eller tager den en tilfældig fra profiles_reminders?
Det var skam med vilje at jeg havde både count() og max() med. Netop for dels at vide hvor mange påmindelser der var sendt ud til den pågældende, og dels for at vide hvornår den seneste var udsendt. :^)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.