Przejdź do głównej treści
INF.03-04-24.06-SGCzerwiec 2024 · 46 kroków · ok. 76 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Galeria zdjęć z bazą (Wersja podstawowa)

Galeria zdjęć to baza galeria (autorzy i ich zdjęcia, relacja 1..n) z czterema zapytaniami - warunek na liczbie polubień, złączenie JOIN z sortowaniem, COUNT z GROUP BY i ALTER TABLE dodający kolumnę - oraz zdjęcie przeskalowane w edytorze grafiki i strona galeria.php z trzema blokami. Skrypt 1 wypełnia środkowy blok zdjęciami z bazy: każde zdjęcie ma ukryty tytuł, autora i odnośnik „Pobierz”, które pokazują się po najechaniu kursorem (przezroczystość opacity, pozycjonowanie absolute względem bloku i płynne przejście transition). Skrypt 2 pokazuje w prawym bloku zdjęcie z co najmniej stu polubieniami.

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: kolumny po nazwach, htmlspecialchars w atrybutach, Skrypt 2 odporny na brak zdjęcia ze stu polubieniami i opis dostępny także z klawiatury.

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

Baza i zdjęcia pochodzą z prawdziwego archiwum pliki4 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu. Podgląd strony od kroków z PHP to wynik prawdziwego uruchomienia kodu z danego kroku w PHP 8.2 na bazie z arkusza.

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

  1. Etap 1: Baza danych

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

    Krok 1: Baza danych galeria

    ok. 2 min
    Polecenie z arkusza

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

    Najpierw archiwum pliki4.zip z pulpitu (hasło (G@LeriA) razem z nawiasami okrągłymi) i folder z numerem zdającego, do którego trafiają rozpakowane pliki - arkusz zaleca, żeby zdjęcia leżały obok pliku strony. W phpMyAdmin: Nowa, nazwa galeria, porównywanie utf8_unicode_ci.

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

    ok. 2 min
    Polecenie z arkusza

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

    Zaznaczona baza galeria, potem Import → baza.sql → Wykonaj. Powstają dwie tabele z obrazu 1: autorzy (11 osób) i zdjecia (12 zdjęć: tytuł, nazwa pliku, liczba polubień i autorzy_id wskazujące autora - relacja 1..n).

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych galeria 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: zdjęcia z co najmniej 100 polubieniami

    Kryteria: ,

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

    R.1.3 Wykonano zapytanie 1 wybierające jedynie pola tytul i plik z tabeli zdjecia dla zdjęć z polubieniami większymi lub równymi 100. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100; oraz wynik działania udokumentowano zrzutem, na którym są widoczne dane: Slava Ukraini! kiev.jpg

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola tytul i plik z tabeli zdjecia dla zdjęć z polubieniami większymi lub równymi 100

    • SELECT tytul, plik - dwa pola,
    • FROM zdjecia,
    • WHERE polubienia >= 100 - „większymi lub równymi”, więc >=.

    Wynik: jeden wiersz - Slava Ukraini! kiev.jpg, jak w kluczu. Z tego zapytania powstanie Skrypt 2 („Najbardziej lubiane”). Zapytania trafiają do kwerendy.txt, zrzut do kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: zdjęcia z autorami według nazwiska

    Kryteria:

    R.1.4 Wykonano zapytanie 2 wybierające jedynie pola plik, tytul, polubienia z tabeli zdjecia oraz odpowiadające im pola imie i nazwisko z tabeli autorzy posortowane rosnąco według nazwiska. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON autorzy_id = autorzy.id ORDER BY nazwisko; (możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE, opcjonalnie ASC przy sortowaniu) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 12 rekordów, jedynie pola plik, tytul, polubienia, imie, nazwisko, wyniki są posortowane wg. nazwiska

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 2: wybierające jedynie pola plik, tytul, polubienia z tabeli zdjecia oraz odpowiadające im pola imie i nazwisko z tabeli autorzy posortowane rosnąco według nazwiska. Należy posłużyć się relacją

    • SELECT plik, tytul, polubienia, imie, nazwisko - trzy pola zdjęcia i dwa autora,
    • FROM zdjecia JOIN autorzy - złączenie,
    • ON zdjecia.autorzy_id = autorzy.id - relacja z obrazu 1,
    • ORDER BY nazwisko - rosnąco (domyślnie, ASC można dopisać).

    Wynik: 12 wierszy od zdjęć Jolanty Białej (Kijów, Praga, Wrocław) - w tej kolejności zdjęcia staną w galerii na obrazie 2. Zrzut: kw2.jpg. Z tego zapytania powstanie Skrypt 1.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;
    
    -- Zapytanie 2
    SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: liczba zdjęć dla każdego imienia

    Kryteria:

    R.1.5 Wykonano zapytanie 3 wybierające jedynie pole imie oraz liczące ile jest zdjęć dla tego imienia. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, COUNT(*) FROM zdjecia JOIN autorzy ON autorzy_id = autorzy.id GROUP BY imie; (lub dowolne pole zamiast *, możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym są widoczne dane: Ewa 1; Ewelina 2; Jadwiga 4; Jan 2; Jolanta 3

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie pole imie oraz liczące ile jest zdjęć dla tego imienia. Należy posłużyć się relacją

    • SELECT imie, COUNT(*) - imię i liczba wierszy w grupie,
    • FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id - imię jest w tabeli autorów, a zdjęcia w drugiej, więc bez złączenia nie da się ich policzyć razem,
    • GROUP BY imie - jeden wiersz na każde imię.

    Wynik: Ewa 1, Ewelina 2, Jadwiga 4, Jan 2, Jolanta 3 - autorzy bez zdjęć nie trafiają do wyniku, bo złączenie nie znajduje dla nich pary. Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;
    
    -- Zapytanie 2
    SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;
    
    -- Zapytanie 3
    SELECT imie, COUNT(*) FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id GROUP BY imie;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: nowa kolumna rozmiarPliku

    Kryteria:

    R.1.6 Wykonano zapytanie 4 modyfikujące strukturę tabeli zdjecia. Dodana jest kolumna rozmiarPliku typu całkowitego. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE zdjecia ADD COLUMN rozmiarPliku INT; (słowo COLUMN jest opcjonalne, dowolny typ całkowity) oraz wynik działania udokumentowano zrzutem, na którym jest widoczny komunikat o poprawnym wykonaniu zapytania lub struktura tabeli z dodanym polem rozmiarPliku typu całkowitego

    ok. 1 min
    Polecenie z arkusza

    Zapytanie 4: modyfikujące strukturę tabeli zdjecia. Dodana jest kolumna rozmiarPliku typu całkowitego

    • ALTER TABLE zdjecia - zmiana struktury tabeli, nie danych,
    • ADD COLUMN rozmiarPliku INT - nowa kolumna typu całkowitego; w istniejących wierszach dostaje wartość NULL.

    Zapytanie nie zwraca wierszy - na zrzucie kw4.jpg widać komunikat o poprawnym wykonaniu albo strukturę tabeli z nowym polem (int(11)). Skrypty strony wybierają konkretne kolumny, więc nowe pole im nie przeszkadza.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;
    
    -- Zapytanie 2
    SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;
    
    -- Zapytanie 3
    SELECT imie, COUNT(*) FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id GROUP BY imie;
    
    -- Zapytanie 4
    ALTER TABLE zdjecia ADD COLUMN rozmiarPliku INT;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

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

    Krok 8: woodpecker.jpg: dokładnie 520 × 346 px

    Kryteria:

    R.2.1 Grafikę woodpecker.jpg przeskalowano do dokładnych wymiarów: szerokość 520 px i wysokość 346 px

    ok. 2 min
    Polecenie z arkusza

    Plik woodpecker.jpg, wypakowany z archiwum, należy przeskalować do dokładnych wymiarów szerokość 520 px i wysokość 346 px.

    Wszystkie zdjęcia z archiwum mają 520 × 346 pikseli - poza woodpecker.jpg (640 × 428). W GIMP-ie: Obraz → Skaluj obraz, rozłączony łańcuch między szerokością a wysokością i wpisane obie wartości: 520 i 346. Przy zamkniętym łańcuchu po wpisaniu szerokości 520 program sam wyliczy wysokość 348 (640 i 428 mają inne proporcje niż 520 i 346), a arkusz wymaga dokładnych wymiarów. Różnica dwóch pikseli nie zniekształca widocznie zdjęcia. Eksport pod tą samą nazwą: Plik → Nadpisz woodpecker.jpg.

    Typowe błędy

    Zdjęcie 520 × 348 (z zamkniętym łańcuchem) nie spełnia warunku „dokładnych wymiarów”.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik galeria.php w HTML5

    ok. 1 min
    Polecenie z arkusza

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

    Deklaracja <!DOCTYPE html>, sekcje head i body. Rozszerzenie .php, bo dojdą skrypty; strona otwiera się przez http://localhost/....

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

    ok. 1 min
    Polecenie z arkusza

    Ustawiony język zawartości strony na polski

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

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

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

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

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

    Kryteria:

    R.2.3 Nadano tytuł stronie: "Galeria"

    ok. 1 min
    Polecenie z arkusza

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

    <title> w <head>.

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

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

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

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  14. Krok 14: Bloki: baner, lewy, środkowy, prawy, stopka

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

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

    Baner to header, stopka footer (klucz wymaga ich wprost - R.2.4). Galeria jest główną treścią strony, więc środkowy blok to main. Bloki po bokach zawierają treść dodatkową (tematy, najbardziej lubiane zdjęcie) - oba to aside, rozróżnione identyfikatorami left i right. Kolejność w kodzie jest taka jak na obrazie 2, od lewej do prawej.

    galeria.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
        </header>
        <aside id="left">
        </aside>
        <main>
        </main>
        <aside id="right">
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  15. Krok 15: Baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: nagłówek pierwszego stopnia o treści „Zdjęcia”

    <h1> w banerze.

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
        </aside>
        <main>
        </main>
        <aside id="right">
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  16. Krok 16: Blok lewy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku lewego: Nagłówek drugiego stopnia o treści: „Tematy zdjęć”

    <h2> na początku bloku lewego.

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
        </aside>
        <main>
        </main>
        <aside id="right">
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  17. Krok 17: Lista numerowana tematów

    Kryteria:

    R.2.6 W bloku lewym umieszczono jedną listę numerowaną z pięcioma elementami, zastosowano znaczniki <ol> i <li>

    ok. 1 min
    Polecenie z arkusza

    Lista numerowana (uporządkowana) z elementami: Zwierzęta, Krajobrazy, Miasta, Przyroda, Samochody

    Lista uporządkowana to <ol> (przeglądarka sama numeruje elementy), każdy temat w <li>.

    galeria.php PHP zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
        </main>
        <aside id="right">
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  18. Krok 18: Blok prawy: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego: Nagłówek drugiego stopnia o treści: „Najbardziej lubiane”

    <h2> na początku bloku prawego. Pod nim stanie efekt Skryptu 2, a blok środkowy w całości wypełni Skrypt 1.

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  19. Krok 19: Napis w znaczniku tekstu o dużym znaczeniu

    Kryteria:

    R.2.9 W bloku prawym umieszczono napis o treści „Zobacz wszystkie nasze zdjęcia” zapisany w znaczniku semantycznym pisanym czcionką pogrubioną i oznaczającym tekst o dużym znaczeniu - znacznik <strong>

    ok. 1 min
    Polecenie z arkusza

    Napis o treści „Zobacz wszystkie nasze zdjęcia” zapisany w znaczniku semantycznym pisanym czcionką pogrubioną i oznaczającym tekst o dużym znaczeniu

    Tekst o dużym znaczeniu to <strong> (domyślnie pogrubiony; <b> też pogrubia, ale nie niesie znaczenia). Celowo bez paragrafu <p> - arkusz go nie wymaga, a za chwilę paragrafy w galerii dostaną styl ukrywający, który nie powinien dotknąć tego napisu.

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  20. Krok 20: Stopka z autorem

    Kryteria:

    R.2.5 W banerze zapisano nagłówek h1: "Zdjęcia" , w bloku lewym h2: "Tematy zdjęć" , w bloku prawym h2: "Najbardziej lubiane" , w stopce h5 z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: nagłówek piątego stopnia o treści „Stronę wykonał: ”, dalej wstawiony numer zdającego

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

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  21. Etap 3: Styl CSS

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

    Krok 21: Krój Helvetica dla wszystkich elementów

    Kryteria:

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

    ok. 1 min
    Polecenie z arkusza

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

    Selektor uniwersalny *. Na Windows Helvetica zwykle nie jest zainstalowana - przeglądarka użyje wtedy kroju domyślnego (na obrazie 2 to Arial); arkusz nie prosi o krój zapasowy.

    styl.css CSS nowy plik
    * {
        font-family: Helvetica;
    }
    Podgląd strony po tym kroku (galeria.php)
  22. Krok 22: Baner i stopka: kolory, odstęp, wyśrodkowanie

    ok. 1 min
    Polecenie z arkusza

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

    Dwa selektory po przecinku - jedna reguła dla obu bloków.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    Podgląd strony po tym kroku (galeria.php)
  23. Krok 23: Blok lewy i prawy: tło i wymiary

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla bloku lewego i prawego: kolor tła NavajoWhite, szerokość 15%, wysokość 700 px

    Identyfikatory z # - kropka (klasa) nie trafiłaby w bloki i zabrałaby R.3.3. NavajoWhite to nazwana barwa CSS (jasny beż).

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    Podgląd strony po tym kroku (galeria.php)
  24. Krok 24: Blok środkowy: wymiary i paski przewijania

    Kryteria: ,

    R.4.3 Ustawiono wysokość bloków lewego, środkowego i prawego na 700px

    R.4.5 Ustawiono wyrównanie tekstu do środka dla banera i stopki oraz zawsze widoczne paski przewijania (overflow: scroll;) dla bloku środkowego

    ok. 2 min
    Polecenie z arkusza

    Dla bloku środkowego: szerokość 70%, wysokość 700 px, zawsze widoczne paski przewijania

    „Zawsze widoczne” to overflow: scroll - pasek jest rysowany od początku, a dwanaście zdjęć i tak nie zmieści się w 700 px, więc galerię przewija się wewnątrz bloku. Ustawione są już wysokości trzech bloków (R.4.3), a wyśrodkowanie banera i stopki razem z paskami tego bloku to R.4.5.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    Podgląd strony po tym kroku (galeria.php)
  25. Krok 25: 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. Nie należy brać pod uwagę bloków generowanych skryptem. (prawidłowo zastosowano właściwości CSS decydujące o układzie strony np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

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

    Trzy bloki pod banerem float: left - stają obok siebie w kolejności z kodu (15% + 70% + 15% = cała szerokość). Stopka z clear: both zaczyna się pod nimi.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (galeria.php)
  26. Krok 26: Obrazy: szerokość 100%

    Kryteria:

    R.4.4 Ustawiono szerokość bloku lewego i prawego 15%, środkowego 70% (width lub grid- template-columns lub flex), selektora img 100%

    ok. 1 min
    Polecenie z arkusza

    Dla selektora obrazu: szerokość 100%

    Obraz zajmuje całą szerokość swojego rodzica: w galerii - bloku zdjęcia, w prawym bloku - całego bloku. Zgodnie z uwagą arkusza selektor to sam znacznik img. Komplet szerokości z klucza (R.4.4).

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    Podgląd strony po tym kroku (galeria.php)
  27. Krok 27: Blok zdjęcia: obok siebie, szerokość, marginesy, pozycja względna

    Kryteria:

    R.4.7 Ustawiono dla bloku generowanego skryptem 1: bloki ustawione obok siebie, szerokość 46%, marginesy zewnętrzne (margin) 2% (np. dla klasy, id jest błędem )

    ok. 2 min
    Polecenie z arkusza

    Dla bloku generowanego skryptem 1 i zawierającego zdjęcie i opis: bloki ustawione obok siebie (opływanie), szerokość 46%, marginesy zewnętrzne 2%, pozycjonowanie względne

    Bloki zdjęć wypisze Skrypt 1 z klasą photo (klucz: klasa, identyfikator byłby błędem - bloków jest dwanaście). „Opływanie” to float: left. 46% + 2% marginesu z każdej strony = 50%, więc w rzędzie mieszczą się dwa zdjęcia. position: relative nie przesuwa bloku, ale czyni go punktem odniesienia dla elementów pozycjonowanych absolute w środku - opis zdjęcia ułoży się na zdjęciu, a nie na całej stronie. Efekt będzie widać, gdy Skrypt 1 wypisze bloki.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    Podgląd strony po tym kroku (galeria.php)
  28. Krok 28: Opis zdjęcia: niewidoczny i pozycjonowany na zdjęciu

    Kryteria:

    R.4.9 Ustawiono pełną przezroczystość dla nagłówka trzeciego stopnia, paragrafu i odnośnika (opacity: 0;)

    ok. 2 min
    Polecenie z arkusza

    Wspólne dla nagłówka trzeciego stopnia, paragrafu, odnośnika: pełna przezroczystość (0), pozycjonowanie pozwalające przesuwać element względem rodzica

    opacity: 0 - element jest w pełni przezroczysty (nadal istnieje i reaguje na kliknięcie, tylko go nie widać). Przesuwanie „względem rodzica” to position: absolute z tabeli 2 arkusza - liczy się od najbliższego przodka z pozycją względną, czyli od bloku photo. Selektory zaczynają się od .photo, żeby styl dotyczył tylko opisu zdjęć: samo p albo a ukryłoby też inne paragrafy i odnośniki, które pojawiłyby się na stronie.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    .photo h3, .photo p, .photo a {
        opacity: 0;
        position: absolute;
    }
    Podgląd strony po tym kroku (galeria.php)
  29. Krok 29: Tytuł: 5% od góry

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla nagłówka trzeciego stopnia: odległość od górnej krawędzi rodzica 5%

    Właściwość top przy pozycji absolute to odległość od górnej krawędzi bloku zdjęcia. Procent liczy się od wysokości bloku.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    .photo h3, .photo p, .photo a {
        opacity: 0;
        position: absolute;
    }
    .photo h3 {
        top: 5%;
    }
    Podgląd strony po tym kroku (galeria.php)
  30. Krok 30: Paragraf: 30% od góry

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla paragrafu: odległość od górnej krawędzi rodzica 30%

    Autor stanie pod tytułem, mniej więcej w jednej trzeciej wysokości zdjęcia.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    .photo h3, .photo p, .photo a {
        opacity: 0;
        position: absolute;
    }
    .photo h3 {
        top: 5%;
    }
    .photo p {
        top: 30%;
    }
    Podgląd strony po tym kroku (galeria.php)
  31. Krok 31: Odnośnik: położenie, tło i odstęp

    Kryteria: , ,

    R.4.8 Ustawiono cechy pozycjonowania (position): relative dla bloku generowanego skryptem 1, absolute dla nagłówka trzeciego stopnia, paragrafu i odnośnika oraz odległości od górnej krawędzi (top) 5% dla nagłówka trzeciego stopnia, 30% dla paragrafu, 70% dla odnośnika oraz od lewej krawędzi (left) 70% dla odnośnika (kryterium należy uznać za spełnione, gdy poprawnie zdefiniowano formatowanie dla co najmniej 4 z 6 elementów)

    R.4.2 Ustawiono kolor tła Sienna i biały kolor czcionki dla banera i stopki, kolor tła: Navaj oWhite dla bloku lewego i prawego oraz kolor tła Sienna dla odnośnika

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 10px dla banera i stopki, 15px dla odnośnika

    ok. 2 min
    Polecenie z arkusza

    Dodatkowo dla odnośnika: odległość od górnej krawędzi rodzica 70%, od lewej krawędzi 70%, kolor tła Sienna, marginesy wewnętrzne 15 px

    top i left stawiają odnośnik w prawym dolnym rogu zdjęcia, a tło Sienna z odstępem 15 px robi z niego przycisk (obraz 3). Pozycjonowanie wszystkich elementów opisu jest komplet (R.4.8), tak samo kolory tła (R.4.2) i marginesy wewnętrzne (R.4.6).

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    .photo h3, .photo p, .photo a {
        opacity: 0;
        position: absolute;
    }
    .photo h3 {
        top: 5%;
    }
    .photo p {
        top: 30%;
    }
    .photo a {
        top: 70%;
        left: 70%;
        background-color: Sienna;
        padding: 15px;
    }
    Podgląd strony po tym kroku (galeria.php)
  32. Krok 32: Blok pod kursorem: zdjęcie blednie, opis się pojawia

    Kryteria:

    R.4.10 W momencie, gdy kursor myszy znajdzie się na bloku generowanym skryptem 1: przezroczystość dla zdjęcia w tym bloku zmienia się na 0.3, przezroczystość dla nagłówka trzeciego stopnia, paragrafu i odnośnika zmienia się na 1, dla zdjęcia zdefiniowano płynne przejście transition: 0.5s ease

    ok. 3 min
    Polecenie z arkusza

    W momencie, gdy kursor myszy znajdzie się na bloku generowanym skryptem 1: Zdjęcia z bloku środkowego przyjmują wartość przezroczystości 0.3 i jest ona zmieniana płynnie przez 0.5 sekundy efektem ease. Nagłówka trzeciego stopnia: brak przezroczystości (1). Paragrafu: brak przezroczystości. Odnośnika: brak przezroczystości

    Selektor .photo:hover img czyta się „obraz w bloku zdjęcia, nad którym stoi kursor” - pseudoklasa dotyczy bloku, a zmiana jego potomków. Zdjęcie przechodzi do przezroczystości 0.3, a tytuł, autor i odnośnik do 1 (pełna widoczność). transition: 0.5s ease stoi w zwykłej regule obrazu, więc zdjęcie blednie przez pół sekundy i tak samo płynnie wraca po zjechaniu kursora; ease to krzywa „wolno - szybko - wolno” (składnię transition podaje tabela 3 arkusza).

    styl.css CSS zmienione: 9 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    .photo h3, .photo p, .photo a {
        opacity: 0;
        position: absolute;
    }
    .photo h3 {
        top: 5%;
    }
    .photo p {
        top: 30%;
    }
    .photo a {
        top: 70%;
        left: 70%;
        background-color: Sienna;
        padding: 15px;
    }
    .photo img {
        transition: 0.5s ease;
    }
    .photo:hover img {
        opacity: 0.3;
    }
    .photo:hover h3, .photo:hover p, .photo:hover a {
        opacity: 1;
    }
    Podgląd strony po tym kroku (galeria.php)
  33. Etap 4: Skrypty PHP

    Kroki 33-42 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 33: Połączenie w Skrypcie 1, zamknięcie w Skrypcie 2

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

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

    Skrypt 1 wypełnia blok środkowy, więc stoi wewnątrz <main>; jest pierwszy na stronie i otwiera połączenie (mysqli_connect łączy się z serwerem i wybiera bazę, uchwyt w $connection). Skrypt 2 stoi w prawym bloku pod nagłówkiem - na razie tylko zamyka połączenie, a swoje instrukcje dostanie nad tą linią. Od tego kroku podgląd to wynik prawdziwego uruchomienia strony.

    galeria.php PHP zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  34. Krok 34: Skrypt 1: zapytanie 2

    Kryteria:

    R.5.3 Skrypt 1 zawiera instrukcje wysyłające do bazy danych zapytanie 2 lub skrypt 2: zapytanie 1

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 2

    Zapytanie 2 bez zmian w zmiennej $query; mysqli_query wysyła je do bazy, wynik czeka w $result.

    galeria.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>

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

  35. Krok 35: Skrypt 1: osobny blok dla każdego wiersza

    Kryteria:

    R.5.4 Skrypt 1 tworzy element blokowy dla każdego zwróconego z bazy wiersza

    ok. 2 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym bloku (obraz 3)

    Pętla while z mysqli_fetch_row przechodzi przez 12 wierszy wyniku i dla każdego wypisuje <div class="photo"> - na razie pusty. Cudzysłowy w HTML-u wewnątrz napisu PHP poprzedza ukośnik \". Numery kolumn w $row liczą się od pól zapytania: $row[0] - plik, $row[1] - tytuł, $row[2] - polubienia, $row[3] - imię, $row[4] - nazwisko.

    galeria.php PHP zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  36. Krok 36: Skrypt 1: zdjęcie z tekstem alternatywnym

    Kryteria: ,

    R.5.5 W każdym bloku wyświetlono zdjęcie, którego źródłem jest pole <plik> z bazy

    R.2.7 W bloku środkowym umieszczono przynajmniej jeden obraz z tekstem alternatywnym "zdjęcie" (wygenerowany skryptem lub w HTML)

    ok. 2 min
    Polecenie z arkusza

    Każdy blok zawiera: Obraz, którego źródło zostało zwrócone zapytaniem, z tekstem alternatywnym „zdjęcie”

    Źródło to nazwa pliku z pierwszej kolumny, a tekst alternatywny - stałe słowo „zdjęcie”, jak w arkuszu. Podgląd wygląda już jak obraz 2: zdjęcia po dwa w rzędzie, od Kijowa, Pragi i Wrocławia, z paskiem przewijania bloku środkowego.

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  37. Krok 37: Skrypt 1: tytuł w nagłówku trzeciego stopnia

    ok. 1 min
    Polecenie z arkusza

    Nagłówek trzeciego stopnia z tytułem zwróconym zapytaniem

    <h3> z tytułem z drugiej kolumny. W podglądzie go nie widać - styl ukrywa go (opacity: 0) do czasu najechania kursorem na zdjęcie.

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  38. Krok 38: Skrypt 1: autor i „Wiele osób polubiło” przy ponad 40 polubieniach

    ok. 2 min
    Polecenie z arkusza

    W przypadku, gdy zwrócona wartość polubień jest większa niż 40: paragraf o treści: „Autor: <imię> <nazwisko>. Wiele osób polubiło ten obraz”, łamanie linii po kropce.

    Warunek na trzeciej kolumnie: $row[2] > 40 - „większa niż”, więc „Urocze jeziorko” z dokładnie 40 polubieniami się nie łapie. Łamanie linii po kropce to <br> w środku paragrafu (obraz 3: „Autor: Jadwiga Kowalska.” i pod spodem „Wiele osób polubiło ten obraz”).

    galeria.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    if ($row[2] > 40) {
                        echo "<p>Autor: $row[3] $row[4].<br>Wiele osób polubiło ten obraz</p>";
                    }
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  39. Krok 39: Skrypt 1: sam autor w przeciwnym wypadku

    Kryteria:

    R.5.7 Gdy zwrócona zapytaniem wartość polubień jest większa niż 40 wyświetlony jest tekst: "Wiele osób polubiło ten obraz" , w przeciwnym wypadku tekst nie jest wyświetlony

    ok. 1 min
    Polecenie z arkusza

    W przeciwnym wypadku paragraf o treści: „Autor: <imię> <nazwisko>”, gdzie pola w nawiasach <> zostały pobrane z bazy danych

    Gałąź else - paragraf bez kropki i bez drugiej linii. Sprawdzone na bazie z arkusza: dłuższy napis dostaje 5 zdjęć (Kijów, Praga, Wrocław, motyl i dzięcioł), krótszy - pozostałe 7.

    galeria.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    if ($row[2] > 40) {
                        echo "<p>Autor: $row[3] $row[4].<br>Wiele osób polubiło ten obraz</p>";
                    } else {
                        echo "<p>Autor: $row[3] $row[4]</p>";
                    }
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  40. Krok 40: Skrypt 1: odnośnik „Pobierz” z atrybutem download

    Kryteria: ,

    R.3.2 Zapisano na stronie przynajmniej jeden odnośnik o treści „Pobierz" , wskazujący na dowolny plik graficzny. Po kliknięciu na odnośnik, zdjęcie jest pobierane - atrybut download (wygenerowana skryptem lub w HTML)

    R.5.6 W każdym bloku wyświetlono tytuł, imię i nazwisko oraz odnośnik prowadzący do grafiki, której nazwa pliku jest zwrócona z bazy

    ok. 2 min
    Polecenie z arkusza

    Odnośnik o treści „Pobierz” wskazujący na nazwę pliku zwróconą zapytaniem. Po kliknięciu na odnośnik, zdjęcie jest pobierane

    Zwykły odnośnik do pliku JPG otworzyłby zdjęcie w przeglądarce. Atrybut download każe je zapisać na dysku (R.3.2). Działa dla plików z tego samego serwera - a zdjęcia leżą obok strony. Każdy blok ma teraz zdjęcie, tytuł, autora i odnośnik do pliku (R.5.6).

    galeria.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    if ($row[2] > 40) {
                        echo "<p>Autor: $row[3] $row[4].<br>Wiele osób polubiło ten obraz</p>";
                    } else {
                        echo "<p>Autor: $row[3] $row[4]</p>";
                    }
                    echo "<a href=\"$row[0]\" download>Pobierz</a>";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  41. Krok 41: Skrypt 2: zapytanie 1

    ok. 1 min
    Polecenie z arkusza

    Wysyła do bazy danych zapytanie 1

    Zmienne $query i $result użyte ponownie - galeria jest już wypisana. Zapytanie zwraca jeden wiersz: tytuł i plik zdjęcia z Kijowa.

    galeria.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    if ($row[2] > 40) {
                        echo "<p>Autor: $row[3] $row[4].<br>Wiele osób polubiło ten obraz</p>";
                    } else {
                        echo "<p>Autor: $row[3] $row[4]</p>";
                    }
                    echo "<a href=\"$row[0]\" download>Pobierz</a>";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                $query = "SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;";
                $result = mysqli_query($connection, $query);
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>

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

  42. Krok 42: Skrypt 2: zdjęcie z tytułem jako tekstem alternatywnym

    Kryteria: , , ,

    R.5.8 Skrypt 2 wyświetla obraz, którego źródło zwrócone zapytaniem 1, wraz z tekstem alternatywnym pobranym z pola tytuł

    R.2.8 W bloku prawym umieszczono obraz z tekstem alternatywnym (wygenerowany skryptem lub w HTML)

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

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

    ok. 2 min
    Polecenie z arkusza

    Wyświetla obraz, którego źródło zostało zwrócone zapytaniem, wraz z tekstem alternatywnym pobranym z pola tytul

    Wiersz jest jeden, więc wystarczy jedno mysqli_fetch_row bez pętli. Kolejność kolumn zapytania 1 jest odwrotna niż w galerii: $row[0] - tytuł (do alt), $row[1] - plik (do src). Obraz ma szerokość całego prawego bloku (img 100%), a pod nim stoi pogrubiony napis - jak na obrazie 2 (R.5.8, R.2.8).

    To ostatni krok skryptów: połączenie zamyka mysqli_close na końcu Skryptu 2 (R.5.2), a wszystkie zmienne mają nazwy mówiące, co przechowują: $connection, $query, $result, $row (R.5.9).

    galeria.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    if ($row[2] > 40) {
                        echo "<p>Autor: $row[3] $row[4].<br>Wiele osób polubiło ten obraz</p>";
                    } else {
                        echo "<p>Autor: $row[3] $row[4]</p>";
                    }
                    echo "<a href=\"$row[0]\" download>Pobierz</a>";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                $query = "SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;";
                $result = mysqli_query($connection, $query);
                $row = mysqli_fetch_row($result);
                echo "<img src=\"$row[1]\" alt=\"$row[0]\">";
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (galeria.php)
  43. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 43-45 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 43: Skrypt 2 odporny na brak zdjęcia i cudzysłów w tytule

    ok. 3 min
    Polecenie z arkusza

    Wyświetla obraz, którego źródło zostało zwrócone zapytaniem, wraz z tekstem alternatywnym pobranym z pola tytul

    Wersja egzaminacyjna sprawdzona na dwóch zmianach w bazie. Gdy żadne zdjęcie nie ma stu polubień (Kijów z 99), mysqli_fetch_row zwraca null i PHP wypisuje ostrzeżenia „Trying to access array offset on value of type null” prosto na stronę. Gdy tytuł zawiera cudzysłów (Kijów "nocą"), atrybut alt urywa się na drugim cudzysłowie i znacznik jest uszkodzony. Poprawki: warunek if ($favourite) wypisuje obraz tylko wtedy, gdy wiersz istnieje, a htmlspecialchars zamienia cudzysłów na &quot;. Przy okazji ORDER BY polubienia DESC LIMIT 1 daje jedno, naprawdę najbardziej lubiane zdjęcie, nawet gdy stu polubień dobije kilka zdjęć, a mysqli_fetch_assoc pozwala pisać $favourite["plik"] zamiast pamiętać numer kolumny. Stare linie zostają w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    galeria.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($row = mysqli_fetch_row($result)) {
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$row[0]\" alt=\"zdjęcie\">";
                    echo "<h3>$row[1]</h3>";
                    if ($row[2] > 40) {
                        echo "<p>Autor: $row[3] $row[4].<br>Wiele osób polubiło ten obraz</p>";
                    } else {
                        echo "<p>Autor: $row[3] $row[4]</p>";
                    }
                    echo "<a href=\"$row[0]\" download>Pobierz</a>";
                    echo "</div>";
                }
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                $query = "SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100 ORDER BY polubienia DESC LIMIT 1;";
                $result = mysqli_query($connection, $query);
                $favourite = mysqli_fetch_assoc($result);
                if ($favourite) {
                    echo "<img src=\"" . htmlspecialchars($favourite["plik"]) . "\" alt=\"" . htmlspecialchars($favourite["tytul"]) . "\">";
                }
                // $query = "SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;";
                // $row = mysqli_fetch_row($result);
                // echo "<img src=\"$row[1]\" alt=\"$row[0]\">";
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>

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

  44. Krok 44: Skrypt 1: kolumny po nazwach i htmlspecialchars

    ok. 3 min
    Polecenie z arkusza

    Każdy zwrócony zapytaniem wiersz jest wyświetlany w osobnym bloku (obraz 3)

    Pięć kolumn po numerach łatwo pomylić - w Skrypcie 2 kolejność była odwrotna. mysqli_fetch_assoc oddaje wiersz z kluczami takimi jak nazwy kolumn ($photo["polubienia"] zamiast $row[2]). Nazwa pliku i autor są policzone raz, do zmiennych, a tytuł, plik i autor przechodzą przez htmlspecialchars - tak jak w Skrypcie 2, cudzysłów albo < w danych nie rozbije znaczników. Strona wygląda tak samo jak wcześniej. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    galeria.php PHP zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Galeria</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h1>Zdjęcia</h1>
        </header>
        <aside id="left">
            <h2>Tematy zdjęć</h2>
            <ol>
                <li>Zwierzęta</li>
                <li>Krajobrazy</li>
                <li>Miasta</li>
                <li>Przyroda</li>
                <li>Samochody</li>
            </ol>
        </aside>
        <main>
            <?php
                $connection = mysqli_connect("localhost", "root", "", "galeria");
                $query = "SELECT plik, tytul, polubienia, imie, nazwisko FROM zdjecia JOIN autorzy ON zdjecia.autorzy_id = autorzy.id ORDER BY nazwisko;";
                $result = mysqli_query($connection, $query);
                while ($photo = mysqli_fetch_assoc($result)) {
                    $file = htmlspecialchars($photo["plik"]);
                    $author = htmlspecialchars($photo["imie"] . " " . $photo["nazwisko"]);
                    echo "<div class=\"photo\">";
                    echo "<img src=\"$file\" alt=\"zdjęcie\">";
                    echo "<h3>" . htmlspecialchars($photo["tytul"]) . "</h3>";
                    if ($photo["polubienia"] > 40) {
                        echo "<p>Autor: $author.<br>Wiele osób polubiło ten obraz</p>";
                    } else {
                        echo "<p>Autor: $author</p>";
                    }
                    echo "<a href=\"$file\" download>Pobierz</a>";
                    echo "</div>";
                }
                // wersja z egzaminu: while ($row = mysqli_fetch_row($result)) - kolumny po numerach $row[0] ... $row[4]
            ?>
        </main>
        <aside id="right">
            <h2>Najbardziej lubiane</h2>
            <?php
                $query = "SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100 ORDER BY polubienia DESC LIMIT 1;";
                $result = mysqli_query($connection, $query);
                $favourite = mysqli_fetch_assoc($result);
                if ($favourite) {
                    echo "<img src=\"" . htmlspecialchars($favourite["plik"]) . "\" alt=\"" . htmlspecialchars($favourite["tytul"]) . "\">";
                }
                // $query = "SELECT tytul, plik FROM zdjecia WHERE polubienia >= 100;";
                // $row = mysqli_fetch_row($result);
                // echo "<img src=\"$row[1]\" alt=\"$row[0]\">";
                mysqli_close($connection);
            ?>
            <strong>Zobacz wszystkie nasze zdjęcia</strong>
        </aside>
        <footer>
            <h5>Stronę wykonał: Bartosz Bryniarski</h5>
        </footer>
    </body>
    </html>

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

  45. Krok 45: Opis widoczny także z klawiatury i na ekranie dotykowym

    ok. 2 min
    Polecenie z arkusza

    W momencie, gdy kursor myszy znajdzie się na bloku generowanym skryptem 1: Zdjęcia z bloku środkowego przyjmują wartość przezroczystości 0.3 i jest ona zmieniana płynnie przez 0.5 sekundy efektem ease. Nagłówka trzeciego stopnia: brak przezroczystości (1). Paragrafu: brak przezroczystości. Odnośnika: brak przezroczystości

    Opis zdjęcia pokazuje się tylko pod kursorem myszy. Kto przechodzi po stronie klawiszem Tab, trafia na niewidoczny odnośnik „Pobierz” - nie widzi ani jego, ani tytułu. Pseudoklasa :focus-within jest prawdziwa dla bloku, w którego środku jest element z fokusem: po dojściu tabulatorem do „Pobierz” zdjęcie blednie, a opis się pojawia - tak samo jak po najechaniu myszą. Na telefonie pierwsze dotknięcie odnośnika działa podobnie. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Helvetica;
    }
    header, footer {
        background-color: Sienna;
        color: white;
        padding: 10px;
        text-align: center;
    }
    #left, #right {
        background-color: NavajoWhite;
        width: 15%;
        height: 700px;
    }
    main {
        width: 70%;
        height: 700px;
        overflow: scroll;
    }
    #left, main, #right {
        float: left;
    }
    footer {
        clear: both;
    }
    img {
        width: 100%;
    }
    .photo {
        float: left;
        width: 46%;
        margin: 2%;
        position: relative;
    }
    .photo h3, .photo p, .photo a {
        opacity: 0;
        position: absolute;
    }
    .photo h3 {
        top: 5%;
    }
    .photo p {
        top: 30%;
    }
    .photo a {
        top: 70%;
        left: 70%;
        background-color: Sienna;
        padding: 15px;
    }
    .photo img {
        transition: 0.5s ease;
    }
    .photo:hover img {
        opacity: 0.3;
    }
    .photo:hover h3, .photo:hover p, .photo:hover a,
    .photo:focus-within h3, .photo:focus-within p, .photo:focus-within a {
        opacity: 1;
    }
    .photo:focus-within img {
        opacity: 0.3;
    }
    Podgląd strony po tym kroku (galeria.php)
  46. Etap 6: Oddanie pracy

    Krok 46 · po tym etapie masz 37 z 37 kryteriów (pkt)

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

    ok. 5 min
    Polecenie z arkusza

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

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

    W folderze z numerem zdającego: galeria.php, import.png, kw1.jpg - kw4.jpg, kwerendy.txt, przeglądarka.txt, styl.css, wszystkie zdjęcia z archiwum (w tym przeskalowany woodpecker.jpg) i rozpakowany baza.sql. Po nagraniu płyty trzeba sprawdzić jej odczyt i opisać ją numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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.