Web app of an e-commerce website, with user registation, login, admin, products and orders management.
Note: this repo is meant as a school project and its not meant to be used in any production environment.
- Backend
- Frontend
- Database
The project integrates a docker enviroment. To launch it enter:
docker-compose -f "docker-compose.yml" up --build
⚠️ The first time the containers are started you should wait a few minutes to let mariadb initialize the database.
this time grows with the number of .sql data to import (due to the auto-import functionality)
If you wish to reset (drop) the database launch this script (it should also be valid for linux):
.\rebuilddb.ps1
Available services in the container:
- Vue.js server:
localhost:8080
- phpMyAdmin:
pma.localhost:8080
- traefik dashboard:
localhost:8001
At the start of every PHP file should import Bootstrap.php
:
require_once __DIR__ . '/../lib/Bootstrap.php';
This will automatically set-up production/debug mode and import 'Database.php'.
To connect to the db there is already a PDO connection established in 'Database.php' so everything you need to do is get the PDO:
Database::$pdo;
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
Must be one of the following:
- build: Changes that affect the build system or external dependencies
- docs: Documentation only changes
- feat: A new feature
- impr: Improved some functionalities/files/logic
- fix: A bug fix
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- wip: Work in process
Optional, can be one of the following:
- vue: Changes to the frontend
- php: Changes to the backend (php)
- sql: Changes to the database
- readme: Changes to the readme file
- docker: Changes to docker configs
conventionalcommits.org - angular specs
Table name: snake_case, singular, lowercase (es. product_image). --- Column name: snake_case, lowercase (es. postal_code).
Always define foreign and primary keys as CONSTRAINT Costraints conventions:
CONSTRAINT `this_table_fk_referenced_table` FOREIGN KEY(column) REFERENCES [...];
CONSTRAINT `this_table_pk` PRIMARY KEY(columns);
CONSTRAINT `this_table_unique` UNIQUE(columns); # You can also use `column_name_unique`
Every .php file should have the first letter capitalized.
Every file should be capitalized. Views and components should go in the folder with the same name (/views and /components). Every component name should be prefixed with the letter 'E' (es. EFooter.vue).
Returns the list of all the categories
[
{ "id": 1, "name": "TV" },
{ "id": 2, "name": "Smartphone" },
{ "id": 3, "name": "Phon" }
// An object for every category
]
- HTTP 200: successful
Adds a new category, if the user is logged AND is an admin
{
"name": "My New Category" // Name of the new category
}
-
HTTP 200: successful
-
HTTP 400: General error
-
HTTP 403: Forbidden (not logged/not admin)
Renames one category, if the user is logged AND is an admin
{
"id": 3, // Category id to rename
"name": "My New Category" // New name of the new category
}
-
HTTP 200: successful
-
HTTP 404: Category not found
-
HTTP 403: Forbidden (not logged/not admin)
?id=[categoryID]
Deletes a category, the user must be admin
-
HTTP 200: successful
-
HTTP 404: Category not found
-
HTTP 403: Forbidden (not logged/not admin)
Same methods, requests and response messages as categories.php
. See above for details.
no query
{
"logged": true, // if the user is logged
"isAdmin": false // if the user is Admin
}
- HTTP 200: successful
login.php?logout
- HTTP 200: successful
{
"email": "[email protected]",
"password": "myPassword"
}
-
HTTP 200: successful
-
HTTP 403: error
no query
{
"name": "Pippo",
"surname": "Baudo",
"email": "[email protected]",
"phoneNumber": "1231231230"
}
-
HTTP 200: successful
-
HTTP 403: error (Not logged)
user.php?all
Returns all the users.
[
{
"name": "Pippo",
"surname": "Baudo",
"email": "[email protected]",
"phoneNumber": "1231231230"
},
...
]
-
HTTP 200: successful
-
HTTP 403: error (Not logged as admin)
{
"name": "Pippo",
"surname": "Baudo",
"email": "[email protected]",
"phoneNumber": "1231231230", // Can be of 9 or 10 chars
"password": "myPassword"
}
-
HTTP 200: successful
-
HTTP 400: general error (Bad Request)
// Example: in case of a registration with an email already in use by someone
{ "error": "E-mail already in use." }
{
"name": "Pippo",
"surname": "Baudo",
"email": "[email protected]"
}
-
HTTP 200: successful
-
HTTP 400: general error
-
HTTP 403: error (Not logged)
// Example in case of a patch with an email already taken
{ "error": "E-mail already in use." }
Same as products.php GET
, but with the field "selectedQuantity"that represents the quantity of the product into the cart
-
HTTP 200: successful
-
HTTP 403: error (Not logged)
{
"id": 4, // Product id
"quantity": 3
}
-
HTTP 200: successful
-
HTTP 400: general error (example: quantity not available)
-
HTTP 403: error (Not logged)
{
"id": 4, // Product id
"quantity": 5
}
-
HTTP 200: successful
-
HTTP 400: general error (example: quantity not available)
-
HTTP 403: error (Not logged)
?cart&id=[productId]
-
HTTP 200: successful (product removed from cart (or it already wasn't there))
-
HTTP 403: error (Not logged)
[
{
"id": 13, // Address id
"cityName": "Firenze", // City name
"city": 234, // City id
"street": "Via dei Polli",
"houseNumber": 123,
"postalCode": 54100,
"phoneNumber": "123123123" // Phone number associated with that address
},
{
"id": 123, // Address id
"cityName": "Novara", // City name
"city": 123, // City id
"street": "Via delle galline",
"houseNumber": 321,
"postalCode": 21300,
"phoneNumber": "456456456" // Phone number associated with that address
}
]
-
HTTP 200: successful
-
HTTP 403: error (Not Logged)
{
"city": 234, // City id
"street": "Via dei Polli",
"houseNumber": 123,
"postalCode": 54100,
"phoneNumber": "123123123" // Phone number associated with that address
}
-
HTTP 200: successful
-
HTTP 400: general error (Bad Request)
?id=[address-id]
-
HTTP 200: successful
-
HTTP 403: error (Not Logged)
{
"id": 123,
"street": "Via dei pollai",
"houseNumber": 123
}
-
HTTP 200: successful
-
HTTP 400: general error (Bad Request)
-
HTTP 403: error (Not logged)
{
"id": 4, // User id
"isAdmin": true // An admin can toggle the user status between admin/not admin
}
-
HTTP 200: successful
-
HTTP 403: forbidden (ex. current user not admin)
Get the list of products bases on a filter
- by title
?q=
- by category
?c=
- by brand
?b=
- by price range
?ps=x&pe=x
(price start and/or price end)
Order by:
- order by price
?sort=price
- order by title
?sort=title
- order by sales
?sales
(best sellers / worst sellers) - Order ASC or DESC
?asc
or?desc
Pagination:
-
?p=
(Example ?p=0 page one, it will show an arbitrary amount of products per page) -
Single product:
?id=
(Seeproducts.php?id=
below for details)
- HTTP 200: successful
Response format:
{
"totalResults": 123,
"productsPerPage": 16,
"data": [
{
"id": 2,
"title": "My product",
"description": "...",
"images": ["...",...],
"sell_price": 43.21, // ONLY sell_price
"quantity": 23, // Products availability
"category_id": 1,
"category": "Smartphone",
"brand_id": 2,
"brand": "Samsung"
},
{
// One object for each product
}
]
}
products.php?id=[productId] GET
- HTTP 200: successful
(similar to products.php GET
)
{
"id": 2,
"title": "My product",
"description": "...",
"images": [
// list to all the images of a product
"my/image/url1",
"my/image/url2",
"my/image/url3"
],
"sell_price": 43.21, // ONLY sell_price
"quantity": 23, // Products availability
"category_id": 1,
"category": "Smartphone",
"brand_id": 2,
"brand": "Samsung"
}
{
"title": "My product",
"description": "...",
"purchase_price": 43.21,
"sell_price": 55.99,
"recommended_price": 50.0,
"quantity": 23, // Products availability
"category_id": 1,
"brand_id": 2
}
-
HTTP 200: successful (User is logged and is admin)
-
HTTP 403: error (Not logged)
products.php?id=[productId]
Deletes a product and its images from the database
-
HTTP 200: successful (User is logged and is admin)
-
HTTP 403: error (Not logged)
products.php?id=[productId] PATCH
Patch data of selected product. You can send only the desired changed values with the same format as in POST requests.
-
HTTP 200: successful (User is logged and is admin)
-
HTTP 403: error (Not logged)
products.php?image&id=[productId]
// TODO: Define how to send images to the server and store them
-
HTTP 200: successful (User is logged and is admin)
-
HTTP 403: error (Not logged)
products.php?image&id=[productId]
Deletes an image from the server
-
HTTP 200: successful (User is logged and is admin)
-
HTTP 403: error (Not logged)
address.php?regions
Returns an array with all the regions of Italy
[
{
"id": 2,
"name": "Toscana"
},
{
"id": 3,
"name": "Emilia Romagna"
},
{
// ... other regions
}
]
address.php?regions?id=[region-id]
{
"id": 2,
"name": "Toscana"
}
address.php?provinces
[
{
"id": 2,
"name": "Firenze",
"region": 12
},
{
"id": 3,
"name": "Bologna",
"region": 13
},
{
// ... other provinces
}
]
address.php?provinces?region=[region-id]
[
{
"id": 2,
"name": "Firenze"
},
{
"id": 3,
"name": "Prato"
},
{
// ... other provinces of that region
}
]
address.php?provinces?id=[province-id]
{
"id": 2,
"name": "Firenze",
"region": 3 // Province's region id
}
address.php?cities
[
{
"id": 2,
"name": "Firenze",
"province": 6
},
{
"id": 3,
"name": "Arezzo",
"province": 9
},
{
// ... other cities of Italy
}
]
address.php?cities?province=[province-id]
[
{
"id": 2,
"name": "Firenze"
},
{
"id": 3,
"name": "Scandicci"
},
{
// ... other provinces of that region
}
]
address.php?cities?id=[city-id]
{
"id": 2,
"name": "Scandicci",
"province": 3 // City's province id
}
[
// orders array
{
"id": 3,
"date": "2020-03-13", // time of the order (timestamp)
"hour": "14:12:54",
"address": "Via di Pippo, 13 (FI)",
"phoneNumber": 123123123,
"shippingCost": 12.3,
"products": [
// Array of products
{
"productId": 3,
"productTitle": "My product",
"quantity": 7,
"price": 33.2,
"brandName": "Samsung"
},
{
// Every object is a product
}
],
"status": "Spedito"
},
{
// Every object is an order
}
]
-
HTTP 200: successful
-
HTTP 403: error (Not logged)
orders.php?admin
[
// Orders array
{
// Every object is an order
// The order has the same format as orders.php GET, but every order also has the references to the user
// ... order data (= to orders.php GET)
// user data
"user": {
"user_id": 33,
"name": "Pippo",
"surname": "Baudo",
"email": "[email protected]"
}
},
{
// ...
}
]
orders.php?purchase
{
"address": 7 // id of the user's address
}
-
HTTP 200: successful
-
HTTP 400: general error
-
HTTP 403: Forbidden (Not logged)