Diskuze: Php kalendář - vytvoření a zachování více událostí
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.


Michal Šmahel:21.2.2019 22:21
Ahoj, nevím, jestli se někdo bude nudit, ale každopádně se určitě najde někdo, kdo obětuje trochu času a pomůže ti. Pošli zdroják a uvidíme, co se dá dělat.
Pro více událostí bude každopádně potřeba využít pole.
<?php
$sekce = "kalendar";
if ( isset( $_REQUEST[ "sekce" ] ) ) {
$sekce = $_REQUEST[ "sekce" ];
}
switch ( $sekce ) {
case "kalendar":
$nazevstrany = "PHP calendar";
break;
}
// nastaveni casoveho pasma
date_default_timezone_set('Europe/Prague');
// ym - rok, mesic - datum
if (isset($_GET['ym'])) {
$ym = $_GET['ym'];
} else {
// soucasny datum
$ym = date('Y-m');
}
$timestamp = strtotime($ym . '-01'); // funkce ktera vypise pocet vterin od data 1. 1. 1970 (pocet vterin nastavi od aktulaniho roku, mesice a den nastavim jako 1.)
print $timestamp; //pouze zkouska jak to funguje
if ($timestamp === false) {
$ym = date('Y-m');
$timestamp = strtotime($ym . '-01');
}
// dnes (Formát:2019-08-8)
$dnes = date('Y-m-j');
// nadpis (Formát:August, 2019)
$nadpis = date('F, Y', $timestamp);
// odkazy na predchozi a nasledujici mesic
$predchozi = date('Y-m', strtotime('-1 month', $timestamp));
$nasledujici = date('Y-m', strtotime('+1 month', $timestamp));
// pocet dni v mesici (t = 28-31 dnu v mesici)
$pocetdnu = date('t', $timestamp);
// 1:Mon 2:Tue 3: Wed ... 7:Sun (N = kazdemu datu pripradi den)
$zacatekmesice = date('N', $timestamp);
// pole pro kalendar - tydny
$tydny = [];
$tyden = '';
// pridani prazdnych policek do kalendare
//bude pridavat prazdne policka po dobu ($zacatekmesice - 1), coz se v pripade unora 2019 rovna 4
$tyden .= str_repeat('<td></td>', $zacatekmesice - 1);
if (isset($_REQUEST['ulozit'])){
$eventDate = $_REQUEST["eventDate"];
$eventName = $_REQUEST["eventName"];
$eventNotes = $_REQUEST["eventNotes"];
}
for ($den = 1; $den <= $pocetdnu; $den++, $zacatekmesice++) {
$datum = $ym . '-' . $den;
if ($dnes == $datum) {
$tyden .= '<td class="today">';
//print("\calendar.php?".$dnes);
} else {
$datum = $ym . '-' . sprintf("%d", $den);
if ((isset($_REQUEST['ulozit'])) && ($eventDate == $datum)){
$tyden .= '<td class="event"><a class="odkaz" href=showevent.php?ymd='.$datum.'&eventName='.$eventName.'&eventNotes='.$eventNotes.'>';
}
else{
$tyden .= '<td class="obsazeno"><a class="odkaz" href=showevent.php?ymd='.$datum.'>';
}
}
$tyden .= $den . '</a></td>';
// nedele nebo posledni den mesice
if ($zacatekmesice % 7 == 0 || $den == $pocetdnu) {
// posledni den mesice
if ($den == $pocetdnu && $zacatekmesice % 7 != 0) {
// prazdne bunky
$tyden .= str_repeat('<td></td>', 7 - $zacatekmesice % 7);
}
$tydny[] = '<tr>' . $tyden . '</tr>';
$tyden = '';
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php print($nazevstrany)?></title>
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<style>
body{
/*margin: 0;
padding 0;*/
}
.kalendar {
font-family: 'Montserrat', sans-serif;
}
.list-inline {
text-align: center;
margin-bottom: 30px;
}
.nadpis {
font-weight: bold;
font-size: 26px;
}
th {
text-align: center;
}
td {
height: 100px;
width: 100px;
text-align: center;
}
.obsazeno:hover{
border: 1px solid black;
}
th:nth-of-type(6), td:nth-of-type(6) {
color: blue;
}
th:nth-of-type(7), td:nth-of-type(7) {
color: red;
}
.today {
background-color: ghostwhite;
border: 1px solid black;
}
.odkaz{
text-decoration: none;
color: black;
}
.odkaz:hover{
}
.event{
background-color: green;
}
</style>
</head>
<body>
<div class="kalendar">
<span class="nadpis"><?= $nadpis; ?></span><br><!--mesic + rok-->
<a href="?ym=<?= $predchozi; ?>">< prev</a> <!--talcitko pro predchozi mesic-->
<a href="?ym=<?= $nasledujici; ?>">next ></a> <!--tlacitko pro nasledujici mesic-->
<a href="event.php">Create new event</a>
<table>
<thead>
<tr>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</tr>
</thead>
<tbody>
<?php
foreach ($tydny as $tyden) {
print $tyden;
}
?>
</tbody>
</table>
</div>
<div class="udalost"><!---pouze pro kontrolu vypisu-->
<?php
if (isset($_REQUEST['ulozit'])){
print($eventDate)."<br>";
print($eventName)."<br>";
print($eventNotes);
}
?>
</div>
</body>
</html>
<?php
if (isset($_GET['ymd'])) {
$ymd = $_GET['ymd'];
} else {
// soucasny datum
$ymd = date('Y-m-d');
}
if (isset($_REQUEST['ulozit'])){
//$eventDate = date('Y-m-d');
$eventDate = $_REQUEST["eventDate"];
$eventName = $_REQUEST["eventName"];
$eventNotes = $_REQUEST["eventNotes"];
}
?><head>
<meta charset="utf-8">
<title>Event creator</title>
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<style>
.formular{
font-family: 'Montserrat', sans-serif;
}
.poznamky{
width: 300px;
}
</style>
</head>
<div class="formular">
<form action="calendar.php" method="post">
Event date: <input type="date" name="eventDate" id="eventDate" value="<?php if (isset($eventDate)) ?>"><br><br>
Event name: <input type="text" name="eventName" id="eventName" value="<?php if (isset($eventName)) ?>"><br><br>
Event notes: <input type="text" name="eventNotes" id="eventNotes" value="<?php if (isset($eventNotes)) ?>" class="poznamky"><br><br>
<input type="submit" name="ulozit" value="Save">
</form>
</div>
<?php
if (isset($_REQUEST["eventName"])){
$eventName = $_REQUEST["eventName"];
}
if (isset($_REQUEST["eventNotes"])){
$eventNotes = $_REQUEST["eventNotes"];
}
if (isset($_REQUEST["eventDate"])){
$eventDate = $_REQUEST["eventDate"];
}
if (isset($_GET['ymd'])) {
$ymd = $_GET['ymd'];
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Event details</title>
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
<style>
.blok{
font-family: 'Montserrat', sans-serif;
}
.nadpis{
font-weight: bold;
font-size: 26px;
}
</style>
</head>
<body>
<?php
if (isset($_REQUEST["eventName"])){
print($eventName)."<br>";
print($eventNotes);
}
else{
?>
<div class="blok">
<p class="nadpis"><?= $ymd; ?></p>
<?php
print("Pro tento den není žádná událost");
}
?>
</div>
</body>
</html>
Mám to ve třech souborech, docela složitě, takže jsou potrěba všechny 3 zrojáky.. za případnou pomoc budu rád.
ahoj, záleží na tom jakou strukturu danému poli dáš...
pole s událostmi může vypadat například takto:
Array
(
[0] => Array
(
['datum'] => 2019-02-20
['nazev'] => schůzka
)
[1] => Array
(
['datum'] => 2019-02-21
['nazev'] => holič
)
)
nebo třeba takto:
Array
(
['2019-02-19'] => Array
(
)
['2019-02-20'] => Array
(
[0] => Array
(
['nazev'] => večeře s kočenou
)
[1] => Array
(
['nazev'] => návštěva rodiče
)
)
nebo i jinak, záleží na tobě jak si ho uspořádáš...
no a pak použiješ funkci patrně foreach, tím projdeš pole/případně jeho
část a pokud záznam splní tvou podmínku, že odpovídá konkrétnímu datu,
načteš si informace a ty si zobrazíš do kalendáře..
data[r][m][d] = array()
data[r][m][d][] = udalost1
data[r][m][d][] = udalost2
nebo
mesic[d] = array()
mesic[d][] = udalost1
mesic[d][] = udalost2
udalost od-do pro vybrany mesic
cyklus(i=od..do nebo i>pocet dni v mesici) mesic[i][] = udalost1
A jeste mne napadlo, zda by nebylo jednodussi vyuzit format souboru ala google kalendar. Tusim IKS. Dneska je spoustu ctecek a editoru kalendaru. Zadas jim jen ftp udaje pro editaci nebo zadne pro view, pokud neni kalendar uzamcen proti verejnemu prohlizeni cizi osobou.
Díky za tipy, prozkouším to a ještě se možná ozvu..
No nakonec jsem dospěl k závěru, že to budu muset rěšit přes databázi, jelikož vy to jinak nemělo moc význam (události by mizely). Tohle mi ale značně komplikuje situaci, jelikož databáze nejsou moje záliba... tohle někod umíte?
Tomáš Novotný:22.2.2019 15:24
pro uchování informací není vždy potřeba db, lze použít i soubor,
nejsou-li potřeba složité operace nad daty, nebo je vyžadován přístup
vícero uživatelů najednou
formát ve kterém je vhodné data uložit je odvislý od jejich struktury a
způsobu použití
zkus se mrknout po textových souborech s koncovkou json, xml, csv či pak
speciálním kalendářovém formátu ics
a pak po funkcích, které umí načíst/uložit informace ze/do souboru
$content = file_get_contents($path/url)
file_put_contents($path, $content); // flock?
fopen ($path/$url)
Netusim, zda je nutne pouzivat zamek flock pro file_put_contents. Udajne mi
nekdo rikal, ze ne.
Ale pro fwrite je dobre pouzivat zamek. Slouzi to k zamknuti souboru, pokud ho
ma nekdo otevreny a zapisuje do nej. Pokud by zapisovali 2 ruzne zdroje, soubor
se smaze a zablokuje. Coz je neprijemne, kdyz resis pres soubor guestbook.
Co mas za problem s databazi? S databazi se pracuje celkem v pohode. Pseudokod nejak takto
$conn = db_connect($host, $user, $psw);
$conn->selectDb($db);
// cteni
$query = "SELECT jmena_sloupcu FROM tabulka WHERE sloupec='$datetime'"; // 'rok mesic. den. 0:0:0'
$data = $conn->query($query)
foreach ($data as $row) var_dump($row);
// zapis - pridani radku
$query = "INSERT INTO tabulka (jmeno_sloupce1, jmeno_sloupce2) VALUES ('$hodnota1', '$value2')";
$result = $conn->query($query);
// smazani - mazani radku
$query = "DELETE FROM tabulka WHERE jmeno_sloupce='$hodnota'";
$result = $conn->query($query);
To se souborem, kdyz budes chtit smazat konkretni radek, budes mit vic potizi, mozna. Zalezi na tom, zda si vygooglujes na to nejakou class. Treba na ICS soubory by mohla byt v php.
Matěj Zábojník:22.2.2019 21:45
Takhle s databazi si asi nejak poradim, jenze kdyz uz mam takhle rozdelany zdrojak, tak ta implementace te db mi dela problem.. proste ja si formularem poslu nejaky 3 atributy a nevim jak presne to poslat do te databaze. Vim ze pomoci insert prikazu, jenze netusim jak presne..
petr.jouza:23.2.2019 8:38
Ahoj,
jestli chceš velice jednoduchý ovladač pro práci s DB přes PHP, tak mohu
jen doporučit PDO ovladač, který je zde na itnetwork s moc pěkně napsanými
tutoriály. Já osobně jsem také nikdy s databázemi nepracoval, ale díky
těmto stránkám jsem se to naučil a moc mi to šetří nervy
Používání DB v PHP: https://www.itnetwork.cz/php/databaze
SQL příkazy: https://www.itnetwork.cz/mysql
Samozřejmě jak už to bývá, jsem se také v mnoha případech spálil a mnohokrát jsem i některé tabulky předělával, ale teď už mi to přijde docela hračka. Fakt na tom není nic složitého.
S ukládáním do databáze je to opravdu snadné.. Ve škole nás to učili nějak divně, tady je to opravdu dobře vysvětlené.
Jen mám problém s výpisem, nebo spíše s SQL příkazem.
$udalosti = Db::queryAll('
SELECT name, notes
FROM udalosti
WHERE date = '.$ymd.'
');
foreach ($udalosti as $u)
{
echo(htmlspecialchars($u['name']));
echo(htmlspecialchars($u['notes']));
}
Tento příkaz nechce nic vypsat. Zkoušel jsem tento příkaz napsat přímo do phpmyadmin (tam jsem zadal nějaký datum co odpovídal řádku v tabulce, ne proměnou) a tam to také nic nevypsalo.. Takže nevím co dělám v tomto případě špatně.
Jestli někdo víte co dělám zle, dejte vědět.. Popřípadě kdyby se nějaká dobrá duše našla trochu času, tak bych poslal zdroják.
Peter Mlich:25.2.2019 7:40
Mohl jsi napsat jak. Kdyby mel nekdo treba stejny problem.
U databaze zalezi na tom, jake tam mas sloupce, typy.
date = '.$ymd.'
Toto bude fungovat pouze tehdy, pokud date bude string 10 (varchar 10), format
yyyymmdd nebo yyyymd nebo yymd, hlavne, pro vsechny zapisy stejny. A mozna,
pokud bude nektery z datetime, timestamp typu. Ale to nemam vyzkousene, vzdycky
pisi cele datum nebo pouziji specialni funkci jako diff.
Kdyz budes mit podobny dotaz, zkus priste uvest i strukturu tabulky a take, co je v $y $m $d.
A take by bylo super, kdyby ses naucil pouzivat prepared statement,
jednoducha ochrana proti hackerum.
https://websitebeaver.com/…ql-injection
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->execute([$_POST['name'], 29]);
$stmt = null;
---
$stmt = $pdo->prepare("UPDATE myTable SET name = :name WHERE id = :id");
$stmt->execute([':name' => 'David', ':id' => $_SESSION['id']]);
$stmt = null;
Krome vetsi slozitosti si to pohlida a escapuje value, treba $_POST['name']
tak, aby tam uzivatel nemohl dat treba: 0 or 1=1
DELETE FROM table WHERE id=$_POST['name']
DELETE FROM table WHERE id=0 or 1=1 -- smaz celou tabulku, ze?
DELETE FROM table WHERE id='0 or 1=1' -- to vyhodi error, 0 radku smazanych,
pravdepodobne
Tu obranu mám napsanou trochu jinak, ale myslím že takhle to je taky dobře ne? Jinak celý problém spočíval v tom, že date v tabulce byl jako typ date.. takže jsem to jen trochu poupravil a šlape to správně.
$udalosti = Db::queryAll('
SELECT name, notes
FROM udalosti
WHERE date =?
', $_GET["ymd"]);
Jinak zde mám co mám v $ymd uloženo:
$ym = date('Y-m');
$ym jsem požíval trochu na něco jiného a pak jsem se přes to dostal až k $ymd
for ($den = 1; $den <= $pocetdnu; $den++, $zacatekmesice++) {
**$datum = $ym . '-' . $den;**
if ($dnes == $datum) {
$tyden .= '<td class="today"><a class="odkaz" **href=showevent.php?ymd='.$datum**.'>';
}
Tady už je vidět, co si posílám do ymd - $ym a za to přilepím den.
To mám pak celé definované jako proměnou
$ymd = $_REQUEST["ymd"];
+5 Zkušeností

Zobrazeno 18 zpráv z 18.