Serwis używa plików cookies do analizy ruchu i poprawy działania. Szczegóły
E.14-04-20.06-SGCzerwiec 2020 · 29 kroków · ok. 82 min · 39 kryteriów z klucza
Rozwiązanie krok po kroku: Sklep z ozdobami choinkowymi (Nowoczesny kod (flex, PDO))
To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza sklep z tabelą zamowienia, użytkownikiem klient i zamówieniem Jana Kowalskiego, ozdoby 300 × 300 px, animacja zmieniająca obraz co 2 sekundy oraz strony galeria.html i zamowienie.php - i tak samo spełnia każde kryterium klucza. Inna jest droga:
flex zamiast float: trzy panele stoją we wspólnym znaczniku <main>, stopka nie potrzebuje clear. Szerokości 25%, 50% i 25% zostają na panelach, bo tam sprawdza je klucz z 2020 roku,
zmienne CSS dla kolorów arkusza, odnośniki w <nav>, formularz z etykietami <label for>,
kolumna id autonumerowana już w kwerendzie 2 - formularz nie ma pola na numer, więc numer nadaje baza,
skrypt JavaScript w osobnym plikugaleria.js, z addEventListener i textContent zamiast atrybutów onmouseover i innerHTML,
PHP na PDO na górze zamowienie.php: sprawdzenie danych na serwerze, zapytanie przygotowane, komunikat dla klienta i przekierowanie po zapisie - odświeżenie strony nie złoży zamówienia drugi raz.
To arkusz E.14 z czerwca 2020 - kwalifikacji formuły 2012, którą zastąpiła INF.03. Zdjęcia pochodzą z oryginalnego archiwum CKE egzamin4.zip (załącznik na stronie arkusza), zapytania są wykonane na MariaDB 10.4, skrypt PHP uruchomiony w PHP 8.2, a JavaScript sprawdzony w Chrome.
Jak liczą się punkty. Klucz ma 39 kryteriów (R.1.1 - R.5.7), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 30 punktów. Przy każdym kroku jest napisane, które kryteria spełnia; klucz przyjmuje zarówno mysqli, jak i PDO (uwaga przy R.5).
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-6 · po tym etapie masz 7 z 39 kryteriów (pkt)
Krok 1: Folder zdającego, archiwum i baza sklep
ok. 3 min
Polecenie z arkusza
Na pulpicie utwórz folder i nazwij go Twoim numerem PESEL. Wszystkie pliki utworzone w czasie egzaminu umieść w tym folderze. Za pomocą narzędzia phpMyAdmin, utwórz bazę sklep. Stosując kwerendy SQL wykonaj operacje na bazie danych. Kwerendy zapisz w pliku kwerendy.txt.
Folder na pulpicie nazwany numerem PESEL (tu: Bartosz Bryniarski), do niego zdjęcia z archiwum egzamin4.zip rozpakowanego z hasłem 6hM9N#k@. W phpMyAdmin nowa baza sklep z porównywaniem utf8mb4_polish_ci, a każde z pięciu zapytań wykonane na karcie SQL trafia do pliku kwerendy.txt.
Krok 2: Kwerenda 1: tabela zamowienia
Kryteria: ,
R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Zapisano zapytanie 1 tworzące tabelę zamowienia zawierającą pola: id, imie, nazwisko, adres_email, liczba_choinek, liczba_mikolajow, liczba_reniferow, info. W pliku z kwerendami istnieje zapis (możliwe alternatywne typy), np.: CREATE TABLE `zamowienia` ( `id` int NOT NULL, `imie` text, `nazwisko` text, `adres_email` text, `liczba_choinek` int, `liczba_mikolajow` int, `liczba_reniferow` int, `info` tinyint(1) );
ok. 4 min
Polecenie z arkusza
Kwerenda 1: tworząca tabelę zamowienia wraz kolumnami: id typ całkowity bez znaku, nie może przyjmować wartości NULL; imie, nazwisko, adres_email typu tekstowego; liczba_choinek, liczba_mikolajow, liczba_reniferow typu całkowitego; info typu logicznego (decyzja klienta, czy chce otrzymywać informacje handlowe). Wszystkie pola oprócz id domyślnie przyjmują wartość NULL
CREATE TABLE zamowienia (
id INT UNSIGNED NOT NULL,
imie VARCHAR(50) DEFAULT NULL,
nazwisko VARCHAR(50) DEFAULT NULL,
adres_email VARCHAR(100) DEFAULT NULL,
liczba_choinek INT UNSIGNED DEFAULT NULL,
liczba_mikolajow INT UNSIGNED DEFAULT NULL,
liczba_reniferow INT UNSIGNED DEFAULT NULL,
info BOOLEAN DEFAULT NULL
);
id INT UNSIGNED NOT NULL - całkowity bez znaku, bez NULL,
imię i nazwisko jako VARCHAR(50), adres jako VARCHAR(100) - typ tekstowy z limitem długości. TEXT (jak w przykładzie z klucza) też jest tekstowy, ale na krótkie pola z formularza wystarczy VARCHAR, który baza może indeksować w całości,
liczby sztuk INT UNSIGNED - nie da się zamówić minus trzech choinek,
info BOOLEAN - w MariaDB skrót od TINYINT(1),
DEFAULT NULL przy wszystkich polach oprócz id.
Plik z zapytaniem daje R.1.2, samo zapytanie R.1.3. Podgląd: karta Struktura po kwerendach 1 i 2.
kwerendy.txtTekstnowy plik
-- Kwerenda 1CREATE TABLE zamowienia ( id INT UNSIGNED NOT NULL, imie VARCHAR(50) DEFAULT NULL, nazwisko VARCHAR(50) DEFAULT NULL, adres_email VARCHAR(100) DEFAULT NULL, liczba_choinek INT UNSIGNED DEFAULT NULL, liczba_mikolajow INT UNSIGNED DEFAULT NULL, liczba_reniferow INT UNSIGNED DEFAULT NULL, info BOOLEAN DEFAULT NULL);
Podgląd strony po tym kroku
Krok 3: Kwerenda 2: klucz główny i autonumerowanie
Kryteria:
R.1.4 Zapisano zapytanie 2 ustawiająca pole id jako klucz główny. W pliku z kwerendami istnieje zapis, np.: ALTER TABLE `zamowienia` ADD PRIMARY KEY(`id`); lub ustawiono pole id jako klucz podstawowy w zapytaniu z R.1.3
ok. 3 min
Polecenie z arkusza
Kwerenda 2: ustawiająca pole id jako klucz główny
ALTER TABLE zamowienia
ADD PRIMARY KEY (id),
MODIFY id INT UNSIGNED NOT NULL AUTO_INCREMENT;
ADD PRIMARY KEY (id) to polecenie z arkusza (R.1.4). Druga część tego samego ALTER TABLE, MODIFY id ... AUTO_INCREMENT, wykracza poza arkusz: formularz na stronie zamowienie.php nie ma pola id, więc numer zamówienia musi nadać baza. AUTO_INCREMENT wymaga klucza na kolumnie - dlatego oba zmiany są w jednym zapytaniu, a MariaDB wykonuje je razem.
W wersji podstawowej, wiernej literze arkusza, numer wylicza skrypt PHP przez MAX(id) + 1 - działa, ale dwa zamówienia wysłane w tej samej chwili mogłyby dostać ten sam numer.
kwerendy.txtTekstzmienione: 5 linii
-- Kwerenda 1CREATE TABLE zamowienia ( id INT UNSIGNED NOT NULL, imie VARCHAR(50) DEFAULT NULL, nazwisko VARCHAR(50) DEFAULT NULL, adres_email VARCHAR(100) DEFAULT NULL, liczba_choinek INT UNSIGNED DEFAULT NULL, liczba_mikolajow INT UNSIGNED DEFAULT NULL, liczba_reniferow INT UNSIGNED DEFAULT NULL, info BOOLEAN DEFAULT NULL);-- Kwerenda 2ALTER TABLE zamowienia ADD PRIMARY KEY (id), MODIFY id INT UNSIGNED NOT NULL AUTO_INCREMENT;
Krok 4: Kwerendy 3 i 4: użytkownik klient tylko do dopisywania
Kryteria: ,
R.1.5 Zapisano zapytanie 3 tworzące użytkownika klient z widocznym hasłem klient123 W pliku z kwerendami istnieje zapis np.: CREATE USER 'klient' IDENTIFIED BY 'klient123';
R.1.6 Zapisano zapytanie 4 nadające użytkownikowi uprawnienia jedynie do wpisywania rekordów do tabel bazy sklep . W pliku z kwerendami istnieje zapis np.: GRANT INSERT ON sklep.* TO klient;
ok. 3 min
Polecenie z arkusza
Kwerenda 3: tworząca użytkownika klient z hasłem klient123. Kwerenda 4: nadająca użytkownikowi uprawnienia jedynie do wpisywania rekordów do tabel bazy sklep
CREATE USER 'klient'@'localhost' IDENTIFIED BY 'klient123' - konto, które łączy się tylko z tego samego komputera (R.1.5),
GRANT INSERT ON sklep.* TO 'klient'@'localhost' - jedyne uprawnienie: dopisywanie wierszy we wszystkich tabelach bazy sklep (R.1.6).
To zasada najmniejszych uprawnień: formularz zamówień potrzebuje tylko INSERT, więc konto nie odczyta ani nie usunie danych klientów, nawet gdy ktoś przejmie hasło.
kwerendy.txtTekstzmienione: 6 linii
-- Kwerenda 1CREATE TABLE zamowienia ( id INT UNSIGNED NOT NULL, imie VARCHAR(50) DEFAULT NULL, nazwisko VARCHAR(50) DEFAULT NULL, adres_email VARCHAR(100) DEFAULT NULL, liczba_choinek INT UNSIGNED DEFAULT NULL, liczba_mikolajow INT UNSIGNED DEFAULT NULL, liczba_reniferow INT UNSIGNED DEFAULT NULL, info BOOLEAN DEFAULT NULL);-- Kwerenda 2ALTER TABLE zamowienia ADD PRIMARY KEY (id), MODIFY id INT UNSIGNED NOT NULL AUTO_INCREMENT;-- Kwerenda 3CREATE USER 'klient'@'localhost' IDENTIFIED BY 'klient123';-- Kwerenda 4GRANT INSERT ON sklep.* TO 'klient'@'localhost';
Krok 5: Kwerenda 5: zamówienie Jana Kowalskiego
Kryteria:
R.1.7 Zapisano zapytanie 5 dodające rekord z danymi: Jan Kowalski, [email protected]. W pliku z kwerendami istnieje zapis np.: INSERT INTO `zamowienia` VALUES ('1', 'Jan', 'Kowalski', '[email protected]', NULL, NULL, NULL, NULL); możliwe również z nazwami pól lub przez SET oraz na zrzucie widoczny jest komunikat o poprawnie wykonanej kwerendzie lub wstawiony rekord
ok. 2 min
Polecenie z arkusza
Kwerenda 5: dodająca rekord z danymi: Jan Kowalski, [email protected] Wykonanie kwerendy udokumentuj zrzutem o nazwie kw5.jpg, zrzut powinien zawierać cały obszar ekranu, z widocznym paskiem zadań
Bez kolumny id - numer 1 nadało autonumerowanie, co phpMyAdmin pokazuje w komunikacie. Zrzut całego ekranu z paskiem zadań: kw5.jpg (R.1.7).
kwerendy.txtTekstzmienione: 4 linie
-- Kwerenda 1CREATE TABLE zamowienia ( id INT UNSIGNED NOT NULL, imie VARCHAR(50) DEFAULT NULL, nazwisko VARCHAR(50) DEFAULT NULL, adres_email VARCHAR(100) DEFAULT NULL, liczba_choinek INT UNSIGNED DEFAULT NULL, liczba_mikolajow INT UNSIGNED DEFAULT NULL, liczba_reniferow INT UNSIGNED DEFAULT NULL, info BOOLEAN DEFAULT NULL);-- Kwerenda 2ALTER TABLE zamowienia ADD PRIMARY KEY (id), MODIFY id INT UNSIGNED NOT NULL AUTO_INCREMENT;-- Kwerenda 3CREATE USER 'klient'@'localhost' IDENTIFIED BY 'klient123';-- Kwerenda 4GRANT INSERT ON sklep.* TO 'klient'@'localhost';-- Kwerenda 5INSERT INTO zamowienia (imie, nazwisko, adres_email)VALUES ('Jan', 'Kowalski', '[email protected]');
Podgląd strony po tym kroku
Krok 6: Eksport tabeli do zamowienia.sql
Kryteria:
R.1.1 Wykonano eksport tabeli zamowienia lub bazy sklep do pliku zamowienia.sql. Czas generowania wpisany w nagłówku pliku jest zgodny z datą i godziną egzaminu
ok. 2 min
Polecenie z arkusza
Tabelę zamowienia wyeksportuj do pliku zamowienia.sql
Tabela zamowienia, karta Eksport, format SQL. Czas generowania w nagłówku pliku musi się zgadzać z datą i godziną egzaminu (R.1.1). Plik w archiwum rozwiązania wyeksportowano z tej samej tabeli narzędziem mysqldump.
zamowienia.sqlSQLnowy plik
-- MariaDB dump 10.19 Distrib 10.4.27-MariaDB, for Win64 (AMD64)---- Host: localhost Database: sklep-- -------------------------------------------------------- Server version 10.4.27-MariaDB/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;/*!40101 SET NAMES utf8mb4 */;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;/*!40103 SET TIME_ZONE='+00:00' */;/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;---- Table structure for table `zamowienia`--DROP TABLE IF EXISTS `zamowienia`;/*!40101 SET @saved_cs_client = @@character_set_client */;/*!40101 SET character_set_client = utf8 */;CREATETABLE `zamowienia` ( `id` int(10) unsignedNOT NULL AUTO_INCREMENT, `imie` varchar(50) DEFAULT NULL, `nazwisko` varchar(50) DEFAULT NULL, `adres_email` varchar(100) DEFAULT NULL, `liczba_choinek` int(10) unsignedDEFAULT NULL, `liczba_mikolajow` int(10) unsignedDEFAULT NULL, `liczba_reniferow` int(10) unsignedDEFAULT NULL, `info` tinyint(1) DEFAULT NULL,PRIMARYKEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2DEFAULTCHARSET=utf8mb4 COLLATE=utf8mb4_polish_ci;/*!40101 SET character_set_client = @saved_cs_client */;---- Dumping data for table `zamowienia`--LOCK TABLES `zamowienia` WRITE;/*!40000 ALTER TABLE `zamowienia` DISABLE KEYS */;INSERTINTO `zamowienia` VALUES (1,'Jan','Kowalski','[email protected]',NULL,NULL,NULL,NULL);/*!40000 ALTER TABLE `zamowienia` ENABLE KEYS */;UNLOCKTABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;-- Dump completed
Etap 2: Grafika i animacja
Kroki 7-8 · po tym etapie masz 10 z 39 kryteriów (pkt)
Krok 7: Ozdoby 1:1, 300 × 300 px
Kryteria:
R.2.1 Zapisano przynajmniej jeden obraz z choinka, mikolaj, renifer o rozmiarze 300 px na 300 px (± 2 px, z zachowaniem proporcji 1:1)
ok. 5 min
Polecenie z arkusza
Przygotowanie grafiki: obrazy choinka, mikolaj, renifer wykadrowane do proporcji 1:1, rozmiar grafiki 300 px na 300 px
Grafika jest taka sama jak w wersji podstawowej - wymagania nie zostawiają wyboru. W GIMP-ie Kadrowanie z proporcjami 1:1 wyśrodkowane na ozdobie, Skaluj obraz do 300 × 300 px, eksport do choinka.jpg, mikolaj.jpg, renifer.jpg (R.2.1).
Podgląd strony po tym kroku
Krok 8: Animacja co 2 sekundy i zrzut interwal.jpg
Kryteria: ,
R.2.2 Utworzono animację animacja.gif składającą się z trzech obrazów
R.2.3 Obrazy w animacji zmieniają się co 2 sekundy. Ustawiony czas interwału udokumentowano zrzutem interwal.jpg , który zawiera cały obszar ekranu
ok. 5 min
Polecenie z arkusza
Przygotowanie animacji o nazwie animacja.gif: wykonana z wcześniej przygotowanych grafik choinka, mikolaj, renifer; obrazy zmieniane co 2 sekundy. Należy wykonać zrzut ekranu dokumentujący ustawienie czasu i zapisać jako plik interwal.jpg. Zrzut powinien zawierać cały obszar ekranu, z widocznym paskiem zadań
Plik → Otwórz jako warstwy - trzy ozdoby w jednym obrazie, od dołu: choinka, mikołaj, renifer (najniższa warstwa to pierwsza klatka). Eksportuj jakoanimacja.gif, w oknie opcji Jako animację, Pętla i opóźnienie 2000 ms z zaznaczonym „Użyj podanego opóźnienia dla wszystkich klatek” (R.2.2). Zrzut całego ekranu z tym oknem: interwal.jpg (R.2.3). Podgląd: odtworzenie okna opcji; gotowy plik ma trzy klatki po 2000 ms.
Podgląd strony po tym kroku
Etap 3: Strona galeria.html
Kroki 9-14 · po tym etapie masz 18 z 39 kryteriów (pkt)
Krok 9: Szkielet: kodowanie, tytuł i arkusz stylów
Kryteria: ,
R.2.5 Przynajmniej jednej stronie nadano tytuł: "Sklep”
R.3.6 Przynajmniej jedna strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css formatowanie pochodzi jedynie od pliku CSS. Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)
ok. 2 min
Polecenie z arkusza
Wspólne wymagania dla wszystkich podstron: Kodowanie polskich znaków. Strona połączona z zewnętrznym arkuszem stylów CSS o nazwie styl.css. Tytuł strony: Sklep
<meta charset="UTF-8">, viewport dla telefonów, <title>Sklep</title> (R.2.5) i <link rel="stylesheet" href="styl.css"> (R.3.6). Całe formatowanie trafi do pliku stylów.
R.2.6 Układ przynajmniej jednej strony zdefiniowano dzieląc ją na baner, panel lewy, środkowy i prawy oraz stopka za pomocą znaczników sekcji
ok. 2 min
Polecenie z arkusza
Podział strony na bloki: baner, panel lewy, środkowy i prawy oraz stopka za pomocą znaczników sekcji. Zawartość banera: nagłówek pierwszego stopnia o treści: „Ozdoby – sklep”. Zawartość stopki: nagłówek trzeciego stopnia o treści: „Autor strony:”, dalej wstawiony numer PESEL zdającego
<header> z <h1>, trzy znaczniki <section> w pojemniku <main> i <footer> z <h3> (R.2.6). <main> oznacza główną treść strony, a w CSS ułoży panele obok siebie. W stopce numer PESEL - tu Bartosz Bryniarski.
⚠️ Rozbieżność treść-ilustracja: obraz 1 pokazuje w stopce „Stronę opracował:”, a treść arkusza i klucz - „Autor strony:”. Obowiązuje treść i klucz.
R.3.4 Na przynajmniej jednej stronie istnieje odnośnik „Galeria”, który prowadzi do pliku galeria.html
R.3.5 Na przynajmniej jednej stronie istnieje odnośnik „Zamówienie”, który prowadzi do pliku zamowienie.php
ok. 2 min
Polecenie z arkusza
Zawartość panelu lewego: nagłówek drugiego stopnia o treści: „OZDOBY”; odnośnik „Galeria” prowadzący do pliku galeria.html; poniżej odnośnik „Zamówienie” prowadzący do pliku zamowienie.php
<h2> i dwa odnośniki ze ścieżkami względnymi (R.3.4, R.3.5) w znaczniku <nav> - to menu strony. Bez <br>: jeden pod drugim ustawi je CSS.
R.2.8 W bloku środkowym strony galeria.html umieszczono obrazy choinka, mikolaj, renifer z tekstem alternatywnym „ozdoby choinkowe”
ok. 2 min
Polecenie z arkusza
Zawartość panelu środkowego dla strony galeria.html: Obrazy choinka, mikolaj, renifer z tekstem alternatywnym „ozdoby choinkowe”, umieszczone obok siebie
Trzy obrazy z tekstem alternatywnym z arkusza (R.2.8). Atrybut data-ornament to własna etykieta obrazu (atrybuty data- są do tego przeznaczone) - skrypt odczyta z niej, którą ozdobę wskazano, bez osobnej funkcji dla każdego obrazu.
Krok 14: Paragraf z poleceniem i paragraf na komunikat
Kryteria:
R.2.7 Na przynajmniej jednej stronie zapisano nagłówki: w banerze h1: "Ozdoby - sklep”, w bloku lewym h2 "OZDOBY", w stopce h3: "Autor strony" i dalej wstawiony numer PESEL zdającego oraz zapisano w bloku środkowym paragraf (znacznik <p>)
ok. 1 min
Polecenie z arkusza
Paragraf (akapit) o treści: „Wybierz ozdobę w kółku”. Efekt działania skryptu 1 umieszczony w kolejnym paragrafie
Dwa paragrafy (z nagłówkami h1, h2, h3 - R.2.7). Drugi jest pusty, a aria-live="polite" każe czytnikowi ekranu odczytać jego treść, gdy skrypt ją zmieni - bez tego niewidomy użytkownik nie dowie się o cenie.
R.2.4 Witrynę internetową zapisano w plikach galeria.html, zamowienie.php oraz z astosowano właściwy standard kodowania polskich znaków na przynajmniej jednej stronie
ok. 2 min
Polecenie z arkusza
Zawartość panelu środkowego dla strony zamowienie.php: Paragraf o treści: „Dodaj użytkownika”
Kopia galeria.html, w której panel środkowy ma tylko paragraf „Dodaj użytkownika”. Obie strony mają nazwy z arkusza i UTF-8 (R.2.4).
R.2.10 W bloku środkowym strony zamowienie.php umieszczono formularz z trzema polami edycyjnymi i przyciskiem WYŚLIJ
R.3.2 Dane z formularza przesyłane są za pomocą metody POST, zastosowano przycisk do wysyłania danych z formularza
R.3.3 Pole edycyjne do wpisania adresu email jest typu email
ok. 3 min
Polecenie z arkusza
Formularz: Dane wysyłane metodą post do tego samego pliku. Pola edycyjne i podpisy zgodne z Obrazem 2. Przycisk WYŚLIJ wysyła dane z formularza. Pole edycyjne do wprowadzenia adresu email jest odpowiedniego typu tak, aby poprawność adresu była sprawdzana automatycznie
method="post" do tego samego pliku i przycisk type="submit" (R.3.2),
<label for="…"> - podpis powiązany z polem przez id: kliknięcie w napis „Imię:” ustawia kursor w polu, a czytnik ekranu czyta podpis razem z polem,
każdy wiersz w <div> - wiersze stoją jeden pod drugim bez <br>,
type="email" - przeglądarka sprawdza adres przed wysłaniem (R.3.3),
required i maxlength - puste pola i za długie wpisy przeglądarka zatrzyma od razu; maxlength odpowiada długościom kolumn w tabeli,
autocomplete - przeglądarka podpowie imię, nazwisko i adres z zapisanych danych.
Kroki 17-21 · po tym etapie masz 32 z 39 kryteriów (pkt)
Krok 17: Zmienne kolorów i formatowanie strony
Kryteria:
R.4.1 Ustawiono formatowanie dla * lub html, lub body, lub kontenera całej strony: czcionka Garamond białego koloru, wyśrodkowana
ok. 2 min
Polecenie z arkusza
Styl CSS zawiera formatowanie: domyślnie: czcionka Garamond koloru białego, tekst wyśrodkowany
Kolory arkusza w zmiennych CSS w :root - ForestGreen występuje trzy razy, a zmienna pozwala zmienić go jednym wpisem. Reguła body: Garamond z krojami zapasowymi, biały tekst, wyśrodkowanie (R.4.1).
R.4.6 Ustawiono wszystkie marginesy wewnętrzne (padding) dla banera i stopki na 10px
ok. 2 min
Polecenie z arkusza
dla banera i stopki: kolor tła ForestGreen, margines wewnętrzny 10 px
padding: 10px z czterech stron (R.4.6). display: flex na <main> ustawia trzy panele w jednym wierszu - bez float, więc stopka sama staje pod nimi. Siatka (grid-template-columns: 25% 50% 25%) byłaby równie dobra, ale klucz z 2020 roku ocenia szerokości na panelach (R.4.4), więc pojemnik tylko układa, a szerokości zostają w regułach paneli.
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z obrazem 1 w arkuszu
R.4.2 Ustawiono kolor tła dla panelu środkowego na Chocolate, dla pozostałych: ForestGreen
R.4.3 Ustawiono wysokość trzech paneli na 490px
R.4.4 Ustawiono szerokość panelu lewego i prawego na 25%, środkowego na 50%
R.4.5 Ustawiono rozmiar czcionki dla panelu lewego i prawego na 30px, środkowego na 25px
ok. 2 min
Polecenie z arkusza
dla panelu lewego i prawego: kolor tła ForestGreen, wysokość 490 px, szerokość: 25%, rozmiar czcionki 30 px; dla panelu środkowego: kolor tła Chocolate, wysokość 490 px, szerokość: 50%, rozmiar czcionki 25 px
Kolory tła (R.4.2), wysokości 490 px (R.4.3), szerokości 25/50/25% (R.4.4), czcionki 30/25/30 px (R.4.5). Panele obok siebie, jak na obrazie 1 (R.3.1).
Krok 20: Ozdoby w kółkach, animacja w granicach panelu
Kryteria: ,
R.4.7 Ustawiono styl wyłącznie dla obrazów z panelu środkowego: wysokość i szerokość 150px
R.4.8 Ustawiono zaokrąglenie rogów obrazu (border-radius) 100% (lub wartości >= 50%)
ok. 2 min
Polecenie z arkusza
wyłącznie dla obrazów z panelu środkowego: rozmiar 150 px na 150 px, zaokrąglenie rogów obrazu 100%
#middle img - tylko obrazy panelu środkowego, 150 × 150 px (R.4.7),
border-radius: 50% - promień zaokrąglenia równy połowie boku zamienia kwadrat w koło. Arkusz podaje 100%, ale większa wartość nic nie zmienia na ekranie, a klucz przyjmuje każdą od 50% (R.4.8),
#right img z max-width: 100% - animacja 300 px nie wyjdzie poza panel, gdy okno jest wąskie (25% z 1000 px to 250 px).
R.4.9 Ustawiono zielony kolor czcionki dla wszystkich elementów formularza
ok. 2 min
Polecenie z arkusza
dla selektora pola edycyjnego i przycisku: zielony kolor czcionki
input, button { color: green; } - pola i przycisk (w wersji nowoczesnej to znacznik <button>, więc potrzebny jest w selektorze) (R.4.9),
nav a - odnośnik w osobnej linii (display: block) i w kolorze tekstu panelu (inherit, tu biały, jak na obrazie 1); domyślny niebieski odnośnik na zielonym tle jest słabo czytelny.
Krok 22 · po tym etapie masz 35 z 39 kryteriów (pkt)
Krok 22: Plik galeria.js: komunikaty po wskazaniu ozdoby
Kryteria: , ,
R.5.1 Napisano skrypt dla strony galeria.html w języku JavaScript, który zawiera przynajmniej jedną instrukcję zgodną ze składnią języka
R.5.3 W skrypcie 1 istnieje funkcja (funkcje) wywoływana po wskazaniu kursorem każdego obrazu z panelu środkowego
R.5.4 Skrypt 1 wyświetla pod obrazami w paragrafie tekst dla choinki: "Wybrałeś choinkę. Cena 10 zł"; dla Mikołaja: "Wybrałeś Mikołaja. Cena 12 zł"; dla renifera: „Wybrałeś renifera. Cena 8 zł”
ok. 5 min
Polecenie z arkusza
Skrypt 1 ze strony galeria.html: Skrypt jest uruchamiany po stronie przeglądarki. Po wskazaniu kursorem obrazu w panelu środkowym jest wyświetlany komunikat w paragrafie przeznaczonym dla tej akcji (obraz 1): wybór choinki: „Wybrałeś choinkę. Cena 10 zł”; wybór Mikołaja: „Wybrałeś mikołaja. Cena 12 zł”; wybór renifera: „Wybrałeś renifera. Cena 8 zł”
Skrypt w osobnym pliku galeria.js, dołączony w <head> z atrybutem defer - przeglądarka pobiera go od razu, a wykonuje dopiero po wczytaniu całej strony, gdy obrazy już istnieją (R.5.1):
messages - obiekt: etykieta ozdoby z data-ornament → komunikat. Ceny są w jednym miejscu, a nowa ozdoba to jedna linia, nie nowa gałąź if,
showMessage(event) - event.target to obraz, nad którym jest kursor, a dataset.ornament odczytuje jego atrybut data-ornament,
textContent zamiast innerHTML - wstawia zwykły tekst; przeglądarka nie potraktuje go jak kodu HTML,
pętla for … of podpina funkcję do zdarzenia mouseover każdego obrazu przez addEventListener - HTML zostaje bez atrybutów onmouseover (R.5.3).
Sprawdzone w Chrome dla każdej ozdoby: trzy komunikaty z klucza (R.5.4). Arkusz pisze „mikołaja”, klucz „Mikołaja” - klucz dopuszcza różnicę wielkości liter. Podgląd: kursor na mikołaju, jak na obrazie 1.
const messages = { choinka: 'Wybrałeś choinkę. Cena 10 zł', mikolaj: 'Wybrałeś Mikołaja. Cena 12 zł', renifer: 'Wybrałeś renifera. Cena 8 zł',};const info = document.getElementById('info');function showMessage(event) { info.textContent = messages[event.target.dataset.ornament];}for (const image ofdocument.querySelectorAll('#middle img')) { image.addEventListener('mouseover', showMessage);}
Podgląd strony po tym kroku (galeria.html)
Etap 7: Skrypt PHP
Kroki 23-27 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 23: Skrypt na górze pliku i połączenie PDO z bazą sklep
Kryteria: ,
R.5.2 Napisano skrypt dla formularza w języku PHP, który zawiera przynajmniej jedną instrukcję zgodną ze składnią języka
R.5.5 W skrypcie 2 zastosowano funkcję realizującą połączenie z serwerem bazy danych na localhost, użytkownik root, bez hasła, baza danych sklep
ok. 4 min
Polecenie z arkusza
Skrypt 2 uruchamiany po wysłaniu danych z formularza na stronie zamowienie.php: Napisany w języku PHP. Skrypt łączy się z serwerem bazy danych na localhost, użytkownik root bez hasła, baza danych o nazwie sklep
Skrypt stoi na samej górze zamowienie.php, przed <!DOCTYPE html>, a pod formularzem zostają trzy linie wypisujące komunikat w paragrafie (R.5.2):
e() - funkcja z htmlspecialchars do wszystkiego, co wypisuje strona,
$_SERVER['REQUEST_METHOD'] === 'POST' - skrypt pracuje tylko po wysłaniu formularza (arkusz: „uruchamiany po wysłaniu danych”),
new PDO(...) - serwer localhost, baza sklep, kodowanie utf8mb4, użytkownik root bez hasła (R.5.5), ERRMODE_EXCEPTION - błędy bazy jako wyjątki,
try / catch - gdy baza nie działa, klient zobaczy zwykłe zdanie zamiast komunikatu PHP z danymi serwera.
Klucz przyjmuje PDO tak samo jak mysqli (uwaga przy R.5). Podgląd: zwykłe wejście na stronę.
R.5.7 Skrypt 2 wysyła do bazy danych zapytanie 5 zmodyfikowane w ten sposób, że odpowiednimi wartościami pól są dane pobrane z formularza
ok. 3 min
Polecenie z arkusza
Tworzy w tabeli zamowienia bazy danych nowy rekord z danymi przesłanymi formularzem (zmodyfikowane zapytanie 5)
Kwerenda 5, w której wartości zastępują parametry:name, :surname, :email: prepare wysyła do bazy treść zapytania, a execute - osobno dane z formularza (R.5.7). Dane nigdy nie staną się kodem SQL, więc nazwisko O'Neill zapisuje się bez błędu, a wpis z fragmentem zapytania (w wersji podstawowej dopisywał drugi wiersz) zapisuje się jako zwykłe, dziwne imię. Numer zamówienia nadaje autonumerowanie z kwerendy 2.
Sprawdzone: po wysłaniu danych Anny Nowak tabela ma wiersze 1 (Jan Kowalski) i 2 (Anna Nowak), a pod formularzem jest „Zamówienie zostało zapisane.”.
R.5.6 Po wykonaniu wszystkich operacji na bazie zastosowano funkcję zamknięcia połączenia z serwerem bazy danych
ok. 2 min
Polecenie z arkusza
Po wykonaniu operacji na bazie danych skrypt zamyka połączenie z serwerem
PDO zamyka połączenie, gdy znika ostatnie odwołanie do obiektu: $statement = null i $pdo = null. Stoją w bloku finally, który wykona się po try zawsze - po udanym zapisie i po wyjątku (R.5.6).
Krok 27: Odświeżenie po zapisie nie składa zamówienia drugi raz
ok. 4 min
Dodatek spoza arkusza - klucz go nie ocenia. Strona po wysłaniu formularza jest wynikiem żądania POST, więc odświeżenie (F5) wysyła dane ponownie i w tabeli ląduje drugie, identyczne zamówienie. Wzorzec PRG (Post/Redirect/Get):
session_start() na początku pliku - sesja przechowa komunikat między dwoma żądaniami,
po udanym zapisie $saved = true, a po bloku finally (połączenie jest już zamknięte) komunikat trafia do $_SESSION, a header('Location: zamowienie.php') każe przeglądarce wczytać stronę zwykłym żądaniem GET; exit zatrzymuje skrypt, bo header tylko ustawia nagłówek,
kolejne wejście odczytuje komunikat z sesji i od razu go usuwa (unset), więc pokaże się raz.
Sprawdzone na prawdziwym PHP: wysłanie formularza daje odpowiedź 302, potem „Zamówienie zostało zapisane.”, a kolejne odświeżenie - stronę bez komunikatu i bez drugiego zamówienia w tabeli. Przy błędnych danych przekierowania nie ma - komunikat zostaje na stronie. Podgląd: stan po przekierowaniu.
Krok 28 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 28: Co jest inaczej i którą wersję wybrać na egzaminie
ok. 3 min
Obie wersje dają komplet 39 punktów. Różnice:
wersja podstawowa
wersja nowoczesna
układ
float: left sekcji, clear stopki
<main> z display: flex
szerokości 25/50/25%
width na panelach
width na panelach (tak ocenia klucz)
kolory
wpisane w każdej regule
zmienne --green, --brown
numer zamówienia
MAX(id) + 1 w skrypcie
AUTO_INCREMENT z kwerendy 2
formularz
napis, pole, <br>
label for, required, maxlength, autocomplete
skrypt JS
w stronie, onmouseover, if, innerHTML
galeria.js z defer, addEventListener, obiekt z komunikatami, textContent
biblioteka bazy
mysqli (tabela 1 arkusza)
PDO z wyjątkami
dane w INSERT
wklejone w treść zapytania
parametry :name, :surname, :email
sprawdzenie danych
tylko w przeglądarce
także na serwerze (filter_input, długości)
po wysłaniu
brak komunikatu, F5 dubluje zamówienie
komunikat, przekierowanie PRG
zamknięcie bazy
mysqli_close na końcu
$pdo = null w finally
Na egzaminie wersja podstawowa trzyma się funkcji z tabeli 1 i łatwiej ją napisać bez dokumentacji. Nowoczesna nie daje się oszukać spreparowanym formularzem, nie wywraca się na apostrofie, informuje klienta o wyniku i nie dubluje zamówień - a klucz przyjmuje obie.
Krok 29 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 29: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
UWAGA: Po zakończeniu pracy utwórz w folderze z numerem PESEL plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny. Nagraj płytę z rezultatami pracy.
W folderze z numerem zdającego: animacja.gif, choinka.jpg, galeria.html, galeria.js, kw5.jpg, kwerendy.txt, interwal.jpg, mikolaj.jpg, przeglądarka.txt, renifer.jpg, styl.css, zamowienia.sql, zamowienie.php. Plik galeria.js mieści się w „ewentualnie inne przygotowane pliki” z arkusza - bez niego galeria nie wyświetli cen. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
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: Bartosz Bryniarski. 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.