Przejdź do głównej treści
INF.03-04-23.01-SGStyczeń 2023 · 43 kroki · ok. 67 min · 32 kryteria z klucza

Rozwiązanie krok po kroku: Portal biura podróży (Wersja podstawowa)

Portal biura turystycznego to baza biuro (z importu zadanie używa tabel wycieczki i zdjecia), cztery zapytania - warunek na polu logicznym, sortowanie malejąco, złączenie z warunkiem na cenie i ALTER TABLE dodające pole w wybranym miejscu - oraz jedna strona wycieczki.php. Skrypt 1 wypisuje dostępne wycieczki jako listę punktowaną według wzoru z arkusza, a Skrypt 2 buduje galerię dziewięciu zdjęć: nazwa pliku z bazy jest źródłem obrazu, a podpis - tekstem alternatywnym. W stylach jest pseudoelement ::first-letter (powiększona pierwsza litera nagłówków) i :hover na obrazie.

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), a na końcu przerobione na wersję z prawdziwych projektów.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, PDO)” jest drugi sposób rozwiązania tego samego arkusza: wszystkie bloki w siatce CSS z nazwanymi obszarami, kolory w zmiennych CSS, oba zapytania wykonane przez PDO na górze pliku wycieczki.php, a w HTML-u tylko pętle foreach z bezpiecznym wypisywaniem danych - obie wersje są zgodne z kluczem.

Baza i zdjęcia pochodzą z prawdziwego archiwum zad4 (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. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu w PHP 8.2 (klucz każe sprawdzać w XAMPP 8.1.2 - zachowanie tych funkcji jest w obu wersjach takie samo); najechanie kursorem na zdjęcie w galerii podświetla jego tło, jak na obrazie 2.

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

    Krok 1: Baza danych biuro

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie biuro

    Najpierw archiwum zad4.zip z pulpitu (hasło &poDrozE$ - z ampersandem na początku i dolarem na końcu) i folder z numerem zdającego, do którego trafiają egzamin3.sql i zdjęcia 1.jpg - 9.jpg. W phpMyAdmin: Nowa, nazwa biuro - plik SQL nazywa się inaczej niż baza.

    Typowe błędy

    Nazwa bazy musi brzmieć dokładnie biuro (nie egzamin3) - skrypty łączą się z bazą po nazwie (R.5.1).

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

    ok. 2 min
    Polecenie z arkusza

    Do bazy biuro zaimportuj tabele z pliku egzamin3.sql z rozpakowanego archiwum

    Przy zaznaczonej bazie biuro: Import → egzamin3.sql → Wykonaj. Plik zawiera osiem tabel z różnych zadań; tu potrzebne są dwie z obrazu 1: wycieczki (9 wycieczek: data, cel, cena, pole dostepna z wartością 1 albo 0 i zdjecia_id) i zdjecia (9 plików z podpisami). Wycieczka jest dostępna, gdy dostepna ma wartość TRUE, czyli 1.

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych biuro 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 pod nazwą import. Nie kadruj zrzutu. Zrzut powinien 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: dostępne wycieczki

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola id, dataWyjazdu, cel i cena z tabeli wycieczki dla dostępnych wycieczek. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE; (lub =1) oraz wynik działania udokumentowano zrzutem, na którym widocznych jest dokładnie 6 rekordów o id = 1, 2, 3, 4, 6, 9, jedynie pola id, dataWyjazdu, cel i cena

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola id, dataWyjazdu, cel i cena z tabeli wycieczki dla dostępnych wycieczek

    • SELECT id, dataWyjazdu, cel, cena - cztery pola; nazwa dataWyjazdu ma wielką literę w środku i tak trzeba ją pisać,
    • FROM wycieczki,
    • WHERE dostepna = TRUE - w MariaDB TRUE to po prostu 1, więc dostepna = 1 daje to samo (sprawdzone, klucz uznaje oba).

    Wynik: 6 wycieczek o id 1, 2, 3, 4, 6 i 9 - jak w kluczu. Z tego zapytania powstanie Skrypt 1. Zapytania trafiają do kwerendy.txt, zrzut wyniku do kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: zdjęcia malejąco po podpisie

    Kryteria:

    R.1.4 Utworzono zapytanie 2 wybierające jedynie pola nazwaPliku i podpis z tabeli zdjecia , sortując je malejąco według kolumny podpis. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC; oraz wynik działania udokumentowano zrzutem, na którym widocznych jest dokładnie 9 rekordów dla kolejnych nazw plików 2, 4, 6, 7, 9, 1, 5, 3, 8, jedynie pola nazwaPliku i podpis

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola nazwaPliku i podpis z tabeli zdjecia, sortując je malejąco według kolumny podpis

    • SELECT nazwaPliku, podpis,
    • FROM zdjecia,
    • ORDER BY podpis DESC - DESC to kierunek malejący (od Z do A); bez niego sortowanie byłoby rosnące.

    Wynik: 9 zdjęć od Wenecji do Barcelony, pliki w kolejności 2, 4, 6, 7, 9, 1, 5, 3, 8 - jak w kluczu i jak w galerii na obrazie 2. Z tego zapytania powstanie Skrypt 2. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    
    -- Zapytanie 2
    SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: wycieczki droższe niż 1200 zł z podpisem zdjęcia

    Kryteria:

    R.1.5 Utworzono zapytanie 3 wybierające jedynie cel i cenę wycieczki z tabeli wycieczki oraz odpowiadający im podpis z tabeli zdjecia dla wycieczek, których cena jest wyższa niż 1200 zł. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT cel, cena, podpis FROM zdjecia JOIN wycieczki ON zdjecia.id = wycieczki.zdjecia_id WHERE cena > 1200; (możliwe też INNER JOIN lub porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym widocznych jest dokładnie 5 rekordów: Francja, Paryz 1300 Paryz; Francja, Paryz 1350 Paryz; Hiszpania, Barcelona 1500 Barcelona; Hiszpania, Barcelona 1500 Barcelona; Hiszpania, Barcelona 1400 Barcelona

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie cel i cenę wycieczki z tabeli wycieczki oraz odpowiadający im podpis z tabeli zdjecia dla wycieczek, których cena jest wyższa niż 1200 zł. Zapytanie wykorzystuje relację

    • SELECT cel, cena, podpis - dwa pola z wycieczek i jedno ze zdjęć,
    • FROM wycieczki JOIN zdjecia - złączenie tabel,
    • ON wycieczki.zdjecia_id = zdjecia.id - relacja z obrazu 1,
    • WHERE cena > 1200 - „wyższa niż”, więc wycieczki za dokładnie 1200 zł odpadają.

    Wynik: 5 wierszy - dwa razy Paryż (1300 i 1350) i trzy razy Barcelona (1500, 1500, 1400) - jak w kluczu. Zapytanie nie sprawdza dostępności, więc są tu też wycieczki bez wolnych miejsc. Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    
    -- Zapytanie 2
    SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;
    
    -- Zapytanie 3
    SELECT cel, cena, podpis FROM wycieczki JOIN zdjecia ON wycieczki.zdjecia_id = zdjecia.id WHERE cena > 1200;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: pole liczbaDni po dataWyjazdu

    Kryteria:

    R.1.6 Utworzono zapytanie 4 dodające do tabeli wycieczki pole liczbaDni przyjmujące tylko liczby naturalne, pole powinno być wstawione po polu dataWyjazdu. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE wycieczki ADD liczbaDni int UNSIGNED AFTER dataWyjazdu; (lub ADD COLUMN, dowolny typ liczbowy całkowity, UNSIGNED obowiązkowe) oraz wynik działania udokumentowano zrzutem, na którym widnieje komunikat o poprawnym dodaniu lub struktura tabeli z dodaną kolumną

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: dodające do tabeli wycieczki pole liczbaDni przyjmujące tylko liczby naturalne, pole powinno być wstawione po polu dataWyjazdu

    • ALTER TABLE wycieczki - zmiana struktury istniejącej tabeli,
    • ADD liczbaDni INT UNSIGNED - nowe pole całkowite; UNSIGNED (bez znaku) wyklucza liczby ujemne, klucz wymaga go wprost,
    • AFTER dataWyjazdu - miejsce nowego pola; bez tego trafiłoby na koniec tabeli.

    Struktura po wykonaniu (DESCRIBE wycieczki) ma liczbaDni między dataWyjazdu a cel; istniejące wycieczki mają w nim NULL. Zapytanie 1 po tej zmianie daje ten sam wynik, bo wybiera pola z nazwy (sprawdzone). Zrzut kw4.jpg pokazuje komunikat i strukturę tabeli.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;
    
    -- Zapytanie 2
    SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;
    
    -- Zapytanie 3
    SELECT cel, cena, podpis FROM wycieczki JOIN zdjecia ON wycieczki.zdjecia_id = zdjecia.id WHERE cena > 1200;
    
    -- Zapytanie 4
    ALTER TABLE wycieczki ADD liczbaDni INT UNSIGNED AFTER dataWyjazdu;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Strona HTML

    Kroki 8-24 · po tym etapie masz 14 z 32 kryteriów (pkt)

    Krok 8: Plik wycieczki.php w HTML5

    Kryteria:

    R.2.1 Witrynę internetową zapisano w pliku PHP o nazwie wycieczki

    ok. 2 min
    Polecenie z arkusza

    Składa się ze strony o nazwie wycieczki.php

    Deklaracja <!DOCTYPE html> i szkielet strony. Rozszerzenie .php, bo strona będzie miała skrypty; na egzaminie folder z numerem zdającego leży w htdocs XAMPP-a i strona otwiera się przez http://localhost/..., inaczej PHP się nie wykona. W tym samym folderze leżą zdjęcia 1.jpg - 9.jpg z archiwum - baza podaje samą nazwę pliku.

    wycieczki.php PHP nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  9. Krok 9: Kodowanie polskich znaków

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> jako pierwszy element <head>.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  10. Krok 10: Język strony

    Kryteria:

    R.2.2 Zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> i zadeklarowano język witryny: polski np. <html lang="pl">

    ok. 1 min
    Polecenie z arkusza

    Zadeklarowany język witryny: polski

    Atrybut lang="pl" w znaczniku <html>. Razem z deklaracją HTML5 i kodowaniem to jedno kryterium klucza (R.2.2).

    wycieczki.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 (wycieczki.php)
  11. Krok 11: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł stronie: "Wycieczki po Europie"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Wycieczki po Europie”

    <title> w <head>.

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

    Kryteria:

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

    Nazwa pliku: styl4.css - z cyfrą 4. Całe formatowanie ma pochodzić z tego pliku.

    Typowe błędy

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

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  13. Krok 13: Bloki: baner, blok z danymi, trzy bloki i stopka

    Kryteria:

    R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: baner, dane, lewy, środkowy, prawy i stopka. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: na górze baner, poniżej blok z danymi, poniżej obok siebie trzy bloki: lewy, środkowy i prawy, poniżej stopka. 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

    Baner to <header>, stopka <footer>, a cztery bloki - <section> z identyfikatorami: trips (blok z danymi - lista wycieczek), left, middle i right. Blok z danymi zajmuje całą szerokość, trzy pozostałe staną obok siebie dzięki CSS.

    wycieczki.php PHP zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
        </header>
        <section id="trips">
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  14. Krok 14: Baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia o treści: „BIURO TURYSTYCZNE”

    <h1> w <header>, wielkimi literami jak w arkuszu.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  15. Krok 15: Blok z danymi: nagłówek trzeciego stopnia

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia o treści „Wycieczki, na które są wolne miejsca”

    <h3> - arkusz tak ustawia stopnie: <h3> nad listą, <h2> w trzech dolnych blokach.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  16. Krok 16: Blok z danymi: pusta lista punktowana

    ok. 1 min
    Polecenie z arkusza

    Lista punktowana (nieuporządkowana) wypełniona skryptem 1

    Lista punktowana to <ul>. Znaczniki listy są w HTML-u, a elementy <li> dopisze Skrypt 1 - po jednym na wycieczkę.

    wycieczki.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  17. Krok 17: Blok lewy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści: „Bestselery”

    <h2> z napisem dokładnie jak w arkuszu („Bestselery” przez jedno „l”).

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  18. Krok 18: Blok lewy: tabela bestsellerów

    Kryteria:

    R.2.7 W bloku lewym zapisano tabelę o dwóch kolumnach i trzech wierszach, zastosowano znaczniki <table>, <tr>, <td>

    ok. 2 min
    Polecenie z arkusza

    Tabela o dwóch kolumnach i trzech wierszach wypełniona danymi: Wenecja - kwiecień, Londyn - lipiec, Rzym - wrzesień

    <table> z trzema wierszami <tr>, a w każdym po dwie komórki <td> - miasto i miesiąc. Dane są stałe, więc tabela jest zwykłym HTML-em, bez skryptu.

    wycieczki.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  19. Krok 19: Blok środkowy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści: „Nasze zdjęcia”

    Pod nagłówkiem stanie galeria wypisana przez Skrypt 2.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
        </section>
        <section id="right">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  20. Krok 20: Blok środkowy: miejsce na Skrypt 2

    ok. 1 min
    Polecenie z arkusza

    Efekt działania skryptu 2

    Galeria zdjęć powstanie w bloku środkowym, pod nagłówkiem - blok PHP dojdzie w etapie skryptów. Ten krok nie zmienia pliku.

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

  21. Krok 21: Blok prawy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści: „Skontaktuj się”

    Trzeci <h2> - wszystkie trzy dostaną to samo formatowanie jedną regułą CSS.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  22. Krok 22: Blok prawy: odnośnik do adresu e-mail

    Kryteria:

    R.3.2 Na stronie umieszczono odnośnik "napisz do nas" łączący z adresem [email protected] (href="mailto:[email protected]")

    ok. 1 min
    Polecenie z arkusza

    Odnośnik do adresu e-mail [email protected] o treści: „napisz do nas”

    Odnośnik do adresu e-mail to <a> z adresem zaczynającym się od mailto: - kliknięcie otwiera program pocztowy z wpisanym odbiorcą.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  23. Krok 23: Blok prawy: akapit z telefonem

    Kryteria:

    R.2.5 W banerze zapisano nagłówek h1: "BIURO TURYSTYCZNE", w bloku dane h3: "Wycieczki, na które są wolne miejsca", w blokach lewym, środkowym i prawym przynajmniej jeden h2 z: "Bestselery", "Nasze zdjęcia", "Skontaktuj się" oraz przynajmniej jeden paragraf

    ok. 1 min
    Polecenie z arkusza

    Paragraf (akapit) o treści: „telefon: 111222333”

    <p> pod odnośnikiem. Strona ma już <h1>, <h3>, <h2> i akapit - komplet do R.2.5.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  24. Krok 24: Stopka

    ok. 1 min
    Polecenie z arkusza

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

    Akapit <p> w <footer>. Na egzaminie w miejscu imienia i nazwiska wpisuje się numer zdającego, czyli PESEL; w tym rozwiązaniu stoi tam „Bartosz Bryniarski”.

    wycieczki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  25. Etap 3: Styl CSS

    Kroki 25-35 · po tym etapie masz 25 z 32 kryteriów (pkt)

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

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

    Ustawione domyślne wartości dla wszystkich selektorów stylu CSS: krój czcionki Helvetica

    Selektor uniwersalny *. Helvetica jest typowa dla komputerów Apple; w Windows przeglądarka zwykle podstawi Arial.

    styl4.css CSS nowy plik
    * {
        font-family: Helvetica;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  26. Krok 26: Baner i stopka

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla banera i stopki: kolor tła #B3BC6D, biały kolor czcionki, wyrównanie tekstu do środka, marginesy wewnętrzne 5 px

    Jedna reguła dla dwóch selektorów; marginesy wewnętrzne to padding.

    styl4.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  27. Krok 27: Blok z danymi

    Kryteria:

    R.4.3 Ustawiono biały kolor czcionki dla banera i stopki oraz Olive dla bloku z danymi

    ok. 1 min
    Polecenie z arkusza

    Dla bloku z danymi: kolor tła #FFFFCE, kolor czcionki Olive, marginesy wewnętrzne: górny i dolny 10 px, prawy i lewy 150 px

    padding: 10px 150px - pierwsza wartość to górny i dolny margines wewnętrzny, druga lewy i prawy. Stąd wcięcie nagłówka i listy na obrazie 2. Kolory czcionek z arkusza są ustawione (R.4.3).

    styl4.css CSS zmienione: 5 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  28. Krok 28: Bloki lewy i prawy

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego i prawego: kolor tła #E6EE9C, szerokość 25%, wysokość 450 px, wyrównanie tekstu do środka

    Dwa identyfikatory po przecinku, wspólne właściwości.

    styl4.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  29. Krok 29: Blok środkowy

    Kryteria:

    R.4.2 Ustawiono kolor tła #B3BC6D dla banera i stopki, #FFFFCE dla bloku z danymi i środkowego, #E6EE9C dla bloku lewego i prawego

    ok. 1 min
    Polecenie z arkusza

    Dla bloku środkowego: kolor tła #FFFFCE, szerokość 50%, wysokość 450 px

    25% + 50% + 25% = 100%, więc trzy bloki zmieszczą się w jednym rzędzie. Wszystkie kolory tła są ustawione (R.4.2).

    styl4.css CSS zmienione: 5 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  30. Krok 30: 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 baner, poniżej blok z danymi, poniżej obok siebie trzy bloki: lewy, środkowy i prawy, poniżej stopka. 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ą tylko trzy dolne bloki - blok z danymi ma zostać na całą szerokość, więc nie może pływać (dlatego selektor wymienia identyfikatory, a nie wszystkie section). Stopka z clear: both zaczyna się pod pływającymi blokami.

    styl4.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    #left, #middle, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  31. Krok 31: Tabela: obramowanie, wyśrodkowanie, szerokość

    Kryteria: ,

    R.4.4 Ustawiono szerokość 25% dla bloków lewego i prawego, 50% dla środkowego (width lub grid-template-columns lub flex), 70% dla selektora table

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

    ok. 1 min
    Polecenie z arkusza

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

    Selektor znacznika table. margin: auto rozdziela wolne miejsce po równo z obu stron - tabela staje na środku bloku. Obramowanie ma tylko tabela, komórki nie - jak na obrazie 2. Wszystkie szerokości z arkusza są ustawione (R.4.4).

    styl4.css CSS zmienione: 5 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    #left, #middle, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    table {
        border: 1px solid Olive;
        margin: auto;
        width: 70%;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  32. Krok 32: Nagłówki drugiego stopnia wyśrodkowane

    Kryteria:

    R.4.7 Ustawiono wyrównanie tekstu do środka dla banera, stopki, bloku lewego, prawego, selektora h2

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka drugiego stopnia: wyrównanie tekstu do środka

    Selektor znacznika h2. Wyśrodkowane są już baner, stopka, bloki lewy i prawy oraz nagłówki (R.4.7).

    styl4.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    #left, #middle, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    table {
        border: 1px solid Olive;
        margin: auto;
        width: 70%;
    }
    h2 {
        text-align: center;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  33. Krok 33: Pierwsza litera nagłówka

    Kryteria:

    R.4.9 Ustawiono styl pseudoelementu first-letter ustawionego dla h2: rozmiar czcionki 150%, kolor czcionki Olive

    ok. 1 min
    Polecenie z arkusza

    Dla pierwszej litery nagłówka drugiego stopnia: rozmiar czcionki 150%, kolor czcionki Olive

    Pseudoelement ::first-letter to sama pierwsza litera tekstu elementu - „B”, „N” i „S” w trzech nagłówkach są większe i oliwkowe, reszta bez zmian.

    styl4.css CSS zmienione: 4 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    #left, #middle, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    table {
        border: 1px solid Olive;
        margin: auto;
        width: 70%;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
        color: Olive;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  34. Krok 34: Obraz: wysokość i marginesy wewnętrzne

    Kryteria: ,

    R.4.5 Ustawiono wysokość 450px dla bloków lewego, środkowego i prawego i 100px dla selektora img

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 5px dla banera i stopki, 7px dla obrazu, 10px górny i dolny i 150px prawy i lewy dla bloku z danymi oraz marginesy zewnętrzne (margin) auto dla tabeli

    ok. 1 min
    Polecenie z arkusza

    Dla selektora obrazu: wysokość 100 px, marginesy wewnętrzne 7 px

    Selektor znacznika img. padding to odstęp wokół zdjęcia wewnątrz elementu - na razie niewidoczny, ale pod kursorem zabarwi się kolorem tła. Wszystkie wysokości i marginesy z arkusza są ustawione (R.4.5, R.4.6).

    styl4.css CSS zmienione: 4 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    #left, #middle, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    table {
        border: 1px solid Olive;
        margin: auto;
        width: 70%;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
        color: Olive;
    }
    img {
        height: 100px;
        padding: 7px;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  35. Krok 35: Obraz pod kursorem

    Kryteria:

    R.4.10 Ustawiono styl pseudoklasy hover dla obrazu: kolor tła #B3BC6D

    ok. 1 min
    Polecenie z arkusza

    W momencie, gdy kursor znajduje się na obrazie, styl obrazu zmienia się na: kolor tła #B3BC6D

    Pseudoklasa :hover. Tło obrazu widać tylko w jego marginesie wewnętrznym (7 px) - dlatego na obrazie 2 środkowe zdjęcie ma zieloną ramkę.

    styl4.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: #B3BC6D;
        color: white;
        text-align: center;
        padding: 5px;
    }
    #trips {
        background-color: #FFFFCE;
        color: Olive;
        padding: 10px 150px;
    }
    #left, #right {
        background-color: #E6EE9C;
        width: 25%;
        height: 450px;
        text-align: center;
    }
    #middle {
        background-color: #FFFFCE;
        width: 50%;
        height: 450px;
    }
    #left, #middle, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    table {
        border: 1px solid Olive;
        margin: auto;
        width: 70%;
    }
    h2 {
        text-align: center;
    }
    h2::first-letter {
        font-size: 150%;
        color: Olive;
    }
    img {
        height: 100px;
        padding: 7px;
    }
    img:hover {
        background-color: #B3BC6D;
    }
    Podgląd strony po tym kroku (wycieczki.php)
  36. Etap 4: Skrypty PHP

    Kroki 36-40 · po tym etapie masz 32 z 32 kryteriów (pkt)

    Krok 36: Połączenie z bazą w Skrypcie 1, zamknięcie w Skrypcie 2

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Łączy się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie biuro

    Na stronie są dwa bloki PHP: Skrypt 1 wewnątrz listy <ul> w bloku z danymi i Skrypt 2 w bloku środkowym pod nagłówkiem. mysqli_connect z czterema argumentami łączy się z serwerem i od razu wybiera bazę; uchwyt trafia do zmiennej $connection. Skrypt 1 jest w kodzie wcześniej, więc to on otwiera połączenie, a Skrypt 2 je zamyka. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    wycieczki.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  37. Krok 37: Skrypt 1: zapytanie 1

    Kryteria:

    R.5.3 Skrypt 1 wysyła do bazy danych zapytanie 1 lub skrypt 2 wysyła zapytanie 2

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 1

    Zapytanie 1 bez zmian, w zmiennej $query. mysqli_query wysyła je do bazy, a w $result zostaje wynik do odczytania wiersz po wierszu.

    wycieczki.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                    $query = "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;";
                    $result = mysqli_query($connection, $query);
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  38. Krok 38: Skrypt 1: wycieczka w elemencie listy według wzoru

    Kryteria: ,

    R.5.4 Skrypt 1 wyświetla każdy zwrócony zapytaniem wiersz w formacie: „<id>. dnia <dataWyjazdu> jedziemy do <cel>, cena: <cena>”, gdzie < > oznacza pole zwrócone zapytaniem

    R.2.6 W bloku z danymi umieszczono listę punktowaną, zastosowano znaczniki <ul>, <li> (w skrypcie lub HTML)

    ok. 3 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w elemencie listy, według wzoru: „<id>. dnia <dataWyjazdu> jedziemy do <cel>, cena: <cena>”, gdzie w znakach < > zapisano pola zwrócone zapytaniem

    mysqli_fetch_row oddaje wiersz jako tablicę w kolejności pól zapytania: $row[0] - id, $row[1] - data, $row[2] - cel, $row[3] - cena. W napisie w cudzysłowach PHP podstawia wartości; kropka po $row[0] i przecinek po $row[2] są zwykłymi znakami wzoru. Podgląd: sześć wycieczek, od 1. dnia 2019-09-08 jedziemy do Wlochy, Wenecja, cena: 1200 - jak na obrazie 2. Lista ma <li> z pętli i <ul> z HTML-a (R.2.6).

    wycieczki.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                    $query = "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0]. dnia $row[1] jedziemy do $row[2], cena: $row[3]</li>";
                    }
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  39. Krok 39: Skrypt 2: zapytanie 2

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 2

    Zapytanie 2 bez zmian. Zmienne $query i $result mają te same nazwy co w Skrypcie 1 - tamten wynik został już wypisany, więc można je użyć ponownie. mysqli_close zostaje ostatnią instrukcją.

    wycieczki.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                    $query = "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0]. dnia $row[1] jedziemy do $row[2], cena: $row[3]</li>";
                    }
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                $query = "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;";
                $result = mysqli_query($connection, $query);
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>

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

  40. Krok 40: Skrypt 2: zdjęcia z bazy

    Kryteria: , ,

    R.5.5 Skrypt 2 wyświetla obrazy na podstawie danych zwróconych zapytaniem, w ten sposób, że pole nazwaPliku jest źródłem obrazu, a pole podpis jest tekstem alternatywnym obrazu

    R.2.8 W bloku środkowym umieszczono przynajmniej jeden obraz (w HTML lub skrypcie)

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

    ok. 3 min
    Polecenie z arkusza

    Dane z każdego zwróconego zapytaniem wiersza są wykorzystane do wyświetlenia kolejnych obrazów, w ten sposób, że pole nazwaPliku jest źródłem obrazu, a pole podpis jest tekstem alternatywnym obrazu

    Dla każdego wiersza jeden <img>: $row[0] (nazwa pliku) w atrybucie src, $row[1] (podpis) w alt. Cudzysłowy atrybutów wewnątrz napisu PHP poprzedza ukośnik \". Obrazy są elementami w linii, więc przy wysokości 100 px układają się po trzy w rzędzie. Podgląd: galeria z obrazu 2, od Wenecji do Barcelony. Zamknięcie połączenia jest ostatnią operacją na bazie (R.5.2).

    wycieczki.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                    $query = "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;";
                    $result = mysqli_query($connection, $query);
                    while ($row = mysqli_fetch_row($result)) {
                        echo "<li>$row[0]. dnia $row[1] jedziemy do $row[2], cena: $row[3]</li>";
                    }
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                $query = "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
                }
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  41. Etap 5: Dobre praktyki (poza kluczem)

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

    Krok 41: Skrypt 1: pola po nazwach i komunikat bez wolnych miejsc

    ok. 3 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w elemencie listy, według wzoru: „<id>. dnia <dataWyjazdu> jedziemy do <cel>, cena: <cena>”, gdzie w znakach < > zapisano pola zwrócone zapytaniem

    Wersja egzaminacyjna sprawdzona na bazie, w której żadna wycieczka nie ma wolnych miejsc (UPDATE wycieczki SET dostepna = 0): pod nagłówkiem „Wycieczki, na które są wolne miejsca” zostaje pusta lista i nie wiadomo, czy coś się zepsuło. mysqli_num_rows (funkcja z tabeli 1 arkusza) zwraca liczbę wierszy - przy zerze skrypt wypisuje „Brak wolnych miejsc na wycieczki”. Przy okazji mysqli_fetch_assoc zamiast numerów kolumn: $trip["dataWyjazdu"] czyta się łatwiej niż $row[1] i nie zależy od kolejności pól w zapytaniu, a tekst celu podróży przechodzi przez htmlspecialchars. Podgląd: lista dla bazy bez wolnych miejsc. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    wycieczki.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                    $query = "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;";
                    $result = mysqli_query($connection, $query);
                    if (mysqli_num_rows($result) == 0) {
                        echo "<li>Brak wolnych miejsc na wycieczki</li>";
                    }
                    while ($trip = mysqli_fetch_assoc($result)) {
                        $target = htmlspecialchars($trip["cel"]);
                        echo "<li>" . $trip["id"] . ". dnia " . $trip["dataWyjazdu"] . " jedziemy do $target, cena: " . $trip["cena"] . "</li>";
                    }
                    // while ($row = mysqli_fetch_row($result)) { ... "$row[0]. dnia $row[1] ..." ... }
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                $query = "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<img src=\"$row[0]\" alt=\"$row[1]\">";
                }
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  42. Krok 42: Skrypt 2: podpis bezpieczny w atrybucie i dymek z nazwą miasta

    ok. 3 min
    Polecenie z arkusza

    Dane z każdego zwróconego zapytaniem wiersza są wykorzystane do wyświetlenia kolejnych obrazów, w ten sposób, że pole nazwaPliku jest źródłem obrazu, a pole podpis jest tekstem alternatywnym obrazu

    Podpis z bazy trafia do atrybutu w cudzysłowach. Test na wersji egzaminacyjnej z podpisem Rzym "Wieczne Miasto" dał znacznik alt="Rzym "Wieczne Miasto"" - cudzysłów z bazy zamyka atrybut w połowie i reszta tekstu wypada z niego. htmlspecialchars zamienia cudzysłów na encję &quot;, więc atrybut zostaje cały (sprawdzone). Dodatkowo atrybut title z tym samym podpisem: najechanie kursorem na zdjęcie pokazuje dymek z nazwą miasta, czego sam alt nie robi. Podgląd: galeria na bazie z arkusza. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    wycieczki.php PHP zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Wycieczki po Europie</title>
        <link rel="stylesheet" href="styl4.css">
    </head>
    <body>
        <header>
            <h1>BIURO TURYSTYCZNE</h1>
        </header>
        <section id="trips">
            <h3>Wycieczki, na które są wolne miejsca</h3>
            <ul>
                <?php
                    $connection = mysqli_connect("localhost", "root", "", "biuro");
                    $query = "SELECT id, dataWyjazdu, cel, cena FROM wycieczki WHERE dostepna = TRUE;";
                    $result = mysqli_query($connection, $query);
                    if (mysqli_num_rows($result) == 0) {
                        echo "<li>Brak wolnych miejsc na wycieczki</li>";
                    }
                    while ($trip = mysqli_fetch_assoc($result)) {
                        $target = htmlspecialchars($trip["cel"]);
                        echo "<li>" . $trip["id"] . ". dnia " . $trip["dataWyjazdu"] . " jedziemy do $target, cena: " . $trip["cena"] . "</li>";
                    }
                    // while ($row = mysqli_fetch_row($result)) { ... "$row[0]. dnia $row[1] ..." ... }
                ?>
            </ul>
        </section>
        <section id="left">
            <h2>Bestselery</h2>
            <table>
                <tr><td>Wenecja</td><td>kwiecień</td></tr>
                <tr><td>Londyn</td><td>lipiec</td></tr>
                <tr><td>Rzym</td><td>wrzesień</td></tr>
            </table>
        </section>
        <section id="middle">
            <h2>Nasze zdjęcia</h2>
            <?php
                $query = "SELECT nazwaPliku, podpis FROM zdjecia ORDER BY podpis DESC;";
                $result = mysqli_query($connection, $query);
                while ($photo = mysqli_fetch_assoc($result)) {
                    $file = htmlspecialchars($photo["nazwaPliku"]);
                    $caption = htmlspecialchars($photo["podpis"]);
                    echo "<img src=\"$file\" alt=\"$caption\" title=\"$caption\">";
                }
                // while ($row = mysqli_fetch_row($result)) { echo "<img src=\"$row[0]\" alt=\"$row[1]\">"; }
                mysqli_close($connection);
            ?>
        </section>
        <section id="right">
            <h2>Skontaktuj się</h2>
            <a href="mailto:[email protected]">napisz do nas</a>
            <p>telefon: 111222333</p>
        </section>
        <footer>
            <p>Stronę wykonał: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (wycieczki.php)
  43. Etap 6: Oddanie pracy

    Krok 43 · po tym etapie masz 32 z 32 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. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Nazwij plik przeglądarka.txt i zapisz 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: 1.jpg - 9.jpg, import.png, kw1.jpg - kw4.jpg, kwerendy.txt, przeglądarka.txt, styl4.css i wycieczki.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 42.

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.