Validate forms
This commit is contained in:
parent
16b4d686e3
commit
6ce3d64649
|
@ -0,0 +1 @@
|
|||
.phan/
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
require 'autoload.php';
|
||||
ini_set('display_errors', true);
|
||||
ini_set('error_log', '/tmp/php.log');
|
||||
|
||||
use ProductList\Http\Request;
|
||||
use ProductList\Http\RequestHandler;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
namespace ProductList\Exception;
|
||||
|
||||
class DuplicateException extends \Exception {}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
namespace ProductList\Exception;
|
||||
|
||||
class InvalidFieldException extends \Exception
|
||||
{
|
||||
public function __construct($field, $code = 0, Throwable $previous = null)
|
||||
{
|
||||
http_response_code(400);
|
||||
parent::__construct("The field '$field' is invalid.", $code, $previous);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace ProductList\Model;
|
||||
|
||||
use ProductList\Exception\InvalidFieldException;
|
||||
|
||||
class Book extends Product
|
||||
{
|
||||
private $weight;
|
||||
|
@ -14,6 +16,11 @@ class Book extends Product
|
|||
$variationId = null
|
||||
) {
|
||||
parent::__construct($sku, $name, $price, $productId, $variationId);
|
||||
|
||||
if (empty($weight) || !is_numeric($weight)) {
|
||||
throw new InvalidFieldException('Weight');
|
||||
}
|
||||
|
||||
$this->weight = $weight;
|
||||
}
|
||||
|
||||
|
@ -24,8 +31,8 @@ class Book extends Product
|
|||
$row['name'],
|
||||
$row['price'],
|
||||
$row['weight'],
|
||||
$row['product_id'],
|
||||
$row['variation_id']
|
||||
$row['productId'],
|
||||
$row['variationId']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -42,8 +49,15 @@ class Book extends Product
|
|||
|
||||
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';
|
||||
return '
|
||||
SELECT
|
||||
'.PRODUCT.'.*,
|
||||
'.BOOK.'.id as variationId,
|
||||
weight
|
||||
FROM
|
||||
'.PRODUCT.'
|
||||
LEFT JOIN
|
||||
'.BOOK.' ON '.PRODUCT.'.id = '.BOOK.'.product_id';
|
||||
}
|
||||
|
||||
public function insert($conn = null) : int
|
||||
|
@ -81,7 +95,7 @@ class Book extends Product
|
|||
$stmt->bind_param('i', $variationId);
|
||||
|
||||
if ($stmt->execute() === false) {
|
||||
throw new \Exception("Unable to delete product with id '$id'");
|
||||
throw new \Exception("Unable to delete product with id '$variationId'");
|
||||
}
|
||||
|
||||
parent::delete($conn);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace ProductList\Model;
|
||||
|
||||
use ProductList\Exception\InvalidFieldException;
|
||||
|
||||
class DVD extends Product
|
||||
{
|
||||
private $size;
|
||||
|
@ -14,6 +16,11 @@ class DVD extends Product
|
|||
$variationId = null
|
||||
) {
|
||||
parent::__construct($sku, $name, $price, $productId, $variationId);
|
||||
|
||||
if (empty($size) || !is_numeric($size)) {
|
||||
throw new InvalidFieldException('Size');
|
||||
}
|
||||
|
||||
$this->size = $size;
|
||||
}
|
||||
|
||||
|
@ -24,8 +31,8 @@ class DVD extends Product
|
|||
$row['name'],
|
||||
$row['price'],
|
||||
$row['size'],
|
||||
$row['product_id'],
|
||||
$row['variation_id']
|
||||
$row['productId'],
|
||||
$row['variationId']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -42,8 +49,15 @@ class DVD extends Product
|
|||
|
||||
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';
|
||||
return '
|
||||
SELECT
|
||||
'.PRODUCT.'.*,
|
||||
'.DVD.'.id as variationId,
|
||||
size
|
||||
FROM
|
||||
'.PRODUCT.'
|
||||
LEFT JOIN
|
||||
'.DVD.' ON '.PRODUCT.'.id = '.DVD.'.product_id';
|
||||
}
|
||||
|
||||
public function insert($conn = null) : int
|
||||
|
@ -66,7 +80,7 @@ class DVD extends Product
|
|||
$this->setVariationId($conn->insert_id);
|
||||
return $conn->insert_id;
|
||||
} else {
|
||||
throw new Exception("Unable to insert object");
|
||||
throw new \Exception("Unable to insert object");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +95,7 @@ class DVD extends Product
|
|||
$stmt->bind_param('i', $variationId);
|
||||
|
||||
if ($stmt->execute() === false) {
|
||||
throw new \Exception("Unable to delete product with id '$id'");
|
||||
throw new \Exception("Unable to delete product with id '$variationId'");
|
||||
}
|
||||
|
||||
parent::delete($conn);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
namespace ProductList\Model;
|
||||
|
||||
use ProductList\Exception\InvalidFieldException;
|
||||
|
||||
class Furniture extends Product
|
||||
{
|
||||
private $height;
|
||||
|
@ -8,7 +10,7 @@ class Furniture extends Product
|
|||
private $length;
|
||||
|
||||
public function __construct(
|
||||
$SKU,
|
||||
$sku,
|
||||
$name,
|
||||
$price,
|
||||
$height,
|
||||
|
@ -17,7 +19,20 @@ class Furniture extends Product
|
|||
$productId = null,
|
||||
$variationId = null
|
||||
) {
|
||||
parent::__construct($SKU, $name, $price, $productId, $variationId);
|
||||
parent::__construct($sku, $name, $price, $productId, $variationId);
|
||||
|
||||
if (empty($height) || !is_numeric($height)) {
|
||||
throw new InvalidFieldException('Height');
|
||||
}
|
||||
|
||||
if (empty($width) || !is_numeric($width)) {
|
||||
throw new InvalidFieldException('Width');
|
||||
}
|
||||
|
||||
if (empty($length) || !is_numeric($length)) {
|
||||
throw new InvalidFieldException('Length');
|
||||
}
|
||||
|
||||
$this->height = $height;
|
||||
$this->width = $width;
|
||||
$this->length = $length;
|
||||
|
@ -32,8 +47,8 @@ class Furniture extends Product
|
|||
$row['height'],
|
||||
$row['width'],
|
||||
$row['length'],
|
||||
$row['product_id'],
|
||||
$row['variation_id']
|
||||
$row['productId'],
|
||||
$row['variationId']
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -62,9 +77,17 @@ class Furniture extends Product
|
|||
|
||||
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';
|
||||
return '
|
||||
SELECT
|
||||
'.PRODUCT.'.*,
|
||||
'.FURNITURE.'.id as variationId,
|
||||
height,
|
||||
width,
|
||||
length
|
||||
FROM
|
||||
'.PRODUCT.'
|
||||
LEFT JOIN '.FURNITURE.' ON
|
||||
'.PRODUCT.'.id = '.FURNITURE.'.product_id';
|
||||
}
|
||||
|
||||
public function insert($conn = null) : int
|
||||
|
@ -107,7 +130,7 @@ class Furniture extends Product
|
|||
$stmt->bind_param('i', $variationId);
|
||||
|
||||
if ($stmt->execute() === false) {
|
||||
throw new \Exception("Unable to delete product with id '$id'");
|
||||
throw new \Exception("Unable to delete product with id '$variationId'");
|
||||
}
|
||||
|
||||
parent::delete($conn);
|
||||
|
|
|
@ -2,33 +2,49 @@
|
|||
namespace ProductList\Model;
|
||||
|
||||
use ProductList\Exception\NotFoundException;
|
||||
use ProductList\Exception\InvalidFieldException;
|
||||
use ProductList\Exception\DuplicateException;
|
||||
|
||||
abstract class Product implements \JsonSerializable
|
||||
{
|
||||
use Model;
|
||||
private $variationId;
|
||||
private $SKU;
|
||||
private $sku;
|
||||
private $name;
|
||||
private $price;
|
||||
private $productId;
|
||||
|
||||
public function __construct(
|
||||
$SKU,
|
||||
$sku,
|
||||
$name,
|
||||
$price,
|
||||
$productId = null,
|
||||
$variationId = null
|
||||
) {
|
||||
if (empty($sku)) {
|
||||
throw new InvalidFieldException('SKU');
|
||||
}
|
||||
|
||||
if (empty($name)) {
|
||||
throw new InvalidFieldException('Name');
|
||||
}
|
||||
|
||||
if (empty($price) || !is_numeric($price)) {
|
||||
throw new InvalidFieldException('Price');
|
||||
}
|
||||
|
||||
$this->productId = $productId;
|
||||
$this->variationId = $variationId;
|
||||
$this->SKU = $SKU;
|
||||
|
||||
|
||||
$this->sku = $sku;
|
||||
$this->name = $name;
|
||||
$this->price = $price;
|
||||
}
|
||||
|
||||
public function getSKU()
|
||||
{
|
||||
return $this->SKU;
|
||||
return $this->sku;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
|
@ -74,7 +90,7 @@ abstract class Product implements \JsonSerializable
|
|||
$stmt->bind_param('i', $productId);
|
||||
|
||||
if ($stmt->execute() === false) {
|
||||
throw new \Exception("Unable to delete product with id '$id'");
|
||||
throw new \Exception("Unable to delete product with id '$productId'");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,26 +118,45 @@ abstract class Product implements \JsonSerializable
|
|||
|
||||
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");
|
||||
switch ($row['productType']) {
|
||||
case 'dvd':
|
||||
return DVD::fromRow($row);
|
||||
case 'book':
|
||||
return Book::fromRow($row);
|
||||
case 'furniture':
|
||||
return Furniture::fromRow($row);
|
||||
default:
|
||||
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';
|
||||
return '
|
||||
SELECT
|
||||
'.PRODUCT.'.id as productId,
|
||||
name,
|
||||
sku,
|
||||
price,
|
||||
size,
|
||||
weight,
|
||||
width,
|
||||
height,
|
||||
length,
|
||||
COALESCE('.DVD.'.id, '.BOOK.'.id, '.FURNITURE.'.id) as variationId,
|
||||
CASE
|
||||
WHEN '.DVD.'.id IS NOT NULL THEN "dvd"
|
||||
WHEN '.BOOK.'.id IS NOT NULL THEN "book"
|
||||
WHEN '.FURNITURE.'.id IS NOT NULL THEN "furniture"
|
||||
END as productType
|
||||
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
|
||||
|
@ -140,11 +175,19 @@ abstract class Product implements \JsonSerializable
|
|||
);
|
||||
$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");
|
||||
try {
|
||||
if ($stmt->execute() === true) {
|
||||
$this->setProductId($conn->insert_id);
|
||||
return $conn->insert_id;
|
||||
} else {
|
||||
throw new \Exception("Unable to insert object");
|
||||
}
|
||||
} catch (\mysqli_sql_exception $e) {
|
||||
if ($e->getCode() === 1062) {
|
||||
throw new DuplicateException('The provided SKU is already registered.');
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,6 @@ namespace ProductList\View;
|
|||
|
||||
use ProductList\Http\Request;
|
||||
use ProductList\Model\Product as ProductModel;
|
||||
use ProductList\Model\DVD;
|
||||
use ProductList\Model\Furniture;
|
||||
use ProductList\Model\Book;
|
||||
use ProductList\Exception\NotFoundException;
|
||||
|
||||
class Product extends View
|
||||
|
@ -38,7 +35,7 @@ class Product extends View
|
|||
|
||||
} catch (NotFoundException $e) {
|
||||
http_response_code(404);
|
||||
echo $e->getMessage();
|
||||
echo "The selected(s) object(s) is(are) not available anymore.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -63,55 +60,12 @@ class Product extends View
|
|||
'length'
|
||||
];
|
||||
if (self::expectArgs($expected, $params)) {
|
||||
$product = null;
|
||||
$type = $params['productType'];
|
||||
$params['productId'] = null;
|
||||
$params['variationId'] = null;
|
||||
|
||||
switch($type) {
|
||||
case 'dvd':
|
||||
$product = new DVD(
|
||||
$params['sku'],
|
||||
$params['name'],
|
||||
$params['price'],
|
||||
$params['size'],
|
||||
);
|
||||
break;
|
||||
case 'furniture':
|
||||
$product = new Furniture(
|
||||
$params['sku'],
|
||||
$params['name'],
|
||||
$params['price'],
|
||||
$params['height'],
|
||||
$params['width'],
|
||||
$params['length'],
|
||||
);
|
||||
break;
|
||||
case 'book':
|
||||
$product = new Book(
|
||||
$params['sku'],
|
||||
$params['name'],
|
||||
$params['price'],
|
||||
$params['weight'],
|
||||
);
|
||||
break;
|
||||
default:
|
||||
http_response_code(400);
|
||||
echo "Invalid 'productType' value '$type'";
|
||||
return;
|
||||
}
|
||||
$product = ProductModel::fromRow($params);
|
||||
|
||||
//try {
|
||||
$product->insert();
|
||||
//} catch (\Exception $e) {
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
public static function test(Request $request)
|
||||
{
|
||||
$params= $request->getQueryParams();
|
||||
if (self::expectArgs(['testarg'], $params)) {
|
||||
echo var_dump($params);
|
||||
$product->insert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,16 @@ $('#delete-product-btn').on('click', () => {
|
|||
const checkboxes = document.querySelectorAll('input[class="delete-checkbox"]:checked');
|
||||
checkboxes.forEach(checkbox => values.push(checkbox.value));
|
||||
|
||||
$.ajax(
|
||||
`product?id=${values.join(',')}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
success: loadItems,
|
||||
error: jqXHR => alert(jqXHR.responseText),
|
||||
}
|
||||
)
|
||||
if(values.length) {
|
||||
$.ajax(
|
||||
`product?id=${values.join(',')}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
success: loadItems,
|
||||
error: jqXHR => alert(jqXHR.responseText),
|
||||
}
|
||||
)
|
||||
} else {
|
||||
alert('Please select a product.');
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue