Compare commits
No commits in common. "6d40f9c2fcc6978f0658ae8e6579eb45e52108b5" and "863829d29132388d0b5eb2948650e3893bc742c9" have entirely different histories.
6d40f9c2fc
...
863829d291
|
@ -1,16 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8"/>
|
|
||||||
<link rel="stylesheet" href="index.css"/>
|
|
||||||
<title>Product Add</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="header">
|
|
||||||
<h1 id="title">Product Add</h1>
|
|
||||||
<div id="buttons">
|
|
||||||
<a href="/"><button>Save</button></a>
|
|
||||||
<a href="/"><button>Cancel</button></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
28
autoload.php
28
autoload.php
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
spl_autoload_register(function ($class) {
|
|
||||||
// project-specific namespace prefix
|
|
||||||
$prefix = 'ProductList\\';
|
|
||||||
|
|
||||||
// base directory for the namespace prefix
|
|
||||||
$base_dir = __DIR__ . '/src/';
|
|
||||||
|
|
||||||
// does the class use the namespace prefix?
|
|
||||||
$len = strlen($prefix);
|
|
||||||
if (strncmp($prefix, $class, $len) !== 0) {
|
|
||||||
// no, move to the next registered autoloader
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the relative class name
|
|
||||||
$relative_class = substr($class, $len);
|
|
||||||
|
|
||||||
// replace the namespace prefix with the base directory, replace namespace
|
|
||||||
// separators with directory separators in the relative class name, append
|
|
||||||
// with .php
|
|
||||||
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
|
|
||||||
|
|
||||||
// if the file exists, require it
|
|
||||||
if (file_exists($file)) {
|
|
||||||
require $file;
|
|
||||||
}
|
|
||||||
});
|
|
48
index.css
48
index.css
|
@ -1,58 +1,14 @@
|
||||||
body {
|
|
||||||
font-family: cursive;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header {
|
#header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 2px solid gray;
|
|
||||||
margin: 0 1em 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#buttons {
|
#buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 0 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#buttons a {
|
|
||||||
align-self: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#buttons button {
|
#buttons button {
|
||||||
font-family: cursive;
|
height: 2em;
|
||||||
padding: .5em 1em;
|
|
||||||
font-size: 1rem;
|
|
||||||
margin: 0 2em;
|
|
||||||
align-self: center;
|
|
||||||
background-color: white;
|
|
||||||
border: 2px solid black;
|
|
||||||
box-shadow: 2px 2px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#buttons button:hover {
|
|
||||||
background-color: #EEE;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#products {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.product {
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
border: 2px solid black;
|
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
position: relative;
|
align-self: center;
|
||||||
}
|
|
||||||
|
|
||||||
.delete-checkbox {
|
|
||||||
border: 1px solid black;
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
}
|
}
|
||||||
|
|
20
index.html
20
index.html
|
@ -1,20 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8"/>
|
|
||||||
<link rel="stylesheet" href="index.css"/>
|
|
||||||
<title>Product List</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="header">
|
|
||||||
<h1 id="title">Product List</h1>
|
|
||||||
<div id="buttons">
|
|
||||||
<a href="add-product"><button>ADD</button></a>
|
|
||||||
<button id="delete-product-btn">MASS DELETE</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="products">
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<script src="index.js"></script>
|
|
||||||
</html>
|
|
47
index.js
47
index.js
|
@ -1,47 +0,0 @@
|
||||||
const productsList = document.getElementById('products');
|
|
||||||
|
|
||||||
const loadItems = () => {
|
|
||||||
const xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onload = function() {
|
|
||||||
console.log(this.responseText);
|
|
||||||
|
|
||||||
const products = JSON.parse(this.responseText);
|
|
||||||
|
|
||||||
const boxes = products.map(product =>
|
|
||||||
`<div class="product">
|
|
||||||
<input type="checkbox" class="delete-checkbox" value="${product.id}">
|
|
||||||
<p>
|
|
||||||
${product.sku}<br>
|
|
||||||
${product.name}<br>
|
|
||||||
${product.price} $<br>
|
|
||||||
${product.attribute}
|
|
||||||
</p>
|
|
||||||
</div>`
|
|
||||||
)
|
|
||||||
|
|
||||||
productsList.innerHTML = boxes.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
xhttp.open('GET', 'src/View/Product', true);
|
|
||||||
xhttp.send();
|
|
||||||
}
|
|
||||||
loadItems();
|
|
||||||
|
|
||||||
const deleteSelected = () => {
|
|
||||||
const checkboxes = document.querySelectorAll('input[class="delete-checkbox"]:checked');
|
|
||||||
let values = [];
|
|
||||||
checkboxes.forEach(checkbox => values.push(checkbox.value));
|
|
||||||
|
|
||||||
const xhttp = new XMLHttpRequest();
|
|
||||||
|
|
||||||
xhttp.onload = function() {
|
|
||||||
loadItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
xhttp.open('DELETE', 'src/View/Product', true);
|
|
||||||
xhttp.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
const deleteButton = document.getElementById('delete-product-btn');
|
|
||||||
deleteButton.addEventListener('click', deleteSelected);
|
|
24
index.php
24
index.php
|
@ -1,4 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<link rel="stylesheet" href="index.css"/>
|
||||||
|
<title>Product List</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<h1 id="title">Product List</h1>
|
||||||
|
<div id="buttons">
|
||||||
|
<button>ADD</button>
|
||||||
|
<button id="delete-product-btn">MASS DELETE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<?php
|
<?php
|
||||||
require 'autoload.php';
|
require 'model/product.php';
|
||||||
|
|
||||||
echo json_encode(ProductList\Model\Product::selectAll());
|
$products = Product::selectAll();
|
||||||
|
// TODO
|
||||||
|
echo json_encode($products);
|
||||||
|
?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
define("PRODUCT", "product");
|
||||||
|
define("DVD", "dvd");
|
||||||
|
define("BOOK", "book");
|
||||||
|
define("FURNITURE", "furniture");
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
const SERVERNAME = "127.0.0.1";
|
||||||
|
const DATABASE = "scandiweb";
|
||||||
|
const USERNAME = "root";
|
||||||
|
const PASSWORD = "root";
|
||||||
|
|
||||||
|
public static function connect() {
|
||||||
|
$conn = new mysqli(self::SERVERNAME, self::USERNAME, self::PASSWORD);
|
||||||
|
$conn->select_db(self::DATABASE);
|
||||||
|
return $conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Model {
|
||||||
|
public abstract static function fromRow($row) : self;
|
||||||
|
public abstract function insert($conn = NULL) : int; // should return id
|
||||||
|
private abstract static function getSelectAllQuery() : string;
|
||||||
|
|
||||||
|
public static function selectAll($conn = NULL) : array {
|
||||||
|
if($conn === NULL) {
|
||||||
|
$conn = Database::connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = self::getSelectAllQuery();
|
||||||
|
|
||||||
|
$rows = $conn->query($sql)->fetch_all(MYSQLI_ASSOC);
|
||||||
|
|
||||||
|
$products = array();
|
||||||
|
foreach($rows as $row) {
|
||||||
|
array_push($products, self::fromRow($row));
|
||||||
|
}
|
||||||
|
return $products;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,262 @@
|
||||||
|
<?php
|
||||||
|
require_once 'db.php';
|
||||||
|
|
||||||
|
abstract class Product implements JsonSerializable {
|
||||||
|
use Model;
|
||||||
|
private $variationId;
|
||||||
|
private $SKU;
|
||||||
|
private $name;
|
||||||
|
private $price;
|
||||||
|
private $productId;
|
||||||
|
|
||||||
|
public function __construct($SKU, $name, $price, $productId = NULL, $variationId = NULL) {
|
||||||
|
$this->productId = $productId;
|
||||||
|
$this->variationId = $variationId;
|
||||||
|
$this->SKU = $SKU;
|
||||||
|
$this->name = $name;
|
||||||
|
$this->price = $price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSKU() {
|
||||||
|
return $this->SKU;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrice() {
|
||||||
|
return $this->price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProductId() {
|
||||||
|
return $this->productId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setVariationId($id) {
|
||||||
|
$this->variationId = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setProductId($id) {
|
||||||
|
$this->productId = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract function getFormatedAttr();
|
||||||
|
|
||||||
|
public static function fromRow($row) : self {
|
||||||
|
if($row['size'] !== NULL) {
|
||||||
|
return DVD::fromRow($row);
|
||||||
|
} elseif($row['weight'] !== NULL) {
|
||||||
|
return Book::fromRow($row);
|
||||||
|
} elseif($row['height'] !== NULL) {
|
||||||
|
return Furniture::fromRow($row);
|
||||||
|
} else {
|
||||||
|
throw new Exception("Product without a type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getSelectAllQuery() : string {
|
||||||
|
return 'SELECT '.PRODUCT.'.id as product_id, COALESCE('.DVD.'.id, '.BOOK.'.id, '.FURNITURE.'.id) as variation_id,
|
||||||
|
name, sku, price, size, weight, width, height, length
|
||||||
|
FROM '.PRODUCT.'
|
||||||
|
LEFT JOIN '.DVD.' ON '.PRODUCT.'.id = '.DVD.'.product_id
|
||||||
|
LEFT JOIN '.BOOK.' ON '.PRODUCT.'.id = '.BOOK.'.product_id
|
||||||
|
LEFT JOIN '.FURNITURE.' ON '.PRODUCT.'.id = '.FURNITURE.'.product_id;';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insert($conn = NULL) : int {
|
||||||
|
if($conn === NULL) {
|
||||||
|
$conn = Database::connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$SKU = $this->getSKU();
|
||||||
|
$name = $this->getName();
|
||||||
|
$price = $this->getPrice();
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("INSERT INTO ".PRODUCT." (sku, name, price) VALUES (?, ?, ?);");
|
||||||
|
$stmt->bind_param('ssd', $SKU, $name, $price);
|
||||||
|
|
||||||
|
if($stmt->execute() === TRUE) {
|
||||||
|
$this->setProductId($conn->insert_id);
|
||||||
|
return $conn->insert_id;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Unable to insert object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize() : mixed {
|
||||||
|
return [
|
||||||
|
'sku' => $this->getSKU(),
|
||||||
|
'name' => $this->getName(),
|
||||||
|
'price' => $this->getPrice(),
|
||||||
|
'attribute' => $this->getFormatedAttr()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DVD extends Product {
|
||||||
|
private $size;
|
||||||
|
|
||||||
|
public function __construct($sku, $name, $price, $size, $productId = null, $variationId = null) {
|
||||||
|
parent::__construct($sku, $name, $price, $productId, $variationId);
|
||||||
|
$this->size = $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromRow($row) : self {
|
||||||
|
return new DVD($row['sku'], $row['name'], $row['price'], $row['size'], $row['product_id'], $row['variation_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSize() {
|
||||||
|
return $this->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormatedAttr() {
|
||||||
|
$size = $this->getSize();
|
||||||
|
return "Size: $size MB";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getSelectAllQuery() : string {
|
||||||
|
return 'SELECT '.PRODUCT.'.*, '.DVD.'.id as variation_id, size
|
||||||
|
FROM '.PRODUCT.' LEFT JOIN '.DVD.' ON '.PRODUCT.'.id = '.DVD.'.product_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insert($conn = NULL) : int {
|
||||||
|
if($conn === NULL) {
|
||||||
|
$conn = Database::connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->getProductId() === NULL) {
|
||||||
|
parent::insert($conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
$productId = $this->getProductId();
|
||||||
|
$size = $this->getSize();
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("INSERT INTO ".DVD." (product_id, size) VALUES (?, ?);");
|
||||||
|
$stmt->bind_param('ii', $productId, $size);
|
||||||
|
|
||||||
|
if($stmt->execute() === TRUE) {
|
||||||
|
$this->setVariationId($conn->insert_id);
|
||||||
|
return $conn->insert_id;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Unable to insert object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Book extends Product {
|
||||||
|
private $weight;
|
||||||
|
|
||||||
|
public function __construct($sku, $name, $price, $weight, $productId = null, $variationId = null) {
|
||||||
|
parent::__construct($sku, $name, $price, $productId, $variationId);
|
||||||
|
$this->weight = $weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromRow($row) : self {
|
||||||
|
return new Book($row['sku'], $row['name'], $row['price'], $row['weight'], $row['product_id'], $row['variation_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWeight() {
|
||||||
|
return $this->weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormatedAttr() {
|
||||||
|
$weight = $this->getWeight();
|
||||||
|
return "Weight: $weight KG";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getSelectAllQuery() : string {
|
||||||
|
return 'SELECT '.PRODUCT.'.*, '.BOOK.'.id as variation_id, size
|
||||||
|
FROM '.PRODUCT.' LEFT JOIN '.BOOK.' ON '.PRODUCT.'.id = '.BOOK.'.product_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insert($conn = NULL) : int {
|
||||||
|
if($conn === NULL) {
|
||||||
|
$conn = Database::connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->getProductId() === NULL) {
|
||||||
|
parent::insert($conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
$productId = $this->getProductId();
|
||||||
|
$weight = $this->getWeight();
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("INSERT INTO ".BOOK." (product_id, weight) VALUES (?, ?);");
|
||||||
|
$stmt->bind_param('id', $productId, $weight);
|
||||||
|
|
||||||
|
if($stmt->execute() === TRUE) {
|
||||||
|
$this->setVariationId($conn->insert_id);
|
||||||
|
return $conn->insert_id;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Unable to insert object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Furniture extends Product {
|
||||||
|
private $height;
|
||||||
|
private $width;
|
||||||
|
private $length;
|
||||||
|
|
||||||
|
public function __construct($SKU, $name, $price, $height, $width, $length, $productId = NULL, $variationId = NULL) {
|
||||||
|
parent::__construct($SKU, $name, $price, $productId, $variationId);
|
||||||
|
$this->height = $height;
|
||||||
|
$this->width = $width;
|
||||||
|
$this->length = $length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fromRow($row) : self {
|
||||||
|
return new Furniture($row['sku'], $row['name'], $row['price'], $row['height'],
|
||||||
|
$row['width'], $row['length'], $row['product_id'], $row['variation_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHeight() {
|
||||||
|
return $this->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWidth() {
|
||||||
|
return $this->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLength() {
|
||||||
|
return $this->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormatedAttr() {
|
||||||
|
$height = $this->getHeight();
|
||||||
|
$width = $this->getWidth();
|
||||||
|
$length = $this->getLength();
|
||||||
|
return 'Dimension: '.$height.'x'.$width.'x'.$length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getSelectAllQuery() : string {
|
||||||
|
return 'SELECT '.PRODUCT.'.*, '.FURNITURE.'.id as variation_id, size
|
||||||
|
FROM '.PRODUCT.' LEFT JOIN '.FURNITURE.' ON '.PRODUCT.'.id = '.FURNITURE.'.product_id';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insert($conn = NULL) : int {
|
||||||
|
if($conn === NULL) {
|
||||||
|
$conn = Database::connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->getProductId() === NULL) {
|
||||||
|
parent::insert($conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
$productId = $this->getProductId();
|
||||||
|
$height = $this->getHeight();
|
||||||
|
$width = $this->getWidth();
|
||||||
|
$length = $this->getLength();
|
||||||
|
|
||||||
|
$stmt = $conn->prepare("INSERT INTO ".FURNITURE." (product_id, height, width, length) VALUES (?, ?, ?, ?);");
|
||||||
|
$stmt->bind_param('iddd', $productId, $height, $width, $length);
|
||||||
|
|
||||||
|
if($stmt->execute() === TRUE) {
|
||||||
|
$this->setVariationId($conn->insert_id);
|
||||||
|
return $conn->insert_id;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Unable to insert object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,72 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace ProductList\Model;
|
|
||||||
|
|
||||||
class Book extends Product
|
|
||||||
{
|
|
||||||
private $weight;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
$sku,
|
|
||||||
$name,
|
|
||||||
$price,
|
|
||||||
$weight,
|
|
||||||
$productId = null,
|
|
||||||
$variationId = null
|
|
||||||
) {
|
|
||||||
parent::__construct($sku, $name, $price, $productId, $variationId);
|
|
||||||
$this->weight = $weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromRow($row) : self
|
|
||||||
{
|
|
||||||
return new Book(
|
|
||||||
$row['sku'],
|
|
||||||
$row['name'],
|
|
||||||
$row['price'],
|
|
||||||
$row['weight'],
|
|
||||||
$row['product_id'],
|
|
||||||
$row['variation_id']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWeight()
|
|
||||||
{
|
|
||||||
return $this->weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFormatedAttr()
|
|
||||||
{
|
|
||||||
$weight = $this->getWeight();
|
|
||||||
return "Weight: $weight KG";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getSelectAllQuery() : string
|
|
||||||
{
|
|
||||||
return 'SELECT '.PRODUCT.'.*, '.BOOK.'.id as variation_id, size
|
|
||||||
FROM '.PRODUCT.' LEFT JOIN '.BOOK.' ON '.PRODUCT.'.id = '.BOOK.'.product_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function insert($conn = null) : int
|
|
||||||
{
|
|
||||||
if ($conn === null) {
|
|
||||||
$conn = Database::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getProductId() === null) {
|
|
||||||
parent::insert($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
$productId = $this->getProductId();
|
|
||||||
$weight = $this->getWeight();
|
|
||||||
|
|
||||||
$stmt = $conn->prepare("INSERT INTO ".BOOK." (product_id, weight) VALUES (?, ?);");
|
|
||||||
$stmt->bind_param('id', $productId, $weight);
|
|
||||||
|
|
||||||
if ($stmt->execute() === true) {
|
|
||||||
$this->setVariationId($conn->insert_id);
|
|
||||||
return $conn->insert_id;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unable to insert object");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace ProductList\Model;
|
|
||||||
|
|
||||||
class DVD extends Product
|
|
||||||
{
|
|
||||||
private $size;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
$sku,
|
|
||||||
$name,
|
|
||||||
$price,
|
|
||||||
$size,
|
|
||||||
$productId = null,
|
|
||||||
$variationId = null
|
|
||||||
) {
|
|
||||||
parent::__construct($sku, $name, $price, $productId, $variationId);
|
|
||||||
$this->size = $size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromRow($row) : self
|
|
||||||
{
|
|
||||||
return new DVD(
|
|
||||||
$row['sku'],
|
|
||||||
$row['name'],
|
|
||||||
$row['price'],
|
|
||||||
$row['size'],
|
|
||||||
$row['product_id'],
|
|
||||||
$row['variation_id']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSize()
|
|
||||||
{
|
|
||||||
return $this->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFormatedAttr()
|
|
||||||
{
|
|
||||||
$size = $this->getSize();
|
|
||||||
return "Size: $size MB";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getSelectAllQuery() : string
|
|
||||||
{
|
|
||||||
return 'SELECT '.PRODUCT.'.*, '.DVD.'.id as variation_id, size
|
|
||||||
FROM '.PRODUCT.' LEFT JOIN '.DVD.' ON '.PRODUCT.'.id = '.DVD.'.product_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function insert($conn = null) : int
|
|
||||||
{
|
|
||||||
if ($conn === null) {
|
|
||||||
$conn = Database::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getProductId() === null) {
|
|
||||||
parent::insert($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
$productId = $this->getProductId();
|
|
||||||
$size = $this->getSize();
|
|
||||||
|
|
||||||
$stmt = $conn->prepare("INSERT INTO ".DVD." (product_id, size) VALUES (?, ?);");
|
|
||||||
$stmt->bind_param('ii', $productId, $size);
|
|
||||||
|
|
||||||
if ($stmt->execute() === true) {
|
|
||||||
$this->setVariationId($conn->insert_id);
|
|
||||||
return $conn->insert_id;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unable to insert object");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace ProductList\Model;
|
|
||||||
|
|
||||||
define("PRODUCT", "product");
|
|
||||||
define("DVD", "dvd");
|
|
||||||
define("BOOK", "book");
|
|
||||||
define("FURNITURE", "furniture");
|
|
||||||
|
|
||||||
class Database
|
|
||||||
{
|
|
||||||
const SERVERNAME = "127.0.0.1";
|
|
||||||
const DATABASE = "scandiweb";
|
|
||||||
const USERNAME = "root";
|
|
||||||
const PASSWORD = "root";
|
|
||||||
|
|
||||||
public static function connect()
|
|
||||||
{
|
|
||||||
$conn = new \mysqli(self::SERVERNAME, self::USERNAME, self::PASSWORD);
|
|
||||||
$conn->select_db(self::DATABASE);
|
|
||||||
return $conn;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace ProductList\Model;
|
|
||||||
|
|
||||||
class Furniture extends Product
|
|
||||||
{
|
|
||||||
private $height;
|
|
||||||
private $width;
|
|
||||||
private $length;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
$SKU,
|
|
||||||
$name,
|
|
||||||
$price,
|
|
||||||
$height,
|
|
||||||
$width,
|
|
||||||
$length,
|
|
||||||
$productId = null,
|
|
||||||
$variationId = null
|
|
||||||
) {
|
|
||||||
parent::__construct($SKU, $name, $price, $productId, $variationId);
|
|
||||||
$this->height = $height;
|
|
||||||
$this->width = $width;
|
|
||||||
$this->length = $length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromRow($row) : self
|
|
||||||
{
|
|
||||||
return new Furniture(
|
|
||||||
$row['sku'],
|
|
||||||
$row['name'],
|
|
||||||
$row['price'],
|
|
||||||
$row['height'],
|
|
||||||
$row['width'],
|
|
||||||
$row['length'],
|
|
||||||
$row['product_id'],
|
|
||||||
$row['variation_id']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHeight()
|
|
||||||
{
|
|
||||||
return $this->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWidth()
|
|
||||||
{
|
|
||||||
return $this->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLength()
|
|
||||||
{
|
|
||||||
return $this->length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFormatedAttr()
|
|
||||||
{
|
|
||||||
$height = $this->getHeight();
|
|
||||||
$width = $this->getWidth();
|
|
||||||
$length = $this->getLength();
|
|
||||||
return 'Dimension: '.$height.'x'.$width.'x'.$length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getSelectAllQuery() : string
|
|
||||||
{
|
|
||||||
return 'SELECT '.PRODUCT.'.*, '.FURNITURE.'.id as variation_id, size
|
|
||||||
FROM '.PRODUCT.'
|
|
||||||
LEFT JOIN '.FURNITURE.' ON '.PRODUCT.'.id = '.FURNITURE.'.product_id';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function insert($conn = null) : int
|
|
||||||
{
|
|
||||||
if ($conn === null) {
|
|
||||||
$conn = Database::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getProductId() === null) {
|
|
||||||
parent::insert($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
$productId = $this->getProductId();
|
|
||||||
$height = $this->getHeight();
|
|
||||||
$width = $this->getWidth();
|
|
||||||
$length = $this->getLength();
|
|
||||||
|
|
||||||
$stmt = $conn->prepare(
|
|
||||||
"INSERT INTO ".FURNITURE." (product_id, height, width, length)
|
|
||||||
VALUES (?, ?, ?, ?);"
|
|
||||||
);
|
|
||||||
$stmt->bind_param('iddd', $productId, $height, $width, $length);
|
|
||||||
|
|
||||||
if ($stmt->execute() === true) {
|
|
||||||
$this->setVariationId($conn->insert_id);
|
|
||||||
return $conn->insert_id;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unable to insert object");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace ProductList\Model;
|
|
||||||
|
|
||||||
trait Model
|
|
||||||
{
|
|
||||||
abstract public static function fromRow($row) : self;
|
|
||||||
abstract public function insert($conn = null) : int; // should return id
|
|
||||||
abstract private static function getSelectAllQuery() : string;
|
|
||||||
|
|
||||||
public static function selectAll($conn = null) : array
|
|
||||||
{
|
|
||||||
if ($conn === null) {
|
|
||||||
$conn = Database::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = self::getSelectAllQuery();
|
|
||||||
|
|
||||||
$rows = $conn->query($sql)->fetch_all(MYSQLI_ASSOC);
|
|
||||||
|
|
||||||
$products = array();
|
|
||||||
foreach($rows as $row) {
|
|
||||||
array_push($products, self::fromRow($row));
|
|
||||||
}
|
|
||||||
return $products;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace ProductList\Model;
|
|
||||||
|
|
||||||
abstract class Product implements \JsonSerializable
|
|
||||||
{
|
|
||||||
use Model;
|
|
||||||
private $variationId;
|
|
||||||
private $SKU;
|
|
||||||
private $name;
|
|
||||||
private $price;
|
|
||||||
private $productId;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
$SKU,
|
|
||||||
$name,
|
|
||||||
$price,
|
|
||||||
$productId = null,
|
|
||||||
$variationId = null
|
|
||||||
) {
|
|
||||||
$this->productId = $productId;
|
|
||||||
$this->variationId = $variationId;
|
|
||||||
$this->SKU = $SKU;
|
|
||||||
$this->name = $name;
|
|
||||||
$this->price = $price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSKU()
|
|
||||||
{
|
|
||||||
return $this->SKU;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPrice()
|
|
||||||
{
|
|
||||||
return $this->price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProductId()
|
|
||||||
{
|
|
||||||
return $this->productId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setVariationId($id)
|
|
||||||
{
|
|
||||||
$this->variationId = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setProductId($id)
|
|
||||||
{
|
|
||||||
$this->productId = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public function getFormatedAttr();
|
|
||||||
|
|
||||||
public static function fromRow($row) : self
|
|
||||||
{
|
|
||||||
if ($row['size'] !== null) {
|
|
||||||
return DVD::fromRow($row);
|
|
||||||
} elseif ($row['weight'] !== null) {
|
|
||||||
return Book::fromRow($row);
|
|
||||||
} elseif ($row['height'] !== null) {
|
|
||||||
return Furniture::fromRow($row);
|
|
||||||
} else {
|
|
||||||
throw new Exception("Product without a type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getSelectAllQuery() : string
|
|
||||||
{
|
|
||||||
return 'SELECT '.PRODUCT.'.id as product_id,
|
|
||||||
COALESCE('.DVD.'.id, '.BOOK.'.id, '.FURNITURE.'.id) as variation_id,
|
|
||||||
name, sku, price, size, weight, width, height, length
|
|
||||||
FROM '.PRODUCT.'
|
|
||||||
LEFT JOIN '.DVD.' ON '.PRODUCT.'.id = '.DVD.'.product_id
|
|
||||||
LEFT JOIN '.BOOK.' ON '.PRODUCT.'.id = '.BOOK.'.product_id
|
|
||||||
LEFT JOIN '.FURNITURE.' ON '.PRODUCT.'.id = '.FURNITURE.'.product_id;';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function insert($conn = null) : int
|
|
||||||
{
|
|
||||||
if ($conn === null) {
|
|
||||||
$conn = Database::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
$SKU = $this->getSKU();
|
|
||||||
$name = $this->getName();
|
|
||||||
$price = $this->getPrice();
|
|
||||||
|
|
||||||
$stmt = $conn->prepare(
|
|
||||||
'INSERT INTO '.PRODUCT.' (sku, name, price)
|
|
||||||
VALUES (?, ?, ?);'
|
|
||||||
);
|
|
||||||
$stmt->bind_param('ssd', $SKU, $name, $price);
|
|
||||||
|
|
||||||
if ($stmt->execute() === true) {
|
|
||||||
$this->setProductId($conn->insert_id);
|
|
||||||
return $conn->insert_id;
|
|
||||||
} else {
|
|
||||||
throw new Exception("Unable to insert object");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function jsonSerialize() : mixed
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'id' => $this->getProductId(),
|
|
||||||
'sku' => $this->getSKU(),
|
|
||||||
'name' => $this->getName(),
|
|
||||||
'price' => $this->getPrice(),
|
|
||||||
'attribute' => $this->getFormatedAttr()
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?php
|
|
||||||
require '../../Autoload.php';
|
|
||||||
|
|
||||||
echo json_encode(ProductList\Model\Product::selectAll());
|
|
Loading…
Reference in New Issue