diff --git a/README.md b/README.md
index 3015fbf2..b16dc023 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-

+
ERP beyond your fridge
-
grocy is a web-based self-hosted groceries & household management solution for your home
+
grocy is a web-based self-hosted groceries & household management solution for your home
Created by @berrnd
-----
diff --git a/changelog/62_UNRELEASED_xxxx-xx-xx.md b/changelog/62_3.1.0_2021-07-16.md
similarity index 98%
rename from changelog/62_UNRELEASED_xxxx-xx-xx.md
rename to changelog/62_3.1.0_2021-07-16.md
index 0edbdc9f..6703f6e4 100644
--- a/changelog/62_UNRELEASED_xxxx-xx-xx.md
+++ b/changelog/62_3.1.0_2021-07-16.md
@@ -2,7 +2,7 @@
> ⚠️ PHP 8 is now supported and from now on the only tested runtime version (although currently PHP 7.2 should still work).
-### New feature: grocycode
+### New feature: grocycode / label printer support
#### (Own) Product/stock entry/chores/batteries labels/barcodes
- Print own labels/barcodes for products/stock entries/chores/batteries and then scan that code on every place a product/stock entry/chore/battery can be selected
- Can be printed (or downloaded) via
@@ -16,8 +16,8 @@
- Label printer communication happens via WebHooks - see the new `LABEL_PRINTER*` `config.php` options
- grocycodes can also be used without a label printer - you can view or download thm as pictures and print them manually
- More information:
- - https://github.com/grocy/grocy/blob/master/docs/grocycode.md
- - https://github.com/grocy/grocy/blob/master/docs/label-printing.md
+ - https://github.com/grocy/grocy/tree/v3.1.0/docs/grocycode.md
+ - https://github.com/grocy/grocy/tree/v3.1.0/docs/label-printing.md
- (Thanks a lot @mistressofjellyfish for the initial work on this)
### New feature: Meal plan sections
diff --git a/config-dist.php b/config-dist.php
index 15b8cff3..dc654736 100644
--- a/config-dist.php
+++ b/config-dist.php
@@ -175,9 +175,8 @@ DefaultUserSetting('batteries_due_soon_days', 5);
// Tasks settings
DefaultUserSetting('tasks_due_soon_days', 5);
-// If the page should be automatically reloaded when there was
-// an external change
-DefaultUserSetting('auto_reload_on_db_change', true);
+// If the page should be automatically reloaded when there was an external change
+DefaultUserSetting('auto_reload_on_db_change', false);
// Show a clock in the header next to the logo or not
DefaultUserSetting('show_clock_in_header', false);
diff --git a/controllers/BaseApiController.php b/controllers/BaseApiController.php
index 96a2d343..7fecc207 100644
--- a/controllers/BaseApiController.php
+++ b/controllers/BaseApiController.php
@@ -6,18 +6,13 @@ use LessQL\Result;
class BaseApiController extends BaseController
{
- protected $OpenApiSpec = null;
-
const PATTERN_FIELD = '[A-Za-z_][A-Za-z0-9_]+';
const PATTERN_OPERATOR = '!?(=|~|<|>|(>=)|(<=)|(§))';
const PATTERN_VALUE = '[A-Za-z\x{0400}-\x{04FF}_0-9.$#^|-]+';
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
+ protected $OpenApiSpec = null;
protected function ApiResponse(\Psr\Http\Message\ResponseInterface $response, $data, $cache = false)
{
diff --git a/controllers/BaseController.php b/controllers/BaseController.php
index 7d76c23b..9d14e15d 100644
--- a/controllers/BaseController.php
+++ b/controllers/BaseController.php
@@ -21,14 +21,14 @@ use Grocy\Services\UsersService;
class BaseController
{
- protected $AppContainer;
-
public function __construct(\DI\Container $container)
{
$this->AppContainer = $container;
$this->View = $container->get('view');
}
+ protected $AppContainer;
+
protected function getApiKeyService()
{
return ApiKeyService::getInstance();
diff --git a/controllers/BatteriesApiController.php b/controllers/BatteriesApiController.php
index 5640d78e..fa054085 100644
--- a/controllers/BatteriesApiController.php
+++ b/controllers/BatteriesApiController.php
@@ -34,7 +34,6 @@ class BatteriesApiController extends BaseApiController
try
{
$trackedTime = date('Y-m-d H:i:s');
-
if (array_key_exists('tracked_time', $requestBody) && IsIsoDateTime($requestBody['tracked_time']))
{
$trackedTime = $requestBody['tracked_time'];
@@ -87,9 +86,4 @@ class BatteriesApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/BatteriesController.php b/controllers/BatteriesController.php
index 7b413a50..95d7441b 100644
--- a/controllers/BatteriesController.php
+++ b/controllers/BatteriesController.php
@@ -3,11 +3,11 @@
namespace Grocy\Controllers;
use Grocy\Helpers\Grocycode;
-use jucksearm\barcode\lib\BarcodeFactory;
-use jucksearm\barcode\lib\DatamatrixFactory;
class BatteriesController extends BaseController
{
+ use GrocycodeTrait;
+
public function BatteriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
if (isset($request->getQueryParams()['include_disabled']))
@@ -98,40 +98,7 @@ class BatteriesController extends BaseController
public function BatteryGrocycodeImage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
- $size = $request->getQueryParam('size', null);
$gc = new Grocycode(Grocycode::BATTERY, $args['batteryId']);
-
- if (GROCY_GROCYCODE_TYPE == '2D')
- {
- $png = (new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
- }
- else
- {
- $png = (new BarcodeFactory())->setType('C128')->setCode((string) $gc)->setHeight($size)->getBarcodePngData();
- }
-
- $isDownload = $request->getQueryParam('download', false);
- if ($isDownload)
- {
- $response = $response->withHeader('Content-Type', 'application/octet-stream')
- ->withHeader('Content-Disposition', 'attachment; filename=grocycode.png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- else
- {
- $response = $response->withHeader('Content-Type', 'image/png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- $response->getBody()->write($png);
- return $response;
- }
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
+ return $this->ServeGrocycodeImage($request, $response, $gc);
}
}
diff --git a/controllers/CalendarApiController.php b/controllers/CalendarApiController.php
index 8d3db47e..3c48d732 100644
--- a/controllers/CalendarApiController.php
+++ b/controllers/CalendarApiController.php
@@ -72,9 +72,4 @@ class CalendarApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/CalendarController.php b/controllers/CalendarController.php
index 1eb88282..a2ce556e 100644
--- a/controllers/CalendarController.php
+++ b/controllers/CalendarController.php
@@ -10,9 +10,4 @@ class CalendarController extends BaseController
'fullcalendarEventSources' => $this->getCalendarService()->GetEvents()
]);
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/ChoresApiController.php b/controllers/ChoresApiController.php
index f782977d..6994602f 100644
--- a/controllers/ChoresApiController.php
+++ b/controllers/ChoresApiController.php
@@ -68,14 +68,12 @@ class ChoresApiController extends BaseApiController
User::checkPermission($request, User::PERMISSION_CHORE_TRACK_EXECUTION);
$trackedTime = date('Y-m-d H:i:s');
-
if (array_key_exists('tracked_time', $requestBody) && (IsIsoDateTime($requestBody['tracked_time']) || IsIsoDate($requestBody['tracked_time'])))
{
$trackedTime = $requestBody['tracked_time'];
}
$doneBy = GROCY_USER_ID;
-
if (array_key_exists('done_by', $requestBody) && !empty($requestBody['done_by']))
{
$doneBy = $requestBody['done_by'];
@@ -133,9 +131,4 @@ class ChoresApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/ChoresController.php b/controllers/ChoresController.php
index f2dd5803..d0f13a25 100644
--- a/controllers/ChoresController.php
+++ b/controllers/ChoresController.php
@@ -3,11 +3,11 @@
namespace Grocy\Controllers;
use Grocy\Helpers\Grocycode;
-use jucksearm\barcode\lib\BarcodeFactory;
-use jucksearm\barcode\lib\DatamatrixFactory;
class ChoresController extends BaseController
{
+ use GrocycodeTrait;
+
public function ChoreEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
$usersService = $this->getUsersService();
@@ -115,40 +115,7 @@ class ChoresController extends BaseController
public function ChoreGrocycodeImage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
- $size = $request->getQueryParam('size', null);
$gc = new Grocycode(Grocycode::CHORE, $args['choreId']);
-
- if (GROCY_GROCYCODE_TYPE == '2D')
- {
- $png = (new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
- }
- else
- {
- $png = (new BarcodeFactory())->setType('C128')->setCode((string) $gc)->setHeight($size)->getBarcodePngData();
- }
-
- $isDownload = $request->getQueryParam('download', false);
- if ($isDownload)
- {
- $response = $response->withHeader('Content-Type', 'application/octet-stream')
- ->withHeader('Content-Disposition', 'attachment; filename=grocycode.png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- else
- {
- $response = $response->withHeader('Content-Type', 'image/png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- $response->getBody()->write($png);
- return $response;
- }
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
+ return $this->ServeGrocycodeImage($request, $response, $gc);
}
}
diff --git a/controllers/EquipmentController.php b/controllers/EquipmentController.php
index e64db7c6..db14fca8 100644
--- a/controllers/EquipmentController.php
+++ b/controllers/EquipmentController.php
@@ -33,9 +33,4 @@ class EquipmentController extends BaseController
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('equipment')
]);
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/ExceptionController.php b/controllers/ExceptionController.php
index cf21dc7c..84a3b2a8 100644
--- a/controllers/ExceptionController.php
+++ b/controllers/ExceptionController.php
@@ -11,17 +11,17 @@ use Throwable;
class ExceptionController extends BaseApiController
{
- /**
- * @var \Slim\App
- */
- private $app;
-
public function __construct(\Slim\App $app, \DI\Container $container)
{
parent::__construct($container);
$this->app = $app;
}
+ /**
+ * @var \Slim\App
+ */
+ private $app;
+
public function __invoke(ServerRequestInterface $request, Throwable $exception, bool $displayErrorDetails, bool $logErrors, bool $logErrorDetails, ?LoggerInterface $logger = null)
{
$response = $this->app->getResponseFactory()->createResponse();
@@ -59,7 +59,10 @@ class ExceptionController extends BaseApiController
if ($exception instanceof HttpNotFoundException)
{
- define('GROCY_AUTHENTICATED', false);
+ if (!defined('GROCY_AUTHENTICATED'))
+ {
+ define('GROCY_AUTHENTICATED', false);
+ }
return $this->renderPage($response->withStatus(404), 'errors/404', [
'exception' => $exception
diff --git a/controllers/FilesApiController.php b/controllers/FilesApiController.php
index 5dbca1ec..45acfce8 100644
--- a/controllers/FilesApiController.php
+++ b/controllers/FilesApiController.php
@@ -118,11 +118,6 @@ class FilesApiController extends BaseApiController
}
}
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
-
/**
* @param string $fileName base64-encoded file-name
* @return false|string the decoded file-name
@@ -151,7 +146,6 @@ class FilesApiController extends BaseApiController
protected function getFilePath(string $group, string $fileName, array $queryParams = [])
{
$forceServeAs = null;
-
if (isset($queryParams['force_serve_as']) && !empty($queryParams['force_serve_as']))
{
$forceServeAs = $queryParams['force_serve_as'];
@@ -160,14 +154,12 @@ class FilesApiController extends BaseApiController
if ($forceServeAs == FilesService::FILE_SERVE_TYPE_PICTURE)
{
$bestFitHeight = null;
-
if (isset($queryParams['best_fit_height']) && !empty($queryParams['best_fit_height']) && is_numeric($queryParams['best_fit_height']))
{
$bestFitHeight = $queryParams['best_fit_height'];
}
$bestFitWidth = null;
-
if (isset($queryParams['best_fit_width']) && !empty($queryParams['best_fit_width']) && is_numeric($queryParams['best_fit_width']))
{
$bestFitWidth = $queryParams['best_fit_width'];
diff --git a/controllers/GenericEntityApiController.php b/controllers/GenericEntityApiController.php
index 7cb2d518..eb4b1e33 100644
--- a/controllers/GenericEntityApiController.php
+++ b/controllers/GenericEntityApiController.php
@@ -213,11 +213,6 @@ class GenericEntityApiController extends BaseApiController
}
}
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
-
private function IsEntityWithEditRequiresAdmin($entity)
{
return in_array($entity, $this->getOpenApiSpec()->components->schemas->ExposedEntityEditRequiresAdmin->enum);
diff --git a/controllers/GenericEntityController.php b/controllers/GenericEntityController.php
index 7b18cb56..2a1b02fe 100644
--- a/controllers/GenericEntityController.php
+++ b/controllers/GenericEntityController.php
@@ -91,9 +91,4 @@ class GenericEntityController extends BaseController
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('userentity-' . $args['userentityName'])
]);
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/GrocycodeTrait.php b/controllers/GrocycodeTrait.php
new file mode 100644
index 00000000..28453a44
--- /dev/null
+++ b/controllers/GrocycodeTrait.php
@@ -0,0 +1,45 @@
+getQueryParam('size', null);
+
+ if (GROCY_GROCYCODE_TYPE == '2D')
+ {
+ $png = (new DatamatrixFactory())->setCode((string) $grocycode)->setSize($size)->getDatamatrixPngData();
+ }
+ else
+ {
+ $png = (new BarcodeFactory())->setType('C128')->setCode((string) $grocycode)->setHeight($size)->getBarcodePngData();
+ }
+
+ $isDownload = $request->getQueryParam('download', false);
+ if ($isDownload)
+ {
+ $response = $response->withHeader('Content-Type', 'application/octet-stream')
+ ->withHeader('Content-Disposition', 'attachment; filename=grocycode.png')
+ ->withHeader('Content-Length', strlen($png))
+ ->withHeader('Cache-Control', 'no-cache')
+ ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
+ }
+ else
+ {
+ $response = $response->withHeader('Content-Type', 'image/png')
+ ->withHeader('Content-Length', strlen($png))
+ ->withHeader('Cache-Control', 'no-cache')
+ ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
+ }
+ $response->getBody()->write($png);
+ return $response;
+ }
+}
diff --git a/controllers/LoginController.php b/controllers/LoginController.php
index 1182e2cc..304b12bc 100644
--- a/controllers/LoginController.php
+++ b/controllers/LoginController.php
@@ -6,11 +6,6 @@ use Grocy\Services\SessionService;
class LoginController extends BaseController
{
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
-
public function LoginPage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
return $this->renderPage($response, 'login');
diff --git a/controllers/OpenApiController.php b/controllers/OpenApiController.php
index 14aa8194..f1517908 100644
--- a/controllers/OpenApiController.php
+++ b/controllers/OpenApiController.php
@@ -85,9 +85,4 @@ class OpenApiController extends BaseApiController
{
return $this->render($response, 'openapiui');
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/PrintApiController.php b/controllers/PrintApiController.php
index d419be8d..511078ff 100644
--- a/controllers/PrintApiController.php
+++ b/controllers/PrintApiController.php
@@ -34,9 +34,4 @@ class PrintApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/RecipesApiController.php b/controllers/RecipesApiController.php
index 46091c84..263d3998 100644
--- a/controllers/RecipesApiController.php
+++ b/controllers/RecipesApiController.php
@@ -76,9 +76,4 @@ class RecipesApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/RecipesController.php b/controllers/RecipesController.php
index af8e99ae..bfc6507e 100644
--- a/controllers/RecipesController.php
+++ b/controllers/RecipesController.php
@@ -8,19 +8,21 @@ class RecipesController extends BaseController
{
public function MealPlan(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
- // Given date is always the first day of the week => load the coming week / 7 days
- if (isset($request->getQueryParams()['week']) && IsIsoDate($request->getQueryParams()['week']))
+ $start = date('Y-m-d');
+ if (isset($request->getQueryParams()['start']) && IsIsoDate($request->getQueryParams()['start']))
{
- $week = $request->getQueryParams()['week'];
- $mealPlanWhereTimespan = "day BETWEEN DATE('$week') AND DATE('$week', '+7 days')";
+ $start = $request->getQueryParams()['start'];
}
- else
+
+ $days = 6;
+ if (isset($request->getQueryParams()['days']) && filter_var($request->getQueryParams()['days'], FILTER_VALIDATE_INT) !== false)
{
- $mealPlanWhereTimespan = "day BETWEEN DATE('now', 'localtime', 'weekday 0', '-7 days') AND DATE(DATE('now', 'localtime', 'weekday 0', '-7 days'), '+7 days')";
+ $days = $request->getQueryParams()['days'];
}
+ $mealPlanWhereTimespan = "day BETWEEN DATE('$start') AND DATE('$start', '+$days days')";
+
$recipes = $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll();
-
$events = [];
foreach ($this->getDatabase()->meal_plan()->where($mealPlanWhereTimespan) as $mealPlanEntry)
{
@@ -214,9 +216,4 @@ class RecipesController extends BaseController
'mealplanSections' => $this->getDatabase()->meal_plan_sections()->where('id > 0')->orderBy('sort_number')
]);
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/StockApiController.php b/controllers/StockApiController.php
index 0f61bf49..5ca88254 100644
--- a/controllers/StockApiController.php
+++ b/controllers/StockApiController.php
@@ -862,9 +862,4 @@ class StockApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/StockController.php b/controllers/StockController.php
index f5bc45f6..7de604fe 100644
--- a/controllers/StockController.php
+++ b/controllers/StockController.php
@@ -4,11 +4,11 @@ namespace Grocy\Controllers;
use Grocy\Helpers\Grocycode;
use Grocy\Services\RecipesService;
-use jucksearm\barcode\lib\BarcodeFactory;
-use jucksearm\barcode\lib\DatamatrixFactory;
class StockController extends BaseController
{
+ use GrocycodeTrait;
+
public function Consume(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
return $this->renderPage($response, 'consume', [
@@ -192,36 +192,8 @@ class StockController extends BaseController
public function ProductGrocycodeImage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
- $size = $request->getQueryParam('size', null);
$gc = new Grocycode(Grocycode::PRODUCT, $args['productId']);
-
- if (GROCY_GROCYCODE_TYPE == '2D')
- {
- $png = (new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
- }
- else
- {
- $png = (new BarcodeFactory())->setType('C128')->setCode((string) $gc)->setHeight($size)->getBarcodePngData();
- }
-
- $isDownload = $request->getQueryParam('download', false);
- if ($isDownload)
- {
- $response = $response->withHeader('Content-Type', 'application/octet-stream')
- ->withHeader('Content-Disposition', 'attachment; filename=grocycode.png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- else
- {
- $response = $response->withHeader('Content-Type', 'image/png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- $response->getBody()->write($png);
- return $response;
+ return $this->ServeGrocycodeImage($request, $response, $gc);
}
public function ProductGroupEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
@@ -488,38 +460,9 @@ class StockController extends BaseController
public function StockEntryGrocycodeImage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
- $size = $request->getQueryParam('size', null);
-
$stockEntry = $this->getDatabase()->stock()->where('id', $args['entryId'])->fetch();
$gc = new Grocycode(Grocycode::PRODUCT, $stockEntry->product_id, [$stockEntry->stock_id]);
-
- if (GROCY_GROCYCODE_TYPE == '2D')
- {
- $png = (new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
- }
- else
- {
- $png = (new BarcodeFactory())->setType('C128')->setCode((string) $gc)->setHeight($size)->getBarcodePngData();
- }
-
- $isDownload = $request->getQueryParam('download', false);
- if ($isDownload)
- {
- $response = $response->withHeader('Content-Type', 'application/octet-stream')
- ->withHeader('Content-Disposition', 'attachment; filename=grocycode.png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- else
- {
- $response = $response->withHeader('Content-Type', 'image/png')
- ->withHeader('Content-Length', strlen($png))
- ->withHeader('Cache-Control', 'no-cache')
- ->withHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT');
- }
- $response->getBody()->write($png);
- return $response;
+ return $this->ServeGrocycodeImage($request, $response, $gc);
}
public function StockEntryGrocycodeLabel(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
@@ -569,11 +512,6 @@ class StockController extends BaseController
]);
}
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
-
public function JournalSummary(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
$entries = $this->getDatabase()->uihelper_stock_journal_summary();
diff --git a/controllers/SystemApiController.php b/controllers/SystemApiController.php
index 51019c95..913edb95 100644
--- a/controllers/SystemApiController.php
+++ b/controllers/SystemApiController.php
@@ -89,9 +89,4 @@ class SystemApiController extends BaseApiController
{
return $this->ApiResponse($response, json_decode($this->getLocalizationService()->GetPoAsJsonString()), true);
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/SystemController.php b/controllers/SystemController.php
index b358c90d..119964cf 100644
--- a/controllers/SystemController.php
+++ b/controllers/SystemController.php
@@ -35,11 +35,6 @@ class SystemController extends BaseController
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl($this->GetEntryPageRelative()));
}
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
-
/**
* Get the entry page of the application based on the value of the entry page setting.
*
diff --git a/controllers/TasksApiController.php b/controllers/TasksApiController.php
index eba0f4ee..5ccffc0d 100644
--- a/controllers/TasksApiController.php
+++ b/controllers/TasksApiController.php
@@ -49,9 +49,4 @@ class TasksApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/TasksController.php b/controllers/TasksController.php
index 7adca972..08eeee4d 100644
--- a/controllers/TasksController.php
+++ b/controllers/TasksController.php
@@ -83,9 +83,4 @@ class TasksController extends BaseController
{
return $this->renderPage($response, 'taskssettings');
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/controllers/Users/User.php b/controllers/Users/User.php
index 4979c144..b260be67 100644
--- a/controllers/Users/User.php
+++ b/controllers/Users/User.php
@@ -67,6 +67,11 @@ class User
const PERMISSION_USERS_READ = 'USERS_READ';
+ public function __construct()
+ {
+ $this->db = DatabaseService::getInstance()->GetDbConnection();
+ }
+
/**
* @var \LessQL\Database|null
*/
@@ -78,11 +83,6 @@ class User
return $user->getPermissionList();
}
- public function __construct()
- {
- $this->db = DatabaseService::getInstance()->GetDbConnection();
- }
-
public static function checkPermission($request, string ...$permissions): void
{
$user = new self();
diff --git a/controllers/UsersApiController.php b/controllers/UsersApiController.php
index b14a84f4..bc724603 100644
--- a/controllers/UsersApiController.php
+++ b/controllers/UsersApiController.php
@@ -231,9 +231,4 @@ class UsersApiController extends BaseApiController
return $this->GenericErrorResponse($response, $ex->getMessage());
}
}
-
- public function __construct(\DI\Container $container)
- {
- parent::__construct($container);
- }
}
diff --git a/helpers/BaseBarcodeLookupPlugin.php b/helpers/BaseBarcodeLookupPlugin.php
index 6e97dc00..c4df8f33 100644
--- a/helpers/BaseBarcodeLookupPlugin.php
+++ b/helpers/BaseBarcodeLookupPlugin.php
@@ -4,6 +4,12 @@ namespace Grocy\Helpers;
abstract class BaseBarcodeLookupPlugin
{
+ final public function __construct($locations, $quantityUnits)
+ {
+ $this->Locations = $locations;
+ $this->QuantityUnits = $quantityUnits;
+ }
+
protected $Locations;
protected $QuantityUnits;
@@ -50,28 +56,24 @@ abstract class BaseBarcodeLookupPlugin
// Check referenced entity ids are valid
$locationId = $pluginOutput['location_id'];
-
if (FindObjectInArrayByPropertyValue($this->Locations, 'id', $locationId) === null)
{
throw new \Exception("Location $locationId is not a valid location id");
}
$quIdPurchase = $pluginOutput['qu_id_purchase'];
-
if (FindObjectInArrayByPropertyValue($this->QuantityUnits, 'id', $quIdPurchase) === null)
{
throw new \Exception("Location $quIdPurchase is not a valid quantity unit id");
}
$quIdStock = $pluginOutput['qu_id_stock'];
-
if (FindObjectInArrayByPropertyValue($this->QuantityUnits, 'id', $quIdStock) === null)
{
throw new \Exception("Location $quIdStock is not a valid quantity unit id");
}
$quFactor = $pluginOutput['qu_factor_purchase_to_stock'];
-
if (empty($quFactor) || !is_numeric($quFactor))
{
throw new \Exception('Quantity unit factor is empty or not a number');
@@ -80,11 +82,5 @@ abstract class BaseBarcodeLookupPlugin
return $pluginOutput;
}
- final public function __construct($locations, $quantityUnits)
- {
- $this->Locations = $locations;
- $this->QuantityUnits = $quantityUnits;
- }
-
abstract protected function ExecuteLookup($barcode);
}
diff --git a/helpers/Grocycode.php b/helpers/Grocycode.php
index 5f8a9907..3f9af599 100644
--- a/helpers/Grocycode.php
+++ b/helpers/Grocycode.php
@@ -25,6 +25,33 @@ class Grocycode
public const MAGIC = 'grcy';
+ /**
+ * Constructs a new instance of the Grocycode class.
+ *
+ * Because php doesn't support overloading, this is a proxy
+ * to either setFromCode($code) or setFromData($type, $id, $extra_data = []).
+ */
+ public function __construct(...$args)
+ {
+ $argc = count($args);
+ if ($argc == 1)
+ {
+ $this->setFromCode($args[0]);
+ return;
+ }
+ elseif ($argc == 2 || $argc == 3)
+ {
+ if ($argc == 2)
+ {
+ $args[] = [];
+ }
+ $this->setFromData($args[0], $args[1], $args[2]);
+ return;
+ }
+
+ throw new \Exception('No suitable overload found.');
+ }
+
/**
* An array that registers all valid grocycode types. Register yours here by appending to this array.
*/
@@ -56,31 +83,26 @@ class Grocycode
}
}
- /**
- * Constructs a new instance of the Grocycode class.
- *
- * Because php doesn't support overloading, this is a proxy
- * to either setFromCode($code) or setFromData($type, $id, $extra_data = []).
- */
- public function __construct(...$args)
+ public function GetId()
{
- $argc = count($args);
- if ($argc == 1)
- {
- $this->setFromCode($args[0]);
- return;
- }
- elseif ($argc == 2 || $argc == 3)
- {
- if ($argc == 2)
- {
- $args[] = [];
- }
- $this->setFromData($args[0], $args[1], $args[2]);
- return;
- }
+ return $this->id;
+ }
- throw new \Exception('No suitable overload found.');
+ public function GetExtraData()
+ {
+ return $this->extra_data;
+ }
+
+ public function GetType()
+ {
+ return $this->type;
+ }
+
+ public function __toString(): string
+ {
+ $arr = array_merge([self::MAGIC, $this->type, $this->id], $this->extra_data);
+
+ return implode(':', $arr);
}
/**
@@ -121,26 +143,4 @@ class Grocycode
$this->id = $id;
$this->extra_data = $extra_data;
}
-
- public function GetId()
- {
- return $this->id;
- }
-
- public function GetExtraData()
- {
- return $this->extra_data;
- }
-
- public function GetType()
- {
- return $this->type;
- }
-
- public function __toString(): string
- {
- $arr = array_merge([self::MAGIC, $this->type, $this->id], $this->extra_data);
-
- return implode(':', $arr);
- }
}
diff --git a/helpers/UrlManager.php b/helpers/UrlManager.php
index 4f137a36..af83476d 100644
--- a/helpers/UrlManager.php
+++ b/helpers/UrlManager.php
@@ -4,6 +4,18 @@ namespace Grocy\Helpers;
class UrlManager
{
+ public function __construct(string $basePath)
+ {
+ if ($basePath === '/')
+ {
+ $this->BasePath = $this->GetBaseUrl();
+ }
+ else
+ {
+ $this->BasePath = $basePath;
+ }
+ }
+
protected $BasePath;
public function ConstructUrl($relativePath, $isResource = false)
@@ -18,18 +30,6 @@ class UrlManager
}
}
- public function __construct(string $basePath)
- {
- if ($basePath === '/')
- {
- $this->BasePath = $this->GetBaseUrl();
- }
- else
- {
- $this->BasePath = $basePath;
- }
- }
-
private function GetBaseUrl()
{
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
diff --git a/helpers/WebhookRunner.php b/helpers/WebhookRunner.php
index a7a1aa25..150155a5 100644
--- a/helpers/WebhookRunner.php
+++ b/helpers/WebhookRunner.php
@@ -8,13 +8,13 @@ use Psr\Http\Message\ResponseInterface;
class WebhookRunner
{
- private $client;
-
public function __construct()
{
$this->client = new Client(['timeout' => 2.0]);
}
+ private $client;
+
public function run($url, $args, $json = false)
{
$reqArgs = [];
diff --git a/helpers/extensions.php b/helpers/extensions.php
index c17f6ab7..27c25f60 100644
--- a/helpers/extensions.php
+++ b/helpers/extensions.php
@@ -4,8 +4,7 @@ function FindObjectInArrayByPropertyValue($array, $propertyName, $propertyValue)
{
foreach ($array as $object)
{
- if ($object->{$propertyName}
- == $propertyValue)
+ if ($object->{$propertyName} == $propertyValue)
{
return $object;
}
@@ -17,37 +16,28 @@ function FindObjectInArrayByPropertyValue($array, $propertyName, $propertyValue)
function FindAllObjectsInArrayByPropertyValue($array, $propertyName, $propertyValue, $operator = '==')
{
$returnArray = [];
-
foreach ($array as $object)
{
switch ($operator)
{
case '==':
-
- if ($object->{$propertyName}
- == $propertyValue)
+ if ($object->{$propertyName} == $propertyValue)
{
$returnArray[] = $object;
}
-
break;
case '>':
-
- if ($object->{$propertyName}
- > $propertyValue)
+ if ($object->{$propertyName} > $propertyValue)
{
$returnArray[] = $object;
}
-
break;
case '<':
- if ($object->{$propertyName}
- < $propertyValue)
+ if ($object->{$propertyName} < $propertyValue)
{
$returnArray[] = $object;
}
-
break;
}
}
@@ -58,7 +48,6 @@ function FindAllObjectsInArrayByPropertyValue($array, $propertyName, $propertyVa
function FindAllItemsInArrayByValue($array, $value, $operator = '==')
{
$returnArray = [];
-
foreach ($array as $item)
{
switch ($operator)
@@ -69,7 +58,6 @@ function FindAllItemsInArrayByValue($array, $value, $operator = '==')
{
$returnArray[] = $item;
}
-
break;
case '>':
@@ -77,7 +65,6 @@ function FindAllItemsInArrayByValue($array, $value, $operator = '==')
{
$returnArray[] = $item;
}
-
break;
case '<':
@@ -85,7 +72,6 @@ function FindAllItemsInArrayByValue($array, $value, $operator = '==')
{
$returnArray[] = $item;
}
-
break;
}
}
@@ -96,7 +82,6 @@ function FindAllItemsInArrayByValue($array, $value, $operator = '==')
function SumArrayValue($array, $propertyName)
{
$sum = 0;
-
foreach ($array as $object)
{
$sum += floatval($object->{$propertyName});
@@ -124,7 +109,6 @@ function GetClassConstants($className, $prefix = null)
function RandomString($length, $allowedChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
$randomString = '';
-
for ($i = 0; $i < $length; $i++)
{
$randomString .= $allowedChars[rand(0, strlen($allowedChars) - 1)];
@@ -190,7 +174,8 @@ function Setting(string $name, $value)
define('GROCY_' . $name, ExternalSettingValue(file_get_contents($settingOverrideFile)));
}
elseif (getenv('GROCY_' . $name) !== false)
- { // An environment variable with the same name and prefix GROCY_ overwrites the given setting
+ {
+ // An environment variable with the same name and prefix GROCY_ overwrites the given setting
define('GROCY_' . $name, ExternalSettingValue(getenv('GROCY_' . $name)));
}
else
diff --git a/localization/he_IL/demo_data.po b/localization/he_IL/demo_data.po
index 2d038990..64327717 100644
--- a/localization/he_IL/demo_data.po
+++ b/localization/he_IL/demo_data.po
@@ -2,7 +2,7 @@
# Translators:
# Adi Zarko , 2020
# Netanel Lazarovich , 2020
-# Yaron Shahrabani , 2020
+# Yaron Shahrabani , 2021
#
msgid ""
msgstr ""
@@ -10,7 +10,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
"PO-Revision-Date: 2019-05-01 17:42+0000\n"
-"Last-Translator: Yaron Shahrabani , 2020\n"
+"Last-Translator: Yaron Shahrabani , 2021\n"
"Language-Team: Hebrew (Israel) (https://www.transifex.com/grocy/teams/93189/he_IL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -402,10 +402,10 @@ msgid "Finnish"
msgstr "פינית"
msgid "Breakfast"
-msgstr ""
+msgstr "ארוחת בוקר"
msgid "Lunch"
-msgstr ""
+msgstr "ארוחת צהריים"
msgid "Dinner"
-msgstr ""
+msgstr "ארוחת ערב"
diff --git a/localization/he_IL/strings.po b/localization/he_IL/strings.po
index c9f0560a..bf23baa3 100644
--- a/localization/he_IL/strings.po
+++ b/localization/he_IL/strings.po
@@ -2481,22 +2481,22 @@ msgid "Stock entry"
msgstr "רשומה במלאי"
msgid "Configure sections"
-msgstr ""
+msgstr "הגדרת סעיפים"
msgid "Meal plan sections"
-msgstr ""
+msgstr "סעיפי תכנית ארוחות"
msgid "Create meal plan section"
-msgstr ""
+msgstr "יצירת סעיף תכנית ארוחות"
msgid "Sections will be ordered by that number on the meal plan"
-msgstr ""
+msgstr "הסעיפים יסודרו לפי המספר על תכנית הארוחות"
msgid "Edit meal plan section"
-msgstr ""
+msgstr "עריכת סעיף תכנית ארוחות"
msgid "Are you sure to delete meal plan section \"%s\"?"
-msgstr ""
+msgstr "למחוק את הסעיף „%s” מתכנית הארוחות?"
msgid "Section"
-msgstr ""
+msgstr "סעיף"
diff --git a/middleware/ApiKeyAuthMiddleware.php b/middleware/ApiKeyAuthMiddleware.php
index ea65025d..7cce2bcd 100644
--- a/middleware/ApiKeyAuthMiddleware.php
+++ b/middleware/ApiKeyAuthMiddleware.php
@@ -9,14 +9,14 @@ use Slim\Routing\RouteContext;
class ApiKeyAuthMiddleware extends AuthMiddleware
{
- protected $ApiKeyHeaderName;
-
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
{
parent::__construct($container, $responseFactory);
$this->ApiKeyHeaderName = $this->AppContainer->get('ApiKeyHeaderName');
}
+ protected $ApiKeyHeaderName;
+
public function authenticate(Request $request)
{
$routeContext = RouteContext::fromRequest($request);
diff --git a/middleware/AuthMiddleware.php b/middleware/AuthMiddleware.php
index 3b3d75f0..bb4fe443 100644
--- a/middleware/AuthMiddleware.php
+++ b/middleware/AuthMiddleware.php
@@ -11,14 +11,14 @@ use Slim\Routing\RouteContext;
abstract class AuthMiddleware extends BaseMiddleware
{
- protected $ResponseFactory;
-
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
{
parent::__construct($container);
$this->ResponseFactory = $responseFactory;
}
+ protected $ResponseFactory;
+
public function __invoke(Request $request, RequestHandler $handler): Response
{
$routeContext = RouteContext::fromRequest($request);
diff --git a/middleware/LocaleMiddleware.php b/middleware/LocaleMiddleware.php
index c0acede4..3b2f6b06 100644
--- a/middleware/LocaleMiddleware.php
+++ b/middleware/LocaleMiddleware.php
@@ -21,7 +21,6 @@ class LocaleMiddleware extends BaseMiddleware
if (defined('GROCY_AUTHENTICATED') && GROCY_AUTHENTICATED)
{
$locale = UsersService::getInstance()->GetUserSetting(GROCY_USER_ID, 'locale');
-
if (isset($locale) && !empty($locale))
{
if (in_array($locale, scandir(__DIR__ . '/../localization')))
@@ -46,7 +45,6 @@ class LocaleMiddleware extends BaseMiddleware
arsort($prefLocales);
$availableLocales = scandir(__DIR__ . '/../localization');
-
foreach ($prefLocales as $locale => $q)
{
if (in_array($locale, $availableLocales))
@@ -60,7 +58,7 @@ class LocaleMiddleware extends BaseMiddleware
return substr($locale, 0, 5);
}
- // e.g: cs
+ // e.g. cs
if (in_array(substr($locale, 0, 2), $availableLocales))
{
return substr($locale, 0, 2);
diff --git a/migrations/0149.sql b/migrations/0149.sql
index cade364f..6e135eeb 100644
--- a/migrations/0149.sql
+++ b/migrations/0149.sql
@@ -12,3 +12,13 @@ VALUES
ALTER TABLE meal_plan
ADD section_id INTEGER NOT NULL DEFAULT -1;
+
+CREATE TRIGGER prevent_internal_meal_plan_section_removal BEFORE DELETE ON meal_plan_sections
+BEGIN
+ SELECT CASE WHEN((
+ SELECT 1
+ FROM meal_plan_sections
+ WHERE id = OLD.id
+ AND id = -1
+ ) NOTNULL) THEN RAISE(ABORT, "This is an internally used/required default section and therefore can't be deleted") END;
+END;
diff --git a/public/js/grocy.js b/public/js/grocy.js
index 73f0dc6b..1208f6ef 100644
--- a/public/js/grocy.js
+++ b/public/js/grocy.js
@@ -1116,5 +1116,12 @@ $(document).on("click", ".change-table-columns-rowgroup-toggle", function()
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_RECIPES)
{
- $("#meal-plan-nav-link").attr("href", $("#meal-plan-nav-link").attr("href") + "?week=" + moment().startOf("week").format("YYYY-MM-DD"));
+ if ($(window).width() < 768)
+ {
+ $("#meal-plan-nav-link").attr("href", $("#meal-plan-nav-link").attr("href") + "?start=" + moment().format("YYYY-MM-DD") + "&days=0");
+ }
+ else
+ {
+ $("#meal-plan-nav-link").attr("href", $("#meal-plan-nav-link").attr("href") + "?start=" + moment().startOf("week").format("YYYY-MM-DD"));
+ }
}
diff --git a/public/viewjs/mealplan.js b/public/viewjs/mealplan.js
index 4775f915..ed8369b5 100644
--- a/public/viewjs/mealplan.js
+++ b/public/viewjs/mealplan.js
@@ -48,7 +48,7 @@ $(".calendar").each(function()
"scrollTime": "00:00:00",
"firstDay": firstDay,
"height": "auto",
- "defaultDate": GetUriParam("week"),
+ "defaultDate": GetUriParam("start"),
"viewRender": function(view)
{
if (!isPrimarySection)
@@ -309,7 +309,7 @@ $(".calendar").each(function()
{
if (isPrimarySection)
{
- UpdateUriParam("week", view.start.format("YYYY-MM-DD"));
+ UpdateUriParam("start", view.start.format("YYYY-MM-DD"));
if (firstRender)
{
diff --git a/services/ApplicationService.php b/services/ApplicationService.php
index 819572ff..ef244d13 100644
--- a/services/ApplicationService.php
+++ b/services/ApplicationService.php
@@ -9,7 +9,6 @@ class ApplicationService extends BaseService
public function GetChangelog()
{
$changelogItems = [];
-
foreach (glob(__DIR__ . '/../changelog/*.md') as $file)
{
$fileName = basename($file);
diff --git a/services/BaseService.php b/services/BaseService.php
index 0dc60297..cff227d8 100644
--- a/services/BaseService.php
+++ b/services/BaseService.php
@@ -6,14 +6,9 @@ class BaseService
{
private static $instances = [];
- public function __construct()
- {
- }
-
public static function getInstance()
{
$className = get_called_class();
-
if (!isset(self::$instances[$className]))
{
self::$instances[$className] = new $className();
diff --git a/services/CalendarService.php b/services/CalendarService.php
index 91ded607..373a3649 100644
--- a/services/CalendarService.php
+++ b/services/CalendarService.php
@@ -6,6 +6,13 @@ use Grocy\Helpers\UrlManager;
class CalendarService extends BaseService
{
+ public function __construct()
+ {
+ $this->UrlManager = new UrlManager(GROCY_BASE_URL);
+ }
+
+ private $UrlManager;
+
public function GetEvents()
{
$stockEvents = [];
@@ -148,10 +155,4 @@ class CalendarService extends BaseService
return array_merge($stockEvents, $taskEvents, $choreEvents, $batteryEvents, $mealPlanRecipeEvents, $mealPlanNotesEvents, $mealPlanProductEvents);
}
-
- public function __construct()
- {
- parent::__construct();
- $this->UrlManager = new UrlManager(GROCY_BASE_URL);
- }
}
diff --git a/services/ChoresService.php b/services/ChoresService.php
index 7f7da859..7f265bfb 100644
--- a/services/ChoresService.php
+++ b/services/ChoresService.php
@@ -38,7 +38,6 @@ class ChoresService extends BaseService
$users = $this->getUsersService()->GetUsersAsDto();
$assignedUsers = [];
-
foreach ($users as $user)
{
if (in_array($user->id, explode(',', $chore->assignment_config)))
@@ -210,11 +209,6 @@ class ChoresService extends BaseService
]);
}
- public function __construct()
- {
- parent::__construct();
- }
-
private function ChoreExists($choreId)
{
$choreRow = $this->getDatabase()->chores()->where('id = :1', $choreId)->fetch();
diff --git a/services/DatabaseMigrationService.php b/services/DatabaseMigrationService.php
index 8385d8e8..014096aa 100644
--- a/services/DatabaseMigrationService.php
+++ b/services/DatabaseMigrationService.php
@@ -4,6 +4,9 @@ namespace Grocy\Services;
class DatabaseMigrationService extends BaseService
{
+ // This migration will be always execute, can be used to fix things manually
+ const EMERGENCY_MIGRATION_ID = 9999;
+
public function MigrateDatabase()
{
$this->getDatabaseService()->ExecuteDbStatement("CREATE TABLE IF NOT EXISTS migrations (migration INTEGER NOT NULL PRIMARY KEY UNIQUE, execution_time_timestamp DATETIME DEFAULT (datetime('now', 'localtime')))");
@@ -36,10 +39,14 @@ class DatabaseMigrationService extends BaseService
{
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
- if (intval($rowCount) === 0)
+ if (intval($rowCount) === 0 || $migrationId == self::EMERGENCY_MIGRATION_ID)
{
include $phpFile;
- $this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
+
+ if ($migrationId != self::EMERGENCY_MIGRATION_ID)
+ {
+ $this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
+ }
}
}
@@ -47,14 +54,18 @@ class DatabaseMigrationService extends BaseService
{
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
- if (intval($rowCount) === 0)
+ if (intval($rowCount) === 0 || $migrationId == self::EMERGENCY_MIGRATION_ID)
{
$this->getDatabaseService()->GetDbConnectionRaw()->beginTransaction();
try
{
$this->getDatabaseService()->ExecuteDbStatement($sql);
- $this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
+
+ if ($migrationId != self::EMERGENCY_MIGRATION_ID)
+ {
+ $this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
+ }
}
catch (Exception $ex)
{
diff --git a/services/DemoDataGeneratorService.php b/services/DemoDataGeneratorService.php
index d57552fc..80c26966 100644
--- a/services/DemoDataGeneratorService.php
+++ b/services/DemoDataGeneratorService.php
@@ -4,6 +4,11 @@ namespace Grocy\Services;
class DemoDataGeneratorService extends BaseService
{
+ public function __construct()
+ {
+ $this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
+ }
+
protected $LocalizationService;
private $LastSupermarketId = 1;
@@ -343,12 +348,6 @@ class DemoDataGeneratorService extends BaseService
}
}
- public function __construct()
- {
- parent::__construct();
- $this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
- }
-
private function DownloadFileIfNotAlreadyExists($sourceUrl, $destinationPath)
{
if (!file_exists($destinationPath))
diff --git a/services/FilesService.php b/services/FilesService.php
index 053dd034..7d070350 100644
--- a/services/FilesService.php
+++ b/services/FilesService.php
@@ -8,6 +8,30 @@ class FilesService extends BaseService
{
const FILE_SERVE_TYPE_PICTURE = 'picture';
+ public function __construct()
+ {
+ $this->StoragePath = GROCY_DATAPATH . '/storage';
+ if (!file_exists($this->StoragePath))
+ {
+ mkdir($this->StoragePath);
+ }
+
+ if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
+ {
+ $dbSuffix = GROCY_DEFAULT_LOCALE;
+ if (defined('GROCY_DEMO_DB_SUFFIX'))
+ {
+ $dbSuffix = GROCY_DEMO_DB_SUFFIX;
+ }
+
+ $this->StoragePath = $this->StoragePath . '/' . $dbSuffix;
+ if (!file_exists($this->StoragePath))
+ {
+ mkdir($this->StoragePath);
+ }
+ }
+ }
+
private $StoragePath;
public function DownscaleImage($group, $fileName, $bestFitHeight = null, $bestFitWidth = null)
@@ -58,8 +82,9 @@ class FilesService extends BaseService
$fileNameWithoutExtension = pathinfo($filePath, PATHINFO_FILENAME);
$fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);
+ // Then the file is an image
if (getimagesize($filePath) !== false)
- { // Then the file is an image
+ {
// Also delete all corresponding "__downscaledto" files when deleting an image
$groupFolderPath = $this->StoragePath . '/' . $group;
$files = scandir($groupFolderPath);
@@ -87,32 +112,4 @@ class FilesService extends BaseService
return $groupFolderPath . '/' . $fileName;
}
-
- public function __construct()
- {
- parent::__construct();
-
- $this->StoragePath = GROCY_DATAPATH . '/storage';
-
- if (!file_exists($this->StoragePath))
- {
- mkdir($this->StoragePath);
- }
-
- if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
- {
- $dbSuffix = GROCY_DEFAULT_LOCALE;
- if (defined('GROCY_DEMO_DB_SUFFIX'))
- {
- $dbSuffix = GROCY_DEMO_DB_SUFFIX;
- }
-
- $this->StoragePath = $this->StoragePath . '/' . $dbSuffix;
-
- if (!file_exists($this->StoragePath))
- {
- mkdir($this->StoragePath);
- }
- }
- }
}
diff --git a/services/LocalizationService.php b/services/LocalizationService.php
index 7a19d633..58013998 100644
--- a/services/LocalizationService.php
+++ b/services/LocalizationService.php
@@ -8,6 +8,13 @@ use Gettext\Translator;
class LocalizationService
{
+ public function __construct(string $culture)
+ {
+ $this->Culture = $culture;
+
+ $this->LoadLocalizations($culture);
+ }
+
protected $Po;
protected $PoUserStrings;
@@ -62,13 +69,6 @@ class LocalizationService
return $this->Po->toJsonString();
}
- public function __construct(string $culture)
- {
- $this->Culture = $culture;
-
- $this->LoadLocalizations($culture);
- }
-
public function __n($number, $singularForm, $pluralForm)
{
$this->CheckAndAddMissingTranslationToPot($singularForm);
diff --git a/services/PrintService.php b/services/PrintService.php
index c6f1053b..220bbb55 100644
--- a/services/PrintService.php
+++ b/services/PrintService.php
@@ -10,6 +10,39 @@ use Mike42\Escpos\Printer;
class PrintService extends BaseService
{
+ /**
+ * @param bool $printHeader Printing of Grocy logo
+ * @param string[] $lines Items to print
+ * @return string[] Returns array with result OK if no exception
+ * @throws Exception If unable to print, an exception is thrown
+ */
+ public function printShoppingList(bool $printHeader, array $lines): array
+ {
+ $printer = self::getPrinterHandle();
+ if ($printer === false)
+ {
+ throw new Exception('Unable to connect to printer');
+ }
+
+ if ($printHeader)
+ {
+ self::printHeader($printer);
+ }
+
+ foreach ($lines as $line)
+ {
+ $printer->text($line);
+ $printer->feed();
+ }
+
+ $printer->feed(3);
+ $printer->cut();
+ $printer->close();
+ return [
+ 'result' => 'OK'
+ ];
+ }
+
/**
* Initialises the printer
* @return Printer Printer handle
@@ -50,37 +83,4 @@ class PrintService extends BaseService
$printer->selectPrintMode();
$printer->feed(2);
}
-
- /**
- * @param bool $printHeader Printing of Grocy logo
- * @param string[] $lines Items to print
- * @return string[] Returns array with result OK if no exception
- * @throws Exception If unable to print, an exception is thrown
- */
- public function printShoppingList(bool $printHeader, array $lines): array
- {
- $printer = self::getPrinterHandle();
- if ($printer === false)
- {
- throw new Exception('Unable to connect to printer');
- }
-
- if ($printHeader)
- {
- self::printHeader($printer);
- }
-
- foreach ($lines as $line)
- {
- $printer->text($line);
- $printer->feed();
- }
-
- $printer->feed(3);
- $printer->cut();
- $printer->close();
- return [
- 'result' => 'OK'
- ];
- }
}
diff --git a/services/RecipesService.php b/services/RecipesService.php
index 0cdc126b..b98b689c 100644
--- a/services/RecipesService.php
+++ b/services/RecipesService.php
@@ -63,8 +63,8 @@ class RecipesService extends BaseService
}
$transactionId = uniqid();
- $recipePositions = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id', $recipeId)->fetchAll();
+ $recipePositions = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id', $recipeId)->fetchAll();
foreach ($recipePositions as $recipePosition)
{
if ($recipePosition->only_check_single_unit_in_stock == 0)
@@ -129,11 +129,6 @@ class RecipesService extends BaseService
return $lastInsertId;
}
- public function __construct()
- {
- parent::__construct();
- }
-
private function RecipeExists($recipeId)
{
$recipeRow = $this->getDataBase()->recipes()->where('id = :1', $recipeId)->fetch();
diff --git a/services/SessionService.php b/services/SessionService.php
index d7033b7c..89013bbc 100644
--- a/services/SessionService.php
+++ b/services/SessionService.php
@@ -12,7 +12,6 @@ class SessionService extends BaseService
public function CreateSession($userId, $stayLoggedInPermanently = false)
{
$newSessionKey = $this->GenerateSessionKey();
-
$expires = date('Y-m-d H:i:s', intval(time() + 2592000));
// Default is that sessions expire in 30 days
@@ -39,7 +38,6 @@ class SessionService extends BaseService
public function GetUserBySessionKey($sessionKey)
{
$sessionRow = $this->getDatabase()->sessions()->where('session_key', $sessionKey)->fetch();
-
if ($sessionRow !== null)
{
return $this->getDatabase()->users($sessionRow->user_id);
@@ -60,7 +58,6 @@ class SessionService extends BaseService
else
{
$sessionRow = $this->getDatabase()->sessions()->where('session_key = :1 AND expires > :2', $sessionKey, date('Y-m-d H:i:s', time()))->fetch();
-
if ($sessionRow !== null)
{
// This should not change the database file modification time as this is used
diff --git a/services/StockService.php b/services/StockService.php
index bf4695a6..f73ac5bd 100644
--- a/services/StockService.php
+++ b/services/StockService.php
@@ -33,7 +33,6 @@ class StockService extends BaseService
}
$missingProducts = $this->GetMissingProducts();
-
foreach ($missingProducts as $missingProduct)
{
$product = $this->getDatabase()->products()->where('id', $missingProduct->id)->fetch();
@@ -42,7 +41,8 @@ class StockService extends BaseService
$alreadyExistingEntry = $this->getDatabase()->shopping_list()->where('product_id', $missingProduct->id)->fetch();
if ($alreadyExistingEntry)
- { // Update
+ {
+ // Update
if ($alreadyExistingEntry->amount < $amountToAdd)
{
$alreadyExistingEntry->update([
@@ -52,7 +52,8 @@ class StockService extends BaseService
}
}
else
- { // Insert
+ {
+ // Insert
$shoppinglistRow = $this->getDatabase()->shopping_list()->createRow([
'product_id' => $missingProduct->id,
'amount' => $amountToAdd,
@@ -197,7 +198,8 @@ class StockService extends BaseService
{
$reps = 1;
if ($runWebhook == 2)
- { // 2 == run $amount times
+ {
+ // 2 == run $amount times
$reps = intval(floor($amount));
}
@@ -428,7 +430,6 @@ class StockService extends BaseService
public function EditStockEntry(int $stockRowId, float $amount, $bestBeforeDate, $locationId, $shoppingLocationId, $price, $open, $purchasedDate)
{
$stockRow = $this->getDatabase()->stock()->where('id = :1', $stockRowId)->fetch();
-
if ($stockRow === null)
{
throw new \Exception('Stock does not exist');
@@ -455,7 +456,6 @@ class StockService extends BaseService
$logOldRowForStockUpdate->save();
$openedDate = $stockRow->opened_date;
-
if (boolval($open) && $openedDate == null)
{
$openedDate = date('Y-m-d');
@@ -505,7 +505,8 @@ class StockService extends BaseService
$pluginOutput = $plugin->Lookup($barcode);
if ($pluginOutput !== null)
- { // Lookup was successful
+ {
+ // Lookup was successful
if ($addFoundProduct === true)
{
// Add product to database and include new product id in output
@@ -522,7 +523,6 @@ class StockService extends BaseService
public function GetCurrentStock($includeNotInStockButMissingProducts = false)
{
$sql = 'SELECT * FROM stock_current';
-
if ($includeNotInStockButMissingProducts)
{
$missingProductsView = 'stock_missing_products_including_opened';
@@ -538,7 +538,6 @@ class StockService extends BaseService
$currentStockMapped = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_GROUP | \PDO::FETCH_OBJ);
$relevantProducts = $this->getDatabase()->products()->where('id IN (SELECT product_id FROM (' . $sql . ') x)');
-
foreach ($relevantProducts as $product)
{
$currentStockMapped[$product->id][0]->product_id = $product->id;
@@ -614,7 +613,6 @@ class StockService extends BaseService
}
$stockCurrentRow = FindObjectinArrayByPropertyValue($this->GetCurrentStock(), 'product_id', $productId);
-
if ($stockCurrentRow == null)
{
$stockCurrentRow = new \stdClass();
@@ -665,7 +663,6 @@ class StockService extends BaseService
{
$consumeCount = 1;
}
-
$spoilRate = ($consumeCountSpoiled * 100.0) / $consumeCount;
return [
@@ -704,7 +701,6 @@ class StockService extends BaseService
}
$potentialProduct = $this->getDatabase()->product_barcodes()->where('barcode = :1', $barcode)->fetch();
-
if ($potentialProduct === null)
{
throw new \Exception("No product with barcode $barcode found");
@@ -722,8 +718,8 @@ class StockService extends BaseService
$returnData = [];
$shoppingLocations = $this->getDatabase()->shopping_locations();
- $rows = $this->getDatabase()->product_price_history()->where('product_id = :1', $productId)->orderBy('purchased_date', 'DESC');
+ $rows = $this->getDatabase()->product_price_history()->where('product_id = :1', $productId)->orderBy('purchased_date', 'DESC');
foreach ($rows as $row)
{
$returnData[] = [
@@ -998,6 +994,7 @@ class StockService extends BaseService
{
$decimals = intval($this->getUsersService()->GetUserSetting(GROCY_USER_ID, 'stock_decimal_places_amounts'));
$newAmount = $productRow->amount - $amount;
+
if ($newAmount < floatval('0.' . str_repeat('0', $decimals - ($decimals <= 0 ? 0 : 1)) . '1'))
{
$productRow->delete();
@@ -1032,13 +1029,16 @@ class StockService extends BaseService
{
$product = $this->getDatabase()->products()->where('id = :1', $row->product_id)->fetch();
$conversion = $this->getDatabase()->quantity_unit_conversions_resolved()->where('product_id = :1 AND from_qu_id = :2 AND to_qu_id = :3', $product->id, $product->qu_id_stock, $row->qu_id)->fetch();
+
$factor = 1.0;
if ($conversion != null)
{
$factor = floatval($conversion->factor);
}
+
$amount = round($row->amount * $factor);
$note = '';
+
if (GROCY_TPRINTER_PRINT_NOTES)
{
if ($row->note != '')
@@ -1047,6 +1047,7 @@ class StockService extends BaseService
}
}
}
+
if (GROCY_TPRINTER_PRINT_QUANTITY_NAME && $isValidProduct)
{
$quantityname = $row->qu_name;
@@ -1054,6 +1055,7 @@ class StockService extends BaseService
{
$quantityname = $row->qu_name_plural;
}
+
array_push($result_quantity, $amount . ' ' . $quantityname);
array_push($result_product, $row->product_name . $note);
}
@@ -1071,6 +1073,7 @@ class StockService extends BaseService
}
}
}
+
//Add padding to look nicer
$maxlength = 1;
foreach ($result_quantity as $quantity)
@@ -1080,6 +1083,7 @@ class StockService extends BaseService
$maxlength = strlen($quantity);
}
}
+
$result = [];
$length = count($result_quantity);
for ($i = 0; $i < $length; $i++)
@@ -1087,6 +1091,7 @@ class StockService extends BaseService
$quantity = str_pad($result_quantity[$i], $maxlength);
array_push($result, $quantity . ' ' . $result_product[$i]);
}
+
return $result;
}
@@ -1222,7 +1227,8 @@ class StockService extends BaseService
$amount -= $stockEntry->amount;
}
else
- { // Stock entry amount is > than needed amount -> split the stock entry resp. update the amount
+ {
+ // Stock entry amount is > than needed amount -> split the stock entry resp. update the amount
$restStockAmount = $stockEntry->amount - $amount;
$logRowForLocationFrom = $this->getDatabase()->stock_log()->createRow([
diff --git a/services/UserfieldsService.php b/services/UserfieldsService.php
index 75161e5a..0f48eddf 100644
--- a/services/UserfieldsService.php
+++ b/services/UserfieldsService.php
@@ -149,11 +149,6 @@ class UserfieldsService extends BaseService
}
}
- public function __construct()
- {
- parent::__construct();
- }
-
protected function getOpenApispec()
{
if ($this->OpenApiSpec == null)
diff --git a/services/UsersService.php b/services/UsersService.php
index 6738ee9b..bc530e1d 100644
--- a/services/UsersService.php
+++ b/services/UsersService.php
@@ -97,7 +97,6 @@ class UsersService extends BaseService
public function SetUserSetting($userId, $settingKey, $settingValue)
{
$settingRow = $this->getDatabase()->user_settings()->where('user_id = :1 AND key = :2', $userId, $settingKey)->fetch();
-
if ($settingRow !== null)
{
$settingRow->update([
diff --git a/version.json b/version.json
index 0e41f51e..5e5fbfce 100644
--- a/version.json
+++ b/version.json
@@ -1,4 +1,4 @@
{
- "Version": "3.0.1",
- "ReleaseDate": "2021-01-05"
+ "Version": "3.1.0",
+ "ReleaseDate": "2021-07-16"
}