Przejdź do głównej treści
INF.03-03-22.06-SGCzerwiec 2022 · 43 kroki · ok. 72 min · 35 kryteriów z klucza

Rozwiązanie krok po kroku: Portal zawodów wędkarskich (Wersja podstawowa)

Portal zawodów wędkarskich to baza wedkarstwo (z importu zadanie używa tabel zawody_wedkarskie, karty_wedkarskie i lowisko), cztery zapytania - INSERT z kluczem nadawanym automatycznie, warunek na tekście, złączenie dwóch tabel relacją i UPDATE zwiększający liczbę punktów - oraz strona zawody.html z formularzem i skrypt zgloszenie.php. Formularz wysyła metodą POST numer łowiska, datę i nazwisko sędziego, a skrypt dopisuje z nich nowe zawody do bazy - to zapytanie 1 z danymi z formularza. W stylach są cień obrazu (box-shadow), interlinia (line-height) i trzy reguły pisane selektorem znacznika (input, img, a).

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ą. Skrypt jest najpierw napisany najprościej, funkcjami z tabeli 1 arkusza (mysqli_connect, mysqli_query, mysqli_close), a na końcu przerobiony na wersję odporną na błędy, które naprawdę wychodzą przy testach.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: siatka CSS zamiast float i clear, kolory w zmiennych CSS i skrypt na PDO, który sprawdza dane z formularza (także to, czy łowisko istnieje), zapisuje je zapytaniem przygotowanym i nie dodaje zawodów drugi raz po odświeżeniu strony - obie wersje są zgodne z kluczem.

Baza i zdjęcie pochodzą z prawdziwego archiwum pliki3.zip (załącznik do arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP. Skrypt jest naprawdę uruchamiany w PHP 8.2 (klucz każe sprawdzać w XAMPP 8.1.2 - zachowanie użytych funkcji jest w obu wersjach takie samo); arkusz nie każe mu nic wypisywać, więc podgląd jego kroków to tabela zawody_wedkarskie po wysłaniu formularza - tak, jak sprawdza to egzaminator w phpMyAdmin.

Jak liczą się punkty. Klucz ma 35 kryteriów (R.1.1 - R.5.5), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 27 punktów - można stracić 8 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 35 kryteriów (pkt)

    Krok 1: Baza danych wedkarstwo

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie wedkarstwo

    Najpierw archiwum pliki3.zip z pulpitu (hasło ZaWodY7% - wielkość liter ma znaczenie, na końcu znak procentu) i folder z numerem zdającego, do którego trafiają baza.sql i zawody.jpg. W phpMyAdmin: Nowa, nazwa wedkarstwo - bez polskich liter.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie wedkarstwo - skrypt łączy się z bazą po nazwie (R.5.1).

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

    ok. 2 min
    Polecenie z arkusza

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

    Przy zaznaczonej bazie wedkarstwo: Import → baza.sql → Wykonaj. Plik zawiera kilka tabel z różnych zadań; tu potrzebne są trzy z obrazu 1: zawody_wedkarskie (4 zawody: zwycięzca, łowisko, data, sędzia), karty_wedkarskie (2 wędkarzy z punktami) i lowisko (6 łowisk). Zawody wskazują łowisko polem Lowisko_id, a zwycięzcę - polem Karty_wedkarskie_id.

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych wedkarstwo 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: nowe zawody

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 dodające rekord do tabeli zawody_wedkarskie o wartościach: klucz główny nadawany automatycznie, 2, 4, „2021-09-28”, Andrzej Nowak. W pliku z kwerendami lub na zrzucie istnieje zapis np.: INSERT INTO zawody_wedkarskie VALUES (NULL, '2', '4', '2021-09- 28', 'Andrzej Nowak');(możliwe różne warianty INSERT INTO) oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnym dodaniu rekordu lub tabela z dodanym rekordem

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 1: wstawiające rekord do tabeli zawody_wedkarskie o wartościach: klucz główny nadawany automatycznie, Karty_wedkarskie_id - 2; Lowisko_id - 4; data_zawodow - „2021-09-28”; sedzia – Andrzej Nowak

    • INSERT INTO zawody_wedkarskie - dopisanie wiersza do tabeli,
    • VALUES (NULL, 2, 4, '2021-09-28', 'Andrzej Nowak') - wartości w kolejności pól tabeli: id, Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia.

    NULL w polu id z AUTO_INCREMENT oznacza „nadaj następny numer” - baza wpisała 5, bo tabela miała zawody 1-4. Liczby bez apostrofów, data i tekst w apostrofach. Klucz uznaje też zapis z listą pól, np. INSERT INTO zawody_wedkarskie (Karty_wedkarskie_id, Lowisko_id, data_zawodow, sedzia) VALUES (2, 4, ...). Zapytania trafiają do kwerendy.txt, zrzut z komunikatem i tabelą do kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    INSERT INTO zawody_wedkarskie VALUES (NULL, 2, 4, '2021-09-28', 'Andrzej Nowak');
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: zawody sędziego Krzysztofa Dobrowolskiego

    Kryteria:

    R.1.4 Utworzono zapytanie 2 wybierające jedynie pola id oraz data_zawodow z tabeli zawody_wedkarskie dla sędziego Krzysztofa Dobrowolskiego . W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, data_zawodow FROM zawody_wedkarskie WHERE sedzia = 'Krzysztof Dobrowolski'; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest tylko jeden rekord: 4, 2018-06-21

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola id oraz data_zawodow z tabeli zawody_wedkarskie dla sędziego Krzysztofa Dobrowolskiego

    • SELECT id, data_zawodow,
    • FROM zawody_wedkarskie,
    • WHERE sedzia = 'Krzysztof Dobrowolski' - w bazie imię i nazwisko sędziego są w jednym polu, w mianowniku.

    Wynik: jeden wiersz 4, 2018-06-21 - jak w kluczu. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    INSERT INTO zawody_wedkarskie VALUES (NULL, 2, 4, '2021-09-28', 'Andrzej Nowak');
    
    -- Zapytanie 2
    SELECT id, data_zawodow FROM zawody_wedkarskie WHERE sedzia = 'Krzysztof Dobrowolski';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: zwycięzca zawodów numer 4

    Kryteria:

    R.1.5 Utworzono zapytanie 3 wybierające jedynie pola imię, nazwisko i punkty z tabeli karty_wedkarskie dla zwycięzcy zawodów wędkarskich o identyfikatorze zawody_wedkarskie.id=4. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, punkty FROM karty_wedkarskie JOIN zawody_wedkarskie ON karty_wedkarskie.id = zawody_wedkarskie.Karty_wedkarskie_id WHERE zawody_wedkarskie.id = 4; (możliwe też INNER JOIN lub przyrównanie kluczy w WHERE) oraz wynik działania udokumentowano zrzutem, na którym widoczny jest tylko jeden rekord z danymi: Andrzej Nowak, 3

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pola imie, nazwisko i punkty z tabeli karty_wedkarskie dla zwycięzcy zawodów wędkarskich o identyfikatorze 4 (identyfikator dotyczy zawodów, a nie wędkarza), należy użyć relacji

    • SELECT imie, nazwisko, punkty - pola wędkarza,
    • FROM karty_wedkarskie JOIN zawody_wedkarskie - złączenie tabel,
    • ON karty_wedkarskie.id = zawody_wedkarskie.Karty_wedkarskie_id - relacja z obrazu 1: zawody wskazują zwycięzcę,
    • WHERE zawody_wedkarskie.id = 4 - numer zawodów; przed id musi stać nazwa tabeli, bo pole o tej nazwie jest w obu tabelach.

    Wynik: Andrzej Nowak 3 - jak w kluczu. Warunek karty_wedkarskie.id = 4 (numer wędkarza) daje pusty wynik, bo w bazie są tylko dwaj wędkarze - przed tym ostrzega nawias w arkuszu. Zrzut: kw3.jpg.

    Typowe błędy

    Samo WHERE id = 4 w złączeniu kończy się błędem „Column 'id' in where clause is ambiguous” - pole id jest w obu tabelach.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    INSERT INTO zawody_wedkarskie VALUES (NULL, 2, 4, '2021-09-28', 'Andrzej Nowak');
    
    -- Zapytanie 2
    SELECT id, data_zawodow FROM zawody_wedkarskie WHERE sedzia = 'Krzysztof Dobrowolski';
    
    -- Zapytanie 3
    SELECT imie, nazwisko, punkty FROM karty_wedkarskie JOIN zawody_wedkarskie ON karty_wedkarskie.id = zawody_wedkarskie.Karty_wedkarskie_id WHERE zawody_wedkarskie.id = 4;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: dwa punkty więcej dla wędkarza numer 1

    Kryteria:

    R.1.6 Utworzono zapytanie 4 aktualizujące dane w tabeli karty_wedkarskie , wartość pola punkty jedynie dla rekordu o identyfikatorze 1 należy zwiększyć o 2. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE karty_wedkarskie SET punkty = punkty + 2 WHERE karty_wedkarskie.id = 1; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnej aktualizacji lub tabela ze zmienioną wartością

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: aktualizujące dane w tabeli karty_wedkarskie, wartość pola punkty dla rekordu o identyfikatorze 1 należy zwiększyć o 2

    • UPDATE karty_wedkarskie,
    • SET punkty = punkty + 2 - nowa wartość liczona ze starej; nie trzeba znać aktualnej liczby punktów,
    • WHERE id = 1 - tylko Jan Kowalski.

    Jan Kowalski miał 23 punkty, po zapytaniu ma 25; Andrzej Nowak bez zmian. Zrzut kw4.jpg ma komunikat o jednym zmodyfikowanym rekordzie i tabelę po zmianie.

    Typowe błędy

    SET punkty = 25 daje dziś ten sam wynik, ale nie jest „zwiększeniem o 2” - klucz wymaga zapytania uniwersalnego dla każdego zestawu danych.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    INSERT INTO zawody_wedkarskie VALUES (NULL, 2, 4, '2021-09-28', 'Andrzej Nowak');
    
    -- Zapytanie 2
    SELECT id, data_zawodow FROM zawody_wedkarskie WHERE sedzia = 'Krzysztof Dobrowolski';
    
    -- Zapytanie 3
    SELECT imie, nazwisko, punkty FROM karty_wedkarskie JOIN zawody_wedkarskie ON karty_wedkarskie.id = zawody_wedkarskie.Karty_wedkarskie_id WHERE zawody_wedkarskie.id = 4;
    
    -- Zapytanie 4
    UPDATE karty_wedkarskie SET punkty = punkty + 2 WHERE id = 1;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

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

    Krok 8: Zdjęcie zawody.jpg: odbicie i wysokość 250 px

    Kryteria:

    R.2.1 Grafikę z pliku o nazwie zawody.jpg odbito w taki sposób, aby osoba na grafice znajdowała się po prawej stronie jak na obrazie 2 oraz przeskalowano z zachowaniem proporcji do wysokości 250 px. Odpowiadająca temu szerokość wynosi 251 px (± 2 px)

    ok. 3 min
    Polecenie z arkusza

    Plik zawody.jpg, wypakowany z archiwum, należy odbić w taki sposób, aby osoba na grafice znajdowała się po prawej stronie, jak na obrazie 2 oraz przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 250 px i zapisać pod tą samą nazwą

    W GIMP-ie dwie operacje: Obraz → Przekształć → Odbij poziomo (wędkarz przechodzi z lewej na prawą stronę) i Obraz → Skaluj obraz z zablokowanym łańcuchem proporcji, wysokość 250 px. Obraz miał 415 × 413 px, więc szerokość sama zmienia się na 251 px - tyle podaje klucz (±2 px). Na koniec Plik → Nadpisz zawody.jpg.

    Typowe błędy

    Odbij pionowo stawia wędkarza do góry nogami - potrzebne jest odbicie w poziomie (lewo-prawo).

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik zawody.html w HTML5

    ok. 1 min
    Polecenie z arkusza

    Składa się ze strony o nazwie zawody.html zapisanej w języku HTML 5 oraz skryptu zgloszenie.php. Poniższe wymagania dotyczą tylko pliku zawody.html

    Deklaracja <!DOCTYPE html> i szkielet strony. Strona sama nie ma kodu PHP, więc ma rozszerzenie .html; skrypt zgloszenie.php powstanie osobno. Formularz będzie działał tylko wtedy, gdy strona jest otwarta przez serwer XAMPP (http://localhost/...) - inaczej po wysłaniu przeglądarka pokaże kod PHP zamiast go wykonać.

    zawody.html HTML nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  10. Krok 10: Język strony

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany język dla witryny: polski

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

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

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku o nazwie zawody.html oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> oraz zadeklarowano dla witryny język polski

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> jako pierwszy element <head>. Razem z nazwą pliku, deklaracją HTML5 i językiem to jedno kryterium klucza (R.2.2).

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

    Kryteria:

    R.2.3 Nadano tytuł strony: Zawody wędkarskie

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Zawody wędkarskie”

    <title> w <head>.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  13. Krok 13: Podpięcie arkusza stylów

    Kryteria:

    R.3.6 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl3.css , formatowanie 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 styl3.css prawidłowo połączony z kodem strony

    Nazwa pliku: styl3.css - z cyfrą 3. Całe formatowanie ma pochodzić z tego pliku, bez atrybutów style.

    Typowe błędy

    Klucz odbiera R.3.6 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  14. Krok 14: Bloki: lewy, prawy, główny i dwie stopki

    Kryteria:

    R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: lewy, prawy, główny i dwa bloki stopki. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

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

    Górne bloki to <section> z identyfikatorami left i right (różne szerokości i wyrównanie), blok główny to <main>, a dwie stopki - dwa znaczniki <footer>. Stopki mają identyczny styl, więc nie potrzebują identyfikatorów: wystarczy reguła dla znacznika footer.

    zawody.html HTML zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
        </section>
        <section id="right">
        </section>
        <main>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  15. Krok 15: Blok lewy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: nagłówek pierwszego stopnia o treści „Zawody polskich wędkarzy”

    <h1> w bloku lewym.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
        </section>
        <main>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  16. Krok 16: Blok prawy: zdjęcie

    Kryteria:

    R.2.7 W bloku prawym umieszczono obraz zawody.jpg z tekstem alternatywnym "wędkowanie"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego: obraz zawody.jpg z tekstem alternatywnym o treści: „wędkowanie”

    <img> z odbitym i przeskalowanym zdjęciem; tekst alternatywny z polską literą „ę”.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  17. Krok 17: Blok główny: nagłówek „Łowiska”

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści: „Łowiska”

    <h3> - arkusz nie używa tu <h2>; stopień nagłówka trzeba wziąć z treści zadania.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  18. Krok 18: Blok główny: lista łowisk

    Kryteria:

    R.2.6 W bloku głównym umieszczono listę punktową z czterema elementami, zastosowano znaczniki <ul>, <li>

    ok. 2 min
    Polecenie z arkusza

    Lista punktowana (nieuporządkowana) zawierająca elementy: Zalew Węgrowski, Zbiornik Bukówka, Jeziorko Bartbetowskie, Warta-Obrzycko

    Lista punktowana to <ul>, a każde łowisko jest osobnym elementem <li>. Lista jest zwykłym HTML-em, nie skryptem - nazwy wpisuje się z polskimi literami tak jak w arkuszu (w tabeli lowisko są zapisane bez nich).

    zawody.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  19. Krok 19: Blok główny: nagłówek nad formularzem

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści: „Dodaj zawody wędkarskie”

    Drugi <h3> bloku głównego.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  20. Krok 20: Blok główny: formularz POST do zgloszenie.php

    Kryteria:

    R.3.5 Formularz wysyła dane metodą POST do skryptu zgloszenie.php

    ok. 2 min
    Polecenie z arkusza

    Formularz wysyłający dane metodą bezpieczną do pliku zgloszenie.php zawierający pola

    <form> z atrybutami action="zgloszenie.php" (dokąd trafią dane) i method="post". Dane idą w treści żądania, a nie w adresie strony.

    ⚠️ Rozbieżność arkusz-klucz: arkusz każe wysyłać dane „metodą bezpieczną”, a w specyfikacji HTTP (RFC 9110) metody bezpieczne (safe) to GET i HEAD - te, które nie zmieniają danych na serwerze. Klucz CKE (R.3.5) wymaga POST - na egzaminie punkt daje wersja z klucza.

    Typowe błędy

    Formularz bez method wysyła dane metodą GET - skrypt czytający $_POST niczego nie dostanie, a R.3.5 nie jest spełnione.

    zawody.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
            </form>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  21. Krok 21: Formularz: pole liczbowe „Łowisko”

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne typu numerycznego poprzedzone tekstem: „Łowisko: ”

    <input type="number"> - w pole wpisuje się numer łowiska z tabeli lowisko. Atrybut name="fishery" to nazwa, pod którą wartość dotrze do skryptu ($_POST["fishery"]); <br> przenosi kolejne pole do nowej linii, jak na obrazie 2.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
            </form>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  22. Krok 22: Formularz: pole daty z kalendarzem

    Kryteria:

    R.3.3 Jedno pole edycyjne jest typu numerycznego, drugie typu date

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne umożliwiające wybranie daty z kalendarza, poprzedzone tekstem: „Data: ”

    <input type="date"> - przeglądarka pokazuje kalendarz do wyboru dnia. Na ekranie data ma format zależny od języka systemu (np. dd.mm.rrrr), ale do skryptu zawsze trafia w postaci 2021-10-02 - dokładnie takiej, jakiej potrzebuje pole DATE w bazie. Pole liczbowe i pole daty są gotowe (R.3.3).

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
                <label for="date">Data: </label><input type="date" id="date" name="date"><br>
            </form>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  23. Krok 23: Formularz: pole „Sędzia”

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne poprzedzone tekstem: „Sędzia: ”

    Zwykłe pole tekstowe z nazwą referee.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
                <label for="date">Data: </label><input type="date" id="date" name="date"><br>
                <label for="referee">Sędzia: </label><input type="text" id="referee" name="referee"><br>
            </form>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  24. Krok 24: Formularz: przycisk CZYŚĆ

    ok. 1 min
    Polecenie z arkusza

    Przycisk czyszczący zawartość formularza z etykietą „CZYŚĆ”

    <input type="reset"> przywraca pola formularza do stanu początkowego - bez żadnego skryptu. Napis na przycisku podaje atrybut value.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
                <label for="date">Data: </label><input type="date" id="date" name="date"><br>
                <label for="referee">Sędzia: </label><input type="text" id="referee" name="referee"><br>
                <input type="reset" value="CZYŚĆ">
            </form>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  25. Krok 25: Formularz: przycisk DODAJ

    Kryteria: ,

    R.2.8 W bloku głównym umieszczono formularz z trzema polami edycyjnymi i dwoma przyciskami, zastosowano znacznik <form>

    R.3.4 Jeden przycisk czyści dane formularza, drugi wysyła dane do skryptu (input lub button z typem submit lub button bez typu)

    ok. 1 min
    Polecenie z arkusza

    Przycisk wysyłający zawartość formularza z etykietą „DODAJ”

    <input type="submit"> wysyła formularz pod adres z action. Oba przyciski są znacznikami input, tak jak pola - jedna reguła CSS dla input obejmie wszystkie kontrolki. Formularz ma trzy pola i dwa przyciski (R.2.8), jeden czyści, drugi wysyła (R.3.4).

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
                <label for="date">Data: </label><input type="date" id="date" name="date"><br>
                <label for="referee">Sędzia: </label><input type="text" id="referee" name="referee"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="DODAJ">
            </form>
        </main>
        <footer>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  26. Krok 26: Pierwsza stopka: odnośnik do kwerendy.txt

    Kryteria:

    R.3.2 Po wybraniu odnośnika "Pobierz" otwiera się lub pobiera plik kwerendy.txt

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku stopki: odnośnik do pliku kwerendy.txt o treści: „Pobierz”

    href z nazwą pliku z tego samego folderu - przeglądarka otworzy plik albo go pobierze; klucz (R.3.2) uznaje oba zachowania.

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
                <label for="date">Data: </label><input type="date" id="date" name="date"><br>
                <label for="referee">Sędzia: </label><input type="text" id="referee" name="referee"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="DODAJ">
            </form>
        </main>
        <footer>
            <a href="kwerendy.txt">Pobierz</a>
        </footer>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  27. Krok 27: Druga stopka

    Kryteria:

    R.2.5 W bloku lewym zapisano nagłówek h1: „Zawody polskich wędkarzy”, w bloku głównym dwa h3: „Łowiska” i „Dodaj zawody wędkarskie” oraz w drugiej stopce akapit o treści "Stronę przygotował:" z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku stopki: akapit (paragraf) o treści: „Stronę przygotował: ”, dalej wstawiony numer zdającego, którym został podpisany arkusz.

    Akapit <p> w drugim <footer>. Na egzaminie w miejscu imienia i nazwiska wpisuje się numer, którym podpisano arkusz, czyli PESEL; w tym rozwiązaniu stoi tam „Bartosz Bryniarski”. Strona ma już <h1>, dwa <h3> i akapit w drugiej stopce (R.2.5).

    zawody.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Zawody wędkarskie</title>
        <link rel="stylesheet" href="styl3.css">
    </head>
    <body>
        <section id="left">
            <h1>Zawody polskich wędkarzy</h1>
        </section>
        <section id="right">
            <img src="zawody.jpg" alt="wędkowanie">
        </section>
        <main>
            <h3>Łowiska</h3>
            <ul>
                <li>Zalew Węgrowski</li>
                <li>Zbiornik Bukówka</li>
                <li>Jeziorko Bartbetowskie</li>
                <li>Warta-Obrzycko</li>
            </ul>
            <h3>Dodaj zawody wędkarskie</h3>
            <form action="zgloszenie.php" method="post">
                <label for="fishery">Łowisko: </label><input type="number" id="fishery" name="fishery"><br>
                <label for="date">Data: </label><input type="date" id="date" name="date"><br>
                <label for="referee">Sędzia: </label><input type="text" id="referee" name="referee"><br>
                <input type="reset" value="CZYŚĆ">
                <input type="submit" value="DODAJ">
            </form>
        </main>
        <footer>
            <a href="kwerendy.txt">Pobierz</a>
        </footer>
        <footer>
            <p>Stronę przygotował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (zawody.html)
  28. Etap 3: Styl CSS

    Kroki 28-37 · po tym etapie masz 30 z 35 kryteriów (pkt)

    Krok 28: Krój czcionki dla wszystkich elementów

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (*): krój czcionki Verdana (w przypadku wymienionych kilku czcionek Verdana jest wymieniona jako pierwsza)

    ok. 1 min
    Polecenie z arkusza

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

    Selektor uniwersalny * - krój dostają wszystkie elementy, także pola i przyciski formularza.

    styl3.css CSS nowy plik
    * {
        font-family: Verdana;
    }
    Podgląd strony po tym kroku (zawody.html)
  29. Krok 29: Bloki lewy i prawy

    ok. 2 min
    Polecenie z arkusza

    Wspólne dla bloku lewego i prawego: kolor tła SeaGreen, biały kolor czcionki, interlinia 150 px, wysokość 260 px, rozmiar czcionki 160%

    Interlinia to line-height - wysokość linii tekstu. 150 px przy wysokości bloku 260 px sprawia, że nagłówek stoi wyraźnie niżej niż przy górnej krawędzi, jak na obrazie 2. Wysokości (R.4.5) i interlinia odnośnika (R.4.6) dojdą przy stopkach i odnośniku.

    styl3.css CSS zmienione: 7 linii
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    Podgląd strony po tym kroku (zawody.html)
  30. Krok 30: Blok lewy: szerokość

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla bloku lewego: szerokość 75%

    Osobna reguła dla #left - tylko to, czym blok lewy różni się od prawego.

    styl3.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    Podgląd strony po tym kroku (zawody.html)
  31. Krok 31: Blok prawy: szerokość i wyrównanie

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla bloku prawego: szerokość 25%, wyrównanie tekstu do prawej strony

    text-align: right działa też na obraz, bo <img> jest elementem w linii - zdjęcie dosuwa się do prawej krawędzi bloku. 75% + 25% = 100%.

    styl3.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    Podgląd strony po tym kroku (zawody.html)
  32. Krok 32: Blok główny

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: kolor tła MintCream, marginesy wewnętrzne 80 px

    Selektor znacznika main; padding: 80px z każdej strony - stąd duże odstępy wokół listy i formularza na obrazie 2.

    styl3.css CSS zmienione: 4 linie
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    main {
        background-color: MintCream;
        padding: 80px;
    }
    Podgląd strony po tym kroku (zawody.html)
  33. Krok 33: Obie stopki

    Kryteria: , ,

    R.4.4 Ustawiono szerokość bloku lewego 75%, prawego 25%, obu bloków stopki 50% (width lub grid-template-columns lub flex)

    R.4.5 Ustawiono wysokość dla bloku lewego i prawego 260px oraz dla obu bloków stopki 70px

    R.4.8 Ustawiono wyrównanie tekstu do prawej strony dla bloku prawego, do środka dla obu bloków stopki oraz ustawiono rozmiar czcionki 160% dla bloków lewego i prawego

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla obu stopek: kolor tła SeaGreen, biały kolor czcionki, szerokość 50%, wysokość 70 px, wyrównanie tekstu do środka

    Jedna reguła dla znacznika footer obejmuje obie stopki. Szerokości bloków (R.4.4), wysokości (R.4.5) i wyrównania tekstu z rozmiarem czcionki (R.4.8) są ustawione.

    styl3.css CSS zmienione: 7 linii
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    main {
        background-color: MintCream;
        padding: 80px;
    }
    footer {
        background-color: SeaGreen;
        color: white;
        width: 50%;
        height: 70px;
        text-align: center;
    }
    Podgląd strony po tym kroku (zawody.html)
  34. Krok 34: Kontrolki formularza

    ok. 1 min
    Polecenie z arkusza

    Dla selektora kontrolki (przyciski i pola edycyjne): margines zewnętrzny dolny 20 px

    Selektor znacznika input - pola i oba przyciski są w HTML-u znacznikami input, więc jedna reguła obejmuje wszystkie kontrolki. Margines zewnętrzny dolny to margin-bottom.

    Typowe błędy

    Przyciski zapisane jako <button> nie dostaną marginesu z reguły dla input - wtedy potrzebny jest selektor input, button.

    styl3.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    main {
        background-color: MintCream;
        padding: 80px;
    }
    footer {
        background-color: SeaGreen;
        color: white;
        width: 50%;
        height: 70px;
        text-align: center;
    }
    input {
        margin-bottom: 20px;
    }
    Podgląd strony po tym kroku (zawody.html)
  35. Krok 35: Cień obrazu

    Kryteria:

    R.4.9 Ustawiono cień dla selektora img o wartości box-shadow: 15px 15px 10px DimGray

    ok. 1 min
    Polecenie z arkusza

    Dla selektora obrazu: cień o przesunięciu 15 px w obu osiach, rozmyciu 10 px i kolorze DimGray

    Właściwość box-shadow, składnia podana w arkuszu: przesunięcie poziome, pionowe, rozmycie, kolor - 15px 15px 10px DimGray. Dodatnie przesunięcia kładą cień w prawo i w dół. Selektor znacznika img, jak każe uwaga pod listą stylów (R.4.9).

    styl3.css CSS zmienione: 3 linie
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    main {
        background-color: MintCream;
        padding: 80px;
    }
    footer {
        background-color: SeaGreen;
        color: white;
        width: 50%;
        height: 70px;
        text-align: center;
    }
    input {
        margin-bottom: 20px;
    }
    img {
        box-shadow: 15px 15px 10px DimGray;
    }
    Podgląd strony po tym kroku (zawody.html)
  36. Krok 36: Odnośnik

    Kryteria: , , , ,

    R.4.2 Ustawiono kolor tła SeaGreen dla bloków lewego, prawego i obu bloków stopki oraz MintCream dla bloku głównego i selektora a

    R.4.3 Ustawiono biały kolor czcionki dla bloków lewego, prawego i obu bloków stopki oraz SeaGreen dla odnośnika

    R.4.6 Ustawiono interlinię dla bloku lewego i prawego: 150px oraz 70px dla odnośnika

    R.4.7 Ustawiono marginesy wewnętrzne (padding) 80px dla bloku głównego, 15px dla odnośnika oraz ustawiono margin-bottom: 20px dla wszystkich kontrolek

    R.4.10 Ustawiono brak podkreślenia dla odnośnika

    ok. 2 min
    Polecenie z arkusza

    Dla selektora odnośnika: brak podkreślenia, kolor tła MintCream, kolor czcionki SeaGreen, marginesy wewnętrzne 15 px, interlinia 70 px

    Selektor znacznika a. Brak podkreślenia to text-decoration: none. Interlinia 70 px równa wysokości stopki stawia napis w pionie na środku stopki, a jasne tło z marginesem wewnętrznym robi z odnośnika „przycisk”, jak na obrazie 2. Wszystkie kolory tła (R.4.2) i czcionki (R.4.3), interlinie (R.4.6), marginesy wewnętrzne razem z marginesem kontrolek (R.4.7) i brak podkreślenia (R.4.10) są ustawione.

    styl3.css CSS zmienione: 7 linii
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    main {
        background-color: MintCream;
        padding: 80px;
    }
    footer {
        background-color: SeaGreen;
        color: white;
        width: 50%;
        height: 70px;
        text-align: center;
    }
    input {
        margin-bottom: 20px;
    }
    img {
        box-shadow: 15px 15px 10px DimGray;
    }
    a {
        text-decoration: none;
        background-color: MintCream;
        color: SeaGreen;
        padding: 15px;
        line-height: 70px;
    }
    Podgląd strony po tym kroku (zawody.html)
  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 układające bloki na stronie, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

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

    float: left dostają bloki lewy i prawy (75% + 25%) oraz obie stopki (50% + 50%) - każda para staje obok siebie. Blok główny dostaje clear: both: zaczyna się pod pływającymi blokami, więc jego margines wewnętrzny 80 px liczy się od dolnej krawędzi bloków górnych. Bez tego blok główny zaczynałby się na samej górze strony, schowany za blokami lewym i prawym, i odstęp nad nagłówkiem „Łowiska” byłby mniejszy niż na obrazie 2.

    styl3.css CSS zmienione: 6 linii
    * {
        font-family: Verdana;
    }
    #left, #right {
        background-color: SeaGreen;
        color: white;
        line-height: 150px;
        height: 260px;
        font-size: 160%;
    }
    #left {
        width: 75%;
    }
    #right {
        width: 25%;
        text-align: right;
    }
    main {
        background-color: MintCream;
        padding: 80px;
    }
    footer {
        background-color: SeaGreen;
        color: white;
        width: 50%;
        height: 70px;
        text-align: center;
    }
    input {
        margin-bottom: 20px;
    }
    img {
        box-shadow: 15px 15px 10px DimGray;
    }
    a {
        text-decoration: none;
        background-color: MintCream;
        color: SeaGreen;
        padding: 15px;
        line-height: 70px;
    }
    #left, #right, footer {
        float: left;
    }
    main {
        clear: both;
    }
    Podgląd strony po tym kroku (zawody.html)
  38. Etap 4: Skrypt PHP

    Kroki 38-40 · po tym etapie masz 35 z 35 kryteriów (pkt)

    Krok 38: Plik zgloszenie.php: połączenie z bazą i zamknięcie

    Kryteria: ,

    R.5.1 Skrypt zawiera działające połączenie z serwerem bazy danych i wybór bazy wedkarstwo

    R.5.2 Ostatnią operacją na bazie jest jej zamknięcie (zgodne ze składnią)

    ok. 2 min
    Polecenie z arkusza

    Wymagania dotyczące skryptu: Napisany w języku PHP, w pliku zgloszenie.php. Skrypt łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie wedkarstwo. Na końcu działania skrypt zamyka połączenie z serwerem.

    zgloszenie.php w tym samym folderze co strona - tam wysyła formularz. Plik zawiera sam kod PHP, bez HTML-u: arkusz nie każe skryptowi nic wypisywać, więc po wysłaniu formularza przeglądarka pokaże pustą stronę, a efekt widać w bazie. mysqli_connect z czterema argumentami łączy się z serwerem i od razu wybiera bazę; uchwyt trafia do zmiennej $connection. Druga linia już teraz zamyka połączenie - kolejne instrukcje będą dopisywane nad nią, więc zamknięcie zostanie ostatnią operacją na bazie (R.5.2). Podgląd tego i kolejnych kroków to tabela zawody_wedkarskie w phpMyAdmin po wysłaniu formularza z łowiskiem 2, datą 2021-10-02 i sędzią Janem Kowalewskim.

    zgloszenie.php PHP nowy plik
    <?php
        $connection = mysqli_connect("localhost", "root", "", "wedkarstwo");
        mysqli_close($connection);
    ?>
    Podgląd strony po tym kroku (zgloszenie.php)
    Podgląd strony po kroku 38
  39. Krok 39: Skrypt: dane z formularza

    Kryteria:

    R.5.4 Skrypt pobiera dane z tablicy globalnej odpowiadającej zastosowanej metodzie formularza ($_POST, $_GET, $_REQUEST)

    ok. 2 min
    Polecenie z arkusza

    Skrypt działa na danych przesłanych z formularza

    Formularz wysyła dane metodą POST, więc skrypt czyta je z tablicy $_POST - kluczami są nazwy z atrybutów name pól: fishery, date i referee. Każda wartość trafia do osobnej zmiennej. Baza jeszcze się nie zmienia - zapytanie dojdzie w następnym kroku.

    zgloszenie.php PHP zmienione: 3 linie
    <?php
        $connection = mysqli_connect("localhost", "root", "", "wedkarstwo");
        $fishery = $_POST["fishery"];
        $date = $_POST["date"];
        $referee = $_POST["referee"];
        mysqli_close($connection);
    ?>
    Podgląd strony po tym kroku (zgloszenie.php)
    Podgląd strony po kroku 39
  40. Krok 40: Skrypt: zmodyfikowane zapytanie 1

    Kryteria: ,

    R.5.3 Skrypt wysyła do bazy danych zmodyfikowane zapytanie 1, tak że w odpowiednich polach są wpisane dane pobrane z formularza

    R.5.5 Skrypt dodaje rekord w tabeli zawody_wedkarskie - sprawdzić w phpMyAdmin

    ok. 3 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 1, które w polu Karty_wedkarskie_id zawiera wartość 0, pozostałe wartości wypełnione są danymi z formularza

    Zapytanie 1 ze zmienionymi wartościami: NULL dla id jak wcześniej, 0 w polu Karty_wedkarskie_id (zwycięzca jeszcze nieznany - tak każe arkusz), a dalej zmienne z formularza. PHP wstawia ich wartości do napisu w cudzysłowach; numer łowiska jest liczbą, więc stoi bez apostrofów, a data i sędzia - w apostrofach SQL-a. mysqli_query wysyła zapytanie. Sprawdzone: po wysłaniu formularza tabela ma nowy wiersz 6 z wartościami 0, 2, 2021-10-02, Jan Kowalewski - to samo zobaczy egzaminator w phpMyAdmin (R.5.5).

    ⚠️ Sprzeczność w arkuszu: wartość 0 nie wskazuje żadnego wędkarza (karty mają numery 1 i 2). Baza ją przyjmuje tylko dlatego, że w pliku baza.sql nie ma kluczy obcych, choć obraz 1 oznacza pola jako FK; z prawdziwym kluczem obcym ten sam INSERT kończy się błędem „foreign key constraint fails” (sprawdzone). Arkusz i klucz CKE wymagają 0 - na egzaminie punkt daje wartość z klucza.

    Typowe błędy

    Puste pole „Łowisko” zostawia w zapytaniu VALUES (NULL, 0, , '2021-10-02', 'Jan Kowalewski') - błąd składni SQL, wyjątek „Uncaught mysqli_sql_exception” i strona się urywa (sprawdzone w PHP 8.2). Klucz tego nie sprawdza - zabezpieczenie jest w etapie „Dobre praktyki”. Tabela zawody_wedkarskie jest w latin1: sędzia z polską literą, np. „Łukasz Żak”, zapisze się jako „?ukasz ?ak” - bez błędu, tylko z ostrzeżeniem w bazie (sprawdzone na MariaDB z XAMPP-a). Testując formularz, wpisz sędziego bez polskich liter, jak „Jan Kowalewski” z bazy.

    zgloszenie.php PHP zmienione: 2 linie
    <?php
        $connection = mysqli_connect("localhost", "root", "", "wedkarstwo");
        $fishery = $_POST["fishery"];
        $date = $_POST["date"];
        $referee = $_POST["referee"];
        $query = "INSERT INTO zawody_wedkarskie VALUES (NULL, 0, $fishery, '$date', '$referee');";
        mysqli_query($connection, $query);
        mysqli_close($connection);
    ?>
    Podgląd strony po tym kroku (zgloszenie.php)
    Podgląd strony po kroku 40
  41. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 41-42 · po tym etapie masz 35 z 35 kryteriów (pkt)

    Krok 41: Skrypt: komunikat i wejście bez formularza

    ok. 3 min
    Polecenie z arkusza

    Skrypt działa na danych przesłanych z formularza

    Wersja egzaminacyjna sprawdzona dwa razy:

    • po poprawnym wysłaniu przeglądarka pokazuje pustą białą stronę - użytkownik nie wie, czy zawody się zapisały,
    • otwarcie zgloszenie.php wprost (z paska adresu, bez formularza) daje trzy ostrzeżenia „Undefined array key”, a zapytanie z pustymi miejscami po zmiennych ma błąd składni - PHP 8 zgłasza wyjątek mysqli_sql_exception i skrypt kończy się błędem krytycznym.

    Teraz cała praca z bazą stoi w warunku isset z trzema nazwami pól - wykona się tylko wtedy, gdy formularz naprawdę przysłał dane. Skrypt wypisuje komunikat i odnośnik powrotny do strony. Podgląd: wynik po wysłaniu formularza. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    zgloszenie.php PHP zmienione: 13 linii
    <?php
        if (isset($_POST["fishery"], $_POST["date"], $_POST["referee"])) {
            $connection = mysqli_connect("localhost", "root", "", "wedkarstwo");
            $fishery = $_POST["fishery"];
            $date = $_POST["date"];
            $referee = $_POST["referee"];
            $query = "INSERT INTO zawody_wedkarskie VALUES (NULL, 0, $fishery, '$date', '$referee');";
            mysqli_query($connection, $query);
            mysqli_close($connection);
            echo "<p>Zawody zostały dodane.</p>";
        } else {
            echo "<p>Brak danych z formularza.</p>";
        }
        echo "<p><a href=\"zawody.html\">Powrót do strony zawodów</a></p>";
    ?>
    Podgląd strony po tym kroku (zgloszenie.php)
  42. Krok 42: Skrypt: puste pola, apostrof i zapytanie przygotowane

    ok. 4 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 1, które w polu Karty_wedkarskie_id zawiera wartość 0, pozostałe wartości wypełnione są danymi z formularza

    Trzy kolejne testy wersji egzaminacyjnej:

    • puste pole „Łowisko” - w zapytaniu zostaje VALUES (NULL, 0, , '2021-10-02', ...), błąd składni i wyjątek, skrypt się wywraca,
    • sędzia Piotr O'Neill - apostrof z nazwiska zamyka napis w SQL-u, znowu wyjątek; ten sam mechanizm pozwala wpisać w pole fragment SQL i zmienić zapytanie,
    • pusta data i pusty sędzia - baza przyjmuje wiersz z datą 0000-00-00 i bez sędziego (XAMPP nie ma trybu ścisłego, więc kończy się tylko ostrzeżeniem w bazie).

    Poprawka: numer łowiska rzutowany na liczbę ((int)), sędzia przycięty trim, a zapis tylko wtedy, gdy wszystkie trzy pola mają sensowną wartość. Samo zapytanie jest przygotowane - mysqli_prepare ze znakami ?, mysqli_stmt_bind_param z typami "iss" (liczba, tekst, tekst) i mysqli_stmt_execute - wartości idą do bazy osobno i żaden znak ich nie rozbije. Po poprawce wszystkie trzy przypadki działają (apostrof zapisuje się poprawnie, puste pola dają komunikat). Podgląd: wynik z sędzią Piotrem O'Neillem. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    zgloszenie.php PHP zmienione: 14 linii
    <?php
        if (isset($_POST["fishery"], $_POST["date"], $_POST["referee"])) {
            $fishery = (int) $_POST["fishery"];
            $date = $_POST["date"];
            $referee = trim($_POST["referee"]);
            if ($fishery > 0 && $date != "" && $referee != "") {
                $connection = mysqli_connect("localhost", "root", "", "wedkarstwo");
                $stmt = mysqli_prepare($connection, "INSERT INTO zawody_wedkarskie VALUES (NULL, 0, ?, ?, ?);");
                mysqli_stmt_bind_param($stmt, "iss", $fishery, $date, $referee);
                mysqli_stmt_execute($stmt);
                mysqli_close($connection);
                echo "<p>Zawody zostały dodane.</p>";
            } else {
                echo "<p>Wypełnij wszystkie pola formularza.</p>";
            }
            // $query = "INSERT INTO zawody_wedkarskie VALUES (NULL, 0, $fishery, '$date', '$referee');";
            // mysqli_query($connection, $query);
        } else {
            echo "<p>Brak danych z formularza.</p>";
        }
        echo "<p><a href=\"zawody.html\">Powrót do strony zawodów</a></p>";
    ?>

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

  43. Etap 6: Oddanie pracy

    Krok 43 · po tym etapie masz 35 z 35 kryteriów (pkt)

    Krok 43: 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 weryfikowałeś poprawność działania witryny. Umieść go w folderze z numerem, którym został podpisany arkusz. 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, przeglądarka.txt, styl3.css, zawody.html, zawody.jpg (odbity, 251 × 250 px) i zgloszenie.php. 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 41.

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.