Tällainen varauskalenteri. Käyttää mysql:ää tiedon tallentamiseen, vaikkei luultavasti sen ominaisuuksia täysin hyväkseen käytäkään. Tämä on lojunut jonkinaikaa kovalevyllä keskeneräisenä, joten jos koodista löytyy jotain kikkailua, niin ilmoitelkaa...
Taulu:
CREATE TABLE `varaukset` ( `aloitus` int(20) default NULL, `lopetus` int(20) default NULL, `brief` varchar(30) NOT NULL default '', `id` int(10) NOT NULL auto_increment, PRIMARY KEY (`id`) );
Testiversio löytyy osoitteesta http://www.zuronet.org/test/varauskalenteri/
<?php $start = 800; // Kellonaika, josta aloitetaan $stop = 2230; // Kellonaika, johon lopetetan $server = "localhost"; // Palvelin $database = ""; // Tietokanta $table = "varaukset"; // Taulukko $pass = ""; // Salasana $user = ""; // Tunnus // Asetetaan muutama muuttuja $http = $_SERVER['PHP_SELF']; $week_days = array("Ma","Ti","Ke","To","Pe","La","Su"); $result = array(); $cycle = array(); Function search_between($val, $arr) { $rtn = false; foreach($arr as $array) { if($array['aloitus'] <= $val && $array['lopetus'] > $val) // Jos aika on varattu, palautetaan varaus { $rtn = $array; break; } } return $rtn; } Function get_last_monday($day,$month,$year) { $timestamp = mktime(0,0,0,$month,$day,$year); While(date('w',$timestamp) != 1) // Jos päivä ei ole maanantai, poistetaan päivä timestampista { $timestamp -= 60*60*24; } return $timestamp; } // Muuttujat... $day = $_GET['day']; $month = $_GET['month']; $year = $_GET['year']; if(empty($_GET['day'])) $day = date('d'); if(empty($_GET['month'])) $month = date('m'); if(empty($_GET['year'])) $year = date('Y'); // Edellinen- ja seuraava viikko-nappeihin arvot $last_monday = get_last_monday($day,$month,$year); $forward['day'] = date("d", ($last_monday+(8*24*3600))); $forward['month'] = date("m", ($last_monday+(8*24*3600))); $forward['year'] = date("Y", ($last_monday+(8*24*3600))); $back['day'] = date("d", ($last_monday-(6*24*3600))); $back['month'] = date("m", ($last_monday-(6*24*3600))); $back['year'] = date("Y", ($last_monday-(6*24*3600))); // Yhdistetään $yhteys = mysql_connect($server, $user, $pass) or die("Virhe kytkettäessä tietokantaan!"); mysql_select_db($database,$yhteys) or die("Virhe valittaessa tietokantaa!"); if(!empty($_GET['id']) && $_GET['act'] == "poista") // Varauksen poistaminen { // Toimenpide $query = "DELETE FROM ".$table." WHERE id = '".mysql_escape_string($_GET['id'])."'"; mysql_query($query, $yhteys) or die('Virhe suoritettaessa komentoa<br>'.$query); mysql_close($yhteys); // Päivitetään sivu siirtämällä käyttäjä. header("Location: ".$http); } elseif(isset($_POST['confirm'])) // Varauksen lisääminen, tarkastetaan onko nappia painetty { // Virheilmoitukset if (empty($_POST['brief'])) die("Virhe! Et määrittänyt kuvausta!"); if ($_POST['day'] > 31) die("Virhe! Montakos päivää voi olla kuukaudessa..?"); if ($_POST['month'] > 12) die("Virhe! Montakos kuukautta olikaan vuodessa?"); if ($_POST['year'] < 2003) die("Virhe! Onko varaus kenties menneisyydessä?"); if ($_POST['hour'] > 24) die("Virhe! Montakos tuntia päivässä olikaan?"); if ($_POST['minute'] > 60) die("Virhe! Montakos niitä minuutteja olikaan?"); if ($_POST['hour2'] > 24) die("Virhe! Montakos tuntia päivässä olikaan?"); if ($_POST['minute2'] > 60) die("Virhe! Montakos niitä minuutteja olikaan?"); if ($_POST['hour'] > $_POST['hour2']) die("Virhe! Aloitustunti on suurempi kuin lopetustunti!"); // Tiedot $start_date = mktime($_POST['hour'], $_POST['minute'], 0, $_POST['month'], $_POST['day'], $_POST['year']); $end_date = mktime($_POST['hour2'], $_POST['minute2'], 0, $_POST['month'], $_POST['day'], $_POST['year']); $brief = mysql_escape_string(htmlspecialchars($_POST['brief'])); // Täytyy tarkistaa onko aika jo varattu $query = "SELECT * FROM ".$table." WHERE aloitus >= ".mktime(0, 0, 0, $_POST['month'], $_POST['day'], $_POST['year'])." AND lopetus <= ".mktime(23, 59, 59, $_POST['month'], $_POST['day'], $_POST['year']); $haku = mysql_query($query, $yhteys) or die('Virhe suoritettaessa komentoa<br>'.$query); $num = mysql_num_rows($haku); while($res = mysql_fetch_array($haku, MYSQL_ASSOC)) $result[] = $res; // tutkitaan, onko varauksen alku yhdenkään varauksen sisällä $gofor = ($end_date-$start_date)/60/30; for($r=0; $r < $gofor; $r++) if(search_between(($start_date+$r*1800), $result) != false) die("Virhe! Aika on jo varattu!"); // Katsotaan, onko varauksen loppu toisen varauksen sisällä if (search_between(($end_date-1), $result) != false) die("Virhe! Aika on jo varattu!"); // Lisätään tauluun $query = "INSERT INTO ".$table."(aloitus, lopetus, brief) VALUES (".$start_date.", ".$end_date.", '".$brief."')"; mysql_query($query, $yhteys) or die('Virhe suoritettaessa komentoa<br>'.$query); mysql_close($yhteys); // Päivitetään sivu siirtämällä käyttäjä. header("Location: ".$http); } // Haetaan viikon tiedot $result-array-muuttujaan $query = "SELECT * FROM ".$table." WHERE aloitus >= ".$last_monday." AND lopetus <= ".($last_monday+(7*60*60*24)); $haku = mysql_query($query, $yhteys) or die('Virhe suoritettaessa komentoa<br>'.$query); while($res = @mysql_fetch_array($haku, MYSQL_ASSOC)) $result[] = $res; mysql_close($yhteys); // Aloitetaan varaustaulukon teko... $contents .= ' <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Kalenteri v0.1</title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <style type="text/css"> <!-- .cornercell { text-align: center; border: 1px solid black; height: 20px; background-color: #DCDCDC; } .daycell { text-align: center; width: 12%; height: 20px; border-bottom: 1px solid black; border-right: 1px solid black; border-top: 1px solid black; background-color: #DCDCDC; } .timecell { text-align: center; border-bottom: 1px solid black; border-right: 1px solid black; border-left: 1px solid black; background-color: #DCDCDC; width: 11%; height: 20px; } .concell { border-right: 1px solid black; border-bottom: 1px solid black; background-color: #F2F2F2; text-align: center; } .setcell { border-right: 1px solid black; border-bottom: 1px solid black; background-color: #EFEFEF; text-align: center; } --> </style> </head> <body> <table cellpadding="6" border="0" width="100%"> <tr> <td align="left"> Tarkasteltava aikaväli: '.date("d.m.Y", $last_monday).' - '.date("d.m.Y", ($last_monday+6*24*3600)).'<br> <a href="'.$http.'?day='.$back['day'].'&month='.$back['month'].'&year='.$back['year'].'">[Edellinen viikko]</a> <a href="'.$http.'?day='.date('d').'&month='.date('m').'&year='.date('Y').'">[Tämä viikko]</a> <a href="'.$http.'?day='.$forward['day'].'&month='.$forward['month'].'&year='.$forward['year'].'">[Seuraava viikko]</a><br> </td> <td align="right"> <form method="get" action="'.$http.'" style="margin: 0px;"> Hae päivä: <input type="text" size="2" value="'.$day.'" maxlength="2" name="day"> <b>.</b> <input type="text" size="2" value="'.$month.'" maxlength="2" name="month"> <b>.</b> <input type="text" size="4" value="'.$year.'" maxlength="4" name="year"> <input type="submit" value=">>"> </form> </td> </tr> </table> <table cellspacing="0" cellpadding="1" width="100%"> <tr> <td class="cornercell"> Aika </td> '; for($f=0;$f<7;$f++) { $contents .= " <td class=\"daycell\"> ".$week_days[$f]." ".date("d.m.Y",$last_monday+($f*60*60*24))." </td>\n"; $set[$g] = 0; } $contents .= " </tr>\n"; for($i=$start; $i<$stop; $i=$i+50) // Aletaan luomaan tunteja ylhäältä alaspäin. { $contents .= " <tr>\n"; // Seuraava pätkä näyttää ajan vasemmassa palkissa.... $first_num = substr($i, 0, -2); if(substr($i, -2) == 50) $last_num = '30'; else $last_num = '00'; if($last_num == 30) { $sec_last_num = '00'; $sec_first_num = $first_num+1; } else { $sec_last_num = '30'; $sec_first_num = $first_num; } $contents .= " <td class=\"timecell\">".$first_num.":".$last_num."-".$sec_first_num.":".$sec_last_num."</td>\n"; // Aletaan käymään viikonpäiviä läpi, 7 päivää... for($g=0; $g<7; $g++) { $seek_time = $g*24*60*60+$last_monday+($first_num*60*60+$last_num*60); $s_result = search_between($seek_time, $result); // Katsotaan, onko tunnille määritetty tietoja. if(!$s_result) // Jos tietoja ei löydetty, on solun sisältö tyhjä { $brief = " "; $not_found = false; } else // Tietoja löydetty, laitetaan sisältö muuttujaam... { $not_found = true; $brief = stripslashes($s_result['brief']); // Jos $cycle muuttujassa ei ole $g-päivän kohdalla enää varausta, ja varaus kestää 1 tunnin tai yli, niin asetetaan se läpikäytäväksi... if($cycle[$g] == 0 && (($s_result['lopetus'] - $s_result['aloitus'])/60/30) >= 1) { $cycle[$g] = ($s_result['lopetus'] - $s_result['aloitus'])/60/30; // Lasketaan, montako tuntia varaus kestää. Tunnit = rowspan, laitetaan $cycle-muuttujaan $g-päivän kohdalle $begin = 1; // Kerrotaan, että täytyy aloittaa solu } } if($cycle[$g] == 0) // Jos ei sisältöä soluun, tulostetaan tyhjä solu { $contents .= " <td class=\"concell\">".$brief." </td>\n"; // Jatketaan vanhan solun piirtämistä tai luodaan uusi tyhjä solu } elseif($begin == 1) // Aloitetaan solu, ja kirjoitetaan siihen sisältö. { $contents .= " <td class=\"setcell\" rowspan=\"".$cycle[$g]."\">"; // Luodaan uusi solu, jolle annetaan rowspan (tunnit) if($not_found) $contents .= '<a href="'.$http.'?act=poista&id='.$s_result['id'].'&day='.$day.'&month='.$month.'&year='.$year.'">[D]</a> '; $contents .= $brief."</td>\n"; $begin = 0; } if($cycle[$g] > 0) // Jos tieto on jo tulostettu soluun, niin odotetaan vielä varauksen loppuun ennen solun lopettamista { $cycle[$g]--; } } $contents .= " </tr>\n"; } $contents .= ' </table><br> <form action="'.$http.'?day='.$day.'&month='.$month.'&year='.$year.'" method="post" name="form"> <table border="0" cellpadding="3" cellspacing="0" width="98%"> <tr> <td valign="middle" align="left">Varattava aika</td> <td valign="middle" align="left"> <input type="text" size="2" value="'.$day.'" maxlength="2" name="day"> <b>.</b> <input type="text" size="2" value="'.$month.'" maxlength="2" name="month"> <b>.</b> <input type="text" size="4" value="'.$year.'" maxlength="4" name="year"> klo: <select name="hour" size="1"> '; for($r=substr($start, 0, -2); $r<=substr($stop, 0, -2); $r++) $contents .= ' <option value="'.$r.'">'.$r."</option>\n"; $contents .= ' </select> <b>:</b> <select name="minute" size="1"> <option value="00">00</option> <option value="30">30</option> </select> - <select name="hour2" size="1"> '; for($r=substr($start, 0, -2); $r<=substr($stop, 0, -2); $r++) $contents .= ' <option value="'.$r.'">'.$r."</option>\n"; $contents .= ' </select> <b>:</b> <select name="minute2" size="1"> <option value="00">00</option> <option value="30">30</option> </select> </td> </tr> <tr> <td valign="middle" align="left">Varauksesta lyhyesti </td> <td valign="middle" align="left"><input type="text" size="30" maxlength="30" name="brief"></td> </tr> <tr> <td valign="middle" align="left">Lisää</td> <td valign="middle" align="left"><input type="submit" name="confirm" value="Lisää"></td> </tr> </table> </form> </body> </html>'; print $contents; ?>
if(!empty($_GET['id']) && $_GET['act'] == "poista") // Varauksen poistaminen { // Toimenpide $query = "DELETE FROM ".$table." WHERE id = '".$_GET['id']."'";
Aika vaarallisen näköinen lause. Mitäpäs jos magic_quotes_gpc sattuu olemaan off-asennossa ja kirjoitan osoiteriville esim.?act=poista&id=1'OR id < '1000
Äkkiä pääteltynä kysely menee kantaan muodossa
"DELETE FROM ".$table." WHERE id = '1'OR id < '1000'";
Noh, jos tuo henkilökohtaisessa käytössä on, niin eipä tuo haittaa, mutta silti tollaiset kannattaisi aina ottaa huomioon.
Auts :(
Nojoo nyt pitäisi olla korjattu: mysql_escape_string(); Luulin tarkistaneeni jo tuollaiset mokat :(
En tiedä onko mitään merkitystä, mutta itse olen käyttänyt id:n yhteydessä mysql_escape_string():n sijasta ihan vain intval(), koska ainakin yleensä - kuten tässäkin tapauksessa - id on kokonaisluku. Lisäksi jostain muistelen lukeneeni, että numeeristen kenttien yhteydessä ei hipsuja tarvitse käyttää.
Edit:Pientä jäsentelyä...
Kätevän oloinen järjestelmä. Voisi ottaa jopa omaan käyttöön jos olisi myslituki sivutilassa...
Haluisiko joku ystävällisesti ihan näin talkoohengessä (tosin ilman ruokapalkkaa), tehdä tähän skriptiin sopivan hakusysteemin:P Oon tässä nyt toista päivää yrittänyt, mutta koska myslistä ei pahemmin kokemusta ole niin ei oikein ota onnistuakseen. Eli jos ihan semmosen saisi, että kun laittaa hakusanaksi jonkun sanan, niin skripti palauttaa taulukon, jossa näkyy kaikki varaukset, joiden kuvauksessa kyseinen sana esiintyy.
Käytän skriptiä kouluni oppilaskunnan sivulla koepäiväkalenterina, joten olisi aika kätevää kun kurssin nimellä saisi suoraan päivämäärän:)
Jos joku jaksaisi (en usko että kovin monimutkaista koodia vaatisi), niin olisin erittäin kiitollinen:)
Koska sivutilassani ei ole mysql-tukea, tai sen saaminen maksaa, niin tein varauskalenterista version, joka ei käytä mysql-tietokantaa, vaan ihan tavallista tekstitiedostoa.
Virittelin sitä myös itselleni sopivaksi, että voi varata myös useamman päivän kerralla. Lopuksi tulostetaan myös yhteenveto kaikista varauksista.
Koeversio löytyy osoitteesta:
http://tarvain.byethost9.com/varauskal.php
Ohessa kalenteriin skripti, joka antaa hakusanalla kaikki varaukset, jossa sana esiintyy. Toimii "myslin" kanssa.
Ohessa linkki koeversioon, jossa sama toimii kalenteriversiolla, joka käyttää tekstitiedostoa:
http://tarvain.byethost9.com/varaukset_haku.php
Seuraavassa siis skripti "mysliin";
<?php require_once('config.php'); //tiedosto, jossa on configurointi tietokantaan require_once('dbopen.php'); // tiedosto, jossa muodostetaan yhteys tietokantaan function lomake1($hakusana, $painike, $PHP_SELF) { ?> <h2 style="border-top: solid thin black; color:#000;background-color:#fed"> Hae varaus</h2> <br><h4> <form action="<?PHP echo $PHP_SELF?>" method="post" name="form"> Hakusana: <input name="hakusana" type="text">     <input type="submit" name="painike" value="Etsi"> </form> <?PHP } lomake1($hakusana, $painike, $PHP_SELF); echo "<br>"; echo '<font size="4" color="#0000FF">'; //echo "Yhteenveto kaikista varauksista:"; echo "</font>"; echo "<br>"; function tulosta($alku, $loppu, $teksti) { echo "     "; echo date("d.m.Y ", $alku); echo " klo "; echo date("H", $alku); echo " :"; echo date("i -----", $alku); echo date(" d.m.Y ", $loppu); echo " klo "; echo date("H", $loppu); echo " :"; echo date("i ", $loppu); echo "     "; echo "$teksti"; } if(isset($painike)){ $query = "SELECT aloitus, lopetus, brief, id FROM varaukset ORDER BY aloitus, lopetus"; $result = mysql_query($query) or die('Kyselyssä tapahtui virhe.: '.$query); $rivienmaara = mysql_num_rows($result); $rivi = mysql_fetch_array($result); $j=0; for($j=0;$j<1;$j++) { for($j=0;$j<13;$j++) { $merkki[3][$j]=0; } } $i = 1; if($rivienmaara >0){ do { $alku = $rivi[0]; $teksti = $rivi[2]; $loppu = $rivi[1]; $k =1; //tutkitaan onko seuraavan päivän varaus sama kuin edellisen päivän while(($teksti == $rivi[2] && ($rivi[0]-$alku)<=($k*86400)&& ($rivi[0]-$alku) >(36600)) || ($teksti == $rivi[2] && $vali < 1800)) //while($teksti == $rivi[2]) { $rivi = mysql_fetch_array($result); $vali = $rivi[0]-$loppu; $i = $i+1; if(($teksti == $rivi[2] && ($rivi[0]-$alku)<=($k*86400)&& ($rivi[0]-$alku) >(36600)) || ($teksti == $rivi[2] && $vali < 1800)){ $loppu = $rivi[1]; $k=$k+1; } } $vali = 0; $teksti2 = strtolower($teksti); $hakusana2 = strtolower($hakusana); $ESIINTYI = strpos($teksti2, $hakusana2); if($ESIINTYI === 0 || $ESIINTYI > 0) { //varaustekstin, alku- ja loppuajan tulostus $v = date("y", $alku); echo "<br>"; if(date("m", $alku)==1 && $merkki[1][$v]==0) { echo '<font size="4" color="#000099">'; echo "TAMMIKUU"; echo "</font>"; echo "<br>"; $merkki[1][$v]=1; } if(date("m", $alku)==2 && $merkki[2][$v]==0) { echo '<font size="4" color="#000099">'; echo "HELMIKUU"; echo "</font>"; echo "<br>"; $merkki[2][$v]=1; } if(date("m", $alku)==3 && $merkki[3][$v]==0) { echo '<font size="4" color="#3333FF">'; echo "MAALISKUU"; echo "<br>"; echo "</font>"; $merkki[3][$v]=1; } if(date("m", $alku)==4 && $merkki[4][$v]==0) { echo '<font size="4" color="#00FFCC">'; echo "HUHTIKUU"; echo "</font>"; echo "<br>"; $merkki[4][$v]=1; } if(date("m", $alku)==5 && $merkki[5][$v]==0) { echo '<font size="4" color="#00FF99">'; echo "TOUKOKUU"; echo "</font>"; echo "<br>"; $merkki[5][$v]=1; } if(date("m", $alku)==6 && $merkki[6][$v]==0) { echo '<font size="4" color="#33CC33">'; echo "KESÄKUU"; echo "</font>"; echo "<br>"; $merkki[6][$v]=1; } if(date("m", $alku)==7 && $merkki[7][$v]==0) { echo '<font size="4" color="#009900">'; echo "HEINÄKUU"; echo "</font>"; echo "<br>"; $merkki[7][$v]=1; } if(date("m", $alku)==8 && $merkki[8][$v]==0) { echo '<font size="4" color="#336600">'; echo "ELOKUU"; echo "</font>"; echo "<br>"; $merkki[8][$v]=1; } if(date("m", $alku)==9 && $merkki[9][$v]==0) { echo '<font size="4" color="#333300">'; echo "SYYSKUU"; echo "</font>"; echo "<br>"; $merkki[9][$v]=1; } if(date("m", $alku)==10 && $merkki[10][$v]==0) { echo '<font size="4" color="#663300">'; echo "LOKAKUU"; echo "</font>"; echo "<br>"; $merkki[10][$v]=1; } if(date("m", $alku)==11 && $merkki[11][$v]==0) { echo '<font size="4" color="#CC3300">'; echo "MARRASKUU"; echo "</font>"; echo "<br>"; $merkki[11][$v]=1; } if(date("m", $alku)==12 && $merkki[12][$v]==0) { echo' <font size="4" color="#FF0000">'; echo "JOULUKUU"; echo "</font>"; echo "<br>"; $merkki[12][$v]=1; } //echo'<a href="'.$http.'?day='.date("d", $alku).'&month='.date("m", $alku).'&year='.date("Y", $alku).'&siirto=10">[Go]</a>'; tulosta($alku, $loppu, $teksti); } } while ($i<=$rivienmaara); } require_once('dbclose.php'); // tiedosto, jossa katkaistaan yhteys tietokantaan } ?>
Kuinka homman pitäisi toimia, että viikon alkuun saisikin nykyisen päivän, eikä aina maanantaita?
Aihe on jo aika vanha, joten et voi enää vastata siihen.