├── favicon.ico ├── images ├── banner-1.png ├── banner-2.png ├── banner-3.png ├── banner-4.png └── banner-5.png ├── admin ├── src │ ├── images │ │ ├── AdminLTELogo.png │ │ └── user2-160x160.jpg │ ├── css │ │ ├── sweetalert2.css │ │ ├── login_signup.css │ │ └── toastr.min.css │ └── js │ │ └── toastr.min.js ├── auth.php ├── includes │ ├── footer.php │ ├── js.php │ ├── css.php │ └── navbar.php ├── index.php ├── user.php ├── results.php ├── dropdown.php ├── fill_in_the_blank.php ├── matching.php ├── topics.php ├── true_false.php ├── test.php ├── question.php └── lesson.php ├── logout └── index.php ├── 404.php ├── config.php ├── about.php ├── login └── index.php ├── index.php ├── includes ├── footer.php └── header.php ├── lessons.php ├── README.md ├── lesson_detail.php └── database.sql /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/favicon.ico -------------------------------------------------------------------------------- /images/banner-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/images/banner-1.png -------------------------------------------------------------------------------- /images/banner-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/images/banner-2.png -------------------------------------------------------------------------------- /images/banner-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/images/banner-3.png -------------------------------------------------------------------------------- /images/banner-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/images/banner-4.png -------------------------------------------------------------------------------- /images/banner-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/images/banner-5.png -------------------------------------------------------------------------------- /admin/src/images/AdminLTELogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/admin/src/images/AdminLTELogo.png -------------------------------------------------------------------------------- /admin/src/images/user2-160x160.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Iqbolshoh/php-education-management/HEAD/admin/src/images/user2-160x160.jpg -------------------------------------------------------------------------------- /logout/index.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | Admin Panel 4 |
5 | Copyright © 2014-2025 Iqbolshoh.uz. All rights reserved. 6 | -------------------------------------------------------------------------------- /admin/includes/js.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /admin/includes/css.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /admin/src/css/sweetalert2.css: -------------------------------------------------------------------------------- 1 | .swal2-popup { 2 | font-family: 'Arial', sans-serif; 3 | } 4 | 5 | .swal2-title { 6 | color: #2c3e50; 7 | font-size: 1.5rem; 8 | } 9 | 10 | .swal2-html-container { 11 | color: #34495e; 12 | font-size: 1rem; 13 | } 14 | 15 | .swal2-confirm { 16 | background-color: #28a745; 17 | color: #fff; 18 | border: none; 19 | border-radius: 4px; 20 | padding: 0.5em 1em; 21 | margin-left: 10px; 22 | } 23 | 24 | .swal2-cancel { 25 | background-color: #dc3545; 26 | color: #fff; 27 | border: none; 28 | border-radius: 4px; 29 | padding: 0.5em 1em; 30 | margin-right: 10px; 31 | } 32 | 33 | .swal2-confirm:hover { 34 | background-color: #218838; 35 | } 36 | 37 | .swal2-cancel:hover { 38 | background-color: #c82333; 39 | } -------------------------------------------------------------------------------- /admin/src/css/login_signup.css: -------------------------------------------------------------------------------- 1 | body { 2 | height: 100vh; 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | font-family: 'Arial', sans-serif; 7 | margin: 0px; 8 | } 9 | 10 | .form-container { 11 | background-color: #fff; 12 | border-radius: 8px; 13 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); 14 | padding: 30px; 15 | width: calc(100% - 40px); 16 | max-width: 450px; 17 | box-sizing: border-box; 18 | } 19 | 20 | h1 { 21 | margin: 0 0 20px; 22 | font-size: 24px; 23 | color: #333; 24 | } 25 | 26 | .form-group { 27 | margin-bottom: 15px; 28 | position: relative; 29 | } 30 | 31 | .form-group label { 32 | display: block; 33 | margin-bottom: 5px; 34 | font-weight: bold; 35 | color: #555; 36 | } 37 | 38 | .form-group input { 39 | width: 100%; 40 | padding: 10px; 41 | border: 1px solid #ddd; 42 | border-radius: 4px; 43 | box-sizing: border-box; 44 | font-size: 16px; 45 | } 46 | 47 | .form-group .password-container { 48 | display: flex; 49 | align-items: center; 50 | } 51 | 52 | .form-group .password-container input { 53 | flex: 1; 54 | padding-right: 40px; 55 | } 56 | 57 | .form-group .password-toggle { 58 | position: absolute; 59 | right: 10px; 60 | font-size: 18px; 61 | cursor: pointer; 62 | border: none; 63 | background: transparent; 64 | } 65 | 66 | .form-group #submit { 67 | width: 100%; 68 | background-color: #007bff; 69 | color: #fff; 70 | border: none; 71 | padding: 12px 15px; 72 | border-radius: 4px; 73 | font-size: 18px; 74 | cursor: pointer; 75 | transition: background-color 0.3s; 76 | } 77 | 78 | .form-group #submit:hover { 79 | background-color: #0056b3; 80 | } 81 | 82 | .text-center { 83 | text-align: center; 84 | margin-top: 15px; 85 | } 86 | 87 | .text-center a { 88 | color: #007bff; 89 | text-decoration: none; 90 | } 91 | 92 | .text-center a:hover { 93 | text-decoration: underline; 94 | } 95 | 96 | #email-message, 97 | #username-message { 98 | color: red; 99 | font-size: 14px; 100 | margin-top: 5px; 101 | } -------------------------------------------------------------------------------- /404.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Page Not Found 10 | 73 | 74 | 75 | 76 |
77 |
78 |

404

79 |

Oops! The page you're looking for cannot be found.

80 | Back to Homepage 81 |
82 |
83 | 84 | 85 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | conn = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); 14 | 15 | if ($this->conn->connect_error) { 16 | die("Database connection error: " . $this->conn->connect_error); 17 | } 18 | } 19 | 20 | public function __destruct() 21 | { 22 | if ($this->conn) { 23 | $this->conn->close(); 24 | } 25 | } 26 | 27 | public function executeQuery($sql, $params = [], $types = "") 28 | { 29 | $result = $this->conn->prepare($sql); 30 | 31 | if (!$result) { 32 | return "SQL error: " . $this->conn->error; 33 | } 34 | 35 | if ($params) { 36 | $result->bind_param($types, ...$params); 37 | } 38 | 39 | if (!$result->execute()) { 40 | return "Execution error: " . $result->error; 41 | } 42 | 43 | return $result; 44 | } 45 | 46 | function validate($value) 47 | { 48 | return htmlspecialchars(trim(stripslashes($value)), ENT_QUOTES, 'UTF-8'); 49 | } 50 | 51 | public function select($table, $columns = "*", $condition = "", $params = [], $types = "") 52 | { 53 | $sql = "SELECT $columns FROM $table" . ($condition ? " WHERE $condition" : ""); 54 | $result = $this->executeQuery($sql, $params, $types); 55 | 56 | if (is_string($result)) { 57 | return $result; 58 | } 59 | 60 | return $result->get_result()->fetch_all(MYSQLI_ASSOC); 61 | } 62 | 63 | public function insert($table, $data) 64 | { 65 | $keys = implode(', ', array_keys($data)); 66 | $placeholders = implode(', ', array_fill(0, count($data), '?')); 67 | $sql = "INSERT INTO $table ($keys) VALUES ($placeholders)"; 68 | $types = str_repeat('s', count($data)); 69 | 70 | $result = $this->executeQuery($sql, array_values($data), $types); 71 | if (is_string($result)) { 72 | return $result; 73 | } 74 | 75 | return $this->conn->insert_id; 76 | } 77 | 78 | public function update($table, $data, $condition = "", $params = [], $types = "") 79 | { 80 | $set = implode(", ", array_map(function ($k) { 81 | return "$k = ?"; 82 | }, array_keys($data))); 83 | $sql = "UPDATE $table SET $set" . ($condition ? " WHERE $condition" : ""); 84 | $types = str_repeat('s', count($data)) . $types; 85 | 86 | $result = $this->executeQuery($sql, array_merge(array_values($data), $params), $types); 87 | if (is_string($result)) { 88 | return $result; 89 | } 90 | 91 | return $this->conn->affected_rows; 92 | } 93 | 94 | public function delete($table, $condition = "", $params = [], $types = "") 95 | { 96 | $sql = "DELETE FROM $table" . ($condition ? " WHERE $condition" : ""); 97 | 98 | $result = $this->executeQuery($sql, $params, $types); 99 | if (is_string($result)) { 100 | return $result; 101 | } 102 | 103 | return $this->conn->affected_rows; 104 | } 105 | 106 | public function hashPassword($password) 107 | { 108 | return hash_hmac('sha256', $password, 'iqbolshoh'); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /about.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | About US 8 | 9 | 10 | 11 | 89 | 90 | 91 | 92 |
93 | 94 |
95 |

Start Learning Today!

96 |

Don't wait to improve your English. Click below to start practicing and 97 | exploring 98 | our lessons!

99 | 100 |
101 | 102 |
103 | 104 |
105 |

Features of Letter edu

106 |

Our platform offers a variety of features to help you succeed:

107 | 114 |
115 | 116 |
117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /login/index.php: -------------------------------------------------------------------------------- 1 | hashPassword($_POST['password']); 15 | $result = $query->select('users', '*', "username = ? AND password = ?", [$username, $password], 'ss'); 16 | 17 | if (count($result) > 0) { 18 | $user = $result[0]; 19 | 20 | $_SESSION['loggedin'] = true; 21 | $_SESSION['user_id'] = $user['id']; 22 | $_SESSION['username'] = $user['username']; 23 | $_SESSION['first_name'] = $user['first_name']; 24 | $_SESSION['last_name'] = $user['last_name']; 25 | ?> 26 | 39 | 42 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Login 66 | 67 | 68 | 69 | 70 | 71 | 72 |
73 | 74 |

Login

75 | 76 |
77 |
78 | 79 | 80 |
81 |
82 | 83 |
84 | 85 | 87 |
88 |
89 |
90 | 91 |
92 |
93 | 94 |
95 | 96 | 97 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /admin/index.php: -------------------------------------------------------------------------------- 1 | 2 | select('users', '*')[0]; 5 | $topics = $query->select('lessons', '*')[0]; 6 | $results = $query->select('results', '*'); 7 | 8 | $tests = count($query->select('test', '*')); 9 | $tru_falses = count($query->select('tru_false', '*')); 10 | $dropdowns = count($query->select('dropdown', '*')); 11 | $fill_in_the_blanks = count($query->select('fill_in_the_blank', '*')); 12 | $matchings = count($query->select('matching', '*')); 13 | $answers = count($query->select('answers', '*')); 14 | 15 | $question = $tests + $tru_falses + $dropdowns + $fill_in_the_blanks + $matchings + $answers; 16 | 17 | ?> 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | AdminLTE 3 | Dashboard 29 | 30 | 31 | 32 | 33 |
34 | 35 |
36 | 37 | "Home", "url" => "./"], 40 | ["title" => "Dashboard", "url" => "#"], 41 | ); 42 | pagePath('Dashboard', $arr); 43 | ?> 44 | 45 |
46 |
47 | 48 |
49 |
50 | 51 |
52 |
53 |

54 | 55 |

56 |
57 |
58 | 59 |
60 | Edit User 61 |
62 |
63 | 64 |
65 | 66 |
67 |
68 |

69 | 70 |

Available in the system

71 |
72 |
73 | 74 |
75 | Add Topics 76 |
77 |
78 | 79 |
80 |
81 |
82 |

83 | 84 |

Total number of questions.

85 |
86 |
87 | 88 |
89 | See questions 90 |
91 |
92 | 93 |
94 | 95 |
96 |
97 |

98 | 99 |

People passed the test.

100 |
101 |
102 | 103 |
104 | View result 105 |
106 | 107 |
108 |
109 | 110 |
111 | 112 |
113 |
114 | 115 | 116 |
117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Home 8 | 9 | 10 | 11 | 110 | 111 | 112 | 113 |
114 | 115 |
116 |

Welcome to Letter edu

117 |

Your trusted platform for online education and services.

118 | 119 |
120 | 121 |
122 | 123 |
124 |

Letter edu is an online platform dedicated to helping individuals learn English 125 | efficiently. Our mission is to provide high-quality education with interactive exercises, vocabulary 126 | building, and advanced language skills to help users progress and master the English language. Whether 127 | you're a beginner or looking to enhance your proficiency, Letter edu has the right tools to assist you 128 | in your learning journey.

129 |
130 | 131 |
132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /includes/footer.php: -------------------------------------------------------------------------------- 1 | 43 | 44 | -------------------------------------------------------------------------------- /includes/header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 140 | 141 | 142 |
143 | 164 |
165 | 166 | -------------------------------------------------------------------------------- /lessons.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | select('lessons', '*') ?> 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Lessons - Letter edu 13 | 14 | 132 | 133 | 134 | 135 | 136 |
137 | 138 |
139 |

Our Lessons

140 |

Explore our lessons designed to help you master the English language at every 141 | level. Choose a lesson below to get started!

142 |
143 | 144 |
145 | 146 |
147 |

Discover our carefully crafted lessons designed to help you improve your English 148 | skills at every level, from beginner to advanced. Whether you're looking to build a solid foundation or 149 | enhance your fluency, we’ve got the perfect lesson for you. Start your journey below and unlock your 150 | potential to speak and write with confidence!

151 |
152 | 153 |
154 | 155 |
156 | 161 |
162 |

163 |

164 | 165 | 166 | 167 |
168 | 173 |
174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /admin/user.php: -------------------------------------------------------------------------------- 1 | 2 | select('users', '*', "id = $user_id"); 6 | 7 | $user = $result[0]; 8 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 9 | $first_name = $_POST['first_name']; 10 | $last_name = $_POST['last_name']; 11 | $email = $_POST['email']; 12 | $username = $_POST['username']; 13 | $password = $_POST['password']; 14 | 15 | $_SESSION['first_name'] = $first_name; 16 | $_SESSION['last_name'] = $last_name; 17 | 18 | if (!empty($password)) { 19 | $password = $query->hashPassword($password); 20 | $query->update('users', [ 21 | 'first_name' => $first_name, 22 | 'last_name' => $last_name, 23 | 'email' => $email, 24 | 'username' => $username, 25 | 'password' => $password 26 | ], "id = $user_id"); 27 | } else { 28 | $query->update('users', [ 29 | 'first_name' => $first_name, 30 | 'last_name' => $last_name, 31 | 'email' => $email, 32 | 'username' => $username 33 | ], "id = $user_id"); 34 | } 35 | 36 | header("Location: " . $_SERVER['HTTP_REFERER']); 37 | exit; 38 | } 39 | ?> 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | AdminLTE 3 | User settings 51 | 52 | 53 | 91 | 92 | 93 |
94 | 95 |
96 | 97 | "Home", "url" => "./"], 100 | ["title" => "User settings", "url" => "#"], 101 | ); 102 | pagePath('User settings', $arr); 103 | ?> 104 | 105 |
106 |
107 | 108 |
109 |
110 |
111 |

User Settings

112 |
113 |
114 | 115 | 116 |
117 |
118 | 119 | 120 |
121 |
122 | 123 | 124 |
125 |
126 | 127 | 128 |
129 |
130 | 131 | 132 | Leave blank to keep the current password. 133 |
134 | 135 |
136 |
137 |
138 |
139 | 140 |
141 | 142 |
143 |
144 | 145 | 146 |
147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /admin/results.php: -------------------------------------------------------------------------------- 1 | 2 | 0) { 7 | $results = $query->select('results', '*', "lesson_id = $lesson_id"); 8 | } else { 9 | $lessons = $query->select('lessons', '*', '1'); 10 | } 11 | ?> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | Results 22 | 23 | 24 | 25 | 26 |
27 | 28 |
29 | 30 | "Home", "url" => "./"], 33 | ["title" => "Results", "url" => "#"], 34 | ); 35 | pagePath('Results', $arr); 36 | ?> 37 | 38 |
39 |
40 |
41 |
42 |
43 |
44 |

Lessons

45 |
46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | $lesson): ?> 58 | 59 | 60 | 63 | 66 | 67 | 68 | 69 |
Lesson NameActions
61 | 62 | 64 | View Results 65 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | $result): ?> 83 | 84 | 85 | 86 | 87 | 88 | 98 | 99 | 100 | 101 | 102 |
Participant NameTotal QuestionsAnswered QuestionsPercentage
89 | 97 |
103 |
104 | Back to Lessons 105 | 106 |

No data available.

107 | 108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | 116 | 117 |
118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🎓 PHP Education Management 2 | 3 | The **`php-education-management`** project offers a **comprehensive** and **adaptable** platform designed for educational institutions. With its **intuitive admin panel** and **dynamic features**, it simplifies administrative tasks, ensuring a **seamless experience** for both educators and students. 4 | 5 | ![📌 Homepage Banner](https://github.com/Iqbolshoh/letter-edu/blob/main/images/banner-1.png) 6 | 7 | --- 8 | 9 | ## 📚 **Project Features** 10 | 11 | ✅ **🏫 Education-Oriented** – Designed for **schools, colleges, and institutions** 12 | ✅ **📂 Course Management** – Add, edit, and organize educational materials 13 | ✅ **📝 Student Data Handling** – Keep track of **student records & progress** 14 | ✅ **📖 Resource Sharing** – Upload **documents, videos, and materials** 15 | ✅ **🖥 Admin Panel** – Manage **everything in one place** 16 | 17 | ![📚 Courses & Tests](https://github.com/Iqbolshoh/letter-edu/blob/main/images/banner-2.png) 18 | 19 | --- 20 | 21 | ## 🔐 **Admin Panel Features** 22 | 23 | The **Admin Panel** is designed with **ease of use** in mind, enabling administrators to: 24 | 25 | - 🛠 **Manage Courses** – Add, update, or delete educational content 26 | - 🏫 **Monitor Student Progress** – Track grades, attendance, and performance 27 | - 📤 **Upload Resources** – Share **documents, videos, and files** 28 | - 🏆 **Generate Reports** – View insights on student performance 29 | 30 | ![⚙ Admin Dashboard](https://github.com/Iqbolshoh/letter-edu/blob/main/images/banner-3.png) 31 | 32 | 🔐 **Admin Credentials** 33 | - **👨‍💻 Admin Login:** `iqbolshoh` 34 | - **🔑 Password:** `IQBOLSHOH` 35 | 36 | --- 37 | 38 | ## 📝 **Add Topics Feature** 39 | 40 | This feature allows **administrators** to effortlessly add **new topics** to courses. By updating content, administrators can ensure that learning materials remain **relevant and up to date**. 41 | 42 | ![📜 Add Topics](https://github.com/Iqbolshoh/letter-edu/blob/main/images/banner-4.png) 43 | 44 | 🔹 **Quickly add new topics** to any course 45 | 🔹 **Modify existing content** for better clarity 46 | 🔹 **Attach PDFs, images, and videos** for better engagement 47 | 48 | --- 49 | 50 | ## 🚀 **Admin Panel Features at a Glance** 51 | 52 | 🎯 **Content Management** – Easily modify **course descriptions, images, and materials** 53 | 📖 **Student Management** – Maintain **detailed records** of enrolled students 54 | 📂 **Resource Sharing** – Upload **documents, videos, and learning materials** 55 | 📊 **Test & Assessment System** – Create and evaluate **student tests** 56 | 57 | ![📋 Add Tests](https://github.com/Iqbolshoh/letter-edu/blob/main/images/banner-5.png) 58 | 59 | --- 60 | 61 | ## 🖥 Technologies Used 62 | ![HTML](https://img.shields.io/badge/HTML-%23E34F26.svg?style=for-the-badge&logo=html5&logoColor=white) 63 | ![CSS](https://img.shields.io/badge/CSS-%231572B6.svg?style=for-the-badge&logo=css3&logoColor=white) 64 | ![Bootstrap](https://img.shields.io/badge/Bootstrap-%23563D7C.svg?style=for-the-badge&logo=bootstrap&logoColor=white) 65 | ![JavaScript](https://img.shields.io/badge/JavaScript-%23F7DF1C.svg?style=for-the-badge&logo=javascript&logoColor=black) 66 | ![jQuery](https://img.shields.io/badge/jQuery-%230e76a8.svg?style=for-the-badge&logo=jquery&logoColor=white) 67 | ![PHP](https://img.shields.io/badge/PHP-%23777BB4.svg?style=for-the-badge&logo=php&logoColor=white) 68 | ![MySQL](https://img.shields.io/badge/MySQL-%234479A1.svg?style=for-the-badge&logo=mysql&logoColor=white) 69 | 70 | ## 📜 License 71 | This project is open-source and available under the **MIT License**. 72 | 73 | ## 🤝 Contributing 74 | 🎯 Contributions are welcome! If you have suggestions or want to enhance the project, feel free to fork the repository and submit a pull request. 75 | 76 | ## 📬 Connect with Me 77 | 💬 I love meeting new people and discussing tech, business, and creative ideas. Let’s connect! You can reach me on these platforms: 78 | 79 |
80 | 81 | 82 | 88 | 94 | 100 | 106 | 112 | 118 | 124 | 130 | 136 | 137 |
83 | 84 | Website 86 | 87 | 89 | 90 | Email 92 | 93 | 95 | 96 | GitHub 98 | 99 | 101 | 102 | LinkedIn 104 | 105 | 107 | 108 | Telegram 110 | 111 | 113 | 114 | WhatsApp 116 | 117 | 119 | 120 | Instagram 122 | 123 | 125 | 126 | X 128 | 129 | 131 | 132 | YouTube 134 | 135 |
138 |
139 | -------------------------------------------------------------------------------- /lesson_detail.php: -------------------------------------------------------------------------------- 1 | select('lessons', '*', "id = $lessonid"); 14 | 15 | if (empty($lesson)) { 16 | include '404.php'; 17 | exit; 18 | } 19 | 20 | $lesson = $lesson[0]; 21 | $lesson_items = $query->select('lesson_items', '*', "lesson_id = $lessonid ORDER BY position ASC"); 22 | } else { 23 | header('Location: lessons.php'); 24 | exit(); 25 | } 26 | 27 | ?> 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | <?= $lesson['title'] ?> 36 | 37 | 177 | 178 | 179 | 180 | 181 |
182 | 183 | 184 |
185 |

186 |

187 |

188 | 189 |
190 | 191 | $item): ?> 192 | 193 |
194 |

195 |

196 |

197 |
198 | 199 |
200 |

201 |

202 | 204 |

205 |

206 |
207 | 208 | 209 | 210 |
212 | Back to Lessons 213 | Worksheet 214 |
215 |
216 | 217 |
218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /admin/dropdown.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | $dropdowns = []; 13 | if ($lessonid) { 14 | $dropdowns = $query->select('dropdown', '*', "lesson_id = '$lessonid'"); 15 | } 16 | 17 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 18 | if (isset($_POST['add_dropdown'])) { 19 | $question = $_POST['question']; 20 | $correct_answer = $_POST['correct_answer']; 21 | $lesson_id = intval($_POST['lesson_id']); 22 | 23 | $query->insert('dropdown', [ 24 | 'lesson_id' => $lesson_id, 25 | 'question' => $question, 26 | 'correct_answer' => $correct_answer 27 | ]); 28 | } 29 | 30 | if (isset($_POST['update_dropdown'])) { 31 | foreach ($_POST['id'] as $id) { 32 | $id = intval($id); 33 | $question = $_POST['question'][$id]; 34 | $correct_answer = $_POST['correct_answer'][$id]; 35 | 36 | $query->update('dropdown', [ 37 | 'question' => $question, 38 | 'correct_answer' => $correct_answer 39 | ], "id = '$id'"); 40 | } 41 | } 42 | 43 | header("Location: " . $_SERVER['PHP_SELF'] . "?lessonid=$lessonid"); 44 | exit; 45 | } 46 | 47 | if (isset($_GET['delete_id'])) { 48 | $delete_id = intval($_GET['delete_id']); 49 | $query->delete('dropdown', "id = '$delete_id'"); 50 | header("Location: " . $_SERVER['PHP_SELF'] . "?lessonid=$lessonid"); 51 | exit; 52 | } 53 | ?> 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Dropdown 63 | 64 | 94 | 95 | 96 | 97 |
98 | 99 |
100 | "Home", "url" => "./"], ["title" => "Dropdown", "url" => "#"]]; 102 | pagePath('Dropdown', $arr); 103 | ?> 104 | 105 |
106 |
107 |
108 | 109 |
110 | 125 | 126 |
127 | 145 |
146 |
147 | 148 |
149 | select('lessons', '*'); ?> 150 | 151 |
152 | 153 | 161 |
162 | 163 |
164 | 165 |
166 |
167 | 168 | 169 | 170 |
171 |
172 |
173 |
174 | 175 | 176 |
177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /admin/src/css/toastr.min.css: -------------------------------------------------------------------------------- 1 | .toast-title { 2 | font-weight: 700 3 | } 4 | 5 | .toast-message { 6 | -ms-word-wrap: break-word; 7 | word-wrap: break-word 8 | } 9 | 10 | .toast-message a, 11 | .toast-message label { 12 | color: #FFF 13 | } 14 | 15 | .toast-message a:hover { 16 | color: #CCC; 17 | text-decoration: none 18 | } 19 | 20 | .toast-close-button { 21 | position: relative; 22 | right: -.3em; 23 | top: -.3em; 24 | float: right; 25 | font-size: 20px; 26 | font-weight: 700; 27 | color: #FFF; 28 | -webkit-text-shadow: 0 1px 0 #fff; 29 | text-shadow: 0 1px 0 #fff; 30 | opacity: .8; 31 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); 32 | filter: alpha(opacity=80); 33 | line-height: 1 34 | } 35 | 36 | .toast-close-button:focus, 37 | .toast-close-button:hover { 38 | color: #000; 39 | text-decoration: none; 40 | cursor: pointer; 41 | opacity: .4; 42 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); 43 | filter: alpha(opacity=40) 44 | } 45 | 46 | .rtl .toast-close-button { 47 | left: -.3em; 48 | float: left; 49 | right: .3em 50 | } 51 | 52 | button.toast-close-button { 53 | padding: 0; 54 | cursor: pointer; 55 | background: 0 0; 56 | border: 0; 57 | -webkit-appearance: none 58 | } 59 | 60 | .toast-top-center { 61 | top: 0; 62 | right: 0; 63 | width: 100% 64 | } 65 | 66 | .toast-bottom-center { 67 | bottom: 0; 68 | right: 0; 69 | width: 100% 70 | } 71 | 72 | .toast-top-full-width { 73 | top: 0; 74 | right: 0; 75 | width: 100% 76 | } 77 | 78 | .toast-bottom-full-width { 79 | bottom: 0; 80 | right: 0; 81 | width: 100% 82 | } 83 | 84 | .toast-top-left { 85 | top: 12px; 86 | left: 12px 87 | } 88 | 89 | .toast-top-right { 90 | top: 12px; 91 | right: 12px 92 | } 93 | 94 | .toast-bottom-right { 95 | right: 12px; 96 | bottom: 12px 97 | } 98 | 99 | .toast-bottom-left { 100 | bottom: 12px; 101 | left: 12px 102 | } 103 | 104 | #toast-container { 105 | position: fixed; 106 | z-index: 999999; 107 | pointer-events: none 108 | } 109 | 110 | #toast-container * { 111 | -moz-box-sizing: border-box; 112 | -webkit-box-sizing: border-box; 113 | box-sizing: border-box 114 | } 115 | 116 | #toast-container>div { 117 | position: relative; 118 | pointer-events: auto; 119 | overflow: hidden; 120 | margin: 0 0 6px; 121 | padding: 15px 15px 15px 50px; 122 | width: 300px; 123 | -moz-border-radius: 3px; 124 | -webkit-border-radius: 3px; 125 | border-radius: 3px; 126 | background-position: 15px center; 127 | background-repeat: no-repeat; 128 | -moz-box-shadow: 0 0 12px #999; 129 | -webkit-box-shadow: 0 0 12px #999; 130 | box-shadow: 0 0 12px #999; 131 | color: #FFF; 132 | opacity: .8; 133 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); 134 | filter: alpha(opacity=80) 135 | } 136 | 137 | #toast-container>div.rtl { 138 | direction: rtl; 139 | padding: 15px 50px 15px 15px; 140 | background-position: right 15px center 141 | } 142 | 143 | #toast-container>div:hover { 144 | -moz-box-shadow: 0 0 12px #000; 145 | -webkit-box-shadow: 0 0 12px #000; 146 | box-shadow: 0 0 12px #000; 147 | opacity: 1; 148 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); 149 | filter: alpha(opacity=100); 150 | cursor: pointer 151 | } 152 | 153 | #toast-container>.toast-info { 154 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=) !important 155 | } 156 | 157 | #toast-container>.toast-error { 158 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=) !important 159 | } 160 | 161 | #toast-container>.toast-success { 162 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==) !important 163 | } 164 | 165 | #toast-container>.toast-warning { 166 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=) !important 167 | } 168 | 169 | #toast-container.toast-bottom-center>div, 170 | #toast-container.toast-top-center>div { 171 | width: 300px; 172 | margin-left: auto; 173 | margin-right: auto 174 | } 175 | 176 | #toast-container.toast-bottom-full-width>div, 177 | #toast-container.toast-top-full-width>div { 178 | width: 96%; 179 | margin-left: auto; 180 | margin-right: auto 181 | } 182 | 183 | .toast { 184 | background-color: #030303 185 | } 186 | 187 | .toast-success { 188 | background-color: #51A351 189 | } 190 | 191 | .toast-error { 192 | background-color: #BD362F 193 | } 194 | 195 | .toast-info { 196 | background-color: #2F96B4 197 | } 198 | 199 | .toast-warning { 200 | background-color: #F89406 201 | } 202 | 203 | .toast-progress { 204 | position: absolute; 205 | left: 0; 206 | bottom: 0; 207 | height: 4px; 208 | background-color: #000; 209 | opacity: .4; 210 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); 211 | filter: alpha(opacity=40) 212 | } 213 | 214 | @media all and (max-width:240px) { 215 | #toast-container>div { 216 | padding: 8px 8px 8px 50px; 217 | width: 11em 218 | } 219 | 220 | #toast-container>div.rtl { 221 | padding: 8px 50px 8px 8px 222 | } 223 | 224 | #toast-container .toast-close-button { 225 | right: -.2em; 226 | top: -.2em 227 | } 228 | 229 | #toast-container .rtl .toast-close-button { 230 | left: -.2em; 231 | right: .2em 232 | } 233 | } 234 | 235 | @media all and (min-width:241px) and (max-width:480px) { 236 | #toast-container>div { 237 | padding: 8px 8px 8px 50px; 238 | width: 18em 239 | } 240 | 241 | #toast-container>div.rtl { 242 | padding: 8px 50px 8px 8px 243 | } 244 | 245 | #toast-container .toast-close-button { 246 | right: -.2em; 247 | top: -.2em 248 | } 249 | 250 | #toast-container .rtl .toast-close-button { 251 | left: -.2em; 252 | right: .2em 253 | } 254 | } 255 | 256 | @media all and (min-width:481px) and (max-width:768px) { 257 | #toast-container>div { 258 | padding: 15px 15px 15px 50px; 259 | width: 25em 260 | } 261 | 262 | #toast-container>div.rtl { 263 | padding: 15px 50px 15px 15px 264 | } 265 | } -------------------------------------------------------------------------------- /admin/fill_in_the_blank.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | $edit_blank_id = isset($_GET['edit_blank_id']) ? intval($_GET['edit_blank_id']) : null; 13 | 14 | $blanks = []; 15 | if ($lessonid !== null) { 16 | $blanks = $query->select('fill_in_the_blank', '*', "lesson_id = '$lessonid'"); 17 | } 18 | 19 | $edit_blank = null; 20 | if ($edit_blank_id !== null) { 21 | $edit_blank = $query->select('fill_in_the_blank', '*', "id = $edit_blank_id")[0] ?? null; 22 | } 23 | 24 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 25 | if (isset($_POST['add_blank'])) { 26 | $sentence = $_POST['sentence']; 27 | $correct_answer = $_POST['correct_answer']; 28 | 29 | $blank_id = $query->insert('fill_in_the_blank', [ 30 | 'lesson_id' => $lessonid, 31 | 'sentence' => $sentence, 32 | 'correct_answer' => $correct_answer 33 | ]); 34 | } elseif (isset($_POST['update_blank'])) { 35 | $blank_id = $_POST['blank_id']; 36 | $sentence = $_POST['sentence']; 37 | $correct_answer = $_POST['correct_answer']; 38 | 39 | $query->update('fill_in_the_blank', [ 40 | 'sentence' => $sentence, 41 | 'correct_answer' => $correct_answer 42 | ], "id = $blank_id"); 43 | } 44 | header("Location: ?lessonid=$lessonid"); 45 | exit; 46 | } 47 | 48 | if (isset($_GET['delete_id'])) { 49 | $delete_id = $_GET['delete_id']; 50 | $query->delete('fill_in_the_blank', "id = '$delete_id'"); 51 | header("Location: ?lessonid=$lessonid"); 52 | exit; 53 | } 54 | ?> 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | AdminLTE 3 | Fill in the Blank 65 | 66 | 67 | 68 | 112 | 113 | 114 |
115 | 116 |
117 | 118 | "Home", "url" => "./"], 121 | ["title" => "Fill in the Blank", "url" => "#"], 122 | ); 123 | pagePath('Fill in the Blank', $arr); 124 | ?> 125 | 126 |
127 |
128 |
129 | 130 | 131 | 132 |
133 |

134 | 135 |
136 | 137 | 138 |
139 |
140 | 141 | 142 |
143 | 144 |
145 | 146 |
147 |
148 | 149 |
150 |
151 |

Blanks List

152 |
153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | $blank): ?> 163 | 164 | 165 | 168 | 172 | 173 | 174 | 175 |
SentenceActions
166 |

167 |
169 | Edit 170 | Delete 171 |
176 |
177 | 178 | 179 |
180 | select('lessons', '*'); ?> 181 | 182 |
183 | 184 | 192 |
193 | 194 |
195 | 196 |
197 |
198 | 199 | 200 | 201 |
202 |
203 |
204 |
205 |
206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /admin/matching.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | $edit_matching_id = isset($_GET['edit_matching_id']) ? intval($_GET['edit_matching_id']) : null; 13 | 14 | $matchings = []; 15 | if ($lessonid !== null) { 16 | $matchings = $query->select('matching', '*', "lesson_id = '$lessonid'"); 17 | } 18 | 19 | $edit_matching = null; 20 | if ($edit_matching_id !== null) { 21 | $edit_matching = $query->select('matching', '*', "id = $edit_matching_id")[0] ?? null; 22 | } 23 | 24 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 25 | if (isset($_POST['add_matching'])) { 26 | $left_side = $_POST['left_side']; 27 | $right_side = $_POST['right_side']; 28 | 29 | $matching_id = $query->insert('matching', [ 30 | 'lesson_id' => $lessonid, 31 | 'left_side' => $left_side, 32 | 'right_side' => $right_side 33 | ]); 34 | } elseif (isset($_POST['update_matching'])) { 35 | $matching_id = $_POST['matching_id']; 36 | $left_side = $_POST['left_side']; 37 | $right_side = $_POST['right_side']; 38 | 39 | $query->update('matching', [ 40 | 'left_side' => $left_side, 41 | 'right_side' => $right_side 42 | ], "id = $matching_id"); 43 | } 44 | header("Location: ?lessonid=$lessonid"); 45 | exit; 46 | } 47 | 48 | if (isset($_GET['delete_id'])) { 49 | $delete_id = $_GET['delete_id']; 50 | $query->delete('matching', "id = '$delete_id'"); 51 | header("Location: ?lessonid=$lessonid"); 52 | exit; 53 | } 54 | ?> 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | AdminLTE 3 | Matching 65 | 66 | 67 | 68 | 112 | 113 | 114 |
115 | 116 |
117 | 118 | "Home", "url" => "./"], 121 | ["title" => "Matching", "url" => "#"], 122 | ); 123 | pagePath('Matching', $arr); 124 | ?> 125 | 126 |
127 |
128 |
129 | 130 | 131 | 132 |
133 |

134 | 135 |
136 | 137 | 138 |
139 |
140 | 141 | 142 |
143 | 144 |
145 | 146 |
147 |
148 | 149 |
150 |
151 |

Matchings List

152 |
153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | $matching): ?> 164 | 165 | 166 | 169 | 170 | 174 | 175 | 176 | 177 |
Left SideRight SideActions
167 |

168 |
171 | Edit 172 | Delete 173 |
178 |
179 | 180 | 181 |
182 | select('lessons', '*'); ?> 183 | 184 |
185 | 186 | 194 |
195 | 196 |
197 | 198 |
199 |
200 | 201 | 202 | 203 |
204 |
205 |
206 |
207 |
208 | 209 | 210 | 211 | -------------------------------------------------------------------------------- /admin/topics.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*'); 5 | 6 | if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['insert'])) { 7 | $title = $_POST['title']; 8 | $description = $_POST['description']; 9 | 10 | $insert = $query->insert('lessons', [ 11 | 'title' => $title, 12 | 'description' => $description 13 | ]); 14 | 15 | if ($insert) { 16 | header("Location: ./topics.php"); 17 | } 18 | } 19 | 20 | if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['delete'])) { 21 | $id = $_POST['id']; 22 | $delete = $query->delete('lessons', "id = $id"); 23 | 24 | if ($delete) { 25 | header("Location: ./topics.php"); 26 | } 27 | } 28 | 29 | if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['id'])) { 30 | $id = $_POST['id'] ?? null; 31 | $title = $_POST['title'] ?? null; 32 | $description = $_POST['description'] ?? null; 33 | 34 | $update = $query->update('lessons', [ 35 | 'title' => $title, 36 | 'description' => $description 37 | ], "id = $id"); 38 | 39 | if ($update) { 40 | header("Location: ./topics.php"); 41 | } 42 | } 43 | ?> 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | AdminLTE 3 | Topics 53 | 54 | 55 | 60 | 61 | 62 |
63 | 64 |
65 | 66 | "Home", "url" => "./"], 69 | ["title" => "Topics", "url" => "#"], 70 | ); 71 | pagePath('Topics', $arr); 72 | ?> 73 | 74 |
75 |
76 |
77 |
78 |
79 |
80 |

Insert New Topic

81 |
82 |
83 |
84 |
85 | 86 | 87 |
88 |
89 | 90 | 91 |
92 | 93 |
94 |
95 |
96 | 97 |
98 |
99 |

Topics List

100 |
101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | "; 117 | echo ""; 118 | echo ""; 119 | echo ""; 120 | echo ""; 134 | echo ""; 135 | $count++; 136 | } 137 | } else { 138 | echo ""; 139 | } 140 | ?> 141 | 142 |
TitleDescriptionActions
{$count}{$topic['title']}{$topic['description']} 121 | 129 |
130 | 131 | 132 |
133 |
No topics found.
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | 151 | 152 |
153 | 154 | 180 | 181 | 182 | 183 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /admin/true_false.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | $true_false = []; 13 | if ($lessonid !== null) { 14 | $true_false = $query->select('tru_false', '*', "lesson_id = '$lessonid'"); 15 | } 16 | 17 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 18 | if (isset($_POST['add_true_false'])) { 19 | $statement = ($_POST['statement']); 20 | $is_true = isset($_POST['is_true']) ? 1 : 0; 21 | 22 | $query->insert('tru_false', [ 23 | 'lesson_id' => $lessonid, 24 | 'statement' => $statement, 25 | 'is_true' => $is_true 26 | ]); 27 | 28 | header("Location: true_false.php?lessonid=$lessonid"); 29 | exit; 30 | } 31 | 32 | if (isset($_POST['update_true_false'])) { 33 | foreach ($_POST['statement'] as $id => $statement) { 34 | $statement = ($statement); 35 | $is_true = isset($_POST['is_true'][$id]) ? 1 : 0; 36 | 37 | $query->update('tru_false', [ 38 | 'statement' => $statement, 39 | 'is_true' => $is_true 40 | ], "id = '$id'"); 41 | } 42 | header("Location: true_false.php?lessonid=$lessonid"); 43 | exit; 44 | } 45 | } 46 | 47 | 48 | if (isset($_GET['delete_id'])) { 49 | $delete_id = $_GET['delete_id']; 50 | $query->delete('tru_false', "id = '$delete_id'"); 51 | header("Location: true_false.php?lessonid=$lessonid"); 52 | exit; 53 | } 54 | ?> 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Admin | True/False 65 | 66 | 67 | 68 | 140 | 141 | 142 |
143 | 144 |
145 | 146 | "Home", "url" => "./"], 149 | ["title" => "True/False", "url" => "#"], 150 | ); 151 | pagePath('True/False', $arr); 152 | ?> 153 | 154 |
155 |
156 |
157 | 158 | 159 |
160 |
161 |
162 |

Add New True/False Question

163 |
164 | 165 | 166 |
167 | 168 | 169 |
170 | 171 |
172 | 173 | Yes 174 |
175 | 176 | 177 |
178 |
179 |
180 | 181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | $question): ?> 194 | 195 | 196 | 199 | 202 | 205 | 206 | 207 | 208 |
StatementAnswerActions
197 | 198 | 200 | > 201 | 203 | Delete 204 |
209 | 210 | 211 |
212 |
213 |
214 |
215 |
216 |
217 | 218 |
219 | select('lessons', '*'); ?> 220 | 221 |
222 | 223 | 231 |
232 | 233 |
234 | 235 |
236 |
237 | 238 | 239 | 240 |
241 |
242 |
243 | 244 |
245 | 246 | 247 |
248 | 249 | 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /admin/includes/navbar.php: -------------------------------------------------------------------------------- 1 | 5 |
6 |
7 |
8 |
9 |

10 | 11 |

12 |
13 |
14 | 24 |
25 |
26 |
27 |
28 | 31 | 32 | 33 | 34 | 79 | 80 | -------------------------------------------------------------------------------- /admin/src/js/toastr.min.js: -------------------------------------------------------------------------------- 1 | ! function (e) { 2 | e(["jquery"], function (e) { 3 | return function () { 4 | function t(e, t, n) { 5 | return g({ 6 | type: O.error, 7 | iconClass: m().iconClasses.error, 8 | message: e, 9 | optionsOverride: n, 10 | title: t 11 | }) 12 | } 13 | 14 | function n(t, n) { 15 | return t || (t = m()), v = e("#" + t.containerId), v.length ? v : (n && (v = d(t)), v) 16 | } 17 | 18 | function o(e, t, n) { 19 | return g({ 20 | type: O.info, 21 | iconClass: m().iconClasses.info, 22 | message: e, 23 | optionsOverride: n, 24 | title: t 25 | }) 26 | } 27 | 28 | function s(e) { 29 | C = e 30 | } 31 | 32 | function i(e, t, n) { 33 | return g({ 34 | type: O.success, 35 | iconClass: m().iconClasses.success, 36 | message: e, 37 | optionsOverride: n, 38 | title: t 39 | }) 40 | } 41 | 42 | function a(e, t, n) { 43 | return g({ 44 | type: O.warning, 45 | iconClass: m().iconClasses.warning, 46 | message: e, 47 | optionsOverride: n, 48 | title: t 49 | }) 50 | } 51 | 52 | function r(e, t) { 53 | var o = m(); 54 | v || n(o), u(e, o, t) || l(o) 55 | } 56 | 57 | function c(t) { 58 | var o = m(); 59 | return v || n(o), t && 0 === e(":focus", t).length ? void h(t) : void(v.children().length && v.remove()) 60 | } 61 | 62 | function l(t) { 63 | for (var n = v.children(), o = n.length - 1; o >= 0; o--) u(e(n[o]), t) 64 | } 65 | 66 | function u(t, n, o) { 67 | var s = !(!o || !o.force) && o.force; 68 | return !(!t || !s && 0 !== e(":focus", t).length) && (t[n.hideMethod]({ 69 | duration: n.hideDuration, 70 | easing: n.hideEasing, 71 | complete: function () { 72 | h(t) 73 | } 74 | }), !0) 75 | } 76 | 77 | function d(t) { 78 | return v = e("
").attr("id", t.containerId).addClass(t.positionClass), v.appendTo(e(t.target)), v 79 | } 80 | 81 | function p() { 82 | return { 83 | tapToDismiss: !0, 84 | toastClass: "toast", 85 | containerId: "toast-container", 86 | debug: !1, 87 | showMethod: "fadeIn", 88 | showDuration: 300, 89 | showEasing: "swing", 90 | onShown: void 0, 91 | hideMethod: "fadeOut", 92 | hideDuration: 1e3, 93 | hideEasing: "swing", 94 | onHidden: void 0, 95 | closeMethod: !1, 96 | closeDuration: !1, 97 | closeEasing: !1, 98 | closeOnHover: !0, 99 | extendedTimeOut: 1e3, 100 | iconClasses: { 101 | error: "toast-error", 102 | info: "toast-info", 103 | success: "toast-success", 104 | warning: "toast-warning" 105 | }, 106 | iconClass: "toast-info", 107 | positionClass: "toast-top-right", 108 | timeOut: 5e3, 109 | titleClass: "toast-title", 110 | messageClass: "toast-message", 111 | escapeHtml: !1, 112 | target: "body", 113 | closeHtml: '', 114 | closeClass: "toast-close-button", 115 | newestOnTop: !0, 116 | preventDuplicates: !1, 117 | progressBar: !1, 118 | progressClass: "toast-progress", 119 | rtl: !1 120 | } 121 | } 122 | 123 | function f(e) { 124 | C && C(e) 125 | } 126 | 127 | function g(t) { 128 | function o(e) { 129 | return null == e && (e = ""), e.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(//g, ">") 130 | } 131 | 132 | function s() { 133 | c(), u(), d(), p(), g(), C(), l(), i() 134 | } 135 | 136 | function i() { 137 | var e = ""; 138 | switch (t.iconClass) { 139 | case "toast-success": 140 | case "toast-info": 141 | e = "polite"; 142 | break; 143 | default: 144 | e = "assertive" 145 | } 146 | I.attr("aria-live", e) 147 | } 148 | 149 | function a() { 150 | E.closeOnHover && I.hover(H, D), !E.onclick && E.tapToDismiss && I.click(b), E.closeButton && j && j.click(function (e) { 151 | e.stopPropagation ? e.stopPropagation() : void 0 !== e.cancelBubble && e.cancelBubble !== !0 && (e.cancelBubble = !0), E.onCloseClick && E.onCloseClick(e), b(!0) 152 | }), E.onclick && I.click(function (e) { 153 | E.onclick(e), b() 154 | }) 155 | } 156 | 157 | function r() { 158 | I.hide(), I[E.showMethod]({ 159 | duration: E.showDuration, 160 | easing: E.showEasing, 161 | complete: E.onShown 162 | }), E.timeOut > 0 && (k = setTimeout(b, E.timeOut), F.maxHideTime = parseFloat(E.timeOut), F.hideEta = (new Date).getTime() + F.maxHideTime, E.progressBar && (F.intervalId = setInterval(x, 10))) 163 | } 164 | 165 | function c() { 166 | t.iconClass && I.addClass(E.toastClass).addClass(y) 167 | } 168 | 169 | function l() { 170 | E.newestOnTop ? v.prepend(I) : v.append(I) 171 | } 172 | 173 | function u() { 174 | if (t.title) { 175 | var e = t.title; 176 | E.escapeHtml && (e = o(t.title)), M.append(e).addClass(E.titleClass), I.append(M) 177 | } 178 | } 179 | 180 | function d() { 181 | if (t.message) { 182 | var e = t.message; 183 | E.escapeHtml && (e = o(t.message)), B.append(e).addClass(E.messageClass), I.append(B) 184 | } 185 | } 186 | 187 | function p() { 188 | E.closeButton && (j.addClass(E.closeClass).attr("role", "button"), I.prepend(j)) 189 | } 190 | 191 | function g() { 192 | E.progressBar && (q.addClass(E.progressClass), I.prepend(q)) 193 | } 194 | 195 | function C() { 196 | E.rtl && I.addClass("rtl") 197 | } 198 | 199 | function O(e, t) { 200 | if (e.preventDuplicates) { 201 | if (t.message === w) return !0; 202 | w = t.message 203 | } 204 | return !1 205 | } 206 | 207 | function b(t) { 208 | var n = t && E.closeMethod !== !1 ? E.closeMethod : E.hideMethod, 209 | o = t && E.closeDuration !== !1 ? E.closeDuration : E.hideDuration, 210 | s = t && E.closeEasing !== !1 ? E.closeEasing : E.hideEasing; 211 | if (!e(":focus", I).length || t) return clearTimeout(F.intervalId), I[n]({ 212 | duration: o, 213 | easing: s, 214 | complete: function () { 215 | h(I), clearTimeout(k), E.onHidden && "hidden" !== P.state && E.onHidden(), P.state = "hidden", P.endTime = new Date, f(P) 216 | } 217 | }) 218 | } 219 | 220 | function D() { 221 | (E.timeOut > 0 || E.extendedTimeOut > 0) && (k = setTimeout(b, E.extendedTimeOut), F.maxHideTime = parseFloat(E.extendedTimeOut), F.hideEta = (new Date).getTime() + F.maxHideTime) 222 | } 223 | 224 | function H() { 225 | clearTimeout(k), F.hideEta = 0, I.stop(!0, !0)[E.showMethod]({ 226 | duration: E.showDuration, 227 | easing: E.showEasing 228 | }) 229 | } 230 | 231 | function x() { 232 | var e = (F.hideEta - (new Date).getTime()) / F.maxHideTime * 100; 233 | q.width(e + "%") 234 | } 235 | var E = m(), 236 | y = t.iconClass || E.iconClass; 237 | if ("undefined" != typeof t.optionsOverride && (E = e.extend(E, t.optionsOverride), y = t.optionsOverride.iconClass || y), !O(E, t)) { 238 | T++, v = n(E, !0); 239 | var k = null, 240 | I = e("
"), 241 | M = e("
"), 242 | B = e("
"), 243 | q = e("
"), 244 | j = e(E.closeHtml), 245 | F = { 246 | intervalId: null, 247 | hideEta: null, 248 | maxHideTime: null 249 | }, 250 | P = { 251 | toastId: T, 252 | state: "visible", 253 | startTime: new Date, 254 | options: E, 255 | map: t 256 | }; 257 | return s(), r(), a(), f(P), E.debug && console && console.log(P), I 258 | } 259 | } 260 | 261 | function m() { 262 | return e.extend({}, p(), b.options) 263 | } 264 | 265 | function h(e) { 266 | v || (v = n()), e.is(":visible") || (e.remove(), e = null, 0 === v.children().length && (v.remove(), w = void 0)) 267 | } 268 | var v, C, w, T = 0, 269 | O = { 270 | error: "error", 271 | info: "info", 272 | success: "success", 273 | warning: "warning" 274 | }, 275 | b = { 276 | clear: r, 277 | remove: c, 278 | error: t, 279 | getContainer: n, 280 | info: o, 281 | options: {}, 282 | subscribe: s, 283 | success: i, 284 | version: "2.1.4", 285 | warning: a 286 | }; 287 | return b 288 | }() 289 | }) 290 | }("function" == typeof define && define.amd ? define : function (e, t) { 291 | "undefined" != typeof module && module.exports ? module.exports = t(require("jquery")) : window.toastr = t(window.jQuery) 292 | }); 293 | //# sourceMappingURL=toastr.js.map -------------------------------------------------------------------------------- /admin/test.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | $edit_test_id = isset($_GET['edit_test_id']) ? intval($_GET['edit_test_id']) : null; 13 | 14 | 15 | 16 | $tests = []; 17 | if ($lessonid !== null) { 18 | $tests = $query->select('test', '*', "lesson_id = '$lessonid'"); 19 | } 20 | 21 | $edit_test = null; 22 | if ($edit_test_id !== null) { 23 | $edit_test = $query->select('test', '*', "id = $edit_test_id")[0] ?? null; 24 | $edit_test_options = $query->select('test_options', '*', "test_id = $edit_test_id"); 25 | } 26 | 27 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 28 | if (isset($_POST['add_test'])) { 29 | $question = $_POST['question']; 30 | $options = $_POST['options']; 31 | $correct_option = $_POST['correct_option']; 32 | 33 | $test_id = $query->insert('test', [ 34 | 'lesson_id' => $lessonid, 35 | 'question' => $question 36 | ]); 37 | 38 | foreach ($options as $index => $option) { 39 | $query->insert('test_options', [ 40 | 'test_id' => $test_id, 41 | 'option_text' => $option, 42 | 'is_correct' => ($correct_option == $index) ? 1 : 0 43 | ]); 44 | } 45 | } elseif (isset($_POST['update_test'])) { 46 | $test_id = $_POST['test_id']; 47 | $question = $_POST['question']; 48 | $options = $_POST['options']; 49 | $correct_option = $_POST['correct_option']; 50 | 51 | $query->update('test', ['question' => $question], "id = $test_id"); 52 | $query->delete('test_options', "test_id = $test_id"); 53 | 54 | foreach ($options as $index => $option) { 55 | $query->insert('test_options', [ 56 | 'test_id' => $test_id, 57 | 'option_text' => $option, 58 | 'is_correct' => ($correct_option == $index) ? 1 : 0 59 | ]); 60 | } 61 | } 62 | header("Location: ?lessonid=$lessonid"); 63 | exit; 64 | } 65 | 66 | if (isset($_GET['delete_id'])) { 67 | $delete_id = $_GET['delete_id']; 68 | $query->delete('test', "id = '$delete_id'"); 69 | header("Location: ?lessonid=$lessonid"); 70 | exit; 71 | } 72 | ?> 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | AdminLTE 3 | Test 83 | 84 | 85 | 86 | 130 | 131 | 132 |
133 | 134 |
135 | 136 | "Home", "url" => "./"], 139 | ["title" => "Worksheet", "url" => "#"], 140 | ); 141 | pagePath('Worksheet', $arr); 142 | ?> 143 | 144 |
145 |
146 |
147 | 148 | 149 | 150 |
151 |

152 | 153 |
154 | 155 | 156 |
157 | 158 |
159 | 160 | 161 | $option): ?> 162 |
163 | 164 | > Correct 165 | 166 |
167 | 168 | 169 |
170 | 171 | Correct 172 |
173 | 174 |
175 | 176 | 177 | 178 |
179 | 180 |
181 |
182 | 183 |
184 |
185 |

Topics List

186 |
187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | $test): ?> 197 | 198 | 199 | 202 | 206 | 207 | 208 | 209 |
QuestionActions
200 |

201 |
203 | Edit 204 | Delete 205 |
210 |
211 | 212 | 213 |
214 | select('lessons', '*'); ?> 215 | 216 |
217 | 218 | 226 |
227 | 228 |
229 | 230 |
231 |
232 | 233 | 234 | 235 |
236 |
237 |
238 | 239 |
240 | 241 | 242 |
243 | 244 | 245 | 264 | 265 | 266 | 267 | -------------------------------------------------------------------------------- /admin/question.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | $edit_question_id = isset($_GET['edit_question_id']) ? intval($_GET['edit_question_id']) : null; 13 | 14 | $questions = []; 15 | if ($lessonid !== null) { 16 | $questions = $query->select('questions', '*', "lesson_id = '$lessonid'"); 17 | } 18 | 19 | $edit_question = null; 20 | if ($edit_question_id !== null) { 21 | $edit_question = $query->select('questions', '*', "id = $edit_question_id")[0] ?? null; 22 | $edit_answers = $query->select('answers', '*', "question_id = $edit_question_id"); 23 | } 24 | 25 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 26 | if (isset($_POST['add_question'])) { 27 | $question_text = $_POST['question_text']; 28 | $question_id = $query->insert('questions', [ 29 | 'lesson_id' => $lessonid, 30 | 'question_text' => $question_text 31 | ]); 32 | 33 | $answers = $_POST['answers']; 34 | 35 | foreach ($answers as $index => $answer) { 36 | $query->insert('answers', [ 37 | 'question_id' => $question_id, 38 | 'answer_text' => $answer, 39 | ]); 40 | } 41 | } elseif (isset($_POST['update_question'])) { 42 | $question_id = $_POST['question_id']; 43 | $question_text = $_POST['question_text']; 44 | $query->update('questions', ['question_text' => $question_text], "id = $question_id"); 45 | 46 | $query->delete('answers', "question_id = $question_id"); 47 | 48 | $answers = $_POST['answers']; 49 | 50 | foreach ($answers as $index => $answer) { 51 | $query->insert('answers', [ 52 | 'question_id' => $question_id, 53 | 'answer_text' => $answer 54 | ]); 55 | } 56 | } 57 | header("Location: ?lessonid=$lessonid"); 58 | exit; 59 | } 60 | 61 | if (isset($_GET['delete_question_id'])) { 62 | $delete_question_id = $_GET['delete_question_id']; 63 | $query->delete('answers', "question_id = '$delete_question_id'"); 64 | $query->delete('questions', "id = '$delete_question_id'"); 65 | header("Location: ?lessonid=$lessonid"); 66 | exit; 67 | } 68 | ?> 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | AdminLTE 3 | Test 79 | 80 | 81 | 82 | 126 | 127 | 128 |
129 | 130 |
131 | 132 | "Home", "url" => "./"], 135 | ["title" => "Questions", "url" => "#"], 136 | ); 137 | pagePath('Questions', $arr); 138 | ?> 139 | 140 |
141 |
142 |
143 | 144 | 145 | 146 |
147 |

148 | 149 |
150 | 151 | 152 |
153 | 154 |
155 | 156 | 157 | $answer): ?> 158 |
159 | 160 | 161 |
162 | 163 | 164 |
165 | 166 |
167 | 168 |
169 | 170 | 171 | 172 |
173 | 174 |
175 |
176 | 177 |
178 |
179 |

Questions List

180 |
181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | $question): ?> 191 | 192 | 193 | 196 | 200 | 201 | 202 | 203 |
QuestionActions
194 | 195 | 197 | Edit 198 | Delete 199 |
204 |
205 | 206 | 207 |
208 | select('lessons', '*'); ?> 209 | 210 |
211 | 212 | 220 |
221 | 222 |
223 | 224 |
225 |
226 | 227 | 228 | 229 |
230 |
231 |
232 |
233 | 234 |
235 | 236 | 237 | 238 | 261 | 262 | 263 | 264 | -------------------------------------------------------------------------------- /database.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS letter_edu; 2 | 3 | CREATE DATABASE IF NOT EXISTS letter_edu; 4 | 5 | USE letter_edu; 6 | 7 | CREATE TABLE IF NOT EXISTS users ( 8 | id INT PRIMARY KEY AUTO_INCREMENT, 9 | first_name VARCHAR(30) NOT NULL, 10 | last_name VARCHAR(30) NOT NULL, 11 | email VARCHAR(100) NOT NULL UNIQUE, 12 | username VARCHAR(30) NOT NULL UNIQUE, 13 | password VARCHAR(255) NOT NULL, 14 | profile_picture VARCHAR(255) DEFAULT 'default.png', 15 | created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP 16 | ); 17 | 18 | CREATE TABLE IF NOT EXISTS lessons ( 19 | id INT PRIMARY KEY AUTO_INCREMENT, 20 | title VARCHAR(100) NOT NULL, 21 | description VARCHAR(255) NOT NULL 22 | ); 23 | 24 | CREATE TABLE IF NOT EXISTS lesson_items ( 25 | id INT PRIMARY KEY AUTO_INCREMENT, 26 | lesson_id INT, 27 | type ENUM('video', 'content') NOT NULL, 28 | title VARCHAR(100) NOT NULL, 29 | description TEXT, 30 | link VARCHAR(255), 31 | position INT NOT NULL, 32 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 33 | ); 34 | 35 | CREATE TABLE IF NOT EXISTS test ( 36 | id INT PRIMARY KEY AUTO_INCREMENT, 37 | lesson_id INT, 38 | question TEXT NOT NULL, 39 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 40 | ); 41 | 42 | CREATE TABLE IF NOT EXISTS test_options ( 43 | id INT PRIMARY KEY AUTO_INCREMENT, 44 | test_id INT NOT NULL, 45 | option_text VARCHAR(255) NOT NULL, 46 | is_correct BOOLEAN DEFAULT FALSE, 47 | FOREIGN KEY (test_id) REFERENCES test(id) ON DELETE CASCADE 48 | ); 49 | 50 | CREATE TABLE IF NOT EXISTS tru_false ( 51 | id INT PRIMARY KEY AUTO_INCREMENT, 52 | lesson_id INT, 53 | statement TEXT NOT NULL, 54 | is_true BOOLEAN NOT NULL, 55 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 56 | ); 57 | 58 | CREATE TABLE IF NOT EXISTS dropdown ( 59 | id INT PRIMARY KEY AUTO_INCREMENT, 60 | lesson_id INT, 61 | question TEXT NOT NULL, 62 | correct_answer VARCHAR(255) NOT NULL, 63 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 64 | ); 65 | 66 | CREATE TABLE IF NOT EXISTS fill_in_the_blank ( 67 | id INT PRIMARY KEY AUTO_INCREMENT, 68 | lesson_id INT, 69 | sentence TEXT NOT NULL, 70 | correct_answer VARCHAR(255) NOT NULL, 71 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 72 | ); 73 | 74 | CREATE TABLE IF NOT EXISTS matching ( 75 | id INT PRIMARY KEY AUTO_INCREMENT, 76 | lesson_id INT, 77 | left_side TEXT NOT NULL, 78 | right_side TEXT NOT NULL, 79 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 80 | ); 81 | 82 | CREATE TABLE IF NOT EXISTS results ( 83 | id INT PRIMARY KEY AUTO_INCREMENT, 84 | lesson_id INT, 85 | participant_name VARCHAR(255) NOT NULL, 86 | total_questions INT NOT NULL, 87 | answered_questions INT NOT NULL, 88 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 89 | ); 90 | 91 | CREATE TABLE questions ( 92 | id INT AUTO_INCREMENT PRIMARY KEY, 93 | lesson_id INT, 94 | question_text TEXT NOT NULL, 95 | FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE 96 | ); 97 | 98 | CREATE TABLE answers ( 99 | id INT AUTO_INCREMENT PRIMARY KEY, 100 | question_id INT, 101 | answer_text VARCHAR(255) NOT NULL, 102 | FOREIGN KEY (question_id) REFERENCES questions(id) 103 | ); 104 | 105 | 106 | -- ============================== 107 | -- 📥 DATA INSERTION (COMPLETE) 108 | -- ============================== 109 | -- DEFAULT PASSWORD: "IQBOLSHOH" (HASHED FOR SECURITY) 110 | -- ============================== 111 | 112 | INSERT INTO 113 | users ( 114 | first_name, 115 | last_name, 116 | email, 117 | username, 118 | password 119 | ) 120 | VALUES 121 | ( 122 | 'Iqbolshoh', 123 | 'Ilhomjonov', 124 | 'iilhomjonov777@gmail.com', 125 | 'iqbolshoh', 126 | '52be5ff91284c65bac56f280df55f797a5c505f7ef66317ff358e34791507027' 127 | ); 128 | 129 | INSERT INTO 130 | lessons (id, title, description) 131 | VALUES 132 | ( 133 | 1, 134 | 'Beginner English', 135 | 'Basic English lessons for beginners.' 136 | ), 137 | ( 138 | 2, 139 | 'Intermediate English', 140 | 'Intermediate-level English to enhance your skills.' 141 | ), 142 | ( 143 | 3, 144 | 'Advanced English', 145 | 'Advanced-level English for fluency and precision.' 146 | ); 147 | 148 | INSERT INTO 149 | lesson_items ( 150 | lesson_id, 151 | type, 152 | title, 153 | description, 154 | link, 155 | position 156 | ) 157 | VALUES 158 | ( 159 | 1, 160 | 'content', 161 | 'Basic Greetings', 162 | 'Learn how to greet people and introduce yourself in English. Understand various greetings used in different contexts such as formal, informal, and casual settings. This lesson will introduce common phrases like " How are you ? " and " Nice to meet you." You will also explore cultural nuances and appropriate responses, helping you feel confident when initiating conversations in English-speaking environments.', 163 | '', 164 | 3 165 | ), 166 | ( 167 | 1, 168 | 'video', 169 | 'Introduction to English Alphabet', 170 | 'This lesson covers the English alphabet, helping you recognize each letter, understand its pronunciation, and discover common words that begin with each letter. You will also see demonstrations of how each letter is articulated in various words. This foundational lesson will strengthen your reading and writing skills and help you improve letter recognition for both uppercase and lowercase characters.', 171 | 'IeaadwctbD4', 172 | 1 173 | ), 174 | ( 175 | 1, 176 | 'content', 177 | 'Common Verbs', 178 | 'This lesson focuses on frequently used verbs in English, their basic forms, and how to incorporate them into different sentence structures. You will learn the most common verbs and practice using them in affirmative, negative, and interrogative sentences. The goal is to help you use verbs naturally in your conversations, and we will provide tips for memorizing them to boost your confidence.', 179 | '', 180 | 4 181 | ), 182 | ( 183 | 1, 184 | 'video', 185 | 'Basic Pronunciation Tips', 186 | 'Improve your pronunciation with clear examples and tips on how to pronounce common words in English. We’ll focus on identifying frequent pronunciation mistakes and strategies to avoid them. This lesson highlights the importance of stress and intonation in spoken English, teaching you how to sound more natural when speaking. You will also practice mimicking native speakers to develop better fluency and clarity in your pronunciation.', 187 | 'IeaadwctbD4', 188 | 2 189 | ), 190 | ( 191 | 1, 192 | 'content', 193 | 'Simple Sentences', 194 | 'This lesson will teach you how to form simple sentences in English, with clear examples to help you understand sentence structure. We will cover how to use basic components such as nouns, verbs, and adjectives in your sentences. You will also learn some of the most common sentence patterns and how to expand them for more variety, allowing you to express simple ideas confidently in English.', 195 | '', 196 | 5 197 | ), 198 | ( 199 | 2, 200 | 'video', 201 | 'Intermediate Grammar Video', 202 | 'This video lesson dives into intermediate grammar concepts like past perfect tense, conditionals, and indirect speech. You will learn how to use these grammatical structures in everyday situations, focusing on their applications in both writing and speaking. The lesson includes interactive examples and practical exercises to help reinforce these rules and enhance your ability to use them in real-life conversations.', 203 | 'IeaadwctbD4', 204 | 1 205 | ), 206 | ( 207 | 2, 208 | 'content', 209 | 'Grammar and Usage', 210 | 'In this lesson, you will explore intermediate-level grammar concepts such as conditionals, relative clauses, and modal verbs. These structures are essential for expressing complex thoughts and ideas in English. You will learn how to integrate these grammar points into your speech and writing to communicate more naturally. Exercises will help you practice their use and improve fluency in real-world situations.', 211 | '', 212 | 3 213 | ), 214 | ( 215 | 2, 216 | 'video', 217 | 'Idioms and Expressions', 218 | 'Discover the world of idioms and expressions in this video lesson. Learn the meanings behind common idioms used in everyday conversations, such as " break the ice " and " get cold feet." We will also explore cultural context and how idioms are used by native speakers. You’ll have the chance to practice these idiomatic expressions in your own sentences and understand their significance in informal conversations.', 219 | 'IeaadwctbD4', 220 | 2 221 | ), 222 | ( 223 | 2, 224 | 'content', 225 | 'Phrasal Verbs', 226 | 'Phrasal verbs are an essential part of conversational English. This lesson will teach you the meanings and usage of common phrasal verbs. You will see examples of these verbs used in different contexts and practice identifying their literal and idiomatic meanings. We will also focus on using phrasal verbs naturally during conversations, improving your spoken English and fluency.', 227 | '', 228 | 4 229 | ), 230 | ( 231 | 2, 232 | 'content', 233 | 'Listening Practice', 234 | 'Enhance your listening skills with intermediate-level dialogues. This lesson includes various audio and video exercises designed to improve your ability to understand different accents and speaking speeds. Focus on picking out key words, main ideas, and supporting details. As you practice, you’ll gain strategies to comprehend complex sentences and follow along more effectively during conversations or presentations.', 235 | '', 236 | 5 237 | ), 238 | ( 239 | 3, 240 | 'content', 241 | 'Complex Sentence Structures', 242 | 'This lesson focuses on constructing and using complex and compound-complex sentences in both written and spoken English. You’ll learn how to use conjunctions, relative clauses, and other advanced sentence elements to express more sophisticated ideas. Exercises will help you practice these structures and build your ability to communicate effectively in professional, academic, and personal settings.', 243 | '', 244 | 3 245 | ), 246 | ( 247 | 3, 248 | 'video', 249 | 'Advanced Grammar and Vocabulary', 250 | 'Master advanced grammar topics and professional vocabulary in this lesson. We’ll cover complex structures like advanced tenses, inversion, and subjunctive mood. Additionally, we will explore high-level vocabulary used in academic and professional contexts. With interactive examples, you’ll learn how to avoid common mistakes and develop confidence in using advanced grammar and vocabulary in your writing and speaking.', 251 | 'IeaadwctbD4', 252 | 1 253 | ), 254 | ( 255 | 3, 256 | 'content', 257 | 'Formal Writing', 258 | 'In this lesson, you’ll learn the principles of formal writing, such as structuring essays, reports, and professional emails. You will understand how to organize ideas logically, use formal vocabulary, and avoid colloquial expressions. Through examples of academic and business writing, you will gain insight into effective communication in professional settings. This lesson will enhance your ability to produce clear and polished written content for formal situations.', 259 | '', 260 | 4 261 | ), 262 | ( 263 | 3, 264 | 'video', 265 | 'Professional Writing Tips', 266 | 'Learn valuable techniques for writing professional and effective documents such as reports, proposals, and business emails. This video lesson will guide you through the process of crafting compelling content, organizing ideas logically, and ensuring error-free writing. You will see real-world examples and gain the confidence to write clearly and persuasively in a professional context.', 267 | 'IeaadwctbD4', 268 | 2 269 | ), 270 | ( 271 | 3, 272 | 'content', 273 | 'Advanced Vocabulary', 274 | 'Expand your English vocabulary with more sophisticated words and their proper usage in various contexts. This lesson will teach you advanced vocabulary for formal and academic writing as well as for everyday conversations. You’ll learn how to substitute common words with more refined alternatives and understand the nuances of similar words. By using these advanced words in speaking and writing exercises, you’ll demonstrate your expertise in the language.', 275 | '', 276 | 5 277 | ); 278 | 279 | INSERT INTO 280 | test (lesson_id, question) 281 | VALUES 282 | (1, 'What is the capital of France?'), 283 | ( 284 | 1, 285 | 'Which of the following is a renewable energy source?' 286 | ), 287 | (2, 'Which of these animals is a mammal?'), 288 | (3, 'What is the primary function of the heart?'); 289 | 290 | INSERT INTO 291 | test_options (test_id, option_text, is_correct) 292 | VALUES 293 | (1, 'Paris', TRUE), 294 | (1, 'London', FALSE), 295 | (1, 'Berlin', FALSE), 296 | (2, 'Solar Energy', TRUE), 297 | (2, 'Coal', FALSE), 298 | (2, 'Oil', FALSE), 299 | (3, 'Dog', TRUE), 300 | (3, 'Eagle', FALSE), 301 | (3, 'Shark', FALSE), 302 | (4, 'Pumping blood', TRUE), 303 | (4, 'Digesting food', FALSE), 304 | (4, 'Producing oxygen', FALSE); 305 | 306 | INSERT INTO 307 | tru_false (lesson_id, statement, is_true) 308 | VALUES 309 | (1, 'The Earth revolves around the Sun.', TRUE), 310 | (1, 'The Earth revolves around the Sun.', TRUE), 311 | (2, 'All squares are rectangles.', TRUE), 312 | (3, 'Water boils at 50°C at sea level.', FALSE); 313 | 314 | INSERT INTO 315 | dropdown (lesson_id, question, correct_answer) 316 | VALUES 317 | ( 318 | 1, 319 | 'Select the correct preposition: " I am going ___ the store." ', 320 | 'to' 321 | ), 322 | ( 323 | 1, 324 | 'Choose the correct option: " The cat is ___ the table."', 325 | 'under' 326 | ); 327 | 328 | INSERT INTO 329 | fill_in_the_blank (lesson_id, sentence, correct_answer) 330 | VALUES 331 | ( 332 | 1, 333 | 'The quick brown ___ jumps over the lazy dog.', 334 | 'fox' 335 | ), 336 | (1, '___ is the capital city of Japan.', 'Tokyo'); 337 | 338 | INSERT INTO 339 | matching (lesson_id, left_side, right_side) 340 | VALUES 341 | (1, 'Apple', 'Fruit'), 342 | (1, 'Carrot', 'Vegetable'), 343 | (1, 'Dog', 'Animal'), 344 | (2, 'Python', 'Programming Language'), 345 | (3, 'HTML', 'Markup Language'); 346 | 347 | INSERT INTO 348 | questions (lesson_id, question_text) 349 | VALUES 350 | ( 351 | 1, 352 | "On 21 January 2023, I bought an Artel 4K Smart TV for $299.95 from your Tashkent Mall branch. I have attached a copy of my receipt for your reference. When I returned home and unpacked the TV, I (1) _____ that it was faulty and could not display 4K content properly. I returned to the Tashkent Mall branch and the sales assistant, who was very unhelpful, told me that you no longer (2) _____ the Artel 4K Smart TV. I explained to the assistant that I didn’t want to incur extra costs for another model, and I would rather (3) _____ a reimbursement for the faulty product. I believe I am (4) _____ to a full refund for this defective product, as it is not functioning as promised. Please contact me (5) _____ the next two weeks to arrange a convenient time for me to return the appliance and collect my refund. I can be (6) _____ at home on the phone number above or at 2461 8032 (7) _____ business hours. I look forward to hearing from you if you wish to (8) _____ this issue further. Yours (9) _____." 353 | ); 354 | 355 | INSERT INTO 356 | answers (question_id, answer_text) 357 | VALUES 358 | (1, 'noticed'), 359 | (1, 'realized'), 360 | (1, 'discovered'), 361 | (1, 'observed'), 362 | (1, 'found'), 363 | (1, 'detected'), 364 | (1, 'saw'), 365 | (1, 'perceived'), 366 | (1, 'recognized') 367 | -------------------------------------------------------------------------------- /admin/lesson.php: -------------------------------------------------------------------------------- 1 | 2 | select('lessons', '*', "id = '$lessonid'"); 8 | } else { 9 | $lessons_test = []; 10 | } 11 | 12 | 13 | if ($_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST['add_lesson'])) { 14 | foreach ($_POST['title'] as $id => $title) { 15 | $description = $_POST['description'][$id]; 16 | $type = $_POST['type'][$id]; 17 | $link = $_POST['link'][$id]; 18 | $position = (int)$_POST['position'][$id]; 19 | 20 | $query->update('lesson_items', [ 21 | 'title' => $title, 22 | 'description' => $description, 23 | 'type' => $type, 24 | 'link' => $link, 25 | 'position' => $position 26 | ], "id = '$id'"); 27 | } 28 | 29 | header("Location: " . $_SERVER['HTTP_REFERER']); 30 | exit; 31 | } 32 | 33 | if (isset($_GET['delete_id'])) { 34 | $delete_id = $_GET['delete_id']; 35 | 36 | $query->delete('lesson_items', "id = '$delete_id'"); 37 | 38 | header("Location: " . $_SERVER['HTTP_REFERER']); 39 | exit; 40 | } 41 | 42 | if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_lesson'])) { 43 | $title = $_POST['title']; 44 | $description = $_POST['description']; 45 | $type = $_POST['type']; 46 | $link = $_POST['link']; 47 | $position = (int)$_POST['position']; 48 | 49 | $query->insert('lesson_items', [ 50 | 'lesson_id' => $lessonid, 51 | 'title' => $title, 52 | 'description' => $description, 53 | 'type' => $type, 54 | 'link' => $link, 55 | 'position' => $position 56 | ]); 57 | 58 | header("Location: " . $_SERVER['HTTP_REFERER']); 59 | exit; 60 | } 61 | 62 | $lessons = $query->select('lesson_items', '*', "lesson_id = '$lessonid' ORDER BY position ASC"); 63 | ?> 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | AdminLTE 3 | Lesson 74 | 75 | 76 | 190 | 191 | 192 |
193 | 194 |
195 | 196 | "Home", "url" => "./"], 199 | ["title" => "Lesson", "url" => "#"], 200 | ); 201 | pagePath('Lesson', $arr); 202 | ?> 203 | 204 |
205 |
206 |
207 | 208 | 209 | 210 |
211 |
212 |

Add New Lesson Item

213 | 214 |
215 | 216 | 217 |
218 | 219 |
220 | 221 | 222 |
223 | 224 |
225 | 226 | 230 |
231 | 232 | 236 | 237 |
238 | 239 | 240 |
241 | 242 | 243 |
244 |
245 | 246 |
247 |
248 | 249 | 250 |
251 |
252 | $lesson): ?> 253 |
254 |
255 |

Item_

256 | 257 | 258 |
259 | 260 |
261 | 262 | 263 |
264 | 265 |
266 | 267 | 271 |
272 | 273 | 277 | 278 |
279 | 280 | 281 |
282 | Delete 283 |
284 | 285 | 286 |
287 |
288 | 289 | 290 | 291 | 292 |
293 | select('lessons', '*'); ?> 294 | 295 |
296 | 297 | 305 |
306 | 307 |
308 | 309 |
310 |
311 | 312 | 313 | 314 |
315 |
316 |
317 | 318 |
319 |
320 | 321 | 322 |
323 | 324 | 325 | 326 | 384 | 385 | 386 | --------------------------------------------------------------------------------