diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..5285d89e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "phpserver.relativePath": "public" +} diff --git a/bootstrap.php b/bootstrap.php index 48f72b81..847028f3 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -3,35 +3,35 @@ use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; -use Grocy\Middleware\SessionMiddleware; -use Grocy\Middleware\JsonMiddleware; -use Grocy\Middleware\CliMiddleware; +use \Grocy\Middleware\SessionAuthMiddleware; +use \Grocy\Middleware\JsonMiddleware; +use \Grocy\Middleware\CliMiddleware; -use Grocy\Services\ApplicationService; +use \Grocy\Services\ApplicationService; require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/data/config.php'; require_once __DIR__ . '/extensions.php'; // Setup base application -$app = new \Slim\App; if (PHP_SAPI !== 'cli') { - $app = new \Slim\App(new \Slim\Container([ + $appContainer = new \Slim\Container([ 'settings' => [ 'displayErrorDetails' => true, 'determineRouteBeforeAppMiddleware' => true ], - ])); - - $container = $app->getContainer(); - $container['view'] = function($container) - { - return new \Slim\Views\Blade(__DIR__ . '/views', __DIR__ . '/data/viewcache'); - }; + 'view' => function($container) + { + return new \Slim\Views\Blade(__DIR__ . '/views', __DIR__ . '/data/viewcache'); + } + ]); + + $app = new \Slim\App($appContainer); } else { + $app = new \Slim\App(); $app->add(\pavlakis\cli\CliRequest::class); } @@ -39,7 +39,7 @@ else $applicationService = new ApplicationService(); if (!$applicationService->IsDemoInstallation()) { - $app->add(SessionMiddleware::class); + $app->add(SessionAuthMiddleware::class); } // Base route diff --git a/build.bat b/build.bat index 61463931..3c50a8fe 100644 --- a/build.bat +++ b/build.bat @@ -8,5 +8,6 @@ for /f "tokens=*" %%a in ('type version.txt') do set version=%%a del "%releasePath%\grocy_%version%.zip" "build_tools\7za.exe" a -r "%releasePath%\grocy_%version%.zip" "%projectPath%\*" -xr!.* -xr!build_tools -xr!build.bat -xr!composer.json -xr!composer.lock -xr!bower.json -xr!publication_assets -"build_tools\7za.exe" a -r "%releasePath%\grocy_%version%.zip" "%projectPath%\.htaccess" +"build_tools\7za.exe" a "%releasePath%\grocy_%version%.zip" "%projectPath%\public\.htaccess" +"build_tools\7za.exe" rn "%releasePath%\grocy_%version%.zip" .htaccess public\.htaccess "build_tools\7za.exe" d "%releasePath%\grocy_%version%.zip" data\*.* data\sessions data\viewcache\* diff --git a/controllers/BaseApiController.php b/controllers/BaseApiController.php index 8f3a1887..e0f2595e 100644 --- a/controllers/BaseApiController.php +++ b/controllers/BaseApiController.php @@ -4,7 +4,7 @@ namespace Grocy\Controllers; class BaseApiController extends BaseController { - protected function ApiEncode($response) + protected function ApiResponse($response) { return json_encode($response); } diff --git a/controllers/BaseController.php b/controllers/BaseController.php index 490fd4d9..4c161d1e 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -2,7 +2,8 @@ namespace Grocy\Controllers; -use Grocy\Services\DatabaseService; +use \Grocy\Services\DatabaseService; +use \Grocy\Services\ApplicationService; class BaseController { @@ -11,6 +12,9 @@ class BaseController $databaseService = new DatabaseService(); $this->Database = $databaseService->GetDbConnection(); + + $applicationService = new ApplicationService(); + $container->view->set('version', $applicationService->GetInstalledVersion()); } protected $AppContainer; diff --git a/controllers/BatteriesApiController.php b/controllers/BatteriesApiController.php index 9d6f08b7..e504e01c 100644 --- a/controllers/BatteriesApiController.php +++ b/controllers/BatteriesApiController.php @@ -2,7 +2,7 @@ namespace Grocy\Controllers; -use Grocy\Services\BatteriesService; +use \Grocy\Services\BatteriesService; class BatteriesApiController extends BaseApiController { @@ -14,7 +14,7 @@ class BatteriesApiController extends BaseApiController protected $BatteriesService; - public function TrackChargeCycle($request, $response, $args) + public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $trackedTime = date('Y-m-d H:i:s'); if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time'])) @@ -22,11 +22,11 @@ class BatteriesApiController extends BaseApiController $trackedTime = $request->getQueryParams()['tracked_time']; } - return $this->ApiEncode(array('success' => $this->BatteriesService->TrackChargeCycle($args['batteryId'], $trackedTime))); + return $this->ApiResponse(array('success' => $this->BatteriesService->TrackChargeCycle($args['batteryId'], $trackedTime))); } - public function BatteryDetails($request, $response, $args) + public function BatteryDetails(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->ApiEncode($this->BatteriesService->GetBatteryDetails($args['batteryId'])); + return $this->ApiResponse($this->BatteriesService->GetBatteryDetails($args['batteryId'])); } } diff --git a/controllers/BatteriesController.php b/controllers/BatteriesController.php index 65d245fa..76421813 100644 --- a/controllers/BatteriesController.php +++ b/controllers/BatteriesController.php @@ -2,7 +2,7 @@ namespace Grocy\Controllers; -use Grocy\Services\BatteriesService; +use \Grocy\Services\BatteriesService; class BatteriesController extends BaseController { @@ -14,49 +14,46 @@ class BatteriesController extends BaseController protected $BatteriesService; - public function Overview($request, $response, $args) + public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { + $nextChargeTimes = array(); + foreach($this->Database->batteries() as $battery) + { + $nextChargeTimes[$battery->id] = $this->BatteriesService->GetNextChargeTime($battery->id); + } + return $this->AppContainer->view->render($response, 'batteriesoverview', [ - 'title' => 'Batteries overview', - 'contentPage' => 'batteriesoverview.php', 'batteries' => $this->Database->batteries(), 'current' => $this->BatteriesService->GetCurrent(), + 'nextChargeTimes' => $nextChargeTimes ]); } - public function TrackChargeCycle($request, $response, $args) + public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'batterytracking', [ - 'title' => 'Battery tracking', - 'contentPage' => 'batterytracking.php', 'batteries' => $this->Database->batteries() ]); } - public function BatteriesList($request, $response, $args) + public function BatteriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'batteries', [ - 'title' => 'Batteries', - 'contentPage' => 'batteries.php', 'batteries' => $this->Database->batteries() ]); } - public function BatteryEditForm($request, $response, $args) + public function BatteryEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { if ($args['batteryId'] == 'new') { return $this->AppContainer->view->render($response, 'batteryform', [ - 'title' => 'Create battery', - 'contentPage' => 'batteryform.php', 'mode' => 'create' ]); } else { return $this->AppContainer->view->render($response, 'batteryform', [ - 'title' => 'Edit battery', - 'contentPage' => 'batteryform.php', 'battery' => $this->Database->batteries($args['batteryId']), 'mode' => 'edit' ]); diff --git a/controllers/CliController.php b/controllers/CliController.php index 8cfa1786..0b0a40fa 100644 --- a/controllers/CliController.php +++ b/controllers/CliController.php @@ -2,12 +2,12 @@ namespace Grocy\Controllers; -use Grocy\Services\ApplicationService; -use Grocy\Services\DatabaseMigrationService; +use \Grocy\Services\ApplicationService; +use \Grocy\Services\DatabaseMigrationService; class CliController extends BaseController { - public function RecreateDemo($request, $response, $args) + public function RecreateDemo(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $applicationService = new ApplicationService(); if ($applicationService->IsDemoInstallation()) diff --git a/controllers/GenericEntityApiController.php b/controllers/GenericEntityApiController.php index db73146d..c72fa370 100644 --- a/controllers/GenericEntityApiController.php +++ b/controllers/GenericEntityApiController.php @@ -4,37 +4,37 @@ namespace Grocy\Controllers; class GenericEntityApiController extends BaseApiController { - public function GetObjects($request, $response, $args) + public function GetObjects(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->ApiEncode($this->Database->{$args['entity']}()); + return $this->ApiResponse($this->Database->{$args['entity']}()); } - public function GetObject($request, $response, $args) + public function GetObject(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->ApiEncode($this->Database->{$args['entity']}($args['objectId'])); + return $this->ApiResponse($this->Database->{$args['entity']}($args['objectId'])); } - public function AddObject($request, $response, $args) + public function AddObject(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $newRow = $this->Database->{$args['entity']}()->createRow($request->getParsedBody()); $newRow->save(); $success = $newRow->isClean(); - return $this->ApiEncode(array('success' => $success)); + return $this->ApiResponse(array('success' => $success)); } - public function EditObject($request, $response, $args) + public function EditObject(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $row = $this->Database->{$args['entity']}($args['objectId']); $row->update($request->getParsedBody()); $success = $row->isClean(); - return $this->ApiEncode(array('success' => $success)); + return $this->ApiResponse(array('success' => $success)); } - public function DeleteObject($request, $response, $args) + public function DeleteObject(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $row = $this->Database->{$args['entity']}($args['objectId']); $row->delete(); $success = $row->isClean(); - return $this->ApiEncode(array('success' => $success)); + return $this->ApiResponse(array('success' => $success)); } } diff --git a/controllers/HabitsApiController.php b/controllers/HabitsApiController.php index 9f54368d..7fcb1718 100644 --- a/controllers/HabitsApiController.php +++ b/controllers/HabitsApiController.php @@ -2,7 +2,7 @@ namespace Grocy\Controllers; -use Grocy\Services\HabitsService; +use \Grocy\Services\HabitsService; class HabitsApiController extends BaseApiController { @@ -14,7 +14,7 @@ class HabitsApiController extends BaseApiController protected $HabitsService; - public function TrackHabitExecution($request, $response, $args) + public function TrackHabitExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $trackedTime = date('Y-m-d H:i:s'); if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time'])) @@ -22,11 +22,11 @@ class HabitsApiController extends BaseApiController $trackedTime = $request->getQueryParams()['tracked_time']; } - return $this->ApiEncode(array('success' => $this->HabitsService->TrackHabit($args['habitId'], $trackedTime))); + return $this->ApiResponse(array('success' => $this->HabitsService->TrackHabit($args['habitId'], $trackedTime))); } - public function HabitDetails($request, $response, $args) + public function HabitDetails(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->ApiEncode($this->HabitsService->GetHabitDetails($args['habitId'])); + return $this->ApiResponse($this->HabitsService->GetHabitDetails($args['habitId'])); } } diff --git a/controllers/HabitsController.php b/controllers/HabitsController.php index 93c54c81..114f6ec9 100644 --- a/controllers/HabitsController.php +++ b/controllers/HabitsController.php @@ -2,7 +2,7 @@ namespace Grocy\Controllers; -use Grocy\Services\HabitsService; +use \Grocy\Services\HabitsService; class HabitsController extends BaseController { @@ -14,52 +14,49 @@ class HabitsController extends BaseController protected $HabitsService; - public function Overview($request, $response, $args) + public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { + $nextHabitTimes = array(); + foreach($this->Database->habits() as $habit) + { + $nextHabitTimes[$habit->id] = $this->HabitsService->GetNextHabitTime($habit->id); + } + return $this->AppContainer->view->render($response, 'habitsoverview', [ - 'title' => 'Habits overview', - 'contentPage' => 'habitsoverview.php', 'habits' => $this->Database->habits(), 'currentHabits' => $this->HabitsService->GetCurrentHabits(), + 'nextHabitTimes' => $nextHabitTimes ]); } - public function TrackHabitExecution($request, $response, $args) + public function TrackHabitExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'habittracking', [ - 'title' => 'Habit tracking', - 'contentPage' => 'habittracking.php', 'habits' => $this->Database->habits() ]); } - public function HabitsList($request, $response, $args) + public function HabitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'habits', [ - 'title' => 'Habits', - 'contentPage' => 'habits.php', 'habits' => $this->Database->habits() ]); } - public function HabitEditForm($request, $response, $args) + public function HabitEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { if ($args['habitId'] == 'new') { return $this->AppContainer->view->render($response, 'habitform', [ - 'title' => 'Create habit', - 'contentPage' => 'habitform.php', - 'periodTypes' => GetClassConstants('Grocy\Services\HabitsService'), + 'periodTypes' => GetClassConstants('\Grocy\Services\HabitsService'), 'mode' => 'create' ]); } else { return $this->AppContainer->view->render($response, 'habitform', [ - 'title' => 'Edit habit', - 'contentPage' => 'habitform.php', 'habit' => $this->Database->habits($args['habitId']), - 'periodTypes' => GetClassConstants('Grocy\Services\HabitsService'), + 'periodTypes' => GetClassConstants('\Grocy\Services\HabitsService'), 'mode' => 'edit' ]); } diff --git a/controllers/LoginController.php b/controllers/LoginController.php index 8831f2d7..592f608c 100644 --- a/controllers/LoginController.php +++ b/controllers/LoginController.php @@ -2,11 +2,10 @@ namespace Grocy\Controllers; -use Grocy\Services\SessionService; -use Grocy\Services\DatabaseService; -use Grocy\Services\ApplicationService; -use Grocy\Services\DatabaseMigrationService; -use Grocy\Services\DemoDataGeneratorService; +use \Grocy\Services\SessionService; +use \Grocy\Services\ApplicationService; +use \Grocy\Services\DatabaseMigrationService; +use \Grocy\Services\DemoDataGeneratorService; class LoginController extends BaseController { @@ -18,7 +17,7 @@ class LoginController extends BaseController protected $SessionService; - public function ProcessLogin($request, $response, $args) + public function ProcessLogin(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $postParams = $request->getParsedBody(); if (isset($postParams['username']) && isset($postParams['password'])) @@ -41,21 +40,18 @@ class LoginController extends BaseController } } - public function LoginPage($request, $response, $args) + public function LoginPage(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->AppContainer->view->render($response, 'login', [ - 'title' => 'Login', - 'contentPage' => 'login.php' - ]); + return $this->AppContainer->view->render($response, 'login'); } - public function Logout($request, $response, $args) + public function Logout(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $this->SessionService->RemoveSession($_COOKIE['grocy_session']); return $response->withRedirect('/'); } - public function Root($request, $response, $args) + public function Root(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { // Schema migration is done here $databaseMigrationService = new DatabaseMigrationService(); diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php index 990871db..ecd8f14f 100644 --- a/controllers/StockApiController.php +++ b/controllers/StockApiController.php @@ -2,7 +2,7 @@ namespace Grocy\Controllers; -use Grocy\Services\StockService; +use \Grocy\Services\StockService; class StockApiController extends BaseApiController { @@ -14,12 +14,12 @@ class StockApiController extends BaseApiController protected $StockService; - public function ProductDetails($request, $response, $args) + public function ProductDetails(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->ApiEncode($this->StockService->GetProductDetails($args['productId'])); + return $this->ApiResponse($this->StockService->GetProductDetails($args['productId'])); } - public function AddProduct($request, $response, $args) + public function AddProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $bestBeforeDate = date('Y-m-d'); if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate'])) @@ -33,10 +33,10 @@ class StockApiController extends BaseApiController $transactionType = $request->getQueryParams()['transactiontype']; } - return $this->ApiEncode(array('success' => $this->StockService->AddProduct($args['productId'], $args['amount'], $bestBeforeDate, $transactionType))); + return $this->ApiResponse(array('success' => $this->StockService->AddProduct($args['productId'], $args['amount'], $bestBeforeDate, $transactionType))); } - public function ConsumeProduct($request, $response, $args) + public function ConsumeProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $spoiled = false; if (isset($request->getQueryParams()['spoiled']) && !empty($request->getQueryParams()['spoiled']) && $request->getQueryParams()['spoiled'] == '1') @@ -50,10 +50,10 @@ class StockApiController extends BaseApiController $transactionType = $request->getQueryParams()['transactiontype']; } - return $this->ApiEncode(array('success' => $this->StockService->ConsumeProduct($args['productId'], $args['amount'], $spoiled, $transactionType))); + return $this->ApiResponse(array('success' => $this->StockService->ConsumeProduct($args['productId'], $args['amount'], $spoiled, $transactionType))); } - public function InventoryProduct($request, $response, $args) + public function InventoryProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $bestBeforeDate = date('Y-m-d'); if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate'])) @@ -61,17 +61,17 @@ class StockApiController extends BaseApiController $bestBeforeDate = $request->getQueryParams()['bestbeforedate']; } - return $this->ApiEncode(array('success' => $this->StockService->InventoryProduct($args['productId'], $args['newAmount'], $bestBeforeDate))); + return $this->ApiResponse(array('success' => $this->StockService->InventoryProduct($args['productId'], $args['newAmount'], $bestBeforeDate))); } - public function CurrentStock($request, $response, $args) + public function CurrentStock(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { - return $this->ApiEncode($this->StockService->GetCurrentStock()); + return $this->ApiResponse($this->StockService->GetCurrentStock()); } - public function AddmissingProductsToShoppingList($request, $response, $args) + public function AddmissingProductsToShoppingList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { $this->StockService->AddMissingProductsToShoppingList(); - return $this->ApiEncode(array('success' => true)); + return $this->ApiResponse(array('success' => true)); } } diff --git a/controllers/StockController.php b/controllers/StockController.php index 84606c3d..c835157e 100644 --- a/controllers/StockController.php +++ b/controllers/StockController.php @@ -2,7 +2,7 @@ namespace Grocy\Controllers; -use Grocy\Services\StockService; +use \Grocy\Services\StockService; class StockController extends BaseController { @@ -15,11 +15,9 @@ class StockController extends BaseController protected $StockService; - public function Overview($request, $response, $args) + public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'stockoverview', [ - 'title' => 'Stock overview', - 'contentPage' => 'stockoverview.php', 'products' => $this->Database->products(), 'quantityunits' => $this->Database->quantity_units(), 'currentStock' => $this->StockService->GetCurrentStock(), @@ -27,38 +25,30 @@ class StockController extends BaseController ]); } - public function Purchase($request, $response, $args) + public function Purchase(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'purchase', [ - 'title' => 'Purchase', - 'contentPage' => 'purchase.php', 'products' => $this->Database->products() ]); } - public function Consume($request, $response, $args) + public function Consume(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'consume', [ - 'title' => 'Consume', - 'contentPage' => 'consume.php', 'products' => $this->Database->products() ]); } - public function Inventory($request, $response, $args) + public function Inventory(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'inventory', [ - 'title' => 'Inventory', - 'contentPage' => 'inventory.php', 'products' => $this->Database->products() ]); } - public function ShoppingList($request, $response, $args) + public function ShoppingList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'shoppinglist', [ - 'title' => 'Shopping list', - 'contentPage' => 'shoppinglist.php', 'listItems' => $this->Database->shopping_list(), 'products' => $this->Database->products(), 'quantityunits' => $this->Database->quantity_units(), @@ -66,42 +56,34 @@ class StockController extends BaseController ]); } - public function ProductsList($request, $response, $args) + public function ProductsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'products', [ - 'title' => 'Products', - 'contentPage' => 'products.php', 'products' => $this->Database->products(), 'locations' => $this->Database->locations(), 'quantityunits' => $this->Database->quantity_units() ]); } - public function LocationsList($request, $response, $args) + public function LocationsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'locations', [ - 'title' => 'Locations', - 'contentPage' => 'locations.php', 'locations' => $this->Database->locations() ]); } - public function QuantityUnitsList($request, $response, $args) + public function QuantityUnitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { return $this->AppContainer->view->render($response, 'quantityunits', [ - 'title' => 'Quantity units', - 'contentPage' => 'quantityunits.php', 'quantityunits' => $this->Database->quantity_units() ]); } - public function ProductEditForm($request, $response, $args) + public function ProductEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { if ($args['productId'] == 'new') { return $this->AppContainer->view->render($response, 'productform', [ - 'title' => 'Create product', - 'contentPage' => 'productform.php', 'locations' => $this->Database->locations(), 'quantityunits' => $this->Database->quantity_units(), 'mode' => 'create' @@ -110,8 +92,6 @@ class StockController extends BaseController else { return $this->AppContainer->view->render($response, 'productform', [ - 'title' => 'Edit product', - 'contentPage' => 'productform.php', 'product' => $this->Database->products($args['productId']), 'locations' => $this->Database->locations(), 'quantityunits' => $this->Database->quantity_units(), @@ -120,55 +100,45 @@ class StockController extends BaseController } } - public function LocationEditForm($request, $response, $args) + public function LocationEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { if ($args['locationId'] == 'new') { return $this->AppContainer->view->render($response, 'locationform', [ - 'title' => 'Create location', - 'contentPage' => 'locationform.php', 'mode' => 'create' ]); } else { return $this->AppContainer->view->render($response, 'locationform', [ - 'title' => 'Edit location', - 'contentPage' => 'locationform.php', 'location' => $this->Database->locations($args['locationId']), 'mode' => 'edit' ]); } } - public function QuantityUnitEditForm($request, $response, $args) + public function QuantityUnitEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { if ($args['quantityunitId'] == 'new') { return $this->AppContainer->view->render($response, 'quantityunitform', [ - 'title' => 'Create quantity unit', - 'contentPage' => 'quantityunitform.php', 'mode' => 'create' ]); } else { return $this->AppContainer->view->render($response, 'quantityunitform', [ - 'title' => 'Edit quantity unit', - 'contentPage' => 'quantityunitform.php', 'quantityunit' => $this->Database->quantity_units($args['quantityunitId']), 'mode' => 'edit' ]); } } - public function ShoppingListItemEditForm($request, $response, $args) + public function ShoppingListItemEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) { if ($args['itemId'] == 'new') { return $this->AppContainer->view->render($response, 'shoppinglistform', [ - 'title' => 'Add shopping list item', - 'contentPage' => 'shoppinglistform.php', 'products' => $this->Database->products(), 'mode' => 'create' ]); @@ -176,8 +146,6 @@ class StockController extends BaseController else { return $this->AppContainer->view->render($response, 'shoppinglistform', [ - 'title' => 'Edit shopping list item', - 'contentPage' => 'shoppinglistform.php', 'listItem' => $this->Database->shopping_list($args['itemId']), 'products' => $this->Database->products(), 'mode' => 'edit' diff --git a/middleware/CliMiddleware.php b/middleware/CliMiddleware.php index c1a4d528..5cc8e82f 100644 --- a/middleware/CliMiddleware.php +++ b/middleware/CliMiddleware.php @@ -12,14 +12,15 @@ class CliMiddleware public function __invoke(\Slim\Http\Request $request, \Slim\Http\Response $response, callable $next) { - $response = $next($request, $response); - if (PHP_SAPI !== 'cli') { $response->write('Please call this only from CLI'); return $response->withHeader('Content-Type', 'text/plain')->withStatus(400); } - - return $response->withHeader('Content-Type', 'text/plain'); + else + { + $response = $next($request, $response, $next); + return $response->withHeader('Content-Type', 'text/plain'); + } } } diff --git a/middleware/SessionMiddleware.php b/middleware/SessionAuthMiddleware.php similarity index 91% rename from middleware/SessionMiddleware.php rename to middleware/SessionAuthMiddleware.php index 2a04eecb..f09cbe72 100644 --- a/middleware/SessionMiddleware.php +++ b/middleware/SessionAuthMiddleware.php @@ -2,9 +2,9 @@ namespace Grocy\Middleware; -use Grocy\Services\SessionService; +use \Grocy\Services\SessionService; -class SessionMiddleware +class SessionAuthMiddleware { public function __construct(\Slim\Container $container) { $this->container = $container; diff --git a/migrations/0001.sql b/migrations/0001.sql new file mode 100644 index 00000000..17686ba3 --- /dev/null +++ b/migrations/0001.sql @@ -0,0 +1,13 @@ +CREATE TABLE products ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + location_id INTEGER NOT NULL, + qu_id_purchase INTEGER NOT NULL, + qu_id_stock INTEGER NOT NULL, + qu_factor_purchase_to_stock REAL NOT NULL, + barcode TEXT, + min_stock_amount INTEGER NOT NULL DEFAULT 0, + default_best_before_days INTEGER NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0002.sql b/migrations/0002.sql new file mode 100644 index 00000000..ed277df0 --- /dev/null +++ b/migrations/0002.sql @@ -0,0 +1,6 @@ +CREATE TABLE locations ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0003.sql b/migrations/0003.sql new file mode 100644 index 00000000..f20536cc --- /dev/null +++ b/migrations/0003.sql @@ -0,0 +1,6 @@ +CREATE TABLE quantity_units ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0004.sql b/migrations/0004.sql new file mode 100644 index 00000000..57d56d8b --- /dev/null +++ b/migrations/0004.sql @@ -0,0 +1,9 @@ +CREATE TABLE stock ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + product_id INTEGER NOT NULL, + amount INTEGER NOT NULL, + best_before_date DATE, + purchased_date DATE DEFAULT (datetime('now', 'localtime')), + stock_id TEXT NOT NULL, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0005.sql b/migrations/0005.sql new file mode 100644 index 00000000..3f303445 --- /dev/null +++ b/migrations/0005.sql @@ -0,0 +1,12 @@ +CREATE TABLE stock_log ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + product_id INTEGER NOT NULL, + amount INTEGER NOT NULL, + best_before_date DATE, + purchased_date DATE, + used_date DATE, + spoiled INTEGER NOT NULL DEFAULT 0, + stock_id TEXT NOT NULL, + transaction_type TEXT NOT NULL, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0006.sql b/migrations/0006.sql new file mode 100644 index 00000000..11490b43 --- /dev/null +++ b/migrations/0006.sql @@ -0,0 +1,19 @@ +INSERT INTO locations + (name, description) +VALUES + ('DefaultLocation', 'This is the first default location, edit or delete it'); + +INSERT INTO quantity_units + (name, description) +VALUES + ('DefaultQuantityUnit', 'This is the first default quantity unit, edit or delete it'); + +INSERT INTO products + (name, description, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) +VALUES + ('DefaultProduct1', 'This is the first default product, edit or delete it', 1, 1, 1, 1); + +INSERT INTO products + (name, description, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) +VALUES + ('DefaultProduct2', 'This is the second default product, edit or delete it', 1, 1, 1, 1); diff --git a/migrations/0007.sql b/migrations/0007.sql new file mode 100644 index 00000000..36b09ab0 --- /dev/null +++ b/migrations/0007.sql @@ -0,0 +1,9 @@ +CREATE VIEW stock_missing_products +AS +SELECT p.id, MAX(p.name) AS name, p.min_stock_amount - IFNULL(SUM(s.amount), 0) AS amount_missing +FROM products p +LEFT JOIN stock s + ON p.id = s.product_id +WHERE p.min_stock_amount != 0 +GROUP BY p.id +HAVING IFNULL(SUM(s.amount), 0) < p.min_stock_amount diff --git a/migrations/0008.sql b/migrations/0008.sql new file mode 100644 index 00000000..05c76cd5 --- /dev/null +++ b/migrations/0008.sql @@ -0,0 +1,6 @@ +CREATE VIEW stock_current +AS +SELECT product_id, SUM(amount) AS amount, MIN(best_before_date) AS best_before_date +FROM stock +GROUP BY product_id +ORDER BY MIN(best_before_date) ASC diff --git a/migrations/0009.sql b/migrations/0009.sql new file mode 100644 index 00000000..bd274b52 --- /dev/null +++ b/migrations/0009.sql @@ -0,0 +1,7 @@ +CREATE TABLE shopping_list ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + product_id INTEGER NOT NULL UNIQUE, + amount INTEGER NOT NULL DEFAULT 0, + amount_autoadded INTEGER NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0010.sql b/migrations/0010.sql new file mode 100644 index 00000000..1fe7db38 --- /dev/null +++ b/migrations/0010.sql @@ -0,0 +1,8 @@ +CREATE TABLE habits ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + period_type TEXT NOT NULL, + period_days INTEGER, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0011.sql b/migrations/0011.sql new file mode 100644 index 00000000..b07c39e8 --- /dev/null +++ b/migrations/0011.sql @@ -0,0 +1,6 @@ +CREATE TABLE habits_log ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + habit_id INTEGER NOT NULL, + tracked_time DATETIME, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0012.sql b/migrations/0012.sql new file mode 100644 index 00000000..330da61b --- /dev/null +++ b/migrations/0012.sql @@ -0,0 +1,6 @@ +CREATE VIEW habits_current +AS +SELECT habit_id, MAX(tracked_time) AS last_tracked_time +FROM habits_log +GROUP BY habit_id +ORDER BY MAX(tracked_time) DESC diff --git a/migrations/0013.sql b/migrations/0013.sql new file mode 100644 index 00000000..8e8d7e23 --- /dev/null +++ b/migrations/0013.sql @@ -0,0 +1,8 @@ +CREATE TABLE batteries ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + name TEXT NOT NULL UNIQUE, + description TEXT, + used_in TEXT, + charge_interval_days INTEGER NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0014.sql b/migrations/0014.sql new file mode 100644 index 00000000..529c0a22 --- /dev/null +++ b/migrations/0014.sql @@ -0,0 +1,6 @@ +CREATE TABLE battery_charge_cycles ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + battery_id TEXT NOT NULL, + tracked_time DATETIME, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0015.sql b/migrations/0015.sql new file mode 100644 index 00000000..d6643b11 --- /dev/null +++ b/migrations/0015.sql @@ -0,0 +1,6 @@ +CREATE VIEW batteries_current +AS +SELECT battery_id, MAX(tracked_time) AS last_tracked_time +FROM battery_charge_cycles +GROUP BY battery_id +ORDER BY MAX(tracked_time) DESC diff --git a/migrations/0016.sql b/migrations/0016.sql new file mode 100644 index 00000000..aae178f2 --- /dev/null +++ b/migrations/0016.sql @@ -0,0 +1 @@ +ALTER TABLE shopping_list RENAME TO shopping_list_old diff --git a/migrations/0017.sql b/migrations/0017.sql new file mode 100644 index 00000000..2ff2f528 --- /dev/null +++ b/migrations/0017.sql @@ -0,0 +1,8 @@ +CREATE TABLE shopping_list ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, + product_id INTEGER, + note TEXT, + amount INTEGER NOT NULL DEFAULT 0, + amount_autoadded INTEGER NOT NULL DEFAULT 0, + row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) +) diff --git a/migrations/0018.sql b/migrations/0018.sql new file mode 100644 index 00000000..05416036 --- /dev/null +++ b/migrations/0018.sql @@ -0,0 +1,4 @@ +INSERT INTO shopping_list + (product_id, amount, amount_autoadded, row_created_timestamp) +SELECT product_id, amount, amount_autoadded, row_created_timestamp +FROM shopping_list_old diff --git a/migrations/0019.sql b/migrations/0019.sql new file mode 100644 index 00000000..2b3b9821 --- /dev/null +++ b/migrations/0019.sql @@ -0,0 +1 @@ +DROP TABLE shopping_list_old diff --git a/.htaccess b/public/.htaccess similarity index 100% rename from .htaccess rename to public/.htaccess diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.eot b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.eot similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.eot rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.eot diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.svg b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.svg similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.svg rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.svg diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.ttf b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.ttf similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.ttf rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.ttf diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff2 b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff2 similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff2 rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700.woff2 diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.eot b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.eot similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.eot rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.eot diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.svg b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.svg similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.svg rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.svg diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.ttf b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.ttf similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.ttf rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.ttf diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff2 b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff2 similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff2 rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-700italic.woff2 diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.eot b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.eot similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.eot rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.eot diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.svg b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.svg similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.svg rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.svg diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.ttf b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.ttf similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.ttf rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.ttf diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff2 b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff2 similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff2 rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-italic.woff2 diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.eot b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.eot similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.eot rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.eot diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.svg b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.svg similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.svg rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.svg diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.ttf b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.ttf similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.ttf rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.ttf diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff2 b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff2 similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff2 rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin-regular.woff2 diff --git a/vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin.css b/public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin.css similarity index 100% rename from vendor_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin.css rename to public/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin.css diff --git a/public/css/grocy.css b/public/css/grocy.css index 6362418d..2cc04ec8 100644 --- a/public/css/grocy.css +++ b/public/css/grocy.css @@ -22,8 +22,8 @@ padding: 20px; overflow-x: hidden; overflow-y: auto; - background-color: #f5f5f5; - border-right: 1px solid #5e5e5e; + background-color: #e5e5e5; + border-right: 1px solid #d6d6d6; min-width: 220px; max-width: 260px; } @@ -47,8 +47,11 @@ .nav-sidebar > .active > a, .nav-sidebar > .active > a:hover, .nav-sidebar > .active > a:focus { - color: #fff; - background-color: #5e5e5e; + background-color: #d6d6d6; +} + +.navbar-default { + background-color: #e5e5e5; } .main { @@ -67,7 +70,7 @@ } .nav-copyright { - color: #b3b3b1; + color: #a7a7a7; font-size: 11px; text-align: center; font-family: 'Arial', sans-serif; @@ -75,21 +78,24 @@ .discrete-link { color: inherit; + transition: all 0.3s; } a.discrete-link:hover { - color: #5cb85c; + color: #337ab7; text-decoration: none; + transition: all 0.3s; } a.discrete-link:focus { - color: #337ab7; + color: #ab2230; text-decoration: none; + transition: all 0.3s; } .navbar-fixed-top { border-bottom: solid; - border-color: #5e5e5e; + border-color: #d6d6d6; } .navbar-brand { diff --git a/public/js/grocy.js b/public/js/grocy.js index fd6a1c0e..d24dca66 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -2,8 +2,11 @@ $(function() { - var menuItem = $('.nav').find("[data-nav-for-page='" + Grocy.ContentPage + "']"); - menuItem.addClass('active'); + if (!Grocy.ActiveNav.isEmpty()) + { + var menuItem = $('.nav').find("[data-nav-for-page='" + Grocy.ActiveNav + "']"); + menuItem.addClass('active'); + } $.timeago.settings.allowFuture = true; $('time.timeago').timeago(); @@ -81,6 +84,11 @@ String.prototype.contains = function(search) return this.toLowerCase().indexOf(search.toLowerCase()) !== -1; }; +String.prototype.isEmpty = function() +{ + return (this.length === 0 || !this.trim()); +}; + Grocy.GetUriParam = function(key) { var currentUri = decodeURIComponent(window.location.search.substring(1)); diff --git a/services/BaseService.php b/services/BaseService.php index 212be5d9..82d12abb 100644 --- a/services/BaseService.php +++ b/services/BaseService.php @@ -2,7 +2,7 @@ namespace Grocy\Services; -use Grocy\Services\DatabaseService; +use \Grocy\Services\DatabaseService; class BaseService { diff --git a/services/DatabaseMigrationService.php b/services/DatabaseMigrationService.php index f6b31122..7e3f2210 100644 --- a/services/DatabaseMigrationService.php +++ b/services/DatabaseMigrationService.php @@ -8,188 +8,18 @@ class DatabaseMigrationService extends BaseService { $this->DatabaseService->ExecuteDbStatement("CREATE TABLE IF NOT EXISTS migrations (migration INTEGER NOT NULL PRIMARY KEY UNIQUE, execution_time_timestamp DATETIME DEFAULT (datetime('now', 'localtime')))"); - $this->ExecuteMigrationWhenNeeded(1, " - CREATE TABLE products ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - name TEXT NOT NULL UNIQUE, - description TEXT, - location_id INTEGER NOT NULL, - qu_id_purchase INTEGER NOT NULL, - qu_id_stock INTEGER NOT NULL, - qu_factor_purchase_to_stock REAL NOT NULL, - barcode TEXT, - min_stock_amount INTEGER NOT NULL DEFAULT 0, - default_best_before_days INTEGER NOT NULL DEFAULT 0, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); + $migrationFiles = array(); + foreach (new \FilesystemIterator(__DIR__ . '/../migrations') as $file) + { + $migrationFiles[$file->getBasename('.sql')] = $file->getPathname(); + } + ksort($migrationFiles); - $this->ExecuteMigrationWhenNeeded(2, " - CREATE TABLE locations ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - name TEXT NOT NULL UNIQUE, - description TEXT, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(3, " - CREATE TABLE quantity_units ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - name TEXT NOT NULL UNIQUE, - description TEXT, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(4, " - CREATE TABLE stock ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - product_id INTEGER NOT NULL, - amount INTEGER NOT NULL, - best_before_date DATE, - purchased_date DATE DEFAULT (datetime('now', 'localtime')), - stock_id TEXT NOT NULL, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(5, " - CREATE TABLE stock_log ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - product_id INTEGER NOT NULL, - amount INTEGER NOT NULL, - best_before_date DATE, - purchased_date DATE, - used_date DATE, - spoiled INTEGER NOT NULL DEFAULT 0, - stock_id TEXT NOT NULL, - transaction_type TEXT NOT NULL, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(6, " - INSERT INTO locations (name, description) VALUES ('DefaultLocation', 'This is the first default location, edit or delete it'); - INSERT INTO quantity_units (name, description) VALUES ('DefaultQuantityUnit', 'This is the first default quantity unit, edit or delete it'); - INSERT INTO products (name, description, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('DefaultProduct1', 'This is the first default product, edit or delete it', 1, 1, 1, 1); - INSERT INTO products (name, description, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('DefaultProduct2', 'This is the second default product, edit or delete it', 1, 1, 1, 1);" - ); - - $this->ExecuteMigrationWhenNeeded(7, " - CREATE VIEW stock_missing_products - AS - SELECT p.id, MAX(p.name) AS name, p.min_stock_amount - IFNULL(SUM(s.amount), 0) AS amount_missing - FROM products p - LEFT JOIN stock s - ON p.id = s.product_id - WHERE p.min_stock_amount != 0 - GROUP BY p.id - HAVING IFNULL(SUM(s.amount), 0) < p.min_stock_amount;" - ); - - $this->ExecuteMigrationWhenNeeded(8, " - CREATE VIEW stock_current - AS - SELECT product_id, SUM(amount) AS amount, MIN(best_before_date) AS best_before_date - FROM stock - GROUP BY product_id - ORDER BY MIN(best_before_date) ASC;" - ); - - $this->ExecuteMigrationWhenNeeded(9, " - CREATE TABLE shopping_list ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - product_id INTEGER NOT NULL UNIQUE, - amount INTEGER NOT NULL DEFAULT 0, - amount_autoadded INTEGER NOT NULL DEFAULT 0, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(10, " - CREATE TABLE habits ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - name TEXT NOT NULL UNIQUE, - description TEXT, - period_type TEXT NOT NULL, - period_days INTEGER, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(11, " - CREATE TABLE habits_log ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - habit_id INTEGER NOT NULL, - tracked_time DATETIME, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(12, " - CREATE VIEW habits_current - AS - SELECT habit_id, MAX(tracked_time) AS last_tracked_time - FROM habits_log - GROUP BY habit_id - ORDER BY MAX(tracked_time) DESC;" - ); - - $this->ExecuteMigrationWhenNeeded(13, " - CREATE TABLE batteries ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - name TEXT NOT NULL UNIQUE, - description TEXT, - used_in TEXT, - charge_interval_days INTEGER NOT NULL DEFAULT 0, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(14, " - CREATE TABLE battery_charge_cycles ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - battery_id TEXT NOT NULL, - tracked_time DATETIME, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(15, " - CREATE VIEW batteries_current - AS - SELECT battery_id, MAX(tracked_time) AS last_tracked_time - FROM battery_charge_cycles - GROUP BY battery_id - ORDER BY MAX(tracked_time) DESC;" - ); - - $this->ExecuteMigrationWhenNeeded(16, " - ALTER TABLE shopping_list RENAME TO shopping_list_old;" - ); - - $this->ExecuteMigrationWhenNeeded(17, " - CREATE TABLE shopping_list ( - id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, - product_id INTEGER, - note TEXT, - amount INTEGER NOT NULL DEFAULT 0, - amount_autoadded INTEGER NOT NULL DEFAULT 0, - row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')) - )" - ); - - $this->ExecuteMigrationWhenNeeded(18, " - INSERT INTO shopping_list - (product_id, amount, amount_autoadded, row_created_timestamp) - SELECT product_id, amount, amount_autoadded, row_created_timestamp - FROM shopping_list_old" - ); - - $this->ExecuteMigrationWhenNeeded(19, " - DROP TABLE shopping_list_old;" - ); + foreach($migrationFiles as $migrationNumber => $migrationFile) + { + $migrationNumber = ltrim($migrationNumber, '0'); + $this->ExecuteMigrationWhenNeeded($migrationNumber, file_get_contents($migrationFile)); + } } private function ExecuteMigrationWhenNeeded(int $migrationId, string $sql) diff --git a/services/DatabaseService.php b/services/DatabaseService.php index f3726655..f23d3412 100644 --- a/services/DatabaseService.php +++ b/services/DatabaseService.php @@ -2,7 +2,7 @@ namespace Grocy\Services; -use Grocy\Services\ApplicationService; +use \Grocy\Services\ApplicationService; class DatabaseService { diff --git a/services/DemoDataGeneratorService.php b/services/DemoDataGeneratorService.php index bcea126d..156c0e48 100644 --- a/services/DemoDataGeneratorService.php +++ b/services/DemoDataGeneratorService.php @@ -87,7 +87,7 @@ class DemoDataGeneratorService extends BaseService public function RecreateDemo() { - unlink(__DIR__ . '/data/grocy.db'); - $this->PopulateDemoData($this->DatabaseService->GetDbConnectionRaw(true)); + unlink(__DIR__ . '/../data/grocy.db'); + $this->PopulateDemoData(); } } diff --git a/services/HabitsService.php b/services/HabitsService.php index 4db54aff..8d11dfc5 100644 --- a/services/HabitsService.php +++ b/services/HabitsService.php @@ -18,7 +18,7 @@ class HabitsService extends BaseService $habit = $this->Database->habits($habitId); $habitLastLogRow = $this->DatabaseService->ExecuteDbQuery("SELECT * from habits_current WHERE habit_id = $habitId LIMIT 1")->fetch(\PDO::FETCH_OBJ); - switch ($habit->period_type) + switch($habit->period_type) { case self::HABIT_TYPE_MANUALLY: return date('Y-m-d H:i:s'); diff --git a/views/batteries.blade.php b/views/batteries.blade.php index 7ee8d43a..cd348c4f 100644 --- a/views/batteries.blade.php +++ b/views/batteries.blade.php @@ -1,5 +1,9 @@ @extends('layout.default') +@section('title', 'Batteries') +@section('activeNav', 'batteries') +@section('viewJsName', 'batteries') + @section('content')