diff --git a/.gitignore b/.gitignore index 1cbbe14..2279778 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ -**/node_modules/ -**.DS_Store -**/.vs/ -**/dist/ -**/.idea +**/node_modules/ +**.DS_Store +**/.vs/ +**/dist/ +**/.idea +**/.sublime-project +**/.sublime-workspace +**/_log diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..e2b1ca8 --- /dev/null +++ b/config/config.php @@ -0,0 +1,25 @@ + 'sum', + '-' => 'sub', + '*' => 'mul', + '/' => 'div' + ]; + + $arg1 = preg_split('/[\+\-\*\/]+/', $str)[0]; + $arg2 = preg_split('/[\+\-\*\/]+/', $str)[1]; + $operation = preg_split('/[^\+\-\*\/]+/', $str)[1]; + + return mathOperation($arg1, $arg2, $operations[$operation]); +} + +function sum($arg1, $arg2){ + return $arg1 + $arg2; +} + +function sub($arg1, $arg2){ + return $arg1 - $arg2; +} + +function mul($arg1, $arg2){ + return $arg1 * $arg2; +} + +function div($arg1, $arg2){ + if($arg2 == 0) { + return 'Ошибка! На ноль делить нельзя.'; + } + return $arg1 / $arg2; +} + +function mathOperation($arg1, $arg2, $operation){ + if(function_exists($operation)){ + return $operation($arg1, $arg2); + } +} diff --git a/engine/catalog.php b/engine/catalog.php new file mode 100644 index 0000000..cb2e1d3 --- /dev/null +++ b/engine/catalog.php @@ -0,0 +1,108 @@ + addToCart($id, $session_id), + 'count' => ++$count, + 'total' => $total + ] + ); + break; + + case 'delete': + echo json_encode( + [ + 'deleted' => deleteFromCart($id, $session_id), + 'count' => --$count, + 'total' => $total + ] + ); + break; + + case 'checkout': + + echo json_encode( + [ + 'ordered' => makeAnOrder($session_id, $total, $login), + ] + ); + break; + } + die(); +} + +function makeAnOrder($session_id, $total, $login):bool { + $result = json_decode(file_get_contents('php://input')); + $date = date("Y-m-d H:i"); + executeQuery("UPDATE `cart` SET `cart_status` = 1 WHERE session_id = '{$session_id}'"); + return executeQuery("INSERT INTO `orders` (login, name, number, mail, session_id, date, total_amount) VALUES ( '{$login}','{$result->name}', '{$result->number}', '{$result->email}', '{$session_id}', '{$date}', '{$total}')"); +} + +function getCart($session_id, $cart_status = 0):array { + + $cart = getAssocResult("SELECT cart.id cart_id, catalog.image, catalog.id catalog_id, catalog.name, catalog.price FROM cart, catalog WHERE cart.good_id=catalog.id AND session_id = '{$session_id}' AND cart_status = {$cart_status}"); + + $each = getEachCartItemsCount($session_id); + + $tmp = []; + $unique = []; + + foreach ($cart as $good) { + if (!in_array($good['catalog_id'], $tmp)) { + $unique[] = $good; + $tmp[] = $good['catalog_id']; + } + } + + function replace($a, $b) { + if ($a['catalog_id'] === $b['catalog_id']) { + $a['count'] = $b['count']; + } + + $a['sub_total'] = (INT)str_replace(' ', '', $a['price']) * $b['count']; + return $a; + } + + return array_map('replace', $unique, $each); +} + +function getAllCartItemsCount($session_id):string { + return getAssocResult("SELECT COUNT(id) as count FROM `cart` WHERE `session_id`='{$session_id}' AND cart_status = 0")[0]['count']; +} + +function getEachCartItemsCount($session_id):array { +// $sql = "SELECT `catalog`.id AS good_id, SUM(`catalog`.price) AS total FROM `cart` INNER JOIN `catalog` ON `catalog`.id = `cart`.good_id GROUP BY `cart`.id"; + return getAssocResult("SELECT `good_id` AS `catalog_id` , COUNT(`good_id`) AS count FROM `cart` WHERE `session_id` = '$session_id' AND cart_status = 0 GROUP BY (good_id)"); +} + +function getTotalPrice($cart) { + $total = 0; + foreach ($cart as $item) { + $total += $item['sub_total']; + } + return $total; +} + +function addToCart($id, $session_id):bool { + return executeQuery("INSERT INTO `cart` (good_id, session_id) VALUES ($id, '$session_id')"); +} + +function deleteFromCart($good_id, $session_id):bool { + return executeQuery("DELETE FROM `cart` WHERE good_id = '{$good_id}' AND session_id = '{$session_id}' AND cart_status = 0 LIMIT 1"); +} \ No newline at end of file diff --git a/engine/classSimpleImage.php b/engine/classSimpleImage.php new file mode 100644 index 0000000..85bac52 --- /dev/null +++ b/engine/classSimpleImage.php @@ -0,0 +1,85 @@ +image_type = $image_info[2]; + if( $this->image_type == IMAGETYPE_JPEG ) { + $this->image = imagecreatefromjpeg($filename); + } elseif( $this->image_type == IMAGETYPE_GIF ) { + $this->image = imagecreatefromgif($filename); + } elseif( $this->image_type == IMAGETYPE_PNG ) { + $this->image = imagecreatefrompng($filename); + } + } + function save($filename, $image_type=IMAGETYPE_JPEG, $compression=75, $permissions=null) { + if( $image_type == IMAGETYPE_JPEG ) { + imagejpeg($this->image,$filename,$compression); + } elseif( $image_type == IMAGETYPE_GIF ) { + imagegif($this->image,$filename); + } elseif( $image_type == IMAGETYPE_PNG ) { + imagepng($this->image,$filename); + } + if( $permissions != null) { + chmod($filename,$permissions); + } + } + function output($image_type=IMAGETYPE_JPEG) { + if( $image_type == IMAGETYPE_JPEG ) { + imagejpeg($this->image); + } elseif( $image_type == IMAGETYPE_GIF ) { + imagegif($this->image); + } elseif( $image_type == IMAGETYPE_PNG ) { + imagepng($this->image); + } + } + function getWidth() { + return imagesx($this->image); + } + function getHeight() { + return imagesy($this->image); + } + function resizeToHeight($height) { + $ratio = $height / $this->getHeight(); + $width = $this->getWidth() * $ratio; + $this->resize($width,$height); + } + function resizeToWidth($width) { + $ratio = $width / $this->getWidth(); + $height = $this->getheight() * $ratio; + $this->resize($width,$height); + } + function scale($scale) { + $width = $this->getWidth() * $scale/100; + $height = $this->getheight() * $scale/100; + $this->resize($width,$height); + } + function resize($width,$height) { + $new_image = imagecreatetruecolor($width, $height); + imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight()); + $this->image = $new_image; + } +} \ No newline at end of file diff --git a/engine/db.php b/engine/db.php new file mode 100644 index 0000000..fdb14f4 --- /dev/null +++ b/engine/db.php @@ -0,0 +1,41 @@ +name, $data->feedback, $data->good_ID); + $response = [ + 'id' => $id, + 'name' => $data->name, + 'feedback' => $data->feedback + ]; + + echo json_encode($response, JSON_UNESCAPED_UNICODE); + break; + + case 'read': + echo json_encode(getOneFeedback(), JSON_UNESCAPED_UNICODE); + break; + + case 'update': + $response = updateFeedback($data); + echo json_encode(['updated' => $response]); + break; + + case 'delete': + $response = deleteFeedback($data); + echo json_encode(['deleted' => $response]); + break; + } + die(); +} + +function createFeedback($name, $feedback, $product_id) { + $name = strip_tags(htmlspecialchars(mysqli_real_escape_string(getDb(), $name))); + $feedback = strip_tags(htmlspecialchars(mysqli_real_escape_string(getDb(), $feedback))); + $sql = "INSERT INTO `feedback` (`name`, `feedback`, `product_id`) VALUES ('{$name}', '{$feedback}', '{$product_id}');"; + executeQuery($sql); + return mysqli_insert_id(getDb()); +} + +function readFeedback() { + return json_decode(file_get_contents('php://input')); +} + +function updateFeedback($data):bool { + return executeQuery("UPDATE `feedback` SET `name` = '{$data->name}', `feedback` = '{$data->feedback}' WHERE `feedback`.`id` = {$data->id}"); +} + +function deleteFeedback($id):bool { + $id = (INT)$id; + return executeQuery("DELETE FROM `feedback` WHERE `feedback`.`id` = {$id}"); +} + +function getOneFeedback():array { + $id = (INT)json_decode(file_get_contents('php://input')); + $sql = "SELECT * FROM feedback WHERE id = {$id}"; + return getAssocResult($sql)[0]; + +} \ No newline at end of file diff --git a/engine/functions.php b/engine/functions.php new file mode 100644 index 0000000..05b7e5e --- /dev/null +++ b/engine/functions.php @@ -0,0 +1,144 @@ + 'item_feedback', 'feedback' => 'feedback']; + switch ($page) { + + case 'auth': + $params['layout'] = 'auth'; + if (isAdmin()) { + $params['orders'] = getAllOrders(); + } else { + if (isset($params['user'])) { + $params['orders'] = getOrdersByLogin($params['user']); + } + } + break; + +//todo [order-details] + +// case 'orderDetails': +// $orderID = (INT)$_GET['id']; +// $params['orderDetails'] = getOrderDetails($orderID, $params['user']); +// break; + + case 'updateOrder': + $id = (INT)$_GET['id']; + if (isAdmin()) { + $params['order'] = getOneOrder($id); + } + if (!empty($_POST) && isAdmin()) { + $params['updated'] = updateOrderInfo($_POST); + } + break; + + case 'signUp': + if (!empty($_POST)) { + $params['error'] = validateData($_POST); + if (!$params['error']) { + $params['signUp'] = signUp($_POST); + } + } + break; + + case 'catalog': + $params['layout'] = 'catalog'; + $params['catalog'] = getCatalog(); + break; + + case 'good': + $id = (INT)$_GET['id']; + $params['layout'] = 'catalog'; + $params['good'] = getOneGood($id); + $params['feedback'] = getAllFeedback($id); + break; + + case 'cart': + $params['layout'] = 'catalog'; + $params['cart'] = getCart($params['session_id']); + $params['total'] = getTotalPrice($params['cart']); + if (isset($params['user'])) { + $params['user_info'] = getAuthorizedUserInfo($params['user']); + } + break; + + case 'cartapi': + cartAction($action, $params['session_id'], $params['user']); + break; + + case 'image': + $params['layout'] = 'gallery'; + $params['image'] = getOneImage((int)$_GET['id']); +// $params['tableName'] = getAllFeedback('item_feedback'); + break; + + case 'addLike': + $params['layout'] = 'catalog'; + addLikes((int)$_GET['id']); + break; + + case 'gallery': + if(isset($_POST['load'])){ + $params['errors'] = uploadImage(); + } + $params['layout'] = 'gallery'; + $params['gallery'] = getGallery(); + break; + + case 'feedback': + $params['layout'] = 'feedback'; + $params['feedback'] = getAllFeedback(); + break; + + case 'feedbackapi': + feedbackAction($action); + break; + + case 'calculator': + if (!empty($_POST['output'])) { + $params['output'] = parseOperations($_POST['output']); + } + $params['layout'] = 'calculator'; + break; + + case 'homework_3': + $params['layout'] = 'homework_3'; + break; + } + return $params; +} + +function render($page, $params){ + return renderTemplate(LAYOUTS_DIR . $params['layout'], [ + 'content' => renderTemplate($page, $params), + 'menu' => renderTemplate('menu', $params), + ] + ); +} + +function renderTemplate($page, $params = []){ + ob_start(); + + if (!is_null($params)) + extract($params); + + $fileName = TEMPLATES_DIR . $page . ".php"; + + if (file_exists($fileName)) { + include $fileName; + } else { + Die("Страницы {$fileName} не существует."); + } + + return ob_get_clean(); +} diff --git a/engine/gallery.php b/engine/gallery.php new file mode 100644 index 0000000..cb2524c --- /dev/null +++ b/engine/gallery.php @@ -0,0 +1,48 @@ + 1024 * 5 * 1024) { + return "Размер файла не более 5 Мб"; + } + + $blacklist = ['.php', '.phtml', '.php3', '.php4']; + foreach ($blacklist as $item) { + if(preg_match("/$item\$/i", $_FILES['image']['name'])){ + return "Загрузка php-файлов запрещена"; + } + } + + if (move_uploaded_file($_FILES['image']['tmp_name'], $path_big)) { + + $filename = mysqli_real_escape_string(getDb(), $_FILES['image']['name']); + executeQuery("INSERT INTO `gallery` (`filename`) VALUES ('{$filename}')"); + + $image = new SimpleImage(); + $image->load($path_big); + $image->resizeToWidth(250); + $image->save($path_small); + header("Location: /gallery"); + } else { + return "Ошибка ресайза файла"; + } +} \ No newline at end of file diff --git a/engine/log.php b/engine/log.php new file mode 100644 index 0000000..e69de29 diff --git a/engine/service.php b/engine/service.php new file mode 100644 index 0000000..ee0c8d7 --- /dev/null +++ b/engine/service.php @@ -0,0 +1,85 @@ + "Логин уже занят!", + "password" => "Пароли не совпадают!", + "phone" => "Данный номер телефона зарегистрирован!", + "email" => "Email уже зарегистрирован!" + ]; + + if ($data['password'] !== $data['password_confirm']) { + return $errorsTemplate['password']; + } + if (getAssocResult("SELECT * FROM `users` WHERE `login` = '{$data['login']}'")) { + return $errorsTemplate['login']; + } + if (getAssocResult("SELECT * FROM `users` WHERE `phone` = '{$data['phone']}'")) { + return $errorsTemplate['phone']; + } + if (getAssocResult("SELECT * FROM `users` WHERE `email` = '{$data['email']}'")) { + return $errorsTemplate['email']; + } + return false; +} + +function signUp($data):bool { + $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT); + return executeQuery("INSERT INTO `users` (login, full_name, phone, email, password) VALUES ('{$data['login']}', '{$data['full_name']}', '{$data['phone']}', '{$data['email']}', '{$data['password']}')"); +} + +/* + * actions for admin + */ + +function getOneOrder($id):array { + return getAssocResult("SELECT * FROM `orders` WHERE `id` = $id")[0]; +} + +function updateOrderInfo($info):bool { + return executeQuery("UPDATE `orders` SET `name` = '{$info['name']}', `number` = '{$info['number']}', `mail` = '{$info['email']}', `order_status` = {$info['status']} WHERE `id` = {$info['id']}"); +} + +function getAllOrders():array{ + return getAssocResult("SELECT * FROM `orders`"); +} + +//todo [order-details] +//function getOrderDetails($orderID, $login):array { +// if (isAdmin()) { +// return getCart(getOrderSessionByID($orderID), 1); +// } +// return getCart(getOrderSessionByLogin($login), 1); +//} + +//todo [order-details] + +/* пример запроса, который мог бы решить проблему с корзинами, но необходим уникальный ключ для каждой + * "SELECT DISTINCT orders.*, cart.good_id + * FROM orders INNER JOIN cart ON orders.session_id = cart.session_id + * INNER JOIN catalog ON cart.good_id = catalog.id + * WHERE orders.id = 35" + * */ +//function getOrderSessionByLogin($login) { +// return getAssocResult("SELECT session_id FROM `orders` WHERE login = '{$login}'")[0]['session_id']; +//} + +//todo [order-details] +//function getOrderSessionByID($orderID) { +// return getAssocResult("SELECT session_id FROM `orders` WHERE id = $orderID")[0]['session_id']; +//} \ No newline at end of file diff --git a/engine/setup.php b/engine/setup.php new file mode 100644 index 0000000..b0697f5 --- /dev/null +++ b/engine/setup.php @@ -0,0 +1,21 @@ +num_rows == 0) { + echo "Таблица пустая. Заполнение данными об изображениях"; + $imgs = scandir(IMG); + $images = array_splice($imgs, 2); + mysqli_query($db, "INSERT INTO `gallery`(`filename`) VALUES ('" . implode("'),('", $images) . "')"); +} else { + echo "Таблица заполнена"; +} \ No newline at end of file diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..d9c1e47 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,10 @@ +RewriteEngine on + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +php_value error_reporting "E_ALL & ~E_NOTICE" + +php_value display_errors on + +RewriteRule . index.php \ No newline at end of file diff --git a/public/images/catalog_img/big/honor.jpg b/public/images/catalog_img/big/honor.jpg new file mode 100644 index 0000000..f29face Binary files /dev/null and b/public/images/catalog_img/big/honor.jpg differ diff --git a/public/images/catalog_img/big/huawei.jpg b/public/images/catalog_img/big/huawei.jpg new file mode 100644 index 0000000..a3ee080 Binary files /dev/null and b/public/images/catalog_img/big/huawei.jpg differ diff --git a/public/images/catalog_img/big/iphone.jpg b/public/images/catalog_img/big/iphone.jpg new file mode 100644 index 0000000..cb5b167 Binary files /dev/null and b/public/images/catalog_img/big/iphone.jpg differ diff --git a/public/images/catalog_img/big/oppo.jpg b/public/images/catalog_img/big/oppo.jpg new file mode 100644 index 0000000..5ddbe15 Binary files /dev/null and b/public/images/catalog_img/big/oppo.jpg differ diff --git a/public/images/catalog_img/big/poco.jpg b/public/images/catalog_img/big/poco.jpg new file mode 100644 index 0000000..0724555 Binary files /dev/null and b/public/images/catalog_img/big/poco.jpg differ diff --git a/public/images/catalog_img/big/samsung.jpg b/public/images/catalog_img/big/samsung.jpg new file mode 100644 index 0000000..002cf3e Binary files /dev/null and b/public/images/catalog_img/big/samsung.jpg differ diff --git a/public/images/catalog_img/small/honor.jpg b/public/images/catalog_img/small/honor.jpg new file mode 100644 index 0000000..7a5a183 Binary files /dev/null and b/public/images/catalog_img/small/honor.jpg differ diff --git a/public/images/catalog_img/small/huawei.jpg b/public/images/catalog_img/small/huawei.jpg new file mode 100644 index 0000000..d1bbc47 Binary files /dev/null and b/public/images/catalog_img/small/huawei.jpg differ diff --git a/public/images/catalog_img/small/iphone.jpg b/public/images/catalog_img/small/iphone.jpg new file mode 100644 index 0000000..ec2b771 Binary files /dev/null and b/public/images/catalog_img/small/iphone.jpg differ diff --git a/public/images/catalog_img/small/oppo.jpg b/public/images/catalog_img/small/oppo.jpg new file mode 100644 index 0000000..2dea5de Binary files /dev/null and b/public/images/catalog_img/small/oppo.jpg differ diff --git a/public/images/catalog_img/small/poco.jpg b/public/images/catalog_img/small/poco.jpg new file mode 100644 index 0000000..9e6bdf5 Binary files /dev/null and b/public/images/catalog_img/small/poco.jpg differ diff --git a/public/images/catalog_img/small/samsung.jpg b/public/images/catalog_img/small/samsung.jpg new file mode 100644 index 0000000..7743c3e Binary files /dev/null and b/public/images/catalog_img/small/samsung.jpg differ diff --git a/public/images/gallery_img/big/n_70.jpg b/public/images/gallery_img/big/n_70.jpg new file mode 100644 index 0000000..d1c5b21 Binary files /dev/null and b/public/images/gallery_img/big/n_70.jpg differ diff --git a/public/images/gallery_img/big/n_72.jpg b/public/images/gallery_img/big/n_72.jpg new file mode 100644 index 0000000..aa1d97c Binary files /dev/null and b/public/images/gallery_img/big/n_72.jpg differ diff --git a/public/images/gallery_img/big/n_73.jpg b/public/images/gallery_img/big/n_73.jpg new file mode 100644 index 0000000..e36fb36 Binary files /dev/null and b/public/images/gallery_img/big/n_73.jpg differ diff --git a/public/images/gallery_img/big/n_76.jpg b/public/images/gallery_img/big/n_76.jpg new file mode 100644 index 0000000..cff5f93 Binary files /dev/null and b/public/images/gallery_img/big/n_76.jpg differ diff --git a/public/images/gallery_img/big/n_82.jpg b/public/images/gallery_img/big/n_82.jpg new file mode 100644 index 0000000..7b92921 Binary files /dev/null and b/public/images/gallery_img/big/n_82.jpg differ diff --git a/public/images/gallery_img/big/n_95.jpg b/public/images/gallery_img/big/n_95.jpg new file mode 100644 index 0000000..b6929b1 Binary files /dev/null and b/public/images/gallery_img/big/n_95.jpg differ diff --git a/public/images/gallery_img/small/n_70.jpg b/public/images/gallery_img/small/n_70.jpg new file mode 100644 index 0000000..3184065 Binary files /dev/null and b/public/images/gallery_img/small/n_70.jpg differ diff --git a/public/images/gallery_img/small/n_72.jpg b/public/images/gallery_img/small/n_72.jpg new file mode 100644 index 0000000..f6105c7 Binary files /dev/null and b/public/images/gallery_img/small/n_72.jpg differ diff --git a/public/images/gallery_img/small/n_73.jpg b/public/images/gallery_img/small/n_73.jpg new file mode 100644 index 0000000..e14dfb8 Binary files /dev/null and b/public/images/gallery_img/small/n_73.jpg differ diff --git a/public/images/gallery_img/small/n_76.jpg b/public/images/gallery_img/small/n_76.jpg new file mode 100644 index 0000000..4a8ee15 Binary files /dev/null and b/public/images/gallery_img/small/n_76.jpg differ diff --git a/public/images/gallery_img/small/n_82.jpg b/public/images/gallery_img/small/n_82.jpg new file mode 100644 index 0000000..0636790 Binary files /dev/null and b/public/images/gallery_img/small/n_82.jpg differ diff --git a/public/images/gallery_img/small/n_95.jpg b/public/images/gallery_img/small/n_95.jpg new file mode 100644 index 0000000..88e8903 Binary files /dev/null and b/public/images/gallery_img/small/n_95.jpg differ diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..827183a --- /dev/null +++ b/public/index.php @@ -0,0 +1,19 @@ + this._eventHandler(e)); + // this._form.addEventListener('submit', e => { + // e.preventDefault(); + // this._postData(e); + // }); + } + + _eventHandler(event) { + + const eventText = event.target.textContent; + + if (eventText === '=' || eventText.length > 1) return; + if(this._output.length > this._maxLengthOfInput) return; + if(event.target.id === 'delete') { this._delete(); return; } + + const reg = new RegExp("[+\\-*\\/]", "g"); + + this._output += eventText; + if ((this._output.match(reg) || []).length > 1) { + this._output = this._output.slice(0, this._output.length - 1); + } + this._render(); + } + + _delete() { + this._output = this._calcOutput.value = this._outputNode.textContent = this._outputNode.textContent.slice(0,-1); + } + + _render(){ + this._outputNode.textContent = this._output; + this._calcOutput.value = this._output; + } +} + +(new Calculator).init(); \ No newline at end of file diff --git a/public/js/cart.js b/public/js/cart.js new file mode 100644 index 0000000..863a75a --- /dev/null +++ b/public/js/cart.js @@ -0,0 +1,146 @@ +'use strict'; + +class Cart { + constructor() { + this._cartActionButtons = document.querySelectorAll('.catalog__item-button'); + this._cartCheckoutButton = document.querySelector('.checkout__button'); + this._fieldList = ["name", "number", "email"]; + } + + init() { + this._cartActionButtons.forEach(button => { + button.addEventListener('click', event => { + this._eventHandler(event); + }); + }); + + if (typeof(this._cartCheckoutButton) != "undefined" && this._cartCheckoutButton !== null) { + this._cartCheckoutButton.addEventListener('click', event => { + this._eventHandler(event); + }); + } + } + + _eventHandler(event) { + switch (event.target.dataset.id) { + case 'buy': + + this._addToCart(this._getProductId(event.path)) + .then(json => { + this._cartCountRender(json); + this._cartEachCountRender(json, event); + this._cartTotalAmountRender(json); + }) + .catch(e => console.error(e)); + + break; + + case 'delete': + + this._deleteFromCart(this._getProductId(event.path)) + .then(json => { + this._cartCountRender(json); + this._cartEachCountRender(json, event); + this._cartTotalAmountRender(json); + }) + .catch(e => console.error(e)); + + break; + + case 'checkout': + this._makeAnOrder(this._readValueData(this._cartCheckoutButton, this._fieldList)) + .catch(e => console.log(e)); + break; + } + } + + async _makeAnOrder(data) { + return await (await fetch(`/cartapi/checkout/`, { + method: 'POST', + headers: new Headers({ + 'Content-Type': 'application/json' + }), + body: JSON.stringify(data) + })).json(); + } + + _readValueData(buttonNode, fieldList) { + const data = {}; + let inputValues = this._getInputValues(buttonNode); + const fieldValues = [...inputValues].map((item) => item.value); + + for (let i = 0; i < fieldValues.length - 1; i++) { + data[fieldList[i]] = `${fieldValues[i]}`; + } + return data; + } + + _getInputValues(node) { + return node.parentNode.children; + } + + async _deleteFromCart(id) { + return await (await fetch('/cartapi/delete/?id=' + id)).json(); + } + + async _addToCart(id) { + return await (await fetch('/cartapi/add/?id=' + id)).json(); + } + + _cartTotalAmountRender(json) { + const target = document.querySelector('.total'); + const numberFormat = new Intl.NumberFormat(); + + if (json.total === 0) { + const cartElem = document.querySelector('.cart'); + this._getParentElement(target).remove(); + cartElem.innerHTML = 'В корзине ничего нет

¯\\_(ツ)_/¯'; + return json; + } + + if (target) { + target.innerText = numberFormat.format(json.total) + " "; + } + return json; + } + + _cartEachCountRender(json, event) { + if (!event.target.parentElement.classList.contains('cart-buttons_wrapper')) return json; + const target = event.target.parentElement.children[1]; + + if (json.hasOwnProperty('added')) { + target.innerText++; + } else { + target.innerText--; + } + + if (target.innerText === '0') { + //remove paragraph with info about good in checkout div + const itemParentId = this._getParentElement(target).id; + document.getElementById('checkoutID:' + itemParentId).remove(); + //remove good from cart + this._getParentElement(event.target).remove(); + return json; + } + } + + _cartCountRender(json) { + const navButtons = document.querySelector('.nav-ul'); + const targetElement = navButtons.children[navButtons.children.length - 2].firstElementChild; + targetElement.innerText = targetElement.innerText.replace(new RegExp(/\d/), json.count); + return json; + } + + _getParentElement(element) { + if (!element.id) return this._getParentElement(element.parentElement); + return element; + } + + _getProductId(path) { + for (let node of path) { + if (node.id) return node.id; + } + } +} + +new Cart().init(); \ No newline at end of file diff --git a/public/js/cartRealizationWithJS.js b/public/js/cartRealizationWithJS.js new file mode 100644 index 0000000..adaf190 --- /dev/null +++ b/public/js/cartRealizationWithJS.js @@ -0,0 +1,91 @@ +'use strict'; + +class Cart { + constructor() { + this._buyButtons = document.querySelectorAll('.catalog__item-button'); + this._cart = {}; + this._currentCartItems = 0; + this._cookieCart = 'cart'; + this._cookieCountName = 'count'; + } + init() { + this._buyButtons.forEach(button => { + button.addEventListener('click', event => { + this._eventHandler(event); + }); + }); + //todo refactor get cookie with 1 request + if (this._getCookie(this._cookieCountName)) { + this._cart = JSON.parse(this._getCookie(this._cookieCart)); + this._currentCartItems = Number(this._getCookie(this._cookieCountName)); + this._cartCountRender(); + } + } + _eventHandler(event) { + this._addToCart(this._getProductId(event.path)); + this._setCookie(this._cookieCart, this._cart); + this._setCookie(this._cookieCountName, this._currentCartItems); + this._cartCountRender(); + } + _cartCountRender() { + const navButtons = document.querySelector('.nav-ul'); + const targetElement = navButtons.children[navButtons.children.length - 1].firstElementChild; + targetElement.innerText = targetElement.innerText.replace(new RegExp(/\d/), this._currentCartItems); + } + _setCookie(name, value, options = {}) { + options = { + path: '/', + ...options + }; + + if (options.expires instanceof Date) { + options.expires = options.expires.toUTCString(); + } + + value = JSON.stringify(value); + + let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value); + + for (let optionKey in options) { + updatedCookie += "; " + optionKey; + let optionValue = options[optionKey]; + if (optionValue !== true) { + updatedCookie += "=" + optionValue; + } + } + + document.cookie = updatedCookie; + } + _getCookie(name) { + let matches = document.cookie.match(new RegExp( + "(?:^|; )" + name.replace(/([.$?*|{}()\[\]\\\/+^])/g, '\\$1') + "=([^;]*)" + )); + return matches ? decodeURIComponent(matches[1]) : undefined; + } + _deleteCookie(name) { + this._setCookie(name, "", { + 'max-age': -1 + }); + } + _deleteFromCart(id) { + this._currentCartItems--; + } + _addToCart(id) { + this._currentCartItems++; + if (Object.keys(this._cart).length === 0) return this._cart[`${id}`] = 1; + return this._cart[`${id}`] ? this._cart[`${id}`] += 1 : this._cart[`${id}`] = 1; + } + getCart(){ + return this._cart; + } + _getProductId(path) { + for (let node of path) { + if (node.id) return node.id; + } + } +} + +let cart = new Cart(); +cart.init(); + +//notice goods should add in to cart with backend only because need to synchronization with db \ No newline at end of file diff --git a/public/js/feedback.js b/public/js/feedback.js new file mode 100644 index 0000000..3ec223f --- /dev/null +++ b/public/js/feedback.js @@ -0,0 +1,184 @@ +'use strict'; +const actionButtons = document.querySelector('.feedback-wrapper'); +const feedbackNode = document.querySelector('.feedback-side'); +const fieldList = ["name", "feedback", "id", "good_id"]; +const feedbackID = getFeedbackID(); + +actionButtons.addEventListener('click', (e) => handleButtonsCRUD(e)); + +async function handleButtonsCRUD(e) { + const buttonNode = e.path[0]; + if (!buttonNode.id) return; + const action = buttonNode.id; + + switch (action) { + case 'create': + if (!validateValueData(buttonNode)) return; + create(buttonNode, action); + break; + + case 'read': + read(buttonNode, action); + break; + + case 'update': + if (!validateValueData(buttonNode)) return; + update(buttonNode, action); + break; + + case 'delete': + remove(buttonNode, action); + break; + } +} + +//CRUD BLOCK +function create(buttonNode, action){ + const data = readValueData(buttonNode, fieldList); + + fetchData(data, action) + .then(response => response.json()) + .then(json => { + clearInputValues(getInputValues(buttonNode)); + renderNewFeedback(json); + toggleSideVisibility(); + }) + .catch(e => console.log(e)); +} + +function read(buttonNode, action) { + getOneFeedback(Number(getParent(buttonNode).id), action) + .catch(e => console.error(e)); +} + +function update(node, action) { + const data = readValueData(node, fieldList); + fetchData(data, action) + .then(response => response.json()) + .then(json => { + if (json.updated) { + removeFeedbackById(data.id); + renderNewFeedback(data); + clearInputValues(getInputValues(node)); + } + }) + .catch(e => console.log(e)); +} + +function remove(buttonNode, action) { + fetchData(Number(getParent(buttonNode).id), action) + .then(res => res.json()) + .then(json => { + if (json.deleted) { + getParent(buttonNode).remove(); + toggleSideVisibility(); + } + }); +} + +//OTHER FUNCTIONS +function validateValueData(node){ + for (const [, value] of Object.entries(readValueData(node, fieldList))) { + if (typeof(value) == "undefined" && value == null) return false; + } + return true; +} + +function readValueData(buttonNode, fieldList) { + const data = {}; + let inputValues = getInputValues(buttonNode); + const fieldValues = [...inputValues].map((item) => item.value); + + for (let i = 0; i < fieldValues.length - 1; i++) { + data[fieldList[i]] = `${fieldValues[i]}`; + } + data['good_ID'] = feedbackID; + return data; +} + +function removeFeedbackById(id){ + [...feedbackNode.children].forEach(node => { + if (node.id === id) node.remove(); + }); +} + +async function getOneFeedback(id, action) { + return await fetchData(id, action) + .then(response => response.json()) + .then(json => { + renderFeedbackToUpdate(json) + }); +} + +async function fetchData(data, action) { + return await fetch(`/feedbackapi/${action}/`, { + method: 'POST', + headers: new Headers({ + 'Content-Type': 'application/json' + }), + body: JSON.stringify(data) + }); +} + +function renderFeedbackToUpdate(feedback){ + let html = ` +
+ + + + +
+ `; + actionButtons.firstElementChild.remove(); + actionButtons.insertAdjacentHTML('afterbegin', html); +} + +function renderNewFeedback(feedback){ + const html = ` +
+

${feedback.name}

+

${feedback.feedback}

+
+ + +
+
+ `; + feedbackNode.insertAdjacentHTML('beforeend', html); +} + +function clearInputValues(inputValues) { + return [...inputValues].map(i => i.value = ''); +} + +function getInputValues(node) { + return node.parentNode.children; +} + +function getParent(node) { + return node.parentNode.parentNode; +} + +function toggleSideVisibility() { + const feedbackNode = document.querySelector('.feedback-side'); + if (feedbackNode.classList.contains('feedback-side_display') || feedbackNode.children.length) { + feedbackNode.classList.remove('feedback-side_display'); + } else { + feedbackNode.classList.add('feedback-side_display'); + } +} + +function isPersonalFeedback(href) { + return href.includes('good'); +} + +function getFeedbackID() { + const href = document.location.href.split('/'); + if (isPersonalFeedback(href)) { + const idStr = href.find(i => { + return i.match(/\d/); + }); + return Number(idStr[idStr.length - 1]); + } + return 0; +} \ No newline at end of file diff --git a/public/js/modal.js b/public/js/modal.js new file mode 100644 index 0000000..c24b089 --- /dev/null +++ b/public/js/modal.js @@ -0,0 +1,11 @@ +const block = document.querySelector('.gallery_wrapper'); + +function handleEvents() { + block.addEventListener('click', (e) => { + if (e.target.classList.contains('gallery_img')) { + e.target.classList.toggle('active'); + e.path[1].children[2].classList.toggle('image-views_invisible'); + } + }); +} +handleEvents(); \ No newline at end of file diff --git a/public/js/service.js b/public/js/service.js new file mode 100644 index 0000000..a726efc --- /dev/null +++ b/public/js/service.js @@ -0,0 +1 @@ +'use strict'; \ No newline at end of file diff --git a/public/styles/style.css b/public/styles/style.css new file mode 100644 index 0000000..86b6158 --- /dev/null +++ b/public/styles/style.css @@ -0,0 +1,629 @@ +@import url(https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic); +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Roboto', Arial, sans-serif; + background-color: #ebebeb; + overflow-x: hidden; + text-align: center; +} + +header { + display: flex; + align-items: center; + justify-content: space-around; + width: 100%; + height: 80px; + background-color: #6b6d79c7; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); +} + +.nav-li { + line-height: 30px; + display: flex; +} + +.nav-ul { + display: flex; +} + +.nav-link:hover { + background-color: rgba(0, 0, 0, 0.1); + cursor: pointer; +} +.nav-link { + font-size: 15px; + font-weight: 300; + text-transform: uppercase; + text-decoration: none; + padding: 8px 10px; + width: 150px; + margin: 2%; + text-align: center; + background-color: #4c4848b8; + color: #fbfbfb; + border-radius: 2px; + transition: background-color 0.2s ease; +} + +.nav-link:hover { + background-color: #212121; + cursor: pointer; +} + +h1 { + font-weight: 100; + margin-bottom: 25px; +} + +p { + text-align: center; + padding: 10px; + color: #aaa; + font-weight: 500; +} + +.container { + margin-top: 50px; + min-width: 900px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.block { + margin: 10px; + border: 1px solid black; +} + +.block_flex-wrapper { + padding: 15px; +} + +.block_main { + display: flex; + justify-content: space-between; +} + +.block_exp { + padding: 5px; +} + +.block_exp-border-none { + border-right: none; +} + +.header_3 { + margin: 20px; +} + +.ul-hidden { + display: none; +} + +.hover:hover > .ul-hidden { + display: block; + position: absolute; + top: 65px; +} + +.gallery_wrapper { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + max-width: 900px; + margin-bottom: 70px; +} + +.gallery-img__votes-wrapper { + display: flex; +} + +.gallery-img__votes { + font-size: 20px; + font-weight: 400; + color: black; +} + +.gallery_img { + width: inherit; + border-radius: 4px; + border: 1px solid black; +} + +.gallery_img-text_wrapper { + display: flex; + justify-content: space-between; +} + +.gallery_img-text_block { + text-decoration: none; + color: black; + font-weight: 300; +} + +.gallery_img-big_img { + max-width: 50%; + border: 1px solid black; + border-radius: 2%; + margin-bottom: 30px; +} + +.gallery_block { + cursor: pointer; + width: 250px; + margin-bottom: 15px; + -webkit-transition: -webkit-transform 0.7s; + transition: transform 0.7s; +} + +.gallery_block:hover { + -webkit-transform: scale(1.1); + transform: scale(1.1); +} + +.image-views_invisible { + display: none; +} + +.image-views { + position: relative; + top: -55px; + left: 105px; +} + +.modal { + -webkit-transition: -webkit-transform 0.7s; + transition: transform 0.7s; +} + +.active { + -webkit-transform: scale(2); + transform: scale(2); +} + +.upload_image { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 80px; + background-color: #747578; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); +} + +.form-group { + padding: 1em; + margin: 1em; +} + +input[type="file"] { + outline: 0; + opacity: 0; + pointer-events: none; + user-select: none; +} + +.label { + height: 60px; + width: 190px; + border: 2px dashed #fbfbfb; + border-radius: 5px; + display: flex; + padding: 1em; + align-items: center; + transition: border 300ms ease; + cursor: pointer; + text-align: center; +} +.label i { + display: block; + font-size: 42px; +} +.label i, +.label .title { + font-weight: 400; + color: #fbfbfb; + transition: 200ms color; +} +.label:hover { + border: 2px solid black; +} +.label:hover i, +.label:hover .title { + color: black; +} + +.submit_button:hover { + background-color: rgba(0, 0, 0, 0.1); + cursor: pointer; +} +.submit_button { + border: none; + line-height: 30px; + font-size: 15px; + font-weight: 300; + text-transform: uppercase; + text-decoration: none; + padding: 8px 10px; + width: 150px; + margin: 2%; + text-align: center; + background-color: #4c4848b8; + color: #fbfbfb; + border-radius: 2px; + transition: background-color 0.2s ease; +} + +.submit_button:hover { + background-color: #212121; + cursor: pointer; +} + +.error { + margin-bottom: 10px; + color: red; +} + +.calculator { + max-width: 300px; + max-height: 400px; + border: 1px solid black; + border-radius: 20px; + padding: 20px; +} + +.calculator-output { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 0 10px; + margin-bottom: 30px; + background-color: white; + width: 260px; + height: 60px; + font-size: 20px; +} + +.calculator-output_input { + visibility: hidden; + /*display: none;*/ +} + +.calculator-buttons { + display: flex; +} + +.calculator-buttons__numbers { + display: flex; + flex-wrap: wrap; +} + +.calculator-buttons__operations { + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.button-style { + background-color: #9799ad; + cursor: pointer; + margin: 5px; + padding: 10px; + width: 50px; + border: 1px solid black; + border-radius: 5px; + text-shadow: 0 1px 1px rgba(255,255,255,.7); + box-shadow: 0 0 0 1px rgba(0,0,0,.1), 0 1px 2px rgba(0,0,0,.1), inset 0 1px 1px rgba(255,255,255,.5); +} + +.button-style:hover { + background-color: #babed6; +} + +.button-style:active { + background-image: linear-gradient(rgba(0,0,0,.1), rgba(0,0,0,0)); + box-shadow: inset 0 0 2px rgba(0,0,0,.2), inset 0 2px 5px rgba(0,0,0,.2), 0 1px rgba(255,255,255,.2); +} + +.feedback-wrapper { + display: flex; + justify-content: space-between; +} + +.feedback { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-end; +} + +.feedback__input { + outline: none; + padding: 10px; + height: 45px; + width: 250px; + font-size: 18px; + text-align: center; + font-weight: 500; + font-family: 'Roboto', Arial, sans-serif; + border: none; + resize: vertical; + margin: 0 0 15px 0; + border-radius: 5px; +} + +.feedback__input_textarea { + height: 80px; +} + +.feedback__button { + cursor: pointer; + font-size: 15px; + font-weight: 300; + text-transform: uppercase; + text-decoration: none; + padding: 8px 10px; + width: 140px; + text-align: center; + background-color: #4c4848b8; + color: #fbfbfb; + border-radius: 5px; + transition: background-color 0.2s ease; + border: none; + outline: none; +} + +.feedback__button:hover { + background-color: #212121; + cursor: pointer; +} + +.feedback__button:active { + background-color: #4c4848b8; +} + +.feedback-side { + margin: 0 0 0 70px; +} + +.feedback-side_display { + display: none; +} + +.feedback-side__item { + display: flex; + flex-direction: column; + border: 1px solid black; + padding: 15px 30px; + margin-bottom: 20px; + max-width: 350px; +} + +.feedback-side__p { + font-size: 18px; + color: black; + border-bottom: 1px solid black; + margin-bottom: 15px; +} + +.feedback-button_wrapper { + display: flex; + justify-content: space-around; +} + +.feedback-side__button { + width: 50px; + padding: 3px; + margin: 0 10px; +} + +.catalog { + display: flex; + justify-content: space-evenly; + width: 50%; + flex-wrap: wrap; + gap: 50px; +} + +.catalog__item_small { + min-height: 350px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-evenly; + transition: .5s all; + border: 2px solid transparent; + border-radius: 10px; + height: 210px; +} + +.catalog__item_side-wrapper { + width: 400px; + margin-left: 60px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-evenly; +} + +.catalog__item_big { + height: auto; + align-items: initial; + flex-direction: initial; +} + +.catalog__item_hover:hover { + background-color: #cccbcb; +} + +.catalog__item-text { + color: black; +} + +.catalog__item-text_left { + text-align: left; +} + +.catalog__item-link { + height: inherit; +} + +.catalog__item-image { + border: 2px solid transparent; + border-radius: 10px; + height: inherit; +} + +.catalog__item_events { + pointer-events: none; +} + +.cart-item { + flex-direction: row; + height: 150px; + width: 800px; + min-height: initial; + justify-content: space-between; + margin: 25px 0; + padding: 0 25px; +} + +.cart__item-button { + width: 50px; +} + +.cart-buttons_wrapper { + display: flex; + justify-content: space-evenly; + min-width: 160px; +} + +.signIn { + display: flex; + flex-direction: column; + justify-content: space-evenly; + align-items: flex-end; +} + +.signIn__label { + cursor: pointer; + font-size: 14px; + font-weight: 400; + text-transform: uppercase; + text-decoration: none; + padding: 8px 10px; + outline: none; + user-select: none; + width: 150px; + display: flex; + justify-content: space-evenly; + align-items: center; + margin-bottom: 15px; +} + +.signIn__input { + margin-bottom: 20px; +} + +.checkout { + padding: 25px; + margin-top: 50px; + border: 1px solid black; + display: flex; + justify-content: space-between; +} + +.checkout-info { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + gap: 15px; +} + +.checkout-info__text { + color: black; + font-weight: 400; + font-size: 18px; +} + +.checkout-info__text_h { + font-size: 26px; + font-weight: 600; +} + +.checkout-buttons_wrapper { + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 10px; +} + +.checkout__input { + text-align: left; +} + +.checkout__button { + width: auto; +} + +.auth-error { + color: red; + font-weight: 400; + margin-bottom: 10px; +} + +.orders-wrapper { + display: flex; + gap: 25px; + flex-wrap: wrap; + justify-content: space-between; +} + +.order-item { + display: flex; + flex-direction: column; + align-items: flex-end; + border: 2px solid black; + padding: 10px; +} + +.order-item_flex-start { + align-items: flex-start; +} + +.order-item__text { + color: black; + font-size: 18px; + padding: 5px 0; + font-weight: 500; +} + +.signUp { + margin-top: 15px; +} + +.signUp_align { + align-self: center; +} + +.signUp-errors { + color: red; +} + +.signUp__button { + width: auto; +} + +.order__buttons-wrapper { + display: flex; + margin-top: 10px; + justify-content: space-between; + gap: 20px; +} \ No newline at end of file diff --git a/templates/addLike.php b/templates/addLike.php new file mode 100644 index 0000000..b245d22 --- /dev/null +++ b/templates/addLike.php @@ -0,0 +1 @@ +

Спасибо, голос учтён!

\ No newline at end of file diff --git a/templates/auth.php b/templates/auth.php new file mode 100644 index 0000000..425037b --- /dev/null +++ b/templates/auth.php @@ -0,0 +1,46 @@ + +

Вход

+ +

+ +
+ + + + + Регистрация +
+ +

Добро пожаловать !

+ +

У вас пока ни одного заказа ¯\_(ツ)_/¯

+ +

Информация о заказах

+
+
+ +
+

Заказ #

+

Имя заказчика:

+

Телефон заказчика:

+

Email заказчика:

+

Дата и время заказа:

+

Статус заказа:

+

Сумма заказа: 

+ + + +
+ +
+ + + + + diff --git a/templates/calculator.php b/templates/calculator.php new file mode 100644 index 0000000..1efab95 --- /dev/null +++ b/templates/calculator.php @@ -0,0 +1,27 @@ +
+
+ +
+
+
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
0
+ +
C
+
+
+
+
+
-
+
*
+
/
+
+
+
\ No newline at end of file diff --git a/templates/cart.php b/templates/cart.php new file mode 100644 index 0000000..1e0e1a5 --- /dev/null +++ b/templates/cart.php @@ -0,0 +1,37 @@ +
¯\_(ツ)_/¯'; ?> + +
+ +
+
+ + catalog-item + +

+

+
+ +

+ +
+
+
+
+ + +
+

Сумма заказа

+ +

Стоимость :

+ +

Итого к оплате:

+
+
+ + + + +
+ +
+ diff --git a/templates/catalog.php b/templates/catalog.php new file mode 100644 index 0000000..20352c2 --- /dev/null +++ b/templates/catalog.php @@ -0,0 +1,13 @@ +

Каталог

+
+ +
+ + catalog-item + +

+

Цена: 

+ +
+ +
\ No newline at end of file diff --git a/templates/feedback.php b/templates/feedback.php new file mode 100644 index 0000000..dca5970 --- /dev/null +++ b/templates/feedback.php @@ -0,0 +1,21 @@ +

Отзывы

+
+
+ + + +
+
+ + + +
+
+ \ No newline at end of file diff --git a/templates/gallery.php b/templates/gallery.php new file mode 100644 index 0000000..d92d49b --- /dev/null +++ b/templates/gallery.php @@ -0,0 +1,27 @@ +

Галерея

+ + +

+
+
+ +
+ +
+ + \ No newline at end of file diff --git a/templates/good.php b/templates/good.php new file mode 100644 index 0000000..d39324b --- /dev/null +++ b/templates/good.php @@ -0,0 +1,34 @@ +
+ + catalog-item + +
+

+

+

Цена:  р

+ +
+
+
+
+

Отзывы

+
+
+ + + +
+
+ + + +
+
+ \ No newline at end of file diff --git a/templates/homework_3.php b/templates/homework_3.php new file mode 100644 index 0000000..25a05c4 --- /dev/null +++ b/templates/homework_3.php @@ -0,0 +1 @@ +

Домашняя работа №3

\ No newline at end of file diff --git a/templates/image.php b/templates/image.php new file mode 100644 index 0000000..1cfa02e --- /dev/null +++ b/templates/image.php @@ -0,0 +1,7 @@ +gallery-img + \ No newline at end of file diff --git a/templates/index.php b/templates/index.php new file mode 100644 index 0000000..e98490a --- /dev/null +++ b/templates/index.php @@ -0,0 +1 @@ +

PHP Курс 1

\ No newline at end of file diff --git a/templates/layouts/auth.php b/templates/layouts/auth.php new file mode 100644 index 0000000..975adc3 --- /dev/null +++ b/templates/layouts/auth.php @@ -0,0 +1,18 @@ + + + + + Кабинет + + + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/templates/layouts/calculator.php b/templates/layouts/calculator.php new file mode 100644 index 0000000..0b7844c --- /dev/null +++ b/templates/layouts/calculator.php @@ -0,0 +1,20 @@ + + + + + Калькулятор + + + + + +
+ +
+
+

Калькулятор

+ +
+ + \ No newline at end of file diff --git a/templates/layouts/catalog.php b/templates/layouts/catalog.php new file mode 100644 index 0000000..3ce5386 --- /dev/null +++ b/templates/layouts/catalog.php @@ -0,0 +1,17 @@ + + + + + Каталог + + + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/templates/layouts/feedback.php b/templates/layouts/feedback.php new file mode 100644 index 0000000..c4f37b4 --- /dev/null +++ b/templates/layouts/feedback.php @@ -0,0 +1,18 @@ + + + + + Отзывы + + + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/templates/layouts/gallery.php b/templates/layouts/gallery.php new file mode 100644 index 0000000..c4272f7 --- /dev/null +++ b/templates/layouts/gallery.php @@ -0,0 +1,18 @@ + + + + + Галерея + + + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/templates/layouts/homework_3.php b/templates/layouts/homework_3.php new file mode 100644 index 0000000..4fc0aa1 --- /dev/null +++ b/templates/layouts/homework_3.php @@ -0,0 +1,16 @@ + + + + + Homework 3 + + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/templates/layouts/main.php b/templates/layouts/main.php new file mode 100644 index 0000000..a02dceb --- /dev/null +++ b/templates/layouts/main.php @@ -0,0 +1,16 @@ + + + + + Главная + + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/templates/menu.php b/templates/menu.php new file mode 100644 index 0000000..f0c4a75 --- /dev/null +++ b/templates/menu.php @@ -0,0 +1,110 @@ + 'Выход', + 'href' => '/?logout', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ] +]; + +$menuList = [ + [ + 'title' => 'Главная', + 'href' => '/', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Дз 3', + 'href' => '/homework_3', + 'style' => 'nav-li', + 'hover' => 'hover', + 'styleLink' => 'nav-link', + 'subHidden' => 'ul-hidden', + 'subMenu' => [ + [ + 'title' => 'Задание 1', + 'href' => '/task_1', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Задание 2', + 'href' => '/task_2', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Задание 3 и 8', + 'href' => '/task_3_8', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Задание 4, 5 и 9', + 'href' => '/task_4_5_9', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + ] + ], + [ + 'title' => 'Галерея', + 'href' => '/gallery', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Каталог', + 'href' => '/catalog', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Калькулятор', + 'href' => '/calculator', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Отзывы', + 'href' => '/feedback', + 'style' => 'nav-li', + 'styleLink' => 'nav-link' + ], + [ + 'title' => 'Корзина [ ' . $count . ' ]', + 'href' => '/cart', + 'style' => 'nav-li', + 'styleLink' => 'nav-link', + ], + [ + 'title' => $params['auth']? 'Кабинет' : 'Вход', + 'href' => '/auth', + 'style' => 'nav-li', + 'hover' => 'hover', + 'subHidden' => 'ul-hidden', + 'styleLink' => 'nav-link', + 'subMenu' => $params['auth']?$authMenu : '' + ] +]; + +function renderMenu($menuList, $params):string { + $res = ""; + return $res; +} + +echo renderMenu($menuList, $params); \ No newline at end of file diff --git a/templates/order.php b/templates/order.php new file mode 100644 index 0000000..8f0a26a --- /dev/null +++ b/templates/order.php @@ -0,0 +1,4 @@ +
+

Спасибо за заказ!

+
+В каталог \ No newline at end of file diff --git a/templates/orderDetails.php b/templates/orderDetails.php new file mode 100644 index 0000000..e69de29 diff --git a/templates/signUp.php b/templates/signUp.php new file mode 100644 index 0000000..362b672 --- /dev/null +++ b/templates/signUp.php @@ -0,0 +1,19 @@ +

Регистрация

+ +

+
+ + + + + + + +
+ +
+

Вы успешно зарегистрировались!

+
+
+ В кабинет + diff --git a/templates/task_1.php b/templates/task_1.php new file mode 100644 index 0000000..f5c7e21 --- /dev/null +++ b/templates/task_1.php @@ -0,0 +1,12 @@ +
+

Задание 1

+
+

С помощью цикла while вывести все числа в промежутке от 0 до 100, которые делятся на 3 без остатка.


+ + + +
+
\ No newline at end of file diff --git a/templates/task_2.php b/templates/task_2.php new file mode 100644 index 0000000..c36b5f9 --- /dev/null +++ b/templates/task_2.php @@ -0,0 +1,19 @@ +
+

Задание 2

+
+

С помощью цикла do…while написать функцию для вывода чисел от 0 до 10.


+ '; + } else if($i & 1) { + echo "{$i} - не чётное
"; + } else { + echo "{$i} - чётное
"; + } + $i++; + } while ( $i <= 10); + ?> +
+
\ No newline at end of file diff --git a/templates/task_3_8.php b/templates/task_3_8.php new file mode 100644 index 0000000..666c182 --- /dev/null +++ b/templates/task_3_8.php @@ -0,0 +1,53 @@ + [ + 'Москва', + 'Зеленоград', + 'Клин' + ], + 'Ленинградская область' => [ + 'Санкт-Петербург', + 'Всеволожск', + 'Павловск', + 'Кронштадт' + ], + 'Рязанская область' => [ + 'Рязань', + 'Касимов', + 'Скопин', + 'Сасово', + 'Ряжск', + 'Рыбное' + ] + ]; + // знаю, что выводить таким образом - плохой тон, но что-то я так и не понял как мне из цикла извлечь эти переменные и отобразить как мне надо в шаблоне + function printAreas($areas){ + foreach ($areas as $area => $city) { + $city = implode(', ', $city) . "."; + echo "
$area:
"; + echo "
$city

"; + } + } + + + // Города начинающиеся с буквы "К". + + // function printCitiesStartsWithChar($areas){ + // foreach ($areas as $area => $city) { + // echo "
$area:
"; + // foreach ($city as $value) { + // if(preg_match('/^(к|К)/', $value)){ + // echo "
$value

"; + // } + // } + // } + // } +?> +
+

Задания 3 и 8

+
+

Объявить массив, в котором в качестве ключей будут использоваться названия областей, а в качестве значений – массивы с названиями городов из соответствующей области. Вывести в цикле значения массива. + Вывести на экран только города, начинающиеся с буквы «К»


+ +
+
\ No newline at end of file diff --git a/templates/task_4_5_9.php b/templates/task_4_5_9.php new file mode 100644 index 0000000..4a8f4f9 --- /dev/null +++ b/templates/task_4_5_9.php @@ -0,0 +1,62 @@ + 'а', + 'б' => 'b', + 'в' => 'v', + 'г' => 'g', + 'д' => 'd', + 'е' => 'e', + 'ё' => 'e', + 'ж' => 'j', + 'з' => 'z', + 'и' => 'i', + 'к' => 'k', + 'л' => 'l', + 'м' => 'm', + 'н' => 'n', + 'о' => 'o', + 'п' => 'p', + 'р' => 'r', + 'с' => 's', + 'т' => 't', + 'у' => 'u', + 'ф' => 'f', + 'х' => 'h', + 'ц' => 'c', + 'ч' => '4', + 'ш' => 'sh', + 'щ' => 'shc', + 'ъ' => '', + 'ы' => 'y', + 'ь' => '', + 'э' => 'e', + 'ю' => 'yu', + 'я' => '9', + ' ' => '_' + ]; + } + + function translit($str){ + $dictionary = getDictionary(); + $res = ''; + + for ($i = 0; $i < mb_strLen($str); $i++) { + $char = mb_substr($str, $i, 1); + if (empty($dictionary[$char])) { + $char = mb_strtolower($char); + $res .= mb_strtoupper($dictionary[$char]); + } else { + $res .= $dictionary[$char]; + } + } + return $res; + } +?> +
+

Задание 4, 5 и 9

+
+

Объявить массив, индексами которого являются буквы русского языка, а значениями – соответствующие латинские буквосочетания.


+ +
+
\ No newline at end of file diff --git a/templates/updateOrder.php b/templates/updateOrder.php new file mode 100644 index 0000000..3d5188c --- /dev/null +++ b/templates/updateOrder.php @@ -0,0 +1,35 @@ + +
+ +

Заказ #

+ + + + + +

Дата и время заказа:

+ +

Сумма заказа: 

+ +
+ +
+
+

Сохранено!

+
+ Назад +