Files
mini-test-projects-2-release/module-a/module-a-uz.md

293 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ⚡ Sinov loyihasi: Modul A — Tezlik testi (Speed Test)
## 1. Loyiha haqida qisqacha ma'lumot
Ushbu baholash veb-texnologiyalar bo'yicha amaliy ko'nikmalarni tez va aniq baholash uchun mo'ljallangan **Tezlik testi** (Speed Test) hisoblanadi. Ishtirokchilar to'rtta toifa — **A (Dizayn)**, **B (Layout)**, **C (Frontend)** va **D (Backend)** bo'yicha jami 20 ta mustaqil topshiriqni belgilangan vaqt ichida bajarishlari kerak. Har bir topshiriq mustaqil bo'lib, ularni istalgan tartibda bajarish mumkin.
---
## 2. Texnologiyalar to'plami (Tech Stack) va cheklovlar
| Toifa | Ruxsat berilgan texnologiyalar | Cheklovlar |
| :--- | :--- | :--- |
| **A. Dizayn** | GIMP | Boshqa grafik tahrirlovchilardan (masalan, Photoshop) foydalanish taqiqlanadi |
| **B. Layout** | HTML, CSS | JavaScript-dan foydalanish taqiqlanadi |
| **C. Frontend** | JavaScript (Vanilla) | Tashqi kutubxonalar yoki freymvorklardan foydalanish taqiqlanadi |
| **D. Backend** | PHP, MySQL | Ma'lumotlar bazasiga ulanish uchun faqat PDO ishlatilishi kerak |
* Barcha natijalar Chrome brauzerining desktop versiyasida tekshiriladi.
* Har bir topshiriq natijasini `/module_a/` papkasi ostidagi topshiriq ID-si bilan nomlangan quyi papkaga saqlang (masalan, `/module_a/a1/`, `/module_a/b1/`).
* Dizayn topshiriqlari uchun GIMP manba fayli (`.xcf`) topshiriladigan papkada bo'lishi shart.
---
## 3. Topshiriqlar
### 🎨 A. Dizayn — GIMP mahorati
> **Taqdim etilgan fayllar**: A1 (`source.png`), A2 (`base.jpg`) va A3 (`photo.jpg`, `mask.png`) uchun fayllar har bir topshiriqning ishchi katalogiga joylashtirilgan. A4 va A5 uchun fayllar taqdim etilmagan; ishtirokchilar barcha elementlarni noldan yaratishlari kerak.
#### **A1. Qatlamlarni birlashtirish va matn joylashtirish** `Oson`
GIMP-da qatlamli tuzilmadan foydalangan holda rasm yarating.
* Kanvas o'lchami: **800×400px**, Ruxsat: **72dpi**
* **1-qatlam**: Fonni `#2C3E50` rangli foni bilan to'ldiring.
* **2-qatlam**: Taqdim etilgan rasmni (`source.png`) oching, uni kanvasning **markaziga** joylashtiring va shaffofligini (opacity) **70%** ga o'rnating.
* **3-qatlam**: **"Hello, GIMP"** matnini oq rangda (`#FFFFFF`), 36pt o'lchamda qo'shing va uni kanvasning yuqori chap burchagiga **(x: 20px, y: 20px)** joylashtiring.
* Loyihani avval `.xcf` formatida saqlang. Keyin barcha qatlamlarni birlashtiring (Flatten Image) va natijani `result.png` sifatida eksport qiling.
#### **A2. Tanlash va qatlamlarni birlashtirish** `Oson`
GIMP-ning tanlash vositalari va qatlamlaridan foydalanib, rasmga shakl effektlarini qo'llang.
* Taqdim etilgan rasmni (`base.jpg`) fon qatlami sifatida oching.
* **1-effekt**: Yangi qatlam qo'shing. "Rectangle Select" (To'rtburchak tanlash) vositasi yordamida yuqori chap burchakdagi **(0, 0) dan (200, 200)** gacha bo'lgan maydonni tanlang, uni `#E74C3C` rang bilan to'ldiring va ushbu qatlamning shaffofligini **60%** ga o'rnating.
* **2-effekt**: Yana bitta yangi qatlam qo'shing. Rasmning **markazida** diametri **150px** bo'lgan elliptik tanlov yarating. `Selection → Border` menyusiga kiring, chegara kengligini **3px** qilib belgilang va hosil bo'lgan tanlovni `#FFFFFF` rangi bilan to'ldiring.
* Loyihani avval `.xcf` formatida saqlang. Keyin barcha qatlamlarni birlashtiring (Flatten Image) va natijani `result.jpg` sifatida eksport qiling.
#### **A3. Rangni to'g'rilash va qatlam maskasi (Layer Mask)** `O'rtacha`
Taqdim etilgan rasmga (`photo.jpg`) rangni to'g'rilash va qatlam maskasini qo'llang.
* **Rangni to'g'rilash**: "Hue-Saturation" vositasidan foydalanib, to'yinganlikni (Saturation) **+40** ga oshiring.
* **Egri chiziqlar (Curves)**: "Curves" vositasidan foydalanib, kontrastni oshirish uchun yorug'lik qiymatini (highlights) **+20 yoki undan ko'proqqa** oshiring va soya qiymatini (shadows) **-20 yoki undan kamroqqa** tushiring.
* **Qatlam maskasi**: Rasm qatlamiga qatlam maskasini qo'shing. Taqdim etilgan maska tasvirini (`mask.png`) qatlam maskasiga joylashtiring, shunda asosiy obyektdan tashqaridagi fon olib tashlanadi.
* Loyihani avval `.xcf` formatida saqlang. Keyin natijani `result.png` sifatida eksport qiling va shaffof fon saqlanib qolganiga ishonch hosil qiling.
#### **A4. Matn effekti va porlash (Glow)** `O'rtacha`
GIMP-da matnga porlash effektini qo'llang.
* Kanvas o'lchami: **600×200px**, Fon rangi: `#1A1A2E`
* **"SPEED TEST"** matnini oq rangda (`#FFFFFF`), qalin (Bold), 60pt o'lchamda kanvas markaziga qo'shing.
* Matn qatlamini nusxalang va nusxasini asl matn qatlamining **ostiga** joylashtiring.
* Nusxalangan qatlamni rasterlang (Layer → Rasterize). Qatlamlar panelida ushbu qatlamning rejimini (Mode) **`Color`** ga o'rnating. Keyin asosiy rangni (foreground) `#4A90D9` ga o'rnating va `Edit → Fill with Foreground Color` orqali ko'k rangni qo'llang.
* Tashqi porlash effektini yakunlash uchun nusxalangan qatlamga **8px** radiusli **Gaussian Blur** filtrini qo'llang.
* Loyihani avval `.xcf` formatida saqlang, so'ngra natijani `result.png` sifatida eksport qiling.
#### **A5. Matnni buzish (Warp) va filtr effektlari** `Qiyin`
Matnni rasterlang va vizual buzilish effektlarini yaratish uchun GIMP-ning "Distorts" filtrlarini qo'llang.
* Kanvas o'lchami: **800×300px**, Fon rangi: `#0D0D0D`
* **"DISTORTION"** matnini oq rangda (`#FFFFFF`), qalin (Bold), 72pt o'lchamda kanvas markaziga qo'shing.
* Matn qatlamini rasterlang (Layer → Rasterize).
* Rasterlangan matn qatlamiga quyidagi ikkita "Distorts" filtrini tartib bilan qo'llang:
* **Ripple**: Amplituda **8**, To'lqin uzunligi (Wavelength) **40**, Yo'nalish: Horizontal
* **Whirl and Pinch**: Whirl burchagi **20** daraja, Pinch **0**, Radius **1.0**
* Buzilgan matn qatlamini nusxalang. Nusxaga **3px** radiusli **Gaussian Blur** filtrini qo'llang va "ghosting" (arvohsimon) effektini yaratish uchun uni asl qatlamning **ostiga** joylashtiring.
* Loyihani avval `.xcf` formatida saqlang, so'ngra natijani `result.png` sifatida eksport qiling.
---
### 📐 B. Layout — Faqat HTML / CSS
#### **B1. Flexbox Card Layout** `Oson`
Faqat HTML va CSS yordamida kartalar ro'yxatini yarating.
* Kartalarni har bir qatorda **4 tadan** joylashtirish uchun **Flexbox** dan foydalaning. (`flex-wrap: wrap` ishlating)
* Har bir karta quyidagilarni o'z ichiga olishi kerak: rasm maydoni (`<div>`, balandligi **160px**, fon rangi bilan), sarlavha (`<h3>`), asosiy matn (`<p>`) va tugma (`<button>`).
* Kartalar orasidagi masofani (gap) **24px** qilib belgilang.
* **8 ta** namunaviy (dummy) karta yarating. Har bir kartaning rasm maydoni har xil fon rangiga ega bo'lishi kerak.
#### **B2. Sticky Header va CSS interaksiyasi** `Oson`
Faqat HTML va CSS yordamida CSS interaksiyalariga ega sarlavha (header) yarating.
* Sarlavhani joylashtirish uchun **Flexbox** dan foydalaning: chapda logotip matni, markazda 4 ta menyu havolasi va o'ngda 2 ta tugma.
* Menyu havolasi ustiga kursor olib borilganda (hover), `transition` effekti bilan **2px qalinlikdagi chiziq** paydo bo'ladigan interaksiyani amalga oshiring. (`border-bottom` yoki `::after` psevdo-elementidan foydalaning)
* Sarlavhani skroll paytida yuqorida qotib turishi uchun `position: sticky; top: 0;` dan foydalaning.
* Skroll qilish imkoniyati bo'lishi uchun sarlavha ostiga kamida **3000px** balandlikdagi namunaviy kontent joylashtiring.
#### **B3. CSS Grid Ikki ustunli maket** `O'rtacha`
Faqat HTML va CSS yordamida CSS Grid orqali ikki ustunli sahifa maketini yarating.
* Chap tomonda mahkamlangan sidebar (**250px**) va o'ng tomonda asosiy kontent maydoni (`1fr`) yaratish uchun **CSS Grid** dan foydalaning.
* Chap sidebarga vertikal navigatsiya menyusini (5 ta element) joylashtiring. Birinchi elementni faol holatda ekanligini ko'rsatish uchun fon rangi va matn rangini o'zgartiring.
* O'ngdagi asosiy maydonda tartib bilan sarlavha, matn va **3 ustunli karta setkasi** (CSS Grid yordamida, 6 ta karta) joylashtiring.
* Umumiy o'rovchi elementga (wrapper) `height: 100vh` va `overflow: hidden` qo'llang. Sidebar va asosiy maydonning har biri alohida skroll bo'lishi uchun ikkalasiga ham `height: 100vh` va `overflow-y: auto` xususiyatlarini bering.
#### **B4. CSS Animatsiyalar va Transitionlar** `O'rtacha`
Faqat HTML va CSS yordamida bitta sahifada turli xil CSS animatsiyalari va transition effektlarini amalga oshiring.
* **Karta hover effekti**: Flexbox yordamida qatorga 4 ta karta joylashtiring. Kursor ustiga kelganda, har bir karta **8px** yuqoriga ko'tarilishi va kuchliroq soyaga ega bo'lishi kerak. (`transform: translateY(-8px)`, `box-shadow` va `transition` ishlating)
* **Yuklanish indikatori (Loading spinner)**: `@keyframes` yordamida aylana shaklidagi spinner yarating. Spinner diametri **48px**, chegarasi (border) **4px** bo'lsin. Faqat yuqori chegara (`border-top`) `#3498DB` rangda bo'lishi kerak, qolganlari esa `#e0e0e0`. Spinner cheksiz aylanadi.
* **Matnning paydo bo'lishi (Fade-in)**: Sahifa yuklanganda sarlavha (`<h1>`) `@keyframes` yordamida `translateY(20px)` dan `translateY(0)` holatiga o'tishi va `opacity: 0` dan `opacity: 1` ga o'zgarishi kerak. (`animation-duration: 0.8s`, `animation-fill-mode: both`)
#### **B5. CSS Grid va kengaytirilgan selektorlar** `Qiyin`
Faqat HTML va CSS yordamida ikki ustunli kontent maketini va faqat CSS-da ishlaydigan tab (sahifa) interaksiyasini yarating.
* **CSS Grid** yordamida ikki ustunli maket yarating: chap ustun (65%) va o'ng ustun (35%).
* **Chap maydon**: Asosiy rasm maydonini (`<div>`, balandligi **300px**, fon rangi bilan) va uning ostida gorizontal rasmchalar (thumbnail) ro'yxatini joylashtiring (Flexbox, `overflow-x: auto`). 5 ta rasmcha bo'lsin, har biri **80×80px** o'lchamdagi va turli fon rangli `<div>` bo'lsin.
* **O'ng maydon — yuqori**: Sarlavha, kichik sarlavha va matn joylashtiring.
* **O'ng maydon — quyi**: 3 ta tab (Umumiy ko'rinish / Tafsilotlar / Sharhlar) va ularga tegishli kontent maydonlarini yarating.
* Faqat tanlangan tab kontentini ko'rsatish uchun **JavaScript-siz** `<input type="radio" name="tab">` va CSS `:checked` selektoridan foydalaning.
* `<input type="radio">` elementlarini `display: none` bilan yashiring va mos keladigan `<label>` elementlarini tab tugmalari kabi dizayn qiling.
* O'ng maydonning eng pastida yonma-yon "Asosiy" va "Yordamchi" tugmalarni joylashtiring. Asosiy tugma ustiga kursor olib kelganda uning fon rangi silliq o'zgarishi uchun `@keyframes` animatsiyasini qo'llang.
---
### ⚡ C. Frontend — JavaScript (Vanilla)
#### **C1. localStorage asosidagi eslatmalar ilovasi** `Oson`
Vanilla JavaScript va `localStorage` yordamida oddiy eslatma (memo) ilovasini yarating.
* Sahifada matn kiritish maydoni (`<textarea>`) va **"Saqlash"** tugmasi bo'lishi kerak.
* "Saqlash" tugmasi bosilganda, eslatma `localStorage`-dagi `memos` kaliti ostida JSON massiviga qo'shiladi. Bo'sh matnni saqlash mumkin emas.
* Saqlangan eslatmalar ro'yxatini kiritish maydoni ostida ko'rsating. Har bir elementda matn va **"O'chirish"** tugmasi bo'lishi kerak.
* "O'chirish" tugmasi bosilganda, element `localStorage`-dan o'chirilishi va ro'yxat darhol yangilanishi kerak.
* Sahifa qayta yuklanganda ham eslatmalar ro'yxati saqlanib qolishi kerak.
#### **C2. DOM manipulyatsiyasi va hodisalarni boshqarish** `Oson`
Vanilla JavaScript yordamida elementlarni boshqarish imkoniyatiga ega dinamik ro'yxat yarating.
* Sahifada matn kiritish maydoni (`<input type="text">`) va **"Qo'shish"** tugmasi bo'lishi kerak.
* "Qo'shish" tugmasi bosilganda yoki Enter tugmasi bosilganda kiritilgan qiymat yangi ro'yxat elementi sifatida qo'shiladi. Bo'sh qiymat qo'shilmasligi kerak. Qo'shilgandan keyin kiritish maydoni tozalanadi.
* Har bir elementda **"Bajarildi"** va **"O'chirish"** tugmalari bo'lishi kerak.
* "Bajarildi" tugmasi bosilganda matn ustidan chiziladi (`text-decoration: line-through`). Qayta bosilganda asl holatiga qaytadi.
* "O'chirish" tugmasi bosilganda element darhol o'chiriladi.
* Ro'yxatning yuqorisida real vaqt rejimida **jami elementlar soni** va **bajarilganlar sonini** ko'rsating.
#### **C3. Dinamik JSON rendering va filtrlash** `O'rtacha`
Vanilla JavaScript va Fetch API yordamida mahalliy JSON faylini yuklaydigan va uning mazmunini dinamik ravishda ko'rsatadigan sahifa yarating.
* `/module_a/c3/posts.json` manzilidagi `posts.json` faylini Fetch API orqali yuklang. Fayl `id`, `title`, `body` va `category` kalitlariga ega bo'lgan obyektlar massivini o'z ichiga oladi (jami 20 ta element).
* Ma'lumot yuklanayotgan vaqtda **yuklanish indikatorini** (CSS animatsiyasi) ko'rsating va yuklash tugagach uni olib tashlang.
* Barcha elementlarni kartalar ko'rinishida ko'rsating. Har bir kartada `id`, `title`, `body` va `category` bo'lishi kerak.
* Qidiruv maydonini yarating, u `title` bo'yicha kartalarni real vaqt rejimida filtrlaydi (katta-kichik harfni farqlamaydi; har bir tugma bosilganda yangilanadi).
* Agar Fetch so'rovi muvaffaqiyatsiz tugasa, ekranda **"Failed to load data."** xatosini ko'rsating.
> **Taqdim etilgan fayl**: `posts.json` (ishtirokchining `/module_a/c3/` ishchi katalogiga joylashtirilgan)
#### **C4. Formani tekshirish (Validation)** `O'rtacha`
Vanilla JavaScript yordamida real vaqt rejimida formani tekshirishni amalga oshiring.
* Quyidagi maydonlarga ega ro'yxatdan o'tish formasini yarating: **Ism**, **Email**, **Parol**, **Parolni tasdiqlash**.
* Har bir maydon uchun tekshirish qoidalari:
* **Ism**: Majburiy, kamida 2 ta belgi.
* **Email**: Majburiy, `@` va `.` belgilarini o'z ichiga olishi kerak.
* **Parol**: Majburiy, kamida 8 ta belgi, harflar va raqamlarni o'z ichiga olishi kerak.
* **Parolni tasdiqlash**: Majburiy, Parol maydoni bilan to'liq mos kelishi kerak.
* Fokus maydondan chiqqanda (`blur` hodisasi), agar qoida buzilgan bo'lsa, o'sha maydon ostida xato xabarini ko'rsating. Shart bajarilishi bilan xato xabarini darhol olib tashlang.
* **"Yuborish"** tugmasi faqat barcha maydonlar to'g'ri to'ldirilganda faollashishi kerak. Tugma bosilganda `alert("Registration complete.")` xabari chiqishi kerak.
#### **C5. IntersectionObserver va kechiktirilgan rendering** `Qiyin`
`IntersectionObserver` yordamida cheksiz skroll va kechiktirilgan renderingni amalga oshiring.
* JavaScript-da 50 ta namunaviy elementdan iborat massiv yarating. Har bir element `id`, `title` va `color` ga ega bo'lishi kerak (`color` - ixtiyoriy `#RRGGBB` formatidagi rang).
* Dastlabki yuklanishda **10 ta** elementni ko'rsating. Har bir element **200px** balandlikdagi rangli `<div>` va uning `title` matnidan iborat bo'lsin. Birinchi 10 ta element o'zining rangini darhol fon sifatida ko'rsatishi kerak.
* Ro'yxatning oxiriga **kuzatuvchi element** (`<div id="sentinel">`) joylashtiring. Ushbu element ko'rinish maydoniga (viewport) kirganda, keyingi 10 ta element avtomatik ravishda qo'shilishi kerak.
* Yangi elementlar qo'shilayotganda kuzatuvchi elementdan oldin yuklanish indikatorini ko'rsating va rendering tugagach uni olib tashlang (`setTimeout` yordamida 600ms kechikishni simulyatsiya qiling).
* Barcha **50 ta element** yuklab bo'lingandan so'ng, kuzatuvchini to'xtating (`observer.unobserve`) va **"All items loaded."** xabarini ko'rsating.
* Yangi elementlar DOM-ga qo'shilganda ularning rangli `<div>`lari dastlab kulrang (`#cccccc`) bo'lishi kerak. Har bir `<div>`ni kuzatish uchun **alohida `IntersectionObserver` nusxasidan** foydalaning va element ekranda ko'rinishi bilan kulrangni elementning `data-color` atributidagi haqiqiy rangga almashtiring.
---
### 🛢️ D. Backend — PHP / MySQL
> **Taqdim etilgan fayllar**: D4 uchun `posts_dump.sql` va D5 uchun `data_dump.sql` har bir topshiriqning ishchi katalogiga joylashtirilgan.
#### **D1. PDO asosidagi CRUD API** `Oson`
PHP va MySQL (PDO) yordamida ma'lumotlarni boshqarish uchun REST API yarating.
* Quyidagi tuzilmada `items` jadvalini yarating. Jadvalni yaratish SQL kodini `table.sql` sifatida topshiring.
* `id` (INT, PK, AUTO_INCREMENT), `title` (VARCHAR 100, NOT NULL), `content` (TEXT), `created_at` (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
* Bitta `api.php` faylida HTTP metodlari (`$_SERVER['REQUEST_METHOD']`) bo'yicha ajratilgan 4 ta endpointni amalga oshiring:
* `GET /module_a/d1/api.php` → Barcha elementlarni JSON massivi sifatida qaytaradi.
* `POST /module_a/d1/api.php` → Yangi element qo'shadi. Body (JSON): `{"title": "...", "content": "..."}`. So'rov tanasini `php://input` orqali o'qing va `json_decode()` bilan tahlil qiling. Muvaffaqiyatli bo'lsa, qo'shilgan qatorni JSON sifatida qaytaring.
* `PUT /module_a/d1/api.php?id={id}``title` va `content`ni yangilaydi. Body (JSON): `{"title": "...", "content": "..."}`. Muvaffaqiyatli bo'lsa, yangilangan qatorni JSON sifatida qaytaring.
* `DELETE /module_a/d1/api.php?id={id}` → Elementni o'chiradi. Muvaffaqiyatli bo'lsa, `{"message": "deleted"}` qaytaring.
* Mavjud bo'lmagan `id` uchun PUT/DELETE so'rovlari yuborilsa, **404** HTTP statusi va `{"error": "Not found"}` qaytaring.
* Barcha javoblarda `Content-Type: application/json` sarlavhasi (header) bo'lishi shart.
#### **D2. Fayl yuklashni boshqarish** `Oson`
PHP yordamida rasm fayllarini yuklash funksiyasini amalga oshiring.
* `upload.php` faylida fayl yuklash HTML formasini (GET) va yuklashni qayta ishlash mantiqini (POST) amalga oshiring. Formaning `enctype` atributini `multipart/form-data` qilib belgilang.
* Yuklash shartlari: faqat **jpg, jpeg, png, gif** kengaytmalariga ruxsat beriladi; fayl o'lchami **2MB yoki undan kam** bo'lishi kerak.
* Tekshiruvdan o'tgan fayllarni `uploads/` papkasiga **`{time()}_{asl_fayl_nomi}`** formatida saqlang. Agar `uploads/` papkasi mavjud bo'lmasa, uni kod orqali yarating.
* Muvaffaqiyatli yuklangandan so'ng, yuklangan rasmni `<img>` tegi orqali ko'rsating.
* Tekshiruv xatolari uchun tegishli xabarlarni chiqaring:
* Noto'g'ri kengaytma: **"File type not allowed."**
* O'lcham oshib ketgan: **"File size exceeds 2MB."**
#### **D3. Sessiya asosidagi autentifikatsiya tizimi** `O'rtacha`
PHP sessiyalari va MySQL yordamida foydalanuvchilarni ro'yxatdan o'tkazish, tizimga kirish va chiqishni amalga oshiring.
* `users` jadvali: `id` (INT, PK, AUTO_INCREMENT), `email` (VARCHAR 100, UNIQUE), `password` (VARCHAR 255), `name` (VARCHAR 50), `created_at` (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
* **`register.php`**: GET so'rovida ro'yxatdan o'tish formasini chiqaring. POST so'rovida email takrorlanmaganini tekshiring, parolni `password_hash()` bilan shifrlab saqlang va hech qanday xabarsiz darhol `login.php` ga yo'naltiring. Agar email band bo'lsa, forma ustida **"This email is already registered."** xatosini ko'rsating.
* **`login.php`**: GET so'rovida kirish formasini chiqaring. POST so'rovida parolni `password_verify()` bilan tekshiring. Muvaffaqiyatli bo'lsa, sessiyada `user_id`, `name` va `email`ni saqlang va `mypage.php` ga yo'naltiring. Xato bo'lsa, **"Incorrect email or password."** xabarini ko'rsating.
* **`logout.php`**: `session_destroy()` orqali sessiyani yakunlang va `login.php` ga yo'naltiring.
* **`mypage.php`**: Agar sessiyada `user_id` bo'lmasa, `login.php` ga yo'naltiring. Tizimga kirgan bo'lsa, **"Welcome, {name}!"** xabari va chiqish (logout) havolasini ko'rsating.
#### **D4. Sahifalash (Pagination)** `O'rtacha`
PHP va MySQL (PDO) yordamida server tomonida sahifalashni amalga oshiring.
* `posts` jadvalini yarating va taqdim etilgan SQL dump (`posts_dump.sql`) faylini import qiling. Jadval tuzilishi: `id`, `title`, `content`, `created_at`.
* `index.php` sahifasida **har bir sahifada 10 ta post** ko'rsating.
* Joriy sahifa URL-dagi `?page={n}` so'rovi orqali aniqlanadi (standart: 1). SQL so'rovida faqat kerakli ma'lumotlarni olish uchun `LIMIT` va `OFFSET` dan foydalaning. Agar `page` 1 dan kichik yoki jami sahifalar sonidan ko'p bo'lsa, 1-sahifaga yo'naltiring.
* Sahifaning pastki qismida sahifalash havolalarini ko'rsating. **Barcha sahifa raqamlarini ko'rsating**, joriy sahifani "active" uslubi bilan belgilang va "Oldingi/Keyingi" tugmalarini qo'shing. Birinchi sahifada "Oldingi", oxirgi sahifada esa "Keyingi" tugmalarini faolsizlantiring (disable).
* Har bir post elementida sarlavha va yaratilgan sana ko'rsatilishi kerak. Sarlavha bosilganda `view.php?id={id}` sahifasiga o'tib, postning to'liq matni ko'rsatiladi.
#### **D5. Bir nechta jadvalli agregat so'rovlar** `Qiyin`
Bir nechta jadvallarni birlashtirish (JOIN) va agregat so'rovlar yordamida statistika API-sini yarating.
* Barcha 3 ta jadvalni yarating va `data_dump.sql` faylini import qiling. **Jadvallar `users` → `posts` → `comments` tartibida yaratilishi kerak** (tashqi kalit bog'liqliklari uchun).
* `users` (`id`, `name`, `created_at`)
* `posts` (`id`, `user_id`, `title`, `category`, `view_count`, `created_at`)
* `comments` (`id`, `post_id`, `created_at`)
* Bitta `stats.php` faylida `type` query stringiga qarab quyidagi 3 xil javobni qaytaring:
* `GET /module_a/d5/stats.php?type=daily` → Oxirgi 7 kundagi har bir kun uchun yangi postlar sonini sana bo'yicha o'sish tartibida qaytaring. Format: `[{"date": "2026-04-06", "count": 5}, ...]`
* `GET /module_a/d5/stats.php?type=category` → Har bir kategoriya bo'yicha jami postlar soni va o'rtacha ko'rishlar sonini, postlar soni kamayish tartibida qaytaring. Format: `[{"category": "tech", "post_count": 12, "avg_views": 340}, ...]`
* `GET /module_a/d5/stats.php?type=top` → Izohlar soni bo'yicha eng yuqori 5 ta postni, izohlar soni kamayish tartibida qaytaring. Format: `[{"post_id": 3, "title": "...", "author": "Alice Johnson", "comment_count": 18}, ...]`
* Barcha so'rovlarda PDO **Prepared Statements** ishlatilishi shart.
* Noma'lum `type` qiymatlari uchun **400** HTTP statusi va `{"error": "Invalid type"}` qaytaring.
---
## 4. Topshirish bo'yicha ko'rsatmalar
Barcha natijalarni serverdagi `/module_a/` katalogiga yuklang. Har bir topshiriq o'zining ID-si bilan nomlangan quyi papkada bo'lishi kerak (masalan, `/module_a/a1/`, `/module_a/b1/`, `/module_a/c1/`, `/module_a/d1/`).
---
## 5. Baholash sxemasi — Jami 25 ball
| Toifa | Topshiriq | Ballar |
| :--- | :--- | :---: |
| **A. Dizayn** | A1. Layer Compositing and Text Placement | 0.5 |
| | A2. Selection and Layer Compositing | 0.5 |
| | A3. Color Correction and Layer Mask | 1.5 |
| | A4. Text Effect and Glow | 1.5 |
| | A5. Text Warp and Filter Effects | 2.0 |
| **B. Layout** | B1. Flexbox Card Layout | 0.5 |
| | B2. Sticky Header and CSS Interaction | 0.5 |
| | B3. CSS Grid Two-Column Layout | 1.5 |
| | B4. CSS Animations and Transitions | 1.5 |
| | B5. CSS Grid and Advanced Selectors | 2.0 |
| **C. Frontend** | C1. localStorage-based Memo App | 0.5 |
| | C2. DOM Manipulation and Event Handling | 0.5 |
| | C3. Dynamic JSON Rendering and Filtering | 1.5 |
| | C4. Form Validation | 1.5 |
| | C5. IntersectionObserver and Deferred Rendering | 2.0 |
| **D. Backend** | D1. PDO-based CRUD API | 0.5 |
| | D2. File Upload Handling | 0.5 |
| | D3. Session-based Authentication System | 1.5 |
| | D4. Pagination | 1.5 |
| | D5. Multi-table Aggregate Queries | 3.0 |
| **Jami** | | **25** |