/**
  * @Get
  * @Route("Categories/{category:string}/{start:int}/{end:int}")
  */
 public function show()
 {
     $category = $this->input->getForDb(1);
     $skip = $this->input->get(2);
     $take = $this->input->get(3) - $skip;
     $this->db->prepare("SELECT\n                            p.id, p.name, p.description, p.price, p.quantity, c.name as category\n                            FROM products p\n                            JOIN products_categories pc\n                            ON p.id = pc.productId\n                            JOIN categories c\n                            ON pc.categoryId = c.id\n                            WHERE quantity > 0 AND c.name LIKE ?\n                            ORDER BY p.id\n                            LIMIT {$take}\n                            OFFSET {$skip}", array($category));
     $response = $this->db->execute()->fetchAllAssoc();
     $products = array();
     foreach ($response as $p) {
         $productId = Normalizer::normalize($p['id'], 'noescape|int');
         $this->db->prepare("SELECT\n                            percentage\n                            FROM promotions\n                            WHERE productId = ? AND NOW() < endDate", array($productId));
         $promos = $this->db->execute()->fetchAllAssoc();
         $bestPromo = 0;
         foreach ($promos as $promo) {
             $currentPromo = Normalizer::normalize($promo['percentage'], 'noescape|double');
             if ($currentPromo > $bestPromo) {
                 $bestPromo = $currentPromo;
             }
         }
         $product = new ProductViewModel(Normalizer::normalize($p['id'], 'noescape|int'), $p['name'], $p['description'], Normalizer::normalize($p['price'], 'noescape|double'), Normalizer::normalize($p['quantity'], 'noescape|int'), $p['category'], $bestPromo);
         $products[] = $product;
     }
     // Escaped one
     $category = $this->input->get(1);
     $this->view->appendToLayout('header', 'header');
     $this->view->appendToLayout('meta', 'meta');
     $this->view->appendToLayout('body', new ShowViewModel($products, $skip, $take + $skip, $category));
     $this->view->appendToLayout('footer', 'footer');
     $this->view->displayLayout('Layouts.products');
 }
 /**
  * @Delete
  * @Route("review/{id:int}/delete")
  * @Role("Moderator")
  */
 public function remove()
 {
     $id = $this->input->get(1);
     $this->db->prepare("SELECT productId\n                            FROM reviews\n                            WHERE id = ?", array($id));
     $response = $this->db->execute()->fetchRowAssoc();
     $productId = Normalizer::normalize($response['productId'], 'noescape|int');
     $this->db->prepare("DELETE FROM reviews\n                            WHERE id = ?", array($id))->execute();
     $this->redirect("/product/{$productId}/show");
 }
 /**
  * @Get
  * @Route("editor/promotions/all")
  * @Role("Editor")
  */
 public function all()
 {
     $response = $this->db->prepare("SELECT pr.name, p.name as product, pr.percentage, pr.endDate\n                            FROM promotions pr\n                            JOIN products p\n                            ON pr.productId = p.id")->execute()->fetchAllAssoc();
     $promotions = array();
     foreach ($response as $p) {
         $promotions[] = new PromotionViewModel($p['name'], $p['product'], Normalizer::normalize($p['percentage'], 'noescape|double'), $p['endDate']);
     }
     $this->view->appendToLayout('header', 'header');
     $this->view->appendToLayout('meta', 'meta');
     $this->view->appendToLayout('body', new AllViewModel($promotions));
     $this->view->appendToLayout('footer', 'footer');
     $this->view->displayLayout('Layouts.Editor.home');
 }
 /**
  * @Authorize
  * @Post
  * @Route("cart/checkout")
  */
 public function checkout()
 {
     $cart = $this->session->cart;
     if (!$cart) {
         throw new \Exception('Cart is empty!', 400);
     }
     $totalPrice = 0;
     $products = array();
     foreach ($cart as $itemId) {
         $this->db->prepare("SELECT\n                            p.price, p.name, p.id\n                            FROM products p\n                            JOIN products_categories pc\n                            ON p.id = pc.productId\n                            JOIN categories c\n                            ON pc.categoryId = c.id\n                            WHERE p.id = ?", array($itemId));
         $response = $this->db->execute()->fetchRowAssoc();
         $price = Normalizer::normalize($response['price'], 'noescape|double');
         $this->db->prepare("SELECT\n                            percentage\n                            FROM promotions\n                            WHERE productId = ? AND NOW() < endDate", array($itemId));
         $promos = $this->db->execute()->fetchAllAssoc();
         $bestPromo = 0;
         foreach ($promos as $promo) {
             $currentPromo = Normalizer::normalize($promo['percentage'], 'noescape|double');
             if ($currentPromo > $bestPromo) {
                 $bestPromo = $currentPromo;
             }
         }
         $price = $price * (1 - $bestPromo / 100);
         $products[] = new Product(Normalizer::normalize($response['id'], 'noescape|int'), $response['name'], $price);
         $totalPrice += $price;
     }
     $this->db->prepare("SELECT\n                            Cash\n                            FROM users\n                            WHERE id = ? AND username = ?", array($this->session->_login, $this->session->_username));
     $response = $this->db->execute()->fetchRowAssoc();
     $money = Normalizer::normalize($response['Cash'], 'noescape|double');
     if ($money - $totalPrice < 0) {
         $diff = $totalPrice - $money;
         throw new \Exception("You don't have enough money for this purchase. Needed {$diff} more!", 400);
     }
     $boughtProducts = array();
     $outOfStockProducts = array();
     foreach ($products as $p => $product) {
         $this->db->prepare("UPDATE products\n                                SET quantity = quantity - 1\n                                WHERE id = ? AND quantity > 0", array($product->getId()));
         $response = $this->db->execute()->affectedRows();
         if ($response) {
             $this->db->prepare("UPDATE users\n                                    SET Cash = Cash - ?\n                                    WHERE id = ? AND username = ?", array($product->getPrice(), $this->session->_login, $this->session->_username));
             $this->db->execute();
             $boughtProducts[] = $product;
         } else {
             $outOfStockProducts[] = $product;
         }
     }
     if (count($outOfStockProducts) !== 0) {
         $viewModel = new CheckoutViewModel('Not all items bought!', $outOfStockProducts);
     } else {
         $viewModel = new CheckoutViewModel('All items bought!', array());
     }
     $this->session->cart = array();
     $this->view->appendToLayout('header', 'header');
     $this->view->appendToLayout('meta', 'meta');
     $this->view->appendToLayout('body', $viewModel);
     $this->view->appendToLayout('footer', 'footer');
     $this->view->displayLayout('Layouts.checkout');
 }
 public static function hasRole($role)
 {
     $col = 'is' . ucfirst($role);
     try {
         $statement = self::$database->prepare("SELECT {$col}\n                      FROM users\n                      WHERE username = ? AND id = ?");
         $statement->bindColumn(1, $col);
         $statement->bindParam(1, App::getInstance()->getSession()->_username);
         $statement->bindParam(2, App::getInstance()->getSession()->_login);
         $statement->execute();
         $response = $statement->fetch(\PDO::FETCH_ASSOC);
         $response = $response['is' . ucfirst($role)];
     } catch (\PDOException $ex) {
         throw new \Exception("Check your db, missing role '{$col}'");
     }
     if ($response) {
         return Normalizer::normalize($response, 'bool');
     }
     return false;
 }
 /**
  * @Route("users/all/{start:int}/{end:int}")
  * @Get
  */
 public function allUsers()
 {
     $skip = $this->input->get(2);
     $take = $this->input->get(3) - $skip;
     $this->db->prepare("SELECT\n                            username,isAdmin, isEditor, isModerator\n                            FROM users\n                            ORDER BY username\n                            LIMIT {$take}\n                            OFFSET {$skip}");
     $response = $this->db->execute()->fetchAllAssoc();
     $users = array();
     foreach ($response as $u) {
         $users[] = new User($u['username'], Normalizer::normalize($u['isAdmin'], 'noescape|bool'), Normalizer::normalize($u['isEditor'], 'noescape|bool'), Normalizer::normalize($u['isModerator'], 'noescape|bool'));
     }
     $this->view->appendToLayout('header', 'header');
     $this->view->appendToLayout('meta', 'meta');
     $this->view->appendToLayout('body', new AllUsersViewModel($users, $skip, $take + $skip));
     $this->view->appendToLayout('footer', 'footer');
     $this->view->displayLayout('Layouts.home');
 }
 /**
  * @param mixed $percentage
  */
 public function setPercentage($percentage)
 {
     $this->percentage = Normalizer::normalize($percentage, 'noescape|double');
 }
 /**
  * @param mixed $price
  */
 public function setPrice($price)
 {
     $this->price = Normalizer::normalize($price, 'noescape|double');
 }
 /**
  * @param mixed $quantity
  */
 public function setQuantity($quantity)
 {
     $this->quantity = Normalizer::normalize($quantity, 'noescape|int');
 }