Przejdź do głównej treści
INF.03-03-24.06-SGCzerwiec 2024 · 53 kroki · ok. 88 min · 39 kryteriów z klucza

Rozwiązanie krok po kroku: Poziomy rzek Dolnego Śląska (Wersja podstawowa)

Serwis o poziomach rzek to baza rzeki (wodowskazy i ich pomiary, relacja 1..n) z czterema zapytaniami - wybór kolumn, złączenie JOIN z warunkiem na datę, to samo złączenie z porównaniem dwóch kolumn (stanWody > stanOstrzegawczy) i AVG z GROUP BY - oraz mapa Polski przygotowana w edytorze grafiki i strona poziomRzek.php. Formularz z trzema polami opcji wysyła wybór metodą POST, a skrypt formularza wypełnia tabelę wszystkimi wodowskazami, tylko tymi ponad stanem ostrzegawczym albo tylko ponad alarmowym. Skrypt 2 wypisuje średni stan wody z każdego dnia pomiarów.

Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypty są najpierw napisane najprościej, funkcjami z tabeli 1 arkusza (mysqli_query, mysqli_fetch_row, isset), a na końcu przerobione na wersję z prawdziwych projektów: tablica warunków zamiast drabinki if, wybrane pole opcji zaznaczone po wysłaniu, wszystkie wodowskazy od pierwszego wejścia, htmlspecialchars i średnie zaokrąglone do części setnych.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: bloki na siatce CSS (grid-template-areas), kolory w zmiennych i PHP na PDO z danymi pobranymi przed HTML-em - obie wersje są zgodne z kluczem.

Baza i grafiki pochodzą z prawdziwego archiwum pliki3 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza - po wybraniu „Wszystkie” i kliknięciu „Pokaż” (obraz 2), a w krokach z warunkami po wybraniu pozostałych pól (obrazy 3 i 4).

Jak liczą się punkty. Klucz ma 39 kryteriów (R.1.1 - R.5.8), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 30 punktów - można stracić 9 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Baza danych

    Kroki 1-7 · po tym etapie masz 6 z 39 kryteriów (pkt)

    Krok 1: Baza danych rzeki

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie rzeki, z zestawem polskich znaków (np. utf8_unicode_ci)

    Najpierw archiwum pliki3.zip z pulpitu (hasło St@ny%RzeK - małpa, procent, wielkość liter ma znaczenie) i folder z numerem zdającego, do którego trafiają rozpakowane pliki. W phpMyAdmin: Nowa, nazwa rzeki, porównywanie utf8_unicode_ci.

  2. Krok 2: Import tabel z pliku baza.sql

    ok. 2 min
    Polecenie z arkusza

    Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum

    Zaznaczona baza rzeki, potem Import → baza.sql → Wykonaj. Powstają dwie tabele z obrazu 1: wodowskazy (17 punktów pomiarowych ze stanem ostrzegawczym i alarmowym) i pomiary (34 pomiary - po jednym dla każdego wodowskazu z 5 i 6 maja 2022). Pole wodowskazy_id łączy pomiar z wodowskazem - to relacja 1..n: jeden wodowskaz, wiele pomiarów.

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych rzeki czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.

    Print Screen, wklejenie do edytora grafiki i zapis jako import.png. Uwaga na formaty: import idzie do PNG, a zrzuty zapytań do JPEG.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

  4. Krok 4: Zapytanie 1: wodowskazy i stan alarmowy

    Kryteria: ,

    R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Wykonano zapytanie 1 wybierające jedynie pola nazwa, rzeka, stanAlarmowy z tabeli wodowskazy . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy; oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 17 wierszy, jedynie pola nazwa, rzeka, stanAlarmowy

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola nazwa, rzeka, stanAlarmowy z tabeli wodowskazy

    • SELECT nazwa, rzeka, stanAlarmowy - trzy pola, w tej kolejności,
    • FROM wodowskazy - bez warunku, więc wszystkie wiersze.

    Wynik: 17 wierszy, jak w kluczu. Zapytania trafiają do kwerendy.txt, zrzut do kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: stany wody z 5 maja 2022

    Kryteria:

    R.1.4 Wykonano zapytanie 2 wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty 2022-05-05. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = wodowskazy_id WHERE dataPomiaru='2022-05-05'; (możliwe również INNER JOIN bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 17 wierszy, jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty pomiaru 2022-05-05. Należy posłużyć się relacją

    • SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody - cztery pola wodowskazu i stan wody z pomiaru,
    • FROM wodowskazy JOIN pomiary - złączenie obu tabel,
    • ON wodowskazy.id = pomiary.wodowskazy_id - relacja z obrazu 1: pomiar wskazuje swój wodowskaz,
    • WHERE dataPomiaru = '2022-05-05' - data w apostrofach, w zapisie rok-miesiąc-dzień.

    Wynik: 17 wierszy - każdy wodowskaz raz, ze stanem z 5 maja. Bez warunku na datę byłoby 34 (dwa pomiary na wodowskaz). To jest tabela z obrazu 2 - z tego zapytania powstanie skrypt formularza. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;
    
    -- Zapytanie 2
    SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: wodowskazy ponad stanem ostrzegawczym

    Kryteria:

    R.1.5 Wykonano zapytanie 3 wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty 2022-05-05 oraz takie, dla których stanWody jest wyższy niż stanOstrzegawczy. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = wodowskazy_id WHERE dataPomiaru='2022-05-05'AND stanWody > stanOstrzegawczy; (możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 5 wierszy, jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody, dla nazw: Jarnołtów, Łazany, Jelenia Góra, Nowogrodziec, Bardo

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pola nazwa, rzeka, stanOstrzegawczy, stanAlarmowy z tabeli wodowskazy oraz odpowiadające im pole stanWody z tabeli pomiary dla daty pomiaru 2022-05-05 oraz takie, dla których stanWody jest wyższy niż stanOstrzegawczy. Należy posłużyć się relacją

    To zapytanie 2 z drugim warunkiem dopisanym przez AND:

    • AND stanWody > stanOstrzegawczy - warunek porównuje dwie kolumny tego samego wiersza, a nie kolumnę z liczbą; „wyższy niż” to ostra nierówność.

    Wynik: 5 wierszy - Jarnołtów, Łazany, Jelenia Góra, Nowogrodziec, Bardo, jak w kluczu i na obrazie 3. Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;
    
    -- Zapytanie 2
    SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05';
    
    -- Zapytanie 3
    SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05' AND stanWody > stanOstrzegawczy;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: średni stan wody w każdym dniu

    Kryteria:

    R.1.6 Wykonano zapytanie 4 wybierające jedynie datę pomiaru oraz liczące średnie stany wody z tabeli pomiary grupując je według daty pomiaru. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru; oraz wynik działania udokumentowano zrzutem, na którym są widoczne dane: 2022-05-05 167.6471 oraz 2022-05-06 179.5882; z dowolną dokładnością

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: wybierające jedynie datę pomiaru oraz liczące średnie stany wody z tabeli pomiary grupując je według daty pomiaru

    • SELECT dataPomiaru, AVG(stanWody) - data i średnia z grupy,
    • FROM pomiary,
    • GROUP BY dataPomiaru - jeden wiersz na każdy dzień.

    Wynik: 2022-05-05 167.6471 i 2022-05-06 179.5882 (MySQL podaje średnią z czterema miejscami po przecinku). Zrzut: kw4.jpg. To zapytanie wyśle Skrypt 2.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, rzeka, stanAlarmowy FROM wodowskazy;
    
    -- Zapytanie 2
    SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05';
    
    -- Zapytanie 3
    SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05' AND stanWody > stanOstrzegawczy;
    
    -- Zapytanie 4
    SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

    Kroki 8-28 · po tym etapie masz 19 z 39 kryteriów (pkt)

    Krok 8: obraz1.png: przezroczyste tło

    ok. 3 min
    Polecenie z arkusza

    Dla grafiki obraz1.png, wypakowanej z archiwum, należy nadać przezroczyste tło oraz wypełnić obszar województwa dolnośląskiego kolorem niebieskim o dowolnym odcieniu. Województwo dolnośląskie znajduje się w lewym dolnym rogu mapy – patrz obraz 2.

    obraz1.png to mapa 100 × 100 pikseli: szare granice województw na białym tle, bez przezroczystości. W GIMP-ie najpierw Warstwa → Przezroczystość → Dodaj kanał alfa (bez niego usunięte piksele staną się kolorem tła, a nie przezroczystością). Potem Zaznaczanie spójnego obszaru (różdżka) i kliknięcie w biel poza mapą - z klawiszem Shift w każdym rogu, jeśli obszary się nie łączą - i klawisz Delete. Różdżka zatrzymuje się na granicy kraju, więc wnętrze województw zostaje białe. Podgląd pokazuje mapę po tym kroku na ciemnym tle - widać, że biel zniknęła tylko na zewnątrz.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: obraz1.png: województwo dolnośląskie na niebiesko

    Kryteria:

    R.2.1 Grafika obraz1.png ma tło przezroczyste, województwo dolnośląskie jest wypełnione kolorem niebieskim (dowolny odcień)

    ok. 2 min
    Polecenie z arkusza

    Dla grafiki obraz1.png, wypakowanej z archiwum, należy nadać przezroczyste tło oraz wypełnić obszar województwa dolnośląskiego kolorem niebieskim o dowolnym odcieniu. Województwo dolnośląskie znajduje się w lewym dolnym rogu mapy – patrz obraz 2.

    Kolor pierwszego planu niebieski, narzędzie Wypełnienie kubełkiem z opcją Wypełnienie podobnych kolorów i kliknięcie we wnętrze województwa w lewym dolnym rogu mapy - nad nim leży lubuskie (łatwo się pomylić, oba są przy zachodniej granicy). Kubełek zalewa biel do granic województwa. Eksport: Plik → Wyeksportuj jako obraz1.png - format PNG zachowuje przezroczystość.

    Typowe błędy

    Eksport do JPEG gubi przezroczystość - tło znowu staje się białe i R.2.1 przepada.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 9
  10. Krok 10: Plik poziomRzek.php w HTML5

    ok. 1 min
    Polecenie z arkusza

    Składa się ze strony o nazwie poziomRzek.php zapisanej w języku HTML5

    Deklaracja <!DOCTYPE html>, sekcje head i body. Nazwa pliku z wielką literą „R” w środku, jak w arkuszu - na serwerze wielkość liter w nazwach plików ma znaczenie. Rozszerzenie .php, bo dojdą skrypty; strona otwiera się przez http://localhost/....

    poziomRzek.php PHP nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  11. Krok 11: Język strony

    ok. 1 min
    Polecenie z arkusza

    Ustawiony język zawartości strony na polski

    Atrybut lang="pl" w znaczniku <html>.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  12. Krok 12: Kodowanie polskich znaków

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku poziomRzek.php oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> i zadeklarowano język witryny polski np.<HTML lang="pl">. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

    Jawnie zastosowany właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwszy element <head>. Ten krok zamyka kryterium R.2.2: nazwa pliku, deklaracja HTML5, język i kodowanie.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  13. Krok 13: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł stronie: "Poziomy rzek"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Poziomy rzek”

    <title> w <head>.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  14. Krok 14: Podpięcie arkusza stylów

    Kryteria:

    R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

    Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony

    Nazwa pliku: styl.css (nie style.css). Klucz przypomina, że R.3.5 przepada także wtedy, gdy któryś selektor jest źle zapisany, np. kropka zamiast # przy identyfikatorze.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  15. Krok 15: Bloki: dwa banery, menu, lewy, prawy, stopka

    Kryteria:

    R.2.4 Układ strony zdefiniowano dzieląc ją na: dwa bloki banera, blok menu, lewy, prawy oraz stopkę. Zastosowano semantyczne znaczniki sekcji HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, stopki - footer, dopuszcza się zagnieżdżenie bloków div w znacznikach semantycznych

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze dwa bloki banera, poniżej menu, poniżej bloki: lewy i prawy, na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    Banery to dwa header (klucz wymaga ich wprost, razem z footer dla stopki - R.2.4), rozróżnione identyfikatorami map i title. Menu z formularzem to nav, blok lewy z tabelą - main (główna treść strony), blok prawy z dodatkowymi informacjami - aside. Kolejność w kodzie jest taka jak na obrazie 2: od góry, od lewej.

    poziomRzek.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
        </header>
        <header id="title">
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  16. Krok 16: Pierwszy baner: mapa

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego banera: obraz1.png z tekstem alternatywnym o treści: „Mapa Polski”

    Mapa przygotowana w etapie grafiki. Przezroczyste tło sprawi, że na granatowym banerze widać tylko kształt Polski.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  17. Krok 17: Drugi baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego banera: nagłówek pierwszego stopnia o treści „Rzeki w województwie dolnośląskim”

    <h1> w drugim banerze.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  18. Krok 18: Menu: formularz wysyłany metodą POST

    Kryteria:

    R.3.3 Formularz wysyła dane metodą POST do tego samego pliku (poprawne również bez atrybutu action )

    ok. 1 min
    Polecenie z arkusza

    Zawartość menu: Formularz wysyłający dane do skryptu na tej samej stronie, metodą bezpieczną.

    method="post" - „metoda bezpieczna” z arkusza: wybór jedzie w treści żądania, nie w adresie strony. W specyfikacji HTTP „bezpieczne” są co prawda metody, które niczego nie zmieniają na serwerze (GET i HEAD), ale arkusz używa tego słowa w innym sensie, a klucz wymaga POST. Atrybut action jest pominięty - formularz bez niego wysyła dane do bieżącego pliku, czyli do skryptu na tej samej stronie (klucz: „poprawne również bez atrybutu action”).

    poziomRzek.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
            </form>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  19. Krok 19: Trzy pola opcji z etykietami w jednej grupie

    ok. 3 min
    Polecenie z arkusza

    Obok siebie 3 pola opcji (radio) zgrupowane, tak aby było możliwe jednoczesne wybranie tylko jednego pola. Etykiety przy polach opcji: „Wszystkie”, „Ponad stan ostrzegawczy”, „Ponad stan alarmowy” (pola opcji będą formatowane jedną klasą CSS)

    „Zgrupowane” to ten sam atrybut name (option) we wszystkich trzech polach - przeglądarka pozwala wtedy zaznaczyć tylko jedno, a do skryptu trafi jedna para option = wartość wybranego pola (all, warning albo alarm). Każde pole ma swoją etykietę <label> połączoną przez for/id (kliknięcie w napis zaznacza pole), a etykiety mają wspólną klasę radio-label - to nią CSS pokoloruje teksty przy polach. Pola i etykiety są liniowe, więc stoją obok siebie.

    poziomRzek.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
            </form>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  20. Krok 20: Przycisk „Pokaż” wysyłający formularz

    Kryteria: ,

    R.2.9 W bloku menu umieszczono formularz z trzema polami opcji i przyciskiem. Pola opcji są podpisane etykietami: "Wszystkie", "Ponad stan ostrzegawczy", "Ponad stan alarmowy", zastosowano znaczniki <label> (dopuszczalne zastosowanie <span> lub <div>)

    R.3.4 W jednym momencie można zaznaczyć tylko jedno pole opcji oraz przycisk wysyła dane do skryptu (typ submit lub button bez typu)

    ok. 1 min
    Polecenie z arkusza

    Przycisk o treści „Pokaż”, wysyłający dane do skryptu

    <button> bez atrybutu type wewnątrz formularza jest przyciskiem wysyłającym (submit). Formularz ma już trzy pola opcji z etykietami i przycisk (R.2.9), a jednocześnie da się zaznaczyć tylko jedno pole (R.3.4).

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  21. Krok 21: Blok lewy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: Nagłówek trzeciego stopnia o treści: „Stany na dzień 2022-05-05”

    <h3> na początku bloku lewego.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  22. Krok 22: Tabela: wiersz komórek nagłówkowych

    Kryteria:

    R.2.7 Pierwszy wiersz tabeli zawiera komórki nagłówkowe o treści: „Wodomierz”, „Rzeka”, „Ostrzegawczy”, „Alarmowy”, „Aktualny”, zastosowano znaczniki <th>

    ok. 2 min
    Polecenie z arkusza

    Tabela zawierająca dane: Pierwszy wiersz wypełniony komórkami nagłówkowymi o treści: „Wodomierz”, „Rzeka”, „Ostrzegawczy”, „Alarmowy”, „Aktualny”

    Komórki nagłówkowe to <th> (domyślnie pogrubione i wyśrodkowane), w jednym wierszu <tr>. Pięć kolumn odpowiada pięciu polom zapytania 2: nazwa, rzeka, stan ostrzegawczy, alarmowy i aktualny stan wody. Pozostałe wiersze wypisze skrypt formularza.

    poziomRzek.php PHP zmienione: 9 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  23. Krok 23: Blok prawy: nagłówek „Informacje”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego: Nagłówek trzeciego stopnia o treści: „Informacje”

    <h3> na początku bloku prawego.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  24. Krok 24: Lista punktowana z trzema informacjami

    Kryteria:

    R.2.8 W bloku prawym umieszczono jedną listę punktowaną o trzech elementach, zastosowano znaczniki <ul>, <li>

    ok. 1 min
    Polecenie z arkusza

    Lista punktowana (nieuporządkowana) zawierająca elementy: „Brak ostrzeżeń o burzach z gradem”, „Smog w mieście Wrocław”, „Silny wiatr w Karkonoszach”

    Lista nieuporządkowana to <ul>, każdy element w <li>.

    poziomRzek.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  25. Krok 25: Nagłówek „Średnie stany wód”

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści: „Średnie stany wód”

    Drugi <h3> w bloku prawym. Pod nim Skrypt 2 wypisze średnie z zapytania 4.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  26. Krok 26: Odnośnik „Dowiedz się więcej”

    Kryteria:

    R.3.2 Odnośnik o treści "Dowiedz się więcej" inicjuje otwarcie strony "https://komunikaty.pl"

    ok. 1 min
    Polecenie z arkusza

    Odnośnik do adresu „https://komunikaty.pl” o treści „Dowiedz się więcej”

    Adres zewnętrzny musi zaczynać się od https:// - bez tego przeglądarka szukałaby pliku komunikaty.pl w folderze strony. Między nagłówkiem a odnośnikiem stanie później Skrypt 2 („Efekt działania skryptu 2” w arkuszu).

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  27. Krok 27: Obraz rzeki

    Kryteria:

    R.2.10 W pierwszym banerze umieszczono obraz mapy z tekstem alternatywnym: „Mapa Polski” oraz w bloku prawym obraz rzeki i tekście alternatywnym „rzeka”

    ok. 1 min
    Polecenie z arkusza

    Obraz o nazwie obraz2.jpg i tekście alternatywnym „rzeka”

    Zdjęcie z archiwum pod odnośnikiem. Strona ma teraz oba obrazy z tekstami alternatywnymi (R.2.10).

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  28. Krok 28: Stopka z autorem

    Kryteria:

    R.2.5 W drugim banerze zapisano nagłówek h1: "Rzeki w województwie dolnośląskim", w bloku lewym h3: "Stany na dzień 2022-05-05", w bloku prawym h3: "Informacje" i "Średnie stany wód" oraz w stopce paragraf z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: akapit (paragraf) o treści: „Stronę wykonał: ”, dalej wstawiony numer zdającego

    Na egzaminie w miejscu imienia i nazwiska wpisuje się numer zdającego, czyli PESEL; w tym rozwiązaniu stoi tam „Bartosz Bryniarski”. Strona ma już wszystkie nagłówki i paragraf stopki z klucza (R.2.5).

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  29. Etap 3: Styl CSS

    Kroki 29-40 · po tym etapie masz 30 z 39 kryteriów (pkt)

    Krok 29: Krój Georgia dla wszystkich elementów

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (dla *): krój czcionki Georgia

    ok. 1 min
    Polecenie z arkusza

    Domyślne formatowanie wszystkich selektorów: krój czcionki Georgia

    Selektor uniwersalny * - krój dostają też przycisk i komórki tabeli.

    styl.css CSS nowy plik
    * {
        font-family: Georgia;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  30. Krok 30: Oba banery: kolory, wyśrodkowanie, wymiary

    Kryteria:

    R.4.6 Ustawiono wyrównanie tekstu do środka dla obu banerów

    ok. 2 min
    Polecenie z arkusza

    Wspólne dla obu bloków banera: kolor tła Navy, biały kolor czcionki, wyrównanie tekstu do środka, wysokość 100 px, szerokość 50%

    Na stronie są dokładnie dwa znaczniki header i oba mają wyglądać tak samo, więc wystarczy selektor znacznika - identyfikatory map i title nie są tu potrzebne. Mapa ma 100 × 100 pikseli, więc wypełnia wysokość banera, a wyśrodkowanie stawia ją pośrodku lewej połowy strony (obraz 2).

    styl.css CSS zmienione: 7 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  31. Krok 31: Menu: tło i marginesy wewnętrzne

    ok. 1 min
    Polecenie z arkusza

    Dla bloku menu: kolor tła Navy, marginesy wewnętrzne 20 px

    padding: 20px odsuwa pola opcji od krawędzi granatowego paska ze wszystkich stron.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  32. Krok 32: Teksty przy polach opcji: kolor i marginesy

    ok. 1 min
    Polecenie z arkusza

    Dla klasy formatującej teksty przy polach opcji: kolor czcionki Silver, marginesy zewnętrzne 50 px

    Selektor klasy z kropką. Etykiety są elementami liniowymi, więc margines 50 px działa tylko w poziomie - rozsuwa pola opcji, jak na obrazie 2.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  33. Krok 33: Tekst pola opcji pod kursorem

    Kryteria:

    R.4.9 W momencie, gdy kursor myszy znajdzie się na tekście przy polu opcji, tekst zmienia kolor na biały i zostaje podkreślony

    ok. 1 min
    Polecenie z arkusza

    W momencie, gdy kursor myszy znajdzie się na tekście pola opcji ma on kolor biały i podkreślenie

    Pseudoklasa :hover dla tej samej klasy - zmiana dotyczy tylko etykiety, nad którą stoi kursor.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  34. Krok 34: Blok lewy i prawy: tło i wysokość

    Kryteria:

    R.4.4 Ustawiono wysokość obu banerów na 100px, bloków lewego i prawego na 550px

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla bloku lewego i prawego: kolor tła Azure, wysokość 550 px

    Dwa selektory po przecinku. Ta sama wysokość obu bloków sprawia, że stopka zaczyna się równo pod nimi. Banery mają 100 px, a teraz bloki 550 px (R.4.4).

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  35. Krok 35: Szerokości bloku lewego i prawego

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo blok lewy ma szerokość 70% a blok prawy szerokość 30%

    70% + 30% = cała szerokość strony - oba bloki zmieszczą się w jednym rzędzie.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    main {
        width: 70%;
    }
    aside {
        width: 30%;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  36. Krok 36: Stopka: kolory

    Kryteria: ,

    R.4.2 Ustawiono kolor tła Navy dla obu banerów, menu i stopki, Azure dla bloków lewego i prawego

    R.4.3 Ustawiono biały kolor czcionki dla obu bloków banera i stopki, kolor Silver dla klasy formatującej teksty przy polach opcji

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: kolor tła Navy, biały kolor czcionki

    Granatowe tło mają teraz oba banery, menu i stopka, a jasne Azure - bloki lewy i prawy (R.4.2). Biały kolor czcionki mają banery i stopka, srebrny - teksty przy polach opcji (R.4.3).

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    main {
        width: 70%;
    }
    aside {
        width: 30%;
    }
    footer {
        background-color: Navy;
        color: white;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  37. Krok 37: Układ bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze dwa bloki banera, poniżej menu, poniżej bloki: lewy i prawy, na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    Banery (50% + 50%) i bloki lewy z prawym (70% + 30%) płyną w lewo - float: left stawia je parami obok siebie. Menu i stopka zajmują całą szerokość i dostają clear: both: menu zaczyna się dopiero pod banerami (bez tego wjechałoby pod nie, bo pływające bloki nie zajmują miejsca w zwykłym układzie), a stopka - pod blokami lewym i prawym.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    main {
        width: 70%;
    }
    aside {
        width: 30%;
    }
    footer {
        background-color: Navy;
        color: white;
    }
    header, main, aside {
        float: left;
    }
    nav, footer {
        clear: both;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  38. Krok 38: Tabela: ramka, wyśrodkowanie, szerokość

    Kryteria: ,

    R.4.8 Ustawiono dla tabeli: obramowanie 1px solid Navy

    R.4.7 Ustawiono marginesy wewnętrzne (padding) dla menu 20px oraz marginesy zewnętrzne (margin) dla klasy formatującej teksty przy polach opcji 50px, dla tabeli - auto

    ok. 2 min
    Polecenie z arkusza

    Dla selektora tabeli: obramowanie linią ciągłą o szerokości 1 px i kolorze Navy, marginesy zewnętrzne automatycznie wyliczane przez przeglądarkę, szerokość 70%

    Zgodnie z uwagą arkusza selektor to sam znacznik table - klucz nie uzna szerokości tabeli nadanej klasą (R.4.5). Ramka obejmuje całą tabelę, nie komórki - jak na obrazie 2. margin: auto dzieli wolne miejsce po równo na lewo i prawo, więc tabela szeroka na 70% bloku staje na środku. Marginesy menu, etykiet i tabeli są już ustawione (R.4.7).

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    main {
        width: 70%;
    }
    aside {
        width: 30%;
    }
    footer {
        background-color: Navy;
        color: white;
    }
    header, main, aside {
        float: left;
    }
    nav, footer {
        clear: both;
    }
    table {
        border: 1px solid Navy;
        margin: auto;
        width: 70%;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  39. Krok 39: Wiersz tabeli pod kursorem

    Kryteria:

    R.4.10 W momencie, gdy kursor myszy znajdzie się na wierszu tabeli, jego kolor tła zmienia się na SkyBlue

    ok. 1 min
    Polecenie z arkusza

    W momencie, gdy kursor myszy znajdzie się na wierszu tabeli, jego kolor tła zmienia się na SkyBlue

    Pseudoklasa :hover dla tr - podświetla się cały wiersz (na obrazie 2 Zgorzelec). Działa też na wierszu nagłówkowym; arkusz tego nie zabrania.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    main {
        width: 70%;
    }
    aside {
        width: 30%;
    }
    footer {
        background-color: Navy;
        color: white;
    }
    header, main, aside {
        float: left;
    }
    nav, footer {
        clear: both;
    }
    table {
        border: 1px solid Navy;
        margin: auto;
        width: 70%;
    }
    tr:hover {
        background-color: SkyBlue;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  40. Krok 40: Obraz w prawym bloku: szerokość

    Kryteria:

    R.4.5 Ustawiono szerokość dla obu banerów na 50%, bloku lewego 70%, bloku prawego 30% (width lub grid-template-columns lub flex), selektora table 70%, obrazu w prawym bloku 90%

    ok. 1 min
    Polecenie z arkusza

    Dla obrazu w prawym bloku: szerokość 90%

    Selektor potomka aside img - dotyczy tylko zdjęcia rzeki; mapa w banerze zostaje w rozmiarze 100 × 100. Szerokości banerów, bloków, tabeli i obrazu są komplet (R.4.5).

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Georgia;
    }
    header {
        background-color: Navy;
        color: white;
        text-align: center;
        height: 100px;
        width: 50%;
    }
    nav {
        background-color: Navy;
        padding: 20px;
    }
    .radio-label {
        color: Silver;
        margin: 50px;
    }
    .radio-label:hover {
        color: white;
        text-decoration: underline;
    }
    main, aside {
        background-color: Azure;
        height: 550px;
    }
    main {
        width: 70%;
    }
    aside {
        width: 30%;
    }
    footer {
        background-color: Navy;
        color: white;
    }
    header, main, aside {
        float: left;
    }
    nav, footer {
        clear: both;
    }
    table {
        border: 1px solid Navy;
        margin: auto;
        width: 70%;
    }
    tr:hover {
        background-color: SkyBlue;
    }
    aside img {
        width: 90%;
    }
    Podgląd strony po tym kroku (poziomRzek.php)
  41. Etap 4: Skrypty PHP

    Kroki 41-49 · po tym etapie masz 39 z 39 kryteriów (pkt)

    Krok 41: Połączenie z bazą rzeki

    Kryteria:

    R.5.1 Skrypt zawiera instrukcje połączenia z serwerem bazy danych i wyboru bazy rzeki

    ok. 2 min
    Polecenie z arkusza

    Skrypty łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie rzeki

    Skrypt formularza stoi wewnątrz tabeli, pod wierszem nagłówkowym - to, co wypisze, stanie się kolejnymi wierszami. Jest pierwszy na stronie, więc otwiera połączenie: mysqli_connect z czterema argumentami łączy się z serwerem i wybiera bazę; uchwyt w zmiennej $connection posłuży też Skryptowi 2, który na stronie stoi niżej i zamknie połączenie. Pod nagłówkiem „Średnie stany wód” czeka już pusty blok Skryptu 2. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony po wybraniu „Wszystkie” i kliknięciu „Pokaż”.

    poziomRzek.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  42. Krok 42: Skrypt formularza: po wysłaniu zapytanie 2

    Kryteria:

    R.5.3 Skrypt skojarzony z formularzem zawiera instrukcje wysyłające do bazy danych zapytanie 2 lub skrypt 2: zapytanie 4

    ok. 3 min
    Polecenie z arkusza

    Skrypt skojarzony z formularzem, po wysłaniu danych z formularza, wyświetla dane w tabeli w zależności od wybranego pola opcji: Wszystkie dane wodomierzy są uzyskane za pomocą zapytania 2 (patrz obraz 2)

    „Po wysłaniu danych z formularza” to warunek isset($_POST["option"]): przy pierwszym wejściu na stronę nikt nic nie wysłał i tabela ma sam nagłówek. Wewnątrz zapytanie 2 bez średnika na końcu - za chwilę będzie do niego dopisywany drugi warunek. mysqli_query wysyła je do bazy, wynik czeka w $result. Apostrofy wokół daty siedzą wewnątrz napisu PHP w cudzysłowach, więc nie trzeba ich niczym poprzedzać.

    poziomRzek.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        $result = mysqli_query($connection, $query);
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 41.

  43. Krok 43: Skrypt formularza: wiersze z nazwą wodowskazu

    ok. 2 min
    Polecenie z arkusza

    Pozostałe wiersze wypełnione przez skrypt skojarzony z formularzem

    mysqli_fetch_row oddaje kolejny wiersz wyniku jako tablicę numerowaną od zera (w kolejności pól z SELECT), a po ostatnim zwraca null i pętla while się kończy. Na razie jedna komórka - widać 17 nazw wodowskazów, od Lubachowa do Ślęży.

    poziomRzek.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  44. Krok 44: Skrypt formularza: pięć kolumn w każdym wierszu

    Kryteria: ,

    R.5.4 Skrypt formularza wyświetla w tabeli wyniki działania zapytania zgodnie z obrazem 2 arkusza egzaminacyjnego

    R.2.6 W bloku lewym umieszczono tabelę o 5 kolumnach, zastosowano znaczniki <table>, <tr>, <td> (tabelę wygenerowano skryptem lub w HTML)

    ok. 2 min
    Polecenie z arkusza

    Wszystkie dane wodomierzy są uzyskane za pomocą zapytania 2 (patrz obraz 2)

    Pozostałe komórki: rzeka, stan ostrzegawczy, alarmowy i aktualny. Podgląd wygląda jak blok lewy na obrazie 2 - 17 wierszy w kolejności zapytania 2 (R.5.4), a tabela ma pięć kolumn ze znaczników table, tr i td (R.2.6).

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  45. Krok 45: Skrypt formularza: ponad stan ostrzegawczy

    Kryteria:

    R.5.5 Gdy w formularzu wybrano "Ponad stan ostrzegawczy" i zatwierdzono, są wyświetlone tylko te rekordy, dla których stan aktualny jest wyższy niż ostrzegawczy

    ok. 2 min
    Polecenie z arkusza

    Dane wodomierzy z przekroczonym stanem ostrzegawczym są uzyskane za pomocą zapytania 3 lub alternatywnie za pomocą zapytania 2 i odpowiednio przygotowanego warunku (patrz obraz 3)

    Zapytanie 3 to zapytanie 2 z dopisanym warunkiem, więc zamiast przepisywać je drugi raz, wystarczy dokleić warunek operatorem . (łączenie napisów w PHP). Spacja na początku dopisku jest konieczna - bez niej powstałoby '2022-05-05'AND. Podgląd pokazuje stronę po wybraniu „Ponad stan ostrzegawczy”: 5 wierszy, jak na obrazie 3.

    poziomRzek.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  46. Krok 46: Skrypt formularza: ponad stan alarmowy

    Kryteria:

    R.5.6 Gdy w formularzu wybrano "Ponad stan alarmowy" i zatwierdzono, są wyświetlone tylko te rekordy, dla których stan aktualny jest wyższy niż alarmowy

    ok. 2 min
    Polecenie z arkusza

    Dane wodomierzy z przekroczonym stanem alarmowym są uzyskane za pomocą zmodyfikowanego zapytania 3 lub alternatywnie za pomocą zapytania 2 i odpowiednio przygotowanego warunku (patrz obraz 4)

    Druga gałąź elseif dokleja warunek ze stanem alarmowym. Dla wartości all żaden warunek nie pasuje i zostaje samo zapytanie 2. Podgląd po wybraniu „Ponad stan alarmowy”: tylko Łazany (300 przy stanie alarmowym 240), jak na obrazie 4.

    poziomRzek.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  47. Krok 47: Skrypt 2: zapytanie 4

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 4

    Skrypt 2 korzysta z połączenia otwartego w skrypcie formularza. Zmienne $query i $result są użyte ponownie - tabela jest już wypisana.

    poziomRzek.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
                $query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";
                $result = mysqli_query($connection, $query);
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  48. Krok 48: Skrypt 2: paragraf „data: średnia” dla każdego dnia

    Kryteria:

    R.5.7 W skrypcie 2 jest wyświetlany każdy zwrócony zapytaniem wiersz o treści: „<data>: <średnia>”, gdzie dane zapisane w <> są pobierane z bazy danych

    ok. 2 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w paragrafie o treści: „<data>: <średnia>”, gdzie dane zapisane w <> są pobierane z bazy danych

    Każdy wiersz zapytania 4 to jeden <p> z datą, dwukropkiem i średnią. Podgląd: „2022-05-05: 167.6471” i „2022-05-06: 179.5882” - jak na obrazie 2. Ten skrypt wypisuje się zawsze, niezależnie od formularza.

    poziomRzek.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
                $query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<p>$row[0]: $row[1]</p>";
                }
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  49. Krok 49: Zamknięcie połączenia na końcu

    Kryteria: ,

    R.5.2 Ostatnią operacją na bazie jest jej zamknięcie

    R.5.8 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych lub funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania

    ok. 1 min
    Polecenie z arkusza

    Na końcu jest zamykane połączenie z serwerem.

    Skrypt 2 jest ostatnim blokiem PHP na stronie, więc tu stoi mysqli_close - ostatnia operacja na bazie (R.5.2). Wszystkie zmienne mają nazwy mówiące, co przechowują ($connection, $query, $result, $row) - to kryterium R.5.8.

    poziomRzek.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
                $query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<p>$row[0]: $row[1]</p>";
                }
                mysqli_close($connection);
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 48.

  50. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 50-52 · po tym etapie masz 39 z 39 kryteriów (pkt)

    Krok 50: Tablica warunków i wszystkie wodowskazy od pierwszego wejścia

    ok. 3 min
    Polecenie z arkusza

    Skrypt skojarzony z formularzem, po wysłaniu danych z formularza, wyświetla dane w tabeli w zależności od wybranego pola opcji: Wszystkie dane wodomierzy są uzyskane za pomocą zapytania 2 (patrz obraz 2)

    Wersja egzaminacyjna przy pierwszym wejściu pokazuje pustą tabelę - użytkownik musi najpierw kliknąć „Pokaż”. Arkusz tego nie zabrania, ale stany wody są najważniejszą treścią strony. Operator ?? przyjmuje all, gdy formularza jeszcze nie wysłano. Drabinkę if/elseif zastępuje tablica warunków: klucz to wartość pola opcji, wartość - dopisek do zapytania. Wartość spoza tablicy (np. xyz wysłane z pominięciem formularza) też daje all - do zapytania trafia tylko tekst z tablicy, nigdy tekst od użytkownika. Dodanie czwartej opcji to jedna linia w tablicy. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    poziomRzek.php PHP zmienione: 16 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all">
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning">
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm">
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    $conditions = [
                        "all" => "",
                        "warning" => " AND stanWody > stanOstrzegawczy",
                        "alarm" => " AND stanWody > stanAlarmowy"
                    ];
                    $option = $_POST["option"] ?? "all";
                    if (!isset($conditions[$option])) {
                        $option = "all";
                    }
                    $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'" . $conditions[$option];
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                    }
                    /* Wersja z egzaminu:
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                    */
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
                $query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<p>$row[0]: $row[1]</p>";
                }
                mysqli_close($connection);
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 48.

  51. Krok 51: Wybrane pole opcji zostaje zaznaczone

    ok. 3 min
    Polecenie z arkusza

    Obok siebie 3 pola opcji (radio) zgrupowane, tak aby było możliwe jednoczesne wybranie tylko jednego pola. Etykiety przy polach opcji: „Wszystkie”, „Ponad stan ostrzegawczy”, „Ponad stan alarmowy” (pola opcji będą formatowane jedną klasą CSS)

    Na obrazach 3 i 4 po wysłaniu formularza zaznaczone jest pole, które wybrano - w wersji egzaminacyjnej strona ładuje się od nowa i wszystkie pola są puste, więc nie widać, który filtr działa. Krótki PHP w każdym polu dopisuje atrybut checked, gdy wartość pola zgadza się z wyborem. Formularz stoi na stronie przed skryptem z tablicą warunków, dlatego linia z $option przenosi się ze skryptu do osobnego bloku PHP na samym początku pliku (przed <!DOCTYPE html> - blok niczego nie wypisuje, więc dokument zaczyna się poprawnie); sprawdzenie w tablicy warunków zostaje w skrypcie. Podgląd: po wybraniu „Ponad stan ostrzegawczy” to pole zostaje zaznaczone, a w tabeli jest 5 wierszy. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    poziomRzek.php PHP zmienione: 6 linii
    <?php
        $option = $_POST["option"] ?? "all";
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all" <?php if ($option == "all") echo "checked"; ?>>
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning" <?php if ($option == "warning") echo "checked"; ?>>
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm" <?php if ($option == "alarm") echo "checked"; ?>>
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    $conditions = [
                        "all" => "",
                        "warning" => " AND stanWody > stanOstrzegawczy",
                        "alarm" => " AND stanWody > stanAlarmowy"
                    ];
                    if (!isset($conditions[$option])) {
                        $option = "all";
                    }
                    $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'" . $conditions[$option];
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                    }
                    /* Wersja z egzaminu:
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                    */
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
                $query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<p>$row[0]: $row[1]</p>";
                }
                mysqli_close($connection);
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  52. Krok 52: Komórki w pętli, htmlspecialchars i średnie z dwoma miejscami po przecinku

    ok. 3 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w paragrafie o treści: „<data>: <średnia>”, gdzie dane zapisane w <> są pobierane z bazy danych

    Trzy poprawki wyświetlania. Pięć komórek wypisuje pętla foreach po wartościach wiersza - zmiana liczby kolumn w zapytaniu nie wymaga zmian w echo. Każda wartość przechodzi przez htmlspecialchars, więc nazwa z < albo & w bazie nie rozbije tabeli. Średnia „167.6471” ma cztery miejsca po przecinku i kropkę dziesiętną - number_format zaokrągla ją do dwóch miejsc z polskim przecinkiem („167,65”). Dopisek „cm” to założenie tego rozwiązania: stany wody na wodowskazach podaje się w centymetrach, ale baza i arkusz jednostki nie podają - w razie wątpliwości lepiej go pominąć. Na egzaminie wystarczy wersja wcześniejsza - klucz sprawdza średnią z bazy „z dowolną dokładnością”, ale bez dopisków.

    poziomRzek.php PHP zmienione: 6 linii
    <?php
        $option = $_POST["option"] ?? "all";
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Poziomy rzek</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header id="map">
            <img src="obraz1.png" alt="Mapa Polski">
        </header>
        <header id="title">
            <h1>Rzeki w województwie dolnośląskim</h1>
        </header>
        <nav>
            <form method="post">
                <input type="radio" id="all" name="option" value="all" <?php if ($option == "all") echo "checked"; ?>>
                <label for="all" class="radio-label">Wszystkie</label>
                <input type="radio" id="warning" name="option" value="warning" <?php if ($option == "warning") echo "checked"; ?>>
                <label for="warning" class="radio-label">Ponad stan ostrzegawczy</label>
                <input type="radio" id="alarm" name="option" value="alarm" <?php if ($option == "alarm") echo "checked"; ?>>
                <label for="alarm" class="radio-label">Ponad stan alarmowy</label>
                <button>Pokaż</button>
            </form>
        </nav>
        <main>
            <h3>Stany na dzień 2022-05-05</h3>
            <table>
                <tr>
                    <th>Wodomierz</th>
                    <th>Rzeka</th>
                    <th>Ostrzegawczy</th>
                    <th>Alarmowy</th>
                    <th>Aktualny</th>
                </tr>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "rzeki");
                    $conditions = [
                        "all" => "",
                        "warning" => " AND stanWody > stanOstrzegawczy",
                        "alarm" => " AND stanWody > stanAlarmowy"
                    ];
                    if (!isset($conditions[$option])) {
                        $option = "all";
                    }
                    $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'" . $conditions[$option];
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<tr>";
                        foreach ($row as $value) {
                            echo "<td>" . htmlspecialchars($value) . "</td>";
                        }
                        echo "</tr>";
                    }
                    /* Wersja z egzaminu:
                    if (isset($_POST["option"])) {
                        $query = "SELECT nazwa, rzeka, stanOstrzegawczy, stanAlarmowy, stanWody FROM wodowskazy JOIN pomiary ON wodowskazy.id = pomiary.wodowskazy_id WHERE dataPomiaru = '2022-05-05'";
                        if ($_POST["option"] == "warning") {
                            $query = $query . " AND stanWody > stanOstrzegawczy";
                        } elseif ($_POST["option"] == "alarm") {
                            $query = $query . " AND stanWody > stanAlarmowy";
                        }
                        $result = mysqli_query($connection, $query);
                        while ($row = mysqli_fetch_row($result)) {
                            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td><td>$row[3]</td><td>$row[4]</td></tr>";
                        }
                    }
                    */
                ?>
            </table>
        </main>
        <aside>
            <h3>Informacje</h3>
            <ul>
                <li>Brak ostrzeżeń o burzach z gradem</li>
                <li>Smog w mieście Wrocław</li>
                <li>Silny wiatr w Karkonoszach</li>
            </ul>
            <h3>Średnie stany wód</h3>
            <?php
                $query = "SELECT dataPomiaru, AVG(stanWody) FROM pomiary GROUP BY dataPomiaru;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<p>$row[0]: " . number_format($row[1], 2, ",", " ") . " cm</p>";   // było: "<p>$row[0]: $row[1]</p>"
                }
                mysqli_close($connection);
            ?>
            <a href="https://komunikaty.pl">Dowiedz się więcej</a>
            <img src="obraz2.jpg" alt="rzeka">
        </aside>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (poziomRzek.php)
  53. Etap 6: Oddanie pracy

    Krok 53 · po tym etapie masz 39 z 39 kryteriów (pkt)

    Krok 53: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wystarczy nazwa przeglądarki, w której była sprawdzana strona.

    W folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, obraz1.png (po obróbce), obraz2.jpg, poziomRzek.php, przeglądarka.txt, styl.css i rozpakowany baza.sql. Po nagraniu płyty trzeba sprawdzić jej odczyt i opisać ją numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

    Podgląd strony bez zmian - taki jak po kroku 52.

Podgląd

To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.

Autor rozwiązania: . Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.