NePo
Vasaris 22, 2008

Kuriame kalendorių

Prisireikė man suprogramuoti kalendorių, ilgai negalvodamas nusprendžiau pasidalinti savo patirtimi. Šiame straipsnyje taip pat naudosime .

Pirmiausiai išsiaiškinime savokas, kad suprastume vienodai ką darome. Mano supratimu turi pateikti tam tikro mėnesio visas dienas. Ant kai kurių dienų turi būti nuorodos vendančios į neaiškius tinklalapius.
Išsiaiškinome pagrindines sąlygas galim imtis darbų.

Pirmiausiai, tradiciškai apsibrėšime duomenų bazės lenteles, šiuo atveju vieną lentelę:

CREATE TABLE /*!32312 IF NOT EXISTS*/ `cal` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `link` varchar(250) DEFAULT NULL,
  `title` varchar(50) DEFAULT NULL,
  `linkdate` date DEFAULT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM\;

Dabar jau galime rašyti kodą, kadangi kodą aš jau pasirašiau, tai pasakosiu iš eilės kaip parašyta, o ne ekperimentuosiu kartu su jumis.
Taigi, aš nusprendžiau, jog GET parametrų pagalba bus galima užsikrauti bet kurį norimą mėnesį, bet kurių metų.

if(isset($_GET['y']))
  $year=(int)$_GET['y'];
else $year=date('Y');
 
if(isset($_GET['m']))
  $month=(int)$_GET['m'];
else $month=date('m');

Pirmasis GET paima metus, antrasis mėnesį. Tiesa šitą vietą būtų galima… t.y. reikėtų dar patobulinti, kad lankytojai nesugalvotų įvesti nulinių ar neigiamų metų bei mėnesių, taip pat, kad nesusidomėtų kas vysktą 13 ar 45 mėnesį, bet manau šią smulkmeną išspręsite ir be mano pagalbos.

Sekantis etapas paimti mus dominančio mėnesio informaciją

$nextmonth=$month+1;
$nextyear=$year+1;
 
$startdate=$year.'-'.$month.'-01';
if($month!=12)
	$enddate=$year.'-'.$nextmonth.'-01';
else $enddate=$nextyear.'-'.$month.'-01';
 
$query = "SELECT * FROM ".$pref."cal where linkdate>='$startdate' and linkdate<'$enddate'";
$result = mysql_query($query);
$countrows=mysql_num_rows($result);
while($row = mysql_fetch_array($result))
{
	$temp=explode('-',$row['linkdate']);
 	$row['targetday']=$temp[2];
 	$mylinks[]=$row;
}

Pirmiausiai apsibrėžiame dvi datas pirmą norimo mėnesio ir pirmą sekančio mėnesio, kad galėtume ištraukti visus duomenis. Kaip galinę datą imame pirmą kito mėnesio, nes spėlioti kiek šitame mėnesyje dienų 28? 29? 30? 31? nematau tikslo. Nors kaip tik sekančiame žingsnyje būtent ir nustatinėsime, kiek dienų yra šiame mėnesyje, tačiau tokiu veiksmu noriu parodyti, jog kartais neverta ieškoti kiek dienų turi mėnuo, galima išsisukti ir paprastai.
“Parsindamas” duomenis, aš atskiriu dieną, nuo visos datos, todėl, kad vėliau būtų man lengva priskirti išrinktus duomenis mėnesio konkrečiai mėnesio dienai.

$startday= date('w',strtotime($startdate));
if($startday==0)
$startday=6;
else $startday-=1;

Šis kodas nustato kokia savaitės diena buvo pirma mėnesio diena. Čia tenka naudoti w, o ne N, nes nevisi serveriai suspėja su šiuolaikinėmis technologijomis (žiūrėti date). O minus vienas, todėl kad masyvai kalboje paprastai sukami nuo nulio, nors, aišku, kiekvienas gali daryti pagal skonį.

$totaldays=cal_days_in_month(CAL_GREGORIAN,$month,$year);

Šita magiška komanda nustato dienų skaičių konkrečiame mėnesyje.

if($finish>35)
$calendarcount=42;
else $calendarcount=35;

Čia nustatome kokio dyžio bus mūsų mėnesio kalendoriaus masyvas. Kodėl 35 ir 42? Todėl, kad dalinasi iš 7. Paprastai paaiškinti nesugebėsiu, todėl geriau pažiūrėkit į paveiksliukus
Pirmas:
npcal1.png
Antras:
npcal2.png
Pirmame paveiksliukyje yra 42 langeliai antrame - 35, aišku, aš visuomet galėčiau daryti 42, bet tuomet kai kuriuose mėnesiuose apačioj atsirastų papildoma tuščia eilutė. Žodžiu, čia skonio reikalas, darykit kaip norit.

for($ii=0;$ii<$calendarcount;$ii++)
{
	$days[$ii]['day']='&nbsp';
	if(($ii+1)%7==0&&$ii!=$calendarcount-1)
		$days[$ii]['break']=1;
	else $days[$ii]['break']=0;
}
 
for($iii=$startday;$iii<$finish;$iii++)
{
	$days[$iii]['day']=$iii-$startday+1;
}	
 
$iiii=0;	
while($iiii<$countrows)
{
 $days[$mylinks[$iiii]['targetday']+$startday-1]['info']=$mylinks[$iiii];
 $iiii++; 
	}

Daug kodo, bet manyčiau viskas labai aišku. Pirmiausiai užpildome masyvą tuščiais simboliais, sekančiame cikle surašome dienas, o trečiame priskiriame dienos informaciją, kurią ištraukėme iš duomenų bazės.
Dar liko tik priskirti kintamuosius , bet tikiuosi jūs tą galite puikiai padaryti be mano pagalbos, o jeigu ne, tai pasiskaitykite čia.
Ir paskutinis punktas iki laimės - pasirašyti šiek tiek kodo:

{foreach from=$days item=day}
   <td>{if !empty($day.info)}<a href='{$day.info.link}'>{$day.day}</a>
       {else}{$day.day}
       {/if}
   </td>
   {if $day.break==1} </tr><tr> {/if}
{/foreach}

Su foreach sukam masyvą, jeigu yra informacijos tai tai išspausdiname nuorodą į ją ir kas septynis elementus viską pradedame rašyti iš naujos eilutės.
Tai štai ką gauname:
npcal3.png

Dizainą aš pasiskolinau iš CSSPLAY. Jeigu naudosite, dizaino autorius parašo jam pervesti šiek tiek pinigų, dydis priklauso nuo jūsų sąžinės.

Kalendorius parsisiuntimui

Panašūs straipsniai


“Kuriame kalendorių” komentarų: 5

  1. asterisk

    Šiaip reikėtų dar pasidaryti, jog vietoje tuščių laukų, rodytų sekančio/ankstesnio mėnesio dienas, kokia nors blanke spalva. Bet esmė aiški :)

  2. Armandas

    else $enddate=$nextyear.’-’.$month.’-01′;

    Kodėl dabar enddate ne po mėnesio, o po metų?

  3. elt.lt » Blog Archive » Apžvalga. Šiandien aš skaičiau… #49

    […] pamokėlė su išsamiais komentarais, kaip su PHP susiprogramuoti paprastą kalendorių. Žinoma, jei tik domitės ta „velnio išmone” - […]

  4. Blogorama #345 : nežinau.lt

    […] NePo Pixel.lt tinklaraštyje šiandien pateikia kalendoriaus programavimo pavyzdį su PHP ir Smarty. O štai Linas siūlo spausdintinių planavimo priemonių šablonų tiems, kam patogiau […]

  5. Piemens nuotykiai - pažintis su gyvuliu (Yahoo UI) » Pixel.lt

    […] Kalendorius. Jeigu jums labiau patinka Javascript kalba nei PHP, tai galite pasinaudoti Yahoo siūlomu kalendoriumi. […]

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.