Webbutvecklingsdagbok (Webbutveckling, 120 hp)

Permalänk

Källkod till PHP Moment 4 & Labb 3 i Databaser troligen godkänd! [Del 4 av 4]

[DEL 4 AV 4]: Källkod till PHP Moment 4 (skapa mapparna "css", "include" och "class" inuti "include" och kör sedan "install.php" och sedan "index.php"):

p-moment4-new-blogposts.php

<?php include("include/config.php");?> <?php $currentBtnAdmin=2; $currentBtn=7; // Mark current page in <nav> (see c-nav.php) & Moment 4 nav ?> <title><?php if(isLoggedIn()){ echo pageTitle("Moment 4 - " . strval($_SESSION['username']) . " inloggad"); }else { echo pageTitle("Moment 4 - Ej inloggad");}?> </title> <?php include("include/c-header.php");?> <?php include("include/c-nav.php");?> <h2 id="specialh2">Moment 4 - Dataanslutningar med PHP | <?php echo isLoggedIn() ? strval($_SESSION['username']) . " inloggad" : " Ej inloggad" ?></h2> <div class="uppgifts-div" id="special1"> <form action="p-moment4-logout.php" method="POST" id="logoutBtnSection"> <?php // Show success message after succeeding logging in showSessionSuccess('loginSuccess','Du är nu inloggad!'); // Show failure message when trying to logout without using log out button showSessionError('logOutWithoutBtn','Logga ut med Logga ut-knappen!'); ?> <span style="font-size: 0.8rem;"><?php if(isLoggedIn()){ // Show username if logged in echo "Inloggad: " . strval($_SESSION['username']); } else { // Else show info that you are not logged in echo "Ej inloggad"; } ?> </span> <?php // If logged in then show button for log out if(isLoggedIn()){ ?> <input type="submit" name="loginOut" value="Logga ut" id="logoutBtn"> <?php } else { // Otherwise, show links to login or register ?> <a class="backA" style="color: #1bbb85;" href="p-moment4-login.php">Inloggning</a> <a class="backA" style="color: #1bbb85;" href="p-moment4-register.php">Registrera</a> <?php }?> </form> <ul id="nav-ul2"> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(1);?>"> <a href="p-moment4.php">Startsida</a></li> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(2);?>"> <a href="p-moment4-new-blogposts.php">Nya inlägg</a></li> <?php if(isLoggedIn()){ ?> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(3);?>"> <a href="p-moment4-manage-blogposts.php">Hantera inlägg</a> </li> <?php }?> </ul> <?php showSessionError('id-error','Du kan inte visa inget inlägg!');?> <hr> <h3 style="margin-top:10px;">Nya blogginlägg</h3> <?php // Retrieve the two latest published blog posts $currentBlogposts = $DB->getAllBlogPosts(""); // and check if 0 blog posts exist by checking length of array if(count($currentBlogposts) == 0){ // If zero blog posts exist, echo info about that echo showError('Inga blogginlägg finns!'); } // If blogposts do exist, output them with foreach() // substr() is used to only show YYYY-MM-DD HH:MM by removing :SS(seconds) // mb_substr() only shows first 200 characters of each blog post else { foreach($currentBlogposts as $blogpost){ ?> <h4 style="margin-top:20px;"><?= htmlspecialchars($blogpost['blogpost_title'], ENT_QUOTES, 'UTF-8');?></h4> <p style="font-size:0.9rem; font-weight:bold; margin-bottom:5px;"><?= "Postad: " . blogPublishDate($blogpost['blogpost_created']) . $blogpost['blogpost_created_by'];?></p> <p style="font-size:1rem;"><?php // Only cut length of blogpost and add ... when over 200 characters long if(mb_strlen(htmlspecialchars($blogpost['blogpost_text'],ENT_QUOTES, 'UTF-8')) > 200){ echo mb_substr(htmlspecialchars($blogpost['blogpost_text'], ENT_QUOTES, 'UTF-8'),0,200) . "..."; } else { echo htmlspecialchars($blogpost['blogpost_text'], ENT_QUOTES, 'UTF-8');} ?></p> <p style="text-align:right;"> <a class="backA" style="color: #1bbb85;" href="p-moment4-view-blogpost.php?id=<?=$blogpost['id'];?>">Läs mer</a></p> <?php } } ?> <hr> </div> <?php include("include/secret.php")?> <?php include("include/c-footer.php");?>

Dold text

p-moment4-register.php

<?php include("include/config.php"); // WHEN REGISTER SUCCEEDS! // Clicked on Registrera? if(clickedP('register')){ // Check the following first, all must be TRUE if( // Valid Username Length Validate::validUsernameLength($_POST['RegisterUsername']) // Valid Username Type && Validate::validUsernameType($_POST['RegisterUsername']) // Valid Email && Validate::isEmail($_POST['RegisterEmail']) // Both Password Fields are same && Validate::IsTwoSame($_POST['RegisterPass'],$_POST['RegisterPassCheck']) // Both Password Fields are valid && Validate::validPassword($_POST['RegisterPass']) && Validate::validPassword($_POST['RegisterPassCheck']) // Username doesn't already exist && !$DB->userAlreadyExist($_POST['RegisterUsername']) // Email doesn't already exist && !$DB->emailAlreadyExist($_POST['RegisterEmail']) ) // Iff All of Above is TRUE then and only then... { // Register new user in database if($DB->registerUser($_POST['RegisterUsername'],$_POST['RegisterEmail'],$_POST['RegisterPass'])){ // Set Session so user is taken to login page after registration $_SESSION['registerSuccess'] = 1;}}} // Check if user registered and then send them to login page if(isset($_SESSION['registerSuccess'])){ header("Location: p-moment4-login.php");}?> <?php $currentBtn=7; // Mark current page in <nav> (see c-nav.php)?> <title><?= pageTitle("Moment 4 - Registrera dig först!"); ?></title> <?php include("include/c-header.php");?> <?php include("include/c-nav.php");?> <h2 id="specialh2">Moment 4 - Dataanslutningar med PHP | Registrering</h2> <div class="uppgifts-div" id="special1"> <h3 style="text-align: left;">Registrera dig</h3> <form id="form3" action="p-moment4-register.php" method="POST"> <div class="login-rows2"> <div class="login-parts"> <input id="dataRegisterName" class="login-fields fieldListen" type="text" name="RegisterUsername" value="<?php echo previousFieldvalueP('register','RegisterUsername'); ?>"> <label for="dataRegisterName">Användarnamn</label> <?php // Demanding to fill out empty field fillOutEmptyFieldP("register","RegisterUsername","Ange ett användarnamn"); // Clicked on Registrera? if(clickedP('register')){ // If string length of Username is not zero but is not at least 6 characters long or more than 21 characters if(strlen($_POST['RegisterUsername']) != 0 && !Validate::validUsernameLength($_POST['RegisterUsername'])){ // Then show error on how to fix echo showError("Användarnamn ska vara mellan 6 och 21 tecken långt."); } // If string of username is not zero but contains forbidden characters if(strlen($_POST['RegisterUsername']) != 0 && !Validate::validUsernameType($_POST['RegisterUsername'])){ // Then show error on how to fix echo showError("Användarnamn får endast innehålla små bokstäver av a-z."); } // If Username is already in use in database if(strlen($_POST['RegisterUsername']) != 0 && $DB->userAlreadyExist($_POST['RegisterUsername'])){ // Then show error on how to fix echo showError("Användarnamnet används redan. Välj ett annat!"); } if(Validate::validUsernameLength($_POST['RegisterUsername']) && Validate::validUsernameType($_POST['RegisterUsername']) && !$DB->userAlreadyExist($_POST['RegisterUsername'])){ echo showSuccess("Användarnamn är ledigt och giltigt."); } } ?> </div> <div class="login-parts"> <input id="dataRegisterEmail" class="login-fields fieldListen" type="text" name="RegisterEmail" value="<?php echo previousFieldvalueP('register','RegisterEmail'); ?>"> <label for="dataRegisterEmail">E-post</label> <?php // Demanding to fill out empty field fillOutEmptyFieldP("register","RegisterEmail","Ange en giltig e-postadress först"); // Clicked on Registrera? if(clickedP('register')){ // If string length of email is not 0 but is still invalid if(strlen($_POST['RegisterEmail']) != 0 && !Validate::isEmail($_POST['RegisterEmail'])){ // Then show error on how to fix echo showError("E-post ska vara i stil med: exempel@domän.se"); } // If Email is already in use in database if(strlen($_POST['RegisterEmail']) != 0 && $DB->emailAlreadyExist($_POST['RegisterEmail'])){ // Then show error on how to fix echo showError("E-postadressen används redan. Ange en annan!"); } if(strlen($_POST['RegisterEmail']) != 0 && Validate::isEmail($_POST['RegisterEmail']) && !$DB->emailAlreadyExist($_POST['RegisterEmail'])){ echo showSuccess("E-postadressen är ledig och giltig."); } } ?> </div> <div class="login-parts"> <input id="dataLoginPass" class="login-fields fieldListen" type="password" name="RegisterPass"> <label for="dataLoginPass">Lösenord</label> <?php // Demanding to fill out empty field fillOutEmptyFieldP("register","RegisterPass","Ange ett giltigt lösenord först"); // Clicked on Registrera? if(clickedP('register')){ // If string length of Password (first field) is not zero but still invalid if(strlen($_POST['RegisterPass']) != 0 && !Validate::validPassword($_POST['RegisterPass'])){ // Then show error on how to fix echo showError("Lösenord ska vara mellan 12-24 tecken långt.<br>- Minst en siffra<br>- Minst en stor bokstav<br>- Minst en liten bokstav<br>- Minst ett specialtecken<br>- A-Z, 0-9 och specialtecknen _?!- får användas!"); } } ?> </div> <div class="login-parts"> <input id="dataRegisterPassCheck" class="login-fields fieldListen" type="password" name="RegisterPassCheck"> <label for="dataRegisterPassCheck">Upprepa lösenord</label> <?php // Demanding to fill out empty field fillOutEmptyFieldP("register","RegisterPassCheck","Ange ett upprepat giltigt lösenord först"); // Clicked on Registrera? if(clickedP('register')){ // If both Passwords fields are not empty then... if($_POST['RegisterPass'] != "" && $_POST['RegisterPassCheck'] != ""){ // ... check if both Password Fields do NOT contain same values... if(!Validate::IsTwoSame($_POST['RegisterPass'],$_POST['RegisterPassCheck'])){ // And Then show error on how to fix echo showError("Både lösenordsfältet och upprepning ska vara lika."); }} else if ($_POST['RegisterPassCheck'] != ""){ echo showError("Mata in samma giltiga lösenord här som ovan."); } } ?> </div> <div style="display: flex; flex-direction: row; justify-content: space-between; width: 100%;"> <input type="submit" name="register" value="Registrera" id="registerBtn"> <p><a style="display:inline-block; line-height: 3;" class="backA" href="p-moment4.php">Logga in</a></p> </div> </div> <?php ?> </form> </div> <?php include("include/secret.php")?> <?php include("include/c-footer.php");?>

Dold text

p-moment4-view-blogpost.php

<?php include("include/config.php");?> <?php $currentBtnAdmin=0; $currentBtn=7; // Mark current page in <nav> (see c-nav.php) // Check if logged in, otherwise redirect to login page // Trying to access view-blogpost without an id if(!isset($_GET['id'])){ $_SESSION['id-error'] = 1; // Set error message header("Location: p-moment4.php"); // to be shown on admin page } ?> <title><?= pageTitle("Moment 4 - " . strval($_SESSION['username']) . " inloggad"); ?></title> <?php include("include/c-header.php");?> <?php include("include/c-nav.php");?> <h2 id="specialh2">Moment 4 - Dataanslutningar med PHP | <?php echo isLoggedIn() ? strval($_SESSION['username']) . " inloggad" : " Ej inloggad" ?></h2> <div class="uppgifts-div" id="special1"> <form action="p-moment4-logout.php" method="POST" id="logoutBtnSection"> <?php showSessionSuccess('loginSuccess','Du är nu inloggad!'); showSessionError('logOutWithoutBtn','Logga ut med Logga ut-knappen!'); ?> <span style="font-size: 0.8rem;"><?php if(isLoggedin()){ echo "Inloggad: " . strval($_SESSION['username']); } else { echo "Ej inloggad"; } ?> </span> <?php if(isLoggedIn()){ ?> <input type="submit" name="loginOut" value="Logga ut" id="logoutBtn"> <?php } else { ?> <a class="backA" style="color: #1bbb85;" href="p-moment4-login.php">Inloggning</a> <a class="backA" style="color: #1bbb85;" href="p-moment4-register.php">Registrera</a> <?php }?> </form> <ul id="nav-ul2"> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(1);?>"> <a href="p-moment4.php">Startsida</a></li> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(2);?>"> <a href="p-moment4-new-blogposts.php">Nya inlägg</a></li> <?php if(isLoggedin()){ ?> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(3);?>"> <a href="p-moment4-manage-blogposts.php">Hantera inlägg</a> </li> <?php }?> </ul> <?php showSessionError('id-error','Du kan inte visa inget inlägg!');?> <hr> <?php // Retrieve blog post by id $currentBlogpost = $DB->getBlogPostById($_GET['id'],""); // and check if 0 blog posts exist by checking length of array if(count($currentBlogpost) == 0){ // If zero blog posts exist, echo info about that echo "<p>Blogginlägget finns inte!</p>"; } // If blogposts do exist, output them with foreach() // substr() is used to only show YYYY-MM-DD HH:MM by removing :SS(seconds) // CSS class "blogpost-feature" uses line-clamp else { foreach($currentBlogpost as $blogpost){ ?> <h3 style="margin-top:20px;"><?= htmlspecialchars($blogpost['blogpost_title'], ENT_QUOTES, 'UTF-8');?></h3> <p style="font-size:0.9rem; font-weight:bold; margin-bottom:5px;"><?= "Postad: " . blogPublishDate($blogpost['blogpost_created']) . $blogpost['blogpost_created_by'];?></p> <p style="font-size:1rem;"><?= htmlspecialchars($blogpost['blogpost_text'], ENT_QUOTES, 'UTF-8') ?></p> <p style="text-align:right;"> <?php // Only show the ability to edit a blogpost if allow editing a blogpost if correct user is logged in! Thus checking with blogposted_created_by from database! if(isset($_SESSION['username'])) { if($_SESSION['username'] === $blogpost['blogpost_created_by']){?> <a class="backA" style="color: #1bbb85;" href="p-moment4-edit-blogpost.php?editid=<?=$blogpost['id'];?>">Ändra inlägg</a></p> <?php }} } } ?> <hr> </div> <?php include("include/secret.php")?> <?php include("include/c-footer.php");?>

Dold text

p-moment4.php

<?php include("include/config.php");?> <?php $currentBtnAdmin=1; $currentBtn=7; // Mark current page in <nav> (see c-nav.php) & Moment 4 nav ?> <title><?php if(isLoggedIn()){ echo pageTitle("Moment 4 - " . strval($_SESSION['username']) . " inloggad"); }else { echo pageTitle("Moment 4 - Ej inloggad");}?> </title> <?php include("include/c-header.php");?> <?php include("include/c-nav.php");?> <h2 id="specialh2">Moment 4 - Dataanslutningar med PHP | <?php echo isLoggedIn() ? strval($_SESSION['username']) . " inloggad" : " Ej inloggad" ?></h2> <div class="uppgifts-div" id="special1"> <form action="p-moment4-logout.php" method="POST" id="logoutBtnSection"> <?php showSessionSuccess('loginSuccess','Du är nu inloggad!'); showSessionError('logOutWithoutBtn','Logga ut med Logga ut-knappen!'); ?> <span style="font-size: 0.8rem;"><?php if(isLoggedin()){ // Show logged in as echo "Inloggad: " . strval($_SESSION['username']); } else { // Or not logged in echo "Ej inloggad"; } ?> </span> <?php // If logged in then show button for log out if(isLoggedIn()){ ?> <input type="submit" name="loginOut" value="Logga ut" id="logoutBtn"> <?php } else { // Otherwise, show links to login or register ?> <a class="backA" style="color: #1bbb85;" href="p-moment4-login.php">Inloggning</a> <a class="backA" style="color: #1bbb85;" href="p-moment4-register.php">Registrera</a> <?php }?> </form> <ul id="nav-ul2"> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(1);?>"> <a href="p-moment4.php">Startsida</a></li> <li class="menu-btn2 <?php echo setCurrentBtnAdmin(2);?>"> <a href="p-moment4-new-blogposts.php">Nya inlägg</a></li> <?php if(isLoggedin()){ ?> <li class="menu-btn2 <?php // This button is only shown when logged in as it is administrative echo setCurrentBtnAdmin(3);?>"> <a href="p-moment4-manage-blogposts.php">Hantera inlägg</a> </li> <?php }?> </ul> <?php showSessionError('id-error','Du kan inte visa inget inlägg!');?> <hr> <h3 style="margin-top:10px;">De 2 senaste blogginläggen</h3> <?php // Retrieve the two latest published blog posts $currentBlogposts = $DB->get2LatestBlogPosts(""); // and check if 0 blog posts exist by checking length of array if(count($currentBlogposts) == 0){ // If zero blog posts exist, echo info about that echo showError('Inga blogginlägg finns!'); } // If blogposts do exist, output them with foreach() // substr() is used to only show YYYY-MM-DD HH:MM by removing :SS(seconds) // mb_substr() only shows first 200 characters of each blog post else { foreach($currentBlogposts as $blogpost){ ?> <h4 style="margin-top:20px;"><?= htmlspecialchars($blogpost['blogpost_title'], ENT_QUOTES, 'UTF-8');?></h4> <p style="font-size:0.9rem; font-weight:bold; margin-bottom:5px;"><?= "Postad: " . blogPublishDate($blogpost['blogpost_created']) . $blogpost['blogpost_created_by'];?></p> <p style="font-size:1rem;"><?php // Only cut length of blogpost and add "..." when over 200 characters long if(mb_strlen(htmlspecialchars($blogpost['blogpost_text'], ENT_QUOTES, 'UTF-8')) > 200){ echo mb_substr(htmlspecialchars($blogpost['blogpost_text'], ENT_QUOTES, 'UTF-8'),0,200) . "..."; } else { echo htmlspecialchars($blogpost['blogpost_text'], ENT_QUOTES, 'UTF-8');} ?></p> <p style="text-align:right;"> <a class="backA" style="color: #1bbb85;" href="p-moment4-view-blogpost.php?id=<?=$blogpost['id'];?>">Läs mer</a></p> <?php } } ?> <hr> </div> <?php include("include/secret.php")?> <?php include("include/c-footer.php");?>

Dold text

På återseende!

Mvh,
WKL.

Permalänk
Medlem

Ett generellt tips är att kod aldrig är färdig. Den kanske är bordlagd en stund för att man prioriterar annat eller byter projekt. Så den versionen du lagt upp här är bara ett axplock i tiden och inte så relevant. Mycket viktigare är historiken och ändringen i tid. Vill du se hur en viss rad blev till så ska man kunna kolla på git, vad ändrades samtidigt som denna, hur tänkte den personen, hur har den sett ut tidigare…

Lägg upp detta på github istället och commita minst flera gånger per dag så du kan se vad som händer över tid

Permalänk
Skrivet av medbor:

Ett generellt tips är att kod aldrig är färdig. Den kanske är bordlagd en stund för att man prioriterar annat eller byter projekt. Så den versionen du lagt upp här är bara ett axplock i tiden och inte så relevant. Mycket viktigare är historiken och ändringen i tid. Vill du se hur en viss rad blev till så ska man kunna kolla på git, vad ändrades samtidigt som denna, hur tänkte den personen, hur har den sett ut tidigare…

Lägg upp detta på github istället och commita minst flera gånger per dag så du kan se vad som händer över tid

I Webbutvecklingsprogrammet sedan PHP-kursen började (Webbutveckling II) så har vi lärt oss använda Git och GitHub och commitar till lärardelade GitHub Classrooms. Detta kommer vi att göra resten av utbildningen från och med den kursen.

Jag vill inte röja mitt GitHub-konto ännu bara!

Mvh,
WKL.

Permalänk

Moment 4 i Webbutveckling II nu tillgänglig på WKL:s GitHub! 😲

På populär begäran så finns Moment 4 nu i sin slutversion (den underhålls ej längre mao):
https://github.com/WebbkodsLarlingen/WKL_VT2023_DT093G-Moment...

Denna version är inte samma som den pågående projektversionen (vilket är en förbättrad och utökad version av Moment 4) vilket i sin tur släpps någon gång i mitten på mars i år.

Mvh,
WKL.

Permalänk

En halvny identitet - en komplett webbupplevelse snart nära dig om drygt en vecka!

Den slutgiltiga webbplatsen kommer att ha mer eller mindre 0 animeringar än överraskningen på startsidan. Ja, det blir fort tröttsamt för den som ej lagt ned tid på CSS-kodandet och man måste därför ofta "kill your own darlings" så att säga!

Mvh,
WKL.

Permalänk

E-postaktivering fungerar & Session_start() förvirrar mig!

Jag har nu lyckats implementera e-postaktivering där du aktiverar ditt registrerade konto med en aktiveringsnyckel:

Fråga till den som vet mer: Vad som förvirrar mig är hur session_start() fungerar. Varje php-sida börjar med att inkludera config.php-filen där session_start() alltid körs innan någon HTML-kod börjar renderas ut. Detta betyder då att alla övriga php-filer som inkluderar config.php bör få ta del av session_start().

Inuti config.php inkluderas en annan php med flitigt använda funktioner så är config-filen inte inkluderad så kommer webbsidan ifråga att krascha direkt på grund av försök att anropa icke-deklarerade funktioner och så vidare.

Så det är inte som om att jag skulle ha glömt att inkludera config-filen här och var. Vad jag tror det verkar vara är att session_start() verkar inte kunna "komma ihåg" lagrade $_SESSION['variabler']; mellan sidor när header("Location: sida.php"); används om man inte besökt sidan innan detta.

Exempelvis hamnar man på inloggningssidan efter utloggning men innan man ens kan logga ut så måste man först ha loggat in. Då har man alltså besökt logga in-sidan innan man loggade ut (vilket är en egen php-fil som bara sätter $_SESSION['variabel']; och sedan använder header("Location: inloggningssida.php");.

På inloggningsssidan har jag en funktion som kollar och skriver ut diverse fel- och rättmeddelanden och sedan unsettar $_SESSION['variabler'];. Detta fungerade inte med aktiveringen, det vill säga, du fick inget rättmeddelande om att du nu kan logga in efter att du har lyckats aktivera konto.

Det fungerar dock nu när jag satt en session_start() precis efter jag inkluderat config.php (som redan kört session_start()) och det är så förvirrande.

Här är koden:

1 // Try activating account with the class 'Activate' 2 if($Activate->activateAccount($user,$email,$key)){ 3 // Prepare success message and send to login page 4 $_SESSION['registerSuccessB'] = 1; 5 header('Location: login.php'); 6 // Otherwise Prepare fail message to show instead 7 } else { $_SESSION['registerFail'] = 1;}

Rad 7 förbereder att ett felmeddelande kan visas på samma sida utan problem med exakt samma funktion som också visar när något gick rätt. Jag provade först en session_start() inuti if-satsen innan rad 4 men det fungerade inte. utan jag behövde ha en session_start() direkt före denna if-sats för att det hela skulle fungera.

Detta är en av många "små detaljer" som jag inte snappat upp ännu inom PHP. Annan sak som förvirrar mig är att veta klassinstansers livscykler innan de får för sig att __destruct(); innan jag är färdiga med dem på en och samma php-sida. Hur vet en klass att den inte ska användas längre ned på sidan innan den får för sig att __destructa? 🤔

Exempelvis har det krånglat med klasser som ansluter till relationsdatabas via MySQLI-objektet vilket ibland fått för sig att stänga sin anslutning fast jag ville använda samma objekt/anslutning på flera ställen på samma php-sida.

Nåja, sistnämnda har jag redan mejlat lärarna om så!

Mvh,
WKL.

Permalänk

"Nostalgitrippen" (PHP-Projekt) släpps i Early Access!

"Nostalgitrippen" (PHP-Projekt) släpps i Early Access! (allt klart förutom chattfunktion)
Du kan registrera dig (mejlaktivering med aktiveringsnyckel obligatoriskt) här: Nostalgitrippen Early Access

Funktioner:
- Begränsad RichEditor av blogginlägg (kan ju ses som "posts" också eftersom det hamnar i ett flöde på startsidan)
- Ladda upp en bild vid varje blogginlägg
- Ta bort/ändra inlägg eller bara dess bild
- Kommentera inlägg
- Radera konto helt
- Se topp 5 mest lästa / kommenterade inlägg
- Se alla registrerade och statistik över dem
- Trångt mobilutseende i all ära!

Imorgon blir jag färdig med chattfunktionen då inlämningsdatum för både projektrapport + projektuppgiften är söndag kl.23:59.

På återseende!

Mvh,
WKL.

P.S. Jag lämnade in Databasprojektet för cirka två dagar sedan och troligen får jag kompletteringskrav på grund av superpetig och/eller opedagogisk lärare.
---------
✔️(B) HT2022 DT057G Datateknik GR (A), Webbutveckling I, 7,5 hp (distans)
✔️(A) HT2022 DT084G Datateknik GR (A), Introduktion till programmering i JavaScript, 7,5 hp (distans)
✔️(A) HT2022 DT068G Datateknik GR (B), Webbanvändbarhet, 7,5 hp (distans)
✔️(B) HT2022 DT200G Datateknik GR (A), Grafisk teknik för webb, 7,5 hp (distans)
🚧(Pågående) VT2023 DT093G Datateknik GR (B), Webbutveckling II, 7,5 hp (distans)
🚧(Inväntar betyg/kompletteringskrav) VT2023 DT003G Datateknik GR (A), Databaser, 7,5 hp (distans)

Permalänk

Databasers teckenkodning gav mig nästan magsjuka!

Databasers teckenkodning gav mig nästan magsjuka!
Jag är nu officiellt färdig med Webbutveckling II-projektuppgiftens webbplats:
http://studenter.miun.se/~maka2207/writeable/php-projekt/

Det finns en trevlig chatt där det går att skriva efter inloggning (dock kan man inte se vilka som är online, men det går att gå in på deras profil och se antal inlägg, kommentarer & chattmeddelanden).

Den uppdaterar chatten direkt när du skriver eller var 15:e sekund (så jag inte blir bannlyst från student-DB:n pga. för många DB-anrop! )

Det som återstår nu är Projektrapportskrivandet. Deadline imorgon kl.23:59 svensk tid!

Nu kör vi! 🫡

Mvh,
WKL.