diff --git a/.gitignore b/.gitignore
index c583050..3836c57 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@ settings.php
nbproject/private
database.mwb.bak
*.sync-conflict*
+images/
+!images/.htaccess
\ No newline at end of file
diff --git a/action.php b/action.php
index 76636bd..72f6b23 100644
--- a/action.php
+++ b/action.php
@@ -229,6 +229,129 @@ switch ($VARS['action']) {
exit("[]");
}
break;
+ case "imageupload":
+ $destpath = FILE_UPLOAD_PATH;
+ if (!is_writable($destpath)) {
+ returnToSender("unwritable_folder", "&id=$VARS[itemid]");
+ }
+
+ if (empty($VARS['itemid']) || !$database->has('items', ['itemid' => $VARS['itemid']])) {
+ returnToSender("invalid_itemid", "&id=$VARS[itemid]");
+ }
+
+ $files = [];
+ foreach ($_FILES['files'] as $key => $all) {
+ foreach ($all as $i => $val) {
+ $files[$i][$key] = $val;
+ }
+ }
+
+ $errors = [];
+ foreach ($files as $f) {
+ if ($f['error'] !== UPLOAD_ERR_OK) {
+ $err = "could not be uploaded.";
+ switch ($f['error']) {
+ case UPLOAD_ERR_INI_SIZE:
+ case UPLOAD_ERR_FORM_SIZE:
+ $err = "is too big.";
+ break;
+ case UPLOAD_ERR_CANT_WRITE:
+ $err = "could not be saved to disk.";
+ break;
+ case UPLOAD_ERR_NO_FILE:
+ $err = "was not actually sent.";
+ break;
+ case UPLOAD_ERR_PARTIAL:
+ $err = "was only partially sent.";
+ break;
+ default:
+ $err = "could not be uploaded.";
+ }
+ $errors[] = htmlspecialchars($f['name']) . " $err";
+ continue;
+ }
+
+ if (filesize($f['tmp_name']) > 11) {
+ $imagetype = exif_imagetype($f['tmp_name']);
+ } else {
+ $imagetype = false;
+ }
+
+ switch ($imagetype) {
+ case IMAGETYPE_JPEG:
+ case IMAGETYPE_GIF:
+ case IMAGETYPE_PNG:
+ case IMAGETYPE_WEBP:
+ $imagevalid = true;
+ break;
+ default:
+ $imagevalid = false;
+ }
+
+ if (!$imagevalid) {
+ $errors[] = htmlspecialchars($f['name']) . " is not a supported image type (JPEG, GIF, PNG, WEBP).";
+ continue;
+ }
+
+ $filename = basename($f['name']);
+ $filename = preg_replace("/[^a-z0-9\._\-]/", "_", strtolower($filename));
+ $n = 1;
+ if (file_exists($destpath . "/" . $filename)) {
+ while (file_exists($destpath . '/' . $n . '_' . $filename)) {
+ $n++;
+ }
+ $filename = $n . '_' . $filename;
+ }
+
+ $finalpath = $destpath . "/" . $filename;
+
+ if (move_uploaded_file($f['tmp_name'], $finalpath)) {
+ $primary = false;
+ if (!$database->has('images', ['AND' => ['itemid' => $VARS['itemid'], 'primary' => true]])) {
+ $primary = true;
+ }
+ $database->insert('images', ['itemid' => $VARS['itemid'], 'imagename' => $filename, 'primary' => $primary]);
+ } else {
+ $errors[] = htmlspecialchars($f['name']) . " could not be uploaded.";
+ }
+ }
+
+ if (count($errors) > 0) {
+ returnToSender("upload_warning", implode("
", $errors) . "&id=$VARS[itemid]");
+ }
+ returnToSender("upload_success", "&id=$VARS[itemid]");
+ break;
+ case "promoteimage":
+ if (empty($VARS['itemid']) || !$database->has('items', ['itemid' => $VARS['itemid']])) {
+ returnToSender("invalid_itemid", "&id=$VARS[itemid]");
+ }
+ if (empty($VARS['imageid']) || !$database->has('images', ['AND' => ['itemid' => $VARS['itemid'], 'imageid' => $VARS['imageid']]])) {
+ returnToSender("invalid_imageid", "&id=$VARS[itemid]");
+ }
+
+ $database->update('images', ['primary' => false], ['itemid' => $VARS['itemid']]);
+ $database->update('images', ['primary' => true], ['AND' => ['itemid' => $VARS['itemid'], 'imageid' => $VARS['imageid']]]);
+ returnToSender("image_promoted", "&id=$VARS[itemid]");
+ break;
+ case "deleteimage":
+ if (empty($VARS['itemid']) || !$database->has('items', ['itemid' => $VARS['itemid']])) {
+ returnToSender("invalid_itemid", "&id=$VARS[itemid]");
+ }
+ if (empty($VARS['imageid']) || !$database->has('images', ['AND' => ['itemid' => $VARS['itemid'], 'imageid' => $VARS['imageid']]])) {
+ returnToSender("invalid_imageid", "&id=$VARS[itemid]");
+ }
+
+ $imagename = $database->get('images', 'imagename', ['imageid' => $VARS['imageid']]);
+ if ($database->count('images', ['imagename' => $imagename]) <= 1) {
+ unlink(FILE_UPLOAD_PATH . "/" . $imagename);
+ }
+ $database->delete('images', ['AND' => ['itemid' => $VARS['itemid'], 'imageid' => $VARS['imageid']]]);
+
+ if (!$database->has('images', ['AND' => ['itemid' => $VARS['itemid'], 'primary' => true]])) {
+ $database->update('images', ['primary' => true], ['itemid' => $VARS['itemid'], 'LIMIT' => 1]);
+ }
+
+ returnToSender("image_deleted", "&id=$VARS[itemid]");
case "signout":
session_destroy();
header('Location: index.php');
diff --git a/composer.lock b/composer.lock
index d07df16..cb6b6d1 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,6 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "831ae7560f5a64a68c52c69b772a8fc5",
"content-hash": "a7d5f4f0d86fc84b983b1a3095ba3288",
"packages": [
{
@@ -64,7 +63,7 @@
"sql",
"sqlite"
],
- "time": "2018-06-14 18:59:08"
+ "time": "2018-06-14T18:59:08+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -129,7 +128,7 @@
"rest",
"web service"
],
- "time": "2018-04-22 15:46:56"
+ "time": "2018-04-22T15:46:56+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -180,7 +179,7 @@
"keywords": [
"promise"
],
- "time": "2016-12-20 10:07:11"
+ "time": "2016-12-20T10:07:11+00:00"
},
{
"name": "guzzlehttp/psr7",
@@ -245,7 +244,7 @@
"uri",
"url"
],
- "time": "2017-03-20 17:10:46"
+ "time": "2017-03-20T17:10:46+00:00"
},
{
"name": "lapinator/ods-php-generator",
@@ -288,7 +287,7 @@
"LibreOffice",
"ods"
],
- "time": "2016-04-14 21:51:27"
+ "time": "2016-04-14T21:51:27+00:00"
},
{
"name": "league/csv",
@@ -355,7 +354,7 @@
"read",
"write"
],
- "time": "2018-05-01 18:32:48"
+ "time": "2018-05-01T18:32:48+00:00"
},
{
"name": "psr/http-message",
@@ -405,7 +404,7 @@
"request",
"response"
],
- "time": "2016-08-06 14:39:51"
+ "time": "2016-08-06T14:39:51+00:00"
}
],
"packages-dev": [],
diff --git a/database.mwb b/database.mwb
index de28faa..5808d6d 100644
Binary files a/database.mwb and b/database.mwb differ
diff --git a/database.sql b/database.sql
index b4bf013..5cac0af 100644
--- a/database.sql
+++ b/database.sql
@@ -1,5 +1,5 @@
-- MySQL Script generated by MySQL Workbench
--- Tue 26 Dec 2017 04:44:44 PM MST
+-- Sat 22 Sep 2018 02:40:11 AM MDT
-- Model: New Model Version: 1.0
-- MySQL Workbench Forward Engineering
@@ -12,15 +12,9 @@ SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
-- -----------------------------------------------------
-- -----------------------------------------------------
--- Schema inventory
--- -----------------------------------------------------
-CREATE SCHEMA IF NOT EXISTS `inventory` DEFAULT CHARACTER SET utf8 ;
-USE `inventory` ;
-
+-- Table `categories`
-- -----------------------------------------------------
--- Table `inventory`.`categories`
--- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `inventory`.`categories` (
+CREATE TABLE IF NOT EXISTS `categories` (
`catid` INT NOT NULL AUTO_INCREMENT,
`catname` VARCHAR(45) NOT NULL,
PRIMARY KEY (`catid`),
@@ -29,9 +23,9 @@ ENGINE = InnoDB;
-- -----------------------------------------------------
--- Table `inventory`.`locations`
+-- Table `locations`
-- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `inventory`.`locations` (
+CREATE TABLE IF NOT EXISTS `locations` (
`locid` INT NOT NULL AUTO_INCREMENT,
`locname` VARCHAR(100) NOT NULL,
`loccode` VARCHAR(45) NOT NULL,
@@ -42,9 +36,9 @@ ENGINE = InnoDB;
-- -----------------------------------------------------
--- Table `inventory`.`items`
+-- Table `items`
-- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `inventory`.`items` (
+CREATE TABLE IF NOT EXISTS `items` (
`itemid` INT NOT NULL AUTO_INCREMENT,
`catid` INT NOT NULL,
`locid` INT NOT NULL,
@@ -57,27 +51,29 @@ CREATE TABLE IF NOT EXISTS `inventory`.`items` (
`qty` INT NOT NULL DEFAULT 1,
`want` INT NOT NULL DEFAULT 0,
`userid` INT NULL,
- PRIMARY KEY (`itemid`, `catid`, `locid`),
+ `cost` DECIMAL(10,2) NULL,
+ `price` DECIMAL(10,2) NULL,
+ PRIMARY KEY (`itemid`),
INDEX `fk_items_categories_idx` (`catid` ASC),
INDEX `fk_items_locations1_idx` (`locid` ASC),
UNIQUE INDEX `itemid_UNIQUE` (`itemid` ASC),
CONSTRAINT `fk_items_categories`
FOREIGN KEY (`catid`)
- REFERENCES `inventory`.`categories` (`catid`)
+ REFERENCES `categories` (`catid`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_items_locations1`
FOREIGN KEY (`locid`)
- REFERENCES `inventory`.`locations` (`locid`)
+ REFERENCES `locations` (`locid`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
--- Table `inventory`.`labels`
+-- Table `labels`
-- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `inventory`.`labels` (
+CREATE TABLE IF NOT EXISTS `labels` (
`rowid` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`value` VARCHAR(100) NOT NULL,
@@ -86,9 +82,9 @@ ENGINE = InnoDB;
-- -----------------------------------------------------
--- Table `inventory`.`permissions`
+-- Table `permissions`
-- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `inventory`.`permissions` (
+CREATE TABLE IF NOT EXISTS `permissions` (
`userid` INT NOT NULL,
`itemid` INT NOT NULL,
`canedit` TINYINT(1) NOT NULL DEFAULT 0,
@@ -96,16 +92,16 @@ CREATE TABLE IF NOT EXISTS `inventory`.`permissions` (
INDEX `fk_permissions_items1_idx` (`itemid` ASC),
CONSTRAINT `fk_permissions_items1`
FOREIGN KEY (`itemid`)
- REFERENCES `inventory`.`items` (`itemid`)
+ REFERENCES `items` (`itemid`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
--- Table `inventory`.`report_access_codes`
+-- Table `report_access_codes`
-- -----------------------------------------------------
-CREATE TABLE IF NOT EXISTS `inventory`.`report_access_codes` (
+CREATE TABLE IF NOT EXISTS `report_access_codes` (
`id` INT NOT NULL AUTO_INCREMENT,
`code` VARCHAR(45) NULL,
`expires` DATETIME NULL,
@@ -114,6 +110,42 @@ CREATE TABLE IF NOT EXISTS `inventory`.`report_access_codes` (
ENGINE = InnoDB;
+-- -----------------------------------------------------
+-- Table `images`
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS `images` (
+ `imageid` INT NOT NULL AUTO_INCREMENT,
+ `itemid` INT NOT NULL,
+ `imagename` VARCHAR(255) NOT NULL,
+ `primary` TINYINT(1) NOT NULL DEFAULT 0,
+ PRIMARY KEY (`imageid`, `itemid`),
+ UNIQUE INDEX `imageid_UNIQUE` (`imageid` ASC),
+ INDEX `fk_images_items1_idx` (`itemid` ASC),
+ CONSTRAINT `fk_images_items1`
+ FOREIGN KEY (`itemid`)
+ REFERENCES `items` (`itemid`)
+ ON DELETE NO ACTION
+ ON UPDATE NO ACTION)
+ENGINE = InnoDB;
+
+
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
+
+-- -----------------------------------------------------
+-- Data for table `labels`
+-- -----------------------------------------------------
+START TRANSACTION;
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (1, 'itemid', 'Item ID');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (2, 'catid', 'Category ID');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (3, 'itemname', 'Item Name');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (4, 'itemnumber1', 'Number Value 1');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (5, 'itemnumber2', 'Number Value 2');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (6, 'itemtext1', 'Text Value 1');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (7, 'itemtext2', 'Text Value 2');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (8, 'itemtext3', 'Text Value 3');
+INSERT INTO `labels` (`rowid`, `name`, `value`) VALUES (9, 'catname', 'Category Name');
+
+COMMIT;
+
diff --git a/database_upgrade/v1.1_1.2.sql b/database_upgrade/v1.1_1.2.sql
index dddaad0..6e9f631 100644
--- a/database_upgrade/v1.1_1.2.sql
+++ b/database_upgrade/v1.1_1.2.sql
@@ -5,12 +5,18 @@
*/
ALTER TABLE `items`
ADD COLUMN `cost` DECIMAL(10,2) NULL DEFAULT NULL AFTER `userid`,
-ADD COLUMN `price` DECIMAL(10,2) NULL DEFAULT NULL AFTER `cost`;
+ADD COLUMN `price` DECIMAL(10,2) NULL DEFAULT NULL AFTER `cost`;\
+
+ALTER TABLE `items`
+DROP PRIMARY KEY,
+ADD PRIMARY KEY (`itemid`);
+
CREATE TABLE IF NOT EXISTS `images` (
`imageid` INT(11) NOT NULL AUTO_INCREMENT,
`itemid` INT(11) NOT NULL,
`imagename` VARCHAR(255) NOT NULL,
+ `primary` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`imageid`, `itemid`),
UNIQUE INDEX `imageid_UNIQUE` (`imageid` ASC),
INDEX `fk_images_items1_idx` (`itemid` ASC),
@@ -20,4 +26,4 @@ CREATE TABLE IF NOT EXISTS `images` (
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
-DEFAULT CHARACTER SET = utf8
+DEFAULT CHARACTER SET = utf8
\ No newline at end of file
diff --git a/image.php b/image.php
new file mode 100644
index 0000000..dc2341d
--- /dev/null
+++ b/image.php
@@ -0,0 +1,62 @@
+ 11) {
+ $imagetype = exif_imagetype($filepath);
+} else {
+ $imagetype = false;
+}
+
+switch ($imagetype) {
+ case IMAGETYPE_JPEG:
+ $mimetype = "image/jpeg";
+ break;
+ case IMAGETYPE_GIF:
+ $mimetype = "image/gif";
+ break;
+ case IMAGETYPE_PNG:
+ $mimetype = "image/png";
+ break;
+ case IMAGETYPE_WEBP:
+ $mimetype = "image/webp";
+ break;
+ default:
+ $mimetype = "application/octet-stream";
+}
+
+header("Content-Type: $mimetype");
+header('Content-Length: ' . filesize($filepath));
+header("X-Content-Type-Options: nosniff");
+$seconds_to_cache = 60 * 60 * 12; // 12 hours
+$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
+header("Expires: $ts");
+header("Pragma: cache");
+header("Cache-Control: max-age=$seconds_to_cache");
+
+ob_end_flush();
+
+readfile($filepath);
diff --git a/images/.htaccess b/images/.htaccess
new file mode 100755
index 0000000..14249c5
--- /dev/null
+++ b/images/.htaccess
@@ -0,0 +1 @@
+Deny from all
\ No newline at end of file
diff --git a/langs/en/images.json b/langs/en/images.json
new file mode 100644
index 0000000..bb9a405
--- /dev/null
+++ b/langs/en/images.json
@@ -0,0 +1,10 @@
+{
+ "Editing images for item": "Editing images for {item}",
+ "Edit Images": "Edit Images",
+ "Browse": "Browse",
+ "Upload": "Upload",
+ "Promoted": "Promoted",
+ "Promote": "Promote",
+ "Delete": "Delete",
+ "Back": "Back"
+}
diff --git a/pages.php b/pages.php
index 2d50c5f..c5b92e5 100644
--- a/pages.php
+++ b/pages.php
@@ -61,6 +61,16 @@ define("PAGES", [
"static/js/edititem.js"
],
],
+ "editimages" => [
+ "title" => "Edit item images",
+ "navbar" => false,
+ "styles" => [
+ "static/css/files.css"
+ ],
+ "scripts" => [
+ "static/js/files.js"
+ ]
+ ],
"editcat" => [
"title" => "Edit category",
"navbar" => false,
diff --git a/pages/editimages.php b/pages/editimages.php
new file mode 100644
index 0000000..0e98ddf
--- /dev/null
+++ b/pages/editimages.php
@@ -0,0 +1,87 @@
+has('items', ['itemid' => $VARS['id']])) {
+ $images = $database->select('images', ['imageid', 'imagename', 'primary'], ['itemid' => $VARS['id']]);
+} else {
+ header('Location: app.php?page=items&msg=invalid_itemid');
+ die();
+}
+?>
+
+