Kalenteri kuvana

empty 12.06.05 12:24

Näyttää pyydetyn kuukauden kalenterin kuvana. Vaatii GD-kirjaston.

 Tekstiversio  Arvo: 1 (5 ääntä)  Äänestä: +  -
<?php
/* Näyttää pyydetyn kuukauden pyydettynä vuonna PNG-kuvana.
 * Kuvaformaatti on helposti muokattavissa muuttamalla alinta riviä itse koodissa.
 * Varsinainen imagecalendar()-funktio palauttaa kuvan PHP:n kuvaresurssina.
 * Sisältää mahdollisuuden lisätä taustakuvan joko varsinaiseen kalenteriin tai koko kuvaan.
 * En takaa täydellistä toimivuutta enkä vastaa siitä jos saat jotain rikki koodin avulla.
 * Vaatii imagecreatefromext()-funktion, joka lataa kuvan tunnistaen tyypin pääteen mukaan.
 * Syntaksi:
 * resource imagecalendar(int year, int month,[ int cellsize, string bgimage, bool fullbg,
 * color bgcolor, color linecolor, color daycolor, color sundaycolor=0xff0000)
 * Ensimmäiset kaksi parametria lienevät selvät.
 * int cellsize = Yhden kalenteriruudun (=päivän) koko pikseleinä
 * string bgimage = Osoite taustakuvaan
 * bool fullbg = Lisätäänkö taustakuva koko kuvaan vai pelkkään kalenteriosioon
 * Viimeiset parametrit lienevät myös selvät. */


function imagecreatefromext($img) {
        $ext = substr($img, strrpos($img,".")+1);
        switch ($ext) {
                case "png":
                        return imagecreatefrompng($img);
                        break;
                case "jpg":
                case "jpeg":
                        return imagecreatefromjpeg($img);
                        break;
                case "gif":
                        return imagecreatefromgif($img);
                        break;
        }
        return FALSE;
}
       
function imagecalendar($year, $month, $cs=100, $bgimage="", $fullbg=FALSE, $bgcolor=0xffffff,
                                           $linecolor=0x000000, $daycolor=0x000055, $sundaycolor) {
       
        // Asetetaan viikonpäivät taulukkoon
        $wk = array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
       
        // Alustetaan muuttujia
        $day = 1;
        $week = 0;
        $initialweek = date("W", mktime(0, 0, 0, $month, $day, $year));
        $capt = date("F Y", mktime(0, 0, 0, $month, $day, $year));
        $fontwidth3 = imagefontwidth(3);
        // Jos on annettu taustakuvan osoite, haetaan se muuttujaan
        if ($bgimage) { $bgimg = imagecreatefromext($bgimage); }
       
        // Tehdään taulukko, jossa on päivät oikeilla kohdillaan kalenteriin nähden
        while (date("m", mktime(0, 0, 0, $month, $day, $year)) == $month) {
                // Jos edellinen päivä oli sunnuntai, vaihdetaan viikkoa
                if ($wd == 6) { $week++; }
                // Otetaan x-akselin sijainti eli viikonpäivä, vähennetään siitä 1,
                // koska date("w") palauttaa sunnuntain ensimmäisenä
                $wd = date("w", mktime(0, 0, 0, $month, $day, $year)) - 1;
                // Muutetaan -1 eli sunnuntai 6:ksi
                $wd = ($wd == -1 ? 6 : $wd);
                // Asetetaan taulukkoon
                $table[$week][$wd]=$day;               
                // Uusi päivä kaiken muuttaa voi...
                $day++;
        }
       
        // Lasketaan kuvan koko
        $imgx = $cs * 7 + 28;
        $imgy = $cs * ($week + 1) + ($week + 1) + 31;
       
        // Luodaan kuva ja lisätään siihen tausta
        $img = imagecreatetruecolor($imgx, $imgy);
        imagefilledrectangle($img, 0, 0, $imgx, $imgy, $bgcolor);
        // Jos taustakuva on ladattu aikaisemmin, lisätään se kuvaan
        // * TODO * Vältä imagecopyresize():n käyttöä
        if ($bgimg) {
                imagecopyresized($img, $bgimg, ($fullbg ? 0 : 20), ($fullbg ? 0 : 30), 0, 0,
                ($fullbg ? $imgx : $imgx - 20), ($fullbg ? $imgy :
                $imgy-30), imagesx($bgimg), imagesy($bgimg));
        }
       
        // Kirjoitetaan kuvaan otsikko
        imagestring($img, 4, $imgx / 2 - strlen($capt) * imagefontwidth(4) / 2,
        -2, $capt, $linecolor);
       
        // Kirjoitetaan viikot ruudukon vasemmalle puolelle
        for ($x = 0; $x < 7; $x++) {
                imagestring($img, 3, $x*$cs+$cs/2-$fontwidth3+20, 29-imagefontheight(3),
                $wk[$x], ($x == 6 ? $sundaycolor : $daycolor));
        }
       
        // Kirjoitetaan viikonpäivät ruudukon päälle
        for ($x = 0; $x < $week + 1; $x++) {
                imagestring($img, 3, 16-$fontwidth3*2, $x*$cs+$x+$cs/2 + 30,
                $initialweek + $x, $daycolor);
        }
       
        // Piirretään ruudukon vaakaviivat
        for ($x = 0; $x < 9; $x++) {
                imageline($img, $x*$cs+$x+20, 30, $x*$cs+$x+20, $imgy, $linecolor);
        }
       
        // Piirretään ruudukon pystyviivat
        for ($x = 0; $x < 7; $x++) {
                imageline($img, 20, $x*$cs+$x+30, $imgx, $x*$cs+$x+30, $linecolor);
        }
       
        // Kirjoitetaan päivämäärät ruutuihin
        foreach ($table as $week => $row) {
                foreach ($row as $wd => $day) {
                        imagestring($img, 4, $wd*$cs+$wd+25, $week*$cs+$week+33, date("d",
                        mktime(0, 0, 0, $month, $day, $year)), ($wd == 6 ? $sundaycolor : $daycolor));
                }
        }
       
        // Palautetaan valmis kuva
        return $img;
}

// Demonstraatiokoodia
header("Content-type: image/png");
$year = ($_GET['year']?$_GET['year']:date("Y"));
$month = ($_GET['month']?$_GET['month']:date("m"));
$cs = ($_GET['cs']?$_GET['cs']:100);
$bg = ($_GET['bg']?$_GET['bg']:'');
$fbg = ($_GET['fbg']?$_GET['fbg']:FALSE);
$bgcol = ($_GET['bgcol']?$_GET['bgcol']:0xffffff);
$linecol = ($_GET['linecol']?$_GET['linecol']:0x00aaff);
$daycol = ($_GET['daycol']?$_GET['daycol']:0x0000ff);
$sundaycol = ($_GET['sundaycol']?$_GET['sundaycol']:0xf00000);
imagepng(imagecalendar($year, $month, $cs, $bg, $fbg, $bgcol, $linecol, $daycol, $sundaycol));
?>

editoitu: 14:27 12.6.05
T.M. 13:15 12.6.05 
imagepng(imagecalendar($year, $month, $cs, $bg, $fbg, $bgcol, $linecol, $daycol, $sundaycol));
Ehkä olis järkevämpää laittaa tuo funktion uloste muuttujaan, joten siihen voi piirtää itse jotain lisää, jos haluaa.


    return $img;
    imagedestroy($img);
Tuota imagedestroy funktiota ei suoriteta, koska funktion suoritus päättyy returniin.


imagecopyresized() on aika raskas funktio (ja turha tässä tapauksessa), kannattaa mielummin käyttää imagecopy() funktiota, ja kertoa käyttäjälle kuinka iso siitä pitää tulla.


date("d", mktime(0, 0, 0, $month, $day, $year))
Mitäs järkeä tuossa on? Palauttaa saman luvun kuin mitä tuossa $day muuttujassa on. Eli siis date() ja mktime() funktion kutsu täysin turhia.


while (1) {
..
}
Ikuisen silmukan luominen ei ole järkevää, ja muutenkin epäselvää koodin kannalta, parempi olisi laittaa while silmukkaan ehto, eikä sinne kaarisulkeiden väliin...


Kutsut monta kertaa imagesx() ja imagesy() funktioita, parempi olisi luoda muuttujat noille arvoille, ja käyttää niitä tarvittaessa.
Samoin kuin imagefontwidth() ja imagefontheight() funktiota näytät kutsuvan monta kertaa. Kuten myös mktime() funktioita samoilla parametreillä.

End of whinetys.
tsuriga 16:12 12.6.05 
Tuo imagepng lopussa on vain esimerkiksi T.M. Hyviä huomioita, itse lisäisin vielä, että lisää kommentteja koodiin.
editoitu: 16:00 13.6.05
empty 16:34 12.6.05 
(älä välitä tästä viestistä)
editoitu: 05:22 13.6.05
Ceez 05:22 13.6.05 
Koititko
while (date("m", mktime(0, 0, 0, $month, $day, $year)) == $month) { ... }
?
empty 13:42 13.6.05 
Koitin. Mutta yritän tässä tän päivän aikana sekä optimoida koodin että korjata tuon seikan.
empty 16:00 13.6.05 
Korjasin turhan date("d"):n ja while()-loopin (Ceez muuten, kyllä tuo toimi kuten odotettua, olin varmaankin vain typottanut tjsp), lisäsin kommentit ja optimoin koodia hieman.
editoitu: 22:16 9.2.07
ape10 22:15 9.2.07 
Tämähän on ihan hieno! Plussat sulle. Ainoo on että olis hyvä jos nimet olis suomeks (siis kuukaudet ja viikon paivat)