mirror of
https://github.com/grocy/grocy.git
synced 2025-08-17 11:06:36 +00:00
Applied PHP formatting rules
This commit is contained in:
23
app.php
23
app.php
@@ -1,20 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Grocy\Controllers\LoginController;
|
||||||
|
use Grocy\Helpers\UrlManager;
|
||||||
use Grocy\Middleware\CorsMiddleware;
|
use Grocy\Middleware\CorsMiddleware;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
|
||||||
use Psr\Container\ContainerInterface as Container;
|
use Psr\Container\ContainerInterface as Container;
|
||||||
use Slim\Factory\AppFactory;
|
use Slim\Factory\AppFactory;
|
||||||
|
|
||||||
use Grocy\Helpers\UrlManager;
|
|
||||||
use Grocy\Controllers\LoginController;
|
|
||||||
|
|
||||||
// Load composer dependencies
|
// Load composer dependencies
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
// Load config files
|
// Load config files
|
||||||
require_once GROCY_DATAPATH . '/config.php';
|
require_once GROCY_DATAPATH . '/config.php';
|
||||||
require_once __DIR__ . '/config-dist.php'; // For not in own config defined values we use the default ones
|
require_once __DIR__ . '/config-dist.php';
|
||||||
|
|
||||||
|
// For not in own config defined values we use the default ones
|
||||||
|
|
||||||
// Definitions for dev/demo/prerelease mode
|
// Definitions for dev/demo/prerelease mode
|
||||||
if ((GROCY_MODE === 'dev' || GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease') && !defined('GROCY_USER_ID'))
|
if ((GROCY_MODE === 'dev' || GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease') && !defined('GROCY_USER_ID'))
|
||||||
@@ -30,6 +29,7 @@ if (GROCY_DISABLE_AUTH === true)
|
|||||||
{
|
{
|
||||||
define('GROCY_USER_ID', 1);
|
define('GROCY_USER_ID', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
define('GROCY_SHOW_AUTH_VIEWS', false);
|
define('GROCY_SHOW_AUTH_VIEWS', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,19 +38,19 @@ AppFactory::setContainer(new DI\Container());
|
|||||||
$app = AppFactory::create();
|
$app = AppFactory::create();
|
||||||
|
|
||||||
$container = $app->getContainer();
|
$container = $app->getContainer();
|
||||||
$container->set('view', function(Container $container)
|
$container->set('view', function (Container $container)
|
||||||
{
|
{
|
||||||
return new Slim\Views\Blade(__DIR__ . '/views', GROCY_DATAPATH . '/viewcache');
|
return new Slim\Views\Blade(__DIR__ . '/views', GROCY_DATAPATH . '/viewcache');
|
||||||
});
|
});
|
||||||
$container->set('LoginControllerInstance', function(Container $container)
|
$container->set('LoginControllerInstance', function (Container $container)
|
||||||
{
|
{
|
||||||
return new LoginController($container, 'grocy_session');
|
return new LoginController($container, 'grocy_session');
|
||||||
});
|
});
|
||||||
$container->set('UrlManager', function(Container $container)
|
$container->set('UrlManager', function (Container $container)
|
||||||
{
|
{
|
||||||
return new UrlManager(GROCY_BASE_URL);
|
return new UrlManager(GROCY_BASE_URL);
|
||||||
});
|
});
|
||||||
$container->set('ApiKeyHeaderName', function(Container $container)
|
$container->set('ApiKeyHeaderName', function (Container $container)
|
||||||
{
|
{
|
||||||
return 'GROCY-API-KEY';
|
return 'GROCY-API-KEY';
|
||||||
});
|
});
|
||||||
@@ -68,7 +68,8 @@ if (GROCY_MODE === 'production' || GROCY_MODE === 'dev')
|
|||||||
{
|
{
|
||||||
$app->add(new \Grocy\Middleware\LocaleMiddleware($container));
|
$app->add(new \Grocy\Middleware\LocaleMiddleware($container));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
define('GROCY_LOCALE', GROCY_DEFAULT_LOCALE);
|
define('GROCY_LOCALE', GROCY_DEFAULT_LOCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,23 +4,13 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class BaseApiController extends BaseController
|
class BaseApiController extends BaseController
|
||||||
{
|
{
|
||||||
|
protected $OpenApiSpec = null;
|
||||||
|
|
||||||
public function __construct(\DI\Container $container)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $OpenApiSpec = null;
|
|
||||||
|
|
||||||
protected function getOpenApispec()
|
|
||||||
{
|
|
||||||
if($this->OpenApiSpec == null)
|
|
||||||
{
|
|
||||||
$this->OpenApiSpec = json_decode(file_get_contents(__DIR__ . '/../grocy.openapi.json'));
|
|
||||||
}
|
|
||||||
return $this->OpenApiSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function ApiResponse(\Psr\Http\Message\ResponseInterface $response, $data)
|
protected function ApiResponse(\Psr\Http\Message\ResponseInterface $response, $data)
|
||||||
{
|
{
|
||||||
$response->getBody()->write(json_encode($data));
|
$response->getBody()->write(json_encode($data));
|
||||||
@@ -34,8 +24,19 @@ class BaseApiController extends BaseController
|
|||||||
|
|
||||||
protected function GenericErrorResponse(\Psr\Http\Message\ResponseInterface $response, $errorMessage, $status = 400)
|
protected function GenericErrorResponse(\Psr\Http\Message\ResponseInterface $response, $errorMessage, $status = 400)
|
||||||
{
|
{
|
||||||
return $response->withStatus($status)->withJson(array(
|
return $response->withStatus($status)->withJson([
|
||||||
'error_message' => $errorMessage
|
'error_message' => $errorMessage
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getOpenApispec()
|
||||||
|
{
|
||||||
|
if ($this->OpenApiSpec == null)
|
||||||
|
{
|
||||||
|
$this->OpenApiSpec = json_decode(file_get_contents(__DIR__ . '/../grocy.openapi.json'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->OpenApiSpec;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -3,114 +3,34 @@
|
|||||||
namespace Grocy\Controllers;
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
use Grocy\Controllers\Users\User;
|
use Grocy\Controllers\Users\User;
|
||||||
use \Grocy\Services\DatabaseService;
|
use Grocy\Services\ApiKeyService;
|
||||||
use \Grocy\Services\ApplicationService;
|
use Grocy\Services\ApplicationService;
|
||||||
use \Grocy\Services\LocalizationService;
|
use Grocy\Services\BatteriesService;
|
||||||
use \Grocy\Services\StockService;
|
use Grocy\Services\CalendarService;
|
||||||
use \Grocy\Services\UsersService;
|
use Grocy\Services\ChoresService;
|
||||||
use \Grocy\Services\UserfieldsService;
|
use Grocy\Services\DatabaseService;
|
||||||
use \Grocy\Services\BatteriesService;
|
use Grocy\Services\FilesService;
|
||||||
use \Grocy\Services\CalendarService;
|
use Grocy\Services\LocalizationService;
|
||||||
use \Grocy\Services\SessionService;
|
use Grocy\Services\RecipesService;
|
||||||
use \Grocy\Services\RecipesService;
|
use Grocy\Services\SessionService;
|
||||||
use \Grocy\Services\TasksService;
|
use Grocy\Services\StockService;
|
||||||
use \Grocy\Services\FilesService;
|
use Grocy\Services\TasksService;
|
||||||
use \Grocy\Services\ChoresService;
|
use Grocy\Services\UserfieldsService;
|
||||||
use \Grocy\Services\ApiKeyService;
|
use Grocy\Services\UsersService;
|
||||||
|
|
||||||
class BaseController
|
class BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container) {
|
protected $AppContainer;
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
$this->AppContainer = $container;
|
$this->AppContainer = $container;
|
||||||
$this->View = $container->get('view');
|
$this->View = $container->get('view');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function render($response, $page, $data = [])
|
protected function getApiKeyService()
|
||||||
{
|
{
|
||||||
$container = $this->AppContainer;
|
return ApiKeyService::getInstance();
|
||||||
|
|
||||||
$versionInfo = $this->getApplicationService()->GetInstalledVersion();
|
|
||||||
$this->View->set('version', $versionInfo->Version);
|
|
||||||
$this->View->set('releaseDate', $versionInfo->ReleaseDate);
|
|
||||||
|
|
||||||
$localizationService = $this->getLocalizationService();
|
|
||||||
$this->View->set('__t', function(string $text, ...$placeholderValues) use($localizationService)
|
|
||||||
{
|
|
||||||
return $localizationService->__t($text, $placeholderValues);
|
|
||||||
});
|
|
||||||
$this->View->set('__n', function($number, $singularForm, $pluralForm) use($localizationService)
|
|
||||||
{
|
|
||||||
return $localizationService->__n($number, $singularForm, $pluralForm);
|
|
||||||
});
|
|
||||||
$this->View->set('GettextPo', $localizationService->GetPoAsJsonString());
|
|
||||||
|
|
||||||
$this->View->set('U', function($relativePath, $isResource = false) use($container)
|
|
||||||
{
|
|
||||||
return $container->get('UrlManager')->ConstructUrl($relativePath, $isResource);
|
|
||||||
});
|
|
||||||
|
|
||||||
$embedded = false;
|
|
||||||
if (isset($_GET['embedded']))
|
|
||||||
{
|
|
||||||
$embedded = true;
|
|
||||||
}
|
|
||||||
$this->View->set('embedded', $embedded);
|
|
||||||
|
|
||||||
$constants = get_defined_constants();
|
|
||||||
foreach ($constants as $constant => $value)
|
|
||||||
{
|
|
||||||
if (substr($constant, 0, 19) !== 'GROCY_FEATURE_FLAG_')
|
|
||||||
{
|
|
||||||
unset($constants[$constant]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->View->set('featureFlags', $constants);
|
|
||||||
|
|
||||||
if (GROCY_AUTHENTICATED)
|
|
||||||
{
|
|
||||||
$this->View->set('permissions', User::PermissionList());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->View->render($response, $page, $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderPage($response, $page, $data = [])
|
|
||||||
{
|
|
||||||
$this->View->set('userentitiesForSidebar', $this->getDatabase()->userentities()->where('show_in_sidebar_menu = 1')->orderBy('name'));
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$usersService = $this->getUsersService();
|
|
||||||
if (defined('GROCY_USER_ID'))
|
|
||||||
{
|
|
||||||
$this->View->set('userSettings', $usersService->GetUserSettings(GROCY_USER_ID));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->View->set('userSettings', null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (\Exception $ex)
|
|
||||||
{
|
|
||||||
// Happens when database is not initialised or migrated...
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render($response, $page, $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getDatabaseService()
|
|
||||||
{
|
|
||||||
return DatabaseService::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getDatabase()
|
|
||||||
{
|
|
||||||
return $this->getDatabaseService()->GetDbConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getLocalizationService()
|
|
||||||
{
|
|
||||||
return LocalizationService::getInstance(GROCY_LOCALE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getApplicationservice()
|
protected function getApplicationservice()
|
||||||
@@ -128,9 +48,29 @@ class BaseController
|
|||||||
return CalendarService::getInstance();
|
return CalendarService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getSessionService()
|
protected function getChoresService()
|
||||||
{
|
{
|
||||||
return SessionService::getInstance();
|
return ChoresService::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDatabase()
|
||||||
|
{
|
||||||
|
return $this->getDatabaseService()->GetDbConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDatabaseService()
|
||||||
|
{
|
||||||
|
return DatabaseService::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFilesService()
|
||||||
|
{
|
||||||
|
return FilesService::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getLocalizationService()
|
||||||
|
{
|
||||||
|
return LocalizationService::getInstance(GROCY_LOCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getRecipesService()
|
protected function getRecipesService()
|
||||||
@@ -138,6 +78,11 @@ class BaseController
|
|||||||
return RecipesService::getInstance();
|
return RecipesService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getSessionService()
|
||||||
|
{
|
||||||
|
return SessionService::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
protected function getStockService()
|
protected function getStockService()
|
||||||
{
|
{
|
||||||
return StockService::getInstance();
|
return StockService::getInstance();
|
||||||
@@ -148,30 +93,93 @@ class BaseController
|
|||||||
return TasksService::getInstance();
|
return TasksService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUsersService()
|
|
||||||
{
|
|
||||||
return UsersService::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getUserfieldsService()
|
protected function getUserfieldsService()
|
||||||
{
|
{
|
||||||
return UserfieldsService::getInstance();
|
return UserfieldsService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getApiKeyService()
|
protected function getUsersService()
|
||||||
{
|
{
|
||||||
return ApiKeyService::getInstance();
|
return UsersService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getChoresService()
|
protected function render($response, $page, $data = [])
|
||||||
{
|
{
|
||||||
return ChoresService::getInstance();
|
$container = $this->AppContainer;
|
||||||
|
|
||||||
|
$versionInfo = $this->getApplicationService()->GetInstalledVersion();
|
||||||
|
$this->View->set('version', $versionInfo->Version);
|
||||||
|
$this->View->set('releaseDate', $versionInfo->ReleaseDate);
|
||||||
|
|
||||||
|
$localizationService = $this->getLocalizationService();
|
||||||
|
$this->View->set('__t', function (string $text, ...$placeholderValues) use ($localizationService)
|
||||||
|
{
|
||||||
|
return $localizationService->__t($text, $placeholderValues);
|
||||||
|
});
|
||||||
|
$this->View->set('__n', function ($number, $singularForm, $pluralForm) use ($localizationService)
|
||||||
|
{
|
||||||
|
return $localizationService->__n($number, $singularForm, $pluralForm);
|
||||||
|
});
|
||||||
|
$this->View->set('GettextPo', $localizationService->GetPoAsJsonString());
|
||||||
|
|
||||||
|
$this->View->set('U', function ($relativePath, $isResource = false) use ($container)
|
||||||
|
{
|
||||||
|
return $container->get('UrlManager')->ConstructUrl($relativePath, $isResource);
|
||||||
|
});
|
||||||
|
|
||||||
|
$embedded = false;
|
||||||
|
|
||||||
|
if (isset($_GET['embedded']))
|
||||||
|
{
|
||||||
|
$embedded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->View->set('embedded', $embedded);
|
||||||
|
|
||||||
|
$constants = get_defined_constants();
|
||||||
|
|
||||||
|
foreach ($constants as $constant => $value)
|
||||||
|
{
|
||||||
|
if (substr($constant, 0, 19) !== 'GROCY_FEATURE_FLAG_')
|
||||||
|
{
|
||||||
|
unset($constants[$constant]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->View->set('featureFlags', $constants);
|
||||||
|
|
||||||
|
if (GROCY_AUTHENTICATED)
|
||||||
|
{
|
||||||
|
$this->View->set('permissions', User::PermissionList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->View->render($response, $page, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getFilesService()
|
protected function renderPage($response, $page, $data = [])
|
||||||
{
|
{
|
||||||
return FilesService::getInstance();
|
$this->View->set('userentitiesForSidebar', $this->getDatabase()->userentities()->where('show_in_sidebar_menu = 1')->orderBy('name'));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$usersService = $this->getUsersService();
|
||||||
|
|
||||||
|
if (defined('GROCY_USER_ID'))
|
||||||
|
{
|
||||||
|
$this->View->set('userSettings', $usersService->GetUserSettings(GROCY_USER_ID));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->View->set('userSettings', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
// Happens when database is not initialised or migrated...
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render($response, $page, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $AppContainer;
|
|
||||||
}
|
}
|
||||||
|
@@ -6,9 +6,22 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class BatteriesApiController extends BaseApiController
|
class BatteriesApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function BatteryDetails(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
try
|
||||||
|
{
|
||||||
|
return $this->ApiResponse($response, $this->getBatteriesService()->GetBatteryDetails($args['batteryId']));
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->ApiResponse($response, $this->getBatteriesService()->GetCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function TrackChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function TrackChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -20,6 +33,7 @@ class BatteriesApiController extends BaseApiController
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$trackedTime = date('Y-m-d H:i:s');
|
$trackedTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
if (array_key_exists('tracked_time', $requestBody) && IsIsoDateTime($requestBody['tracked_time']))
|
if (array_key_exists('tracked_time', $requestBody) && IsIsoDateTime($requestBody['tracked_time']))
|
||||||
{
|
{
|
||||||
$trackedTime = $requestBody['tracked_time'];
|
$trackedTime = $requestBody['tracked_time'];
|
||||||
@@ -32,23 +46,7 @@ class BatteriesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function BatteryDetails(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return $this->ApiResponse($response, $this->getBatteriesService()->GetBatteryDetails($args['batteryId']));
|
|
||||||
}
|
|
||||||
catch (\Exception $ex)
|
|
||||||
{
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->ApiResponse($response, $this->getBatteriesService()->GetCurrent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UndoChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UndoChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -64,5 +62,12 @@ class BatteriesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,9 +4,46 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class BatteriesController extends BaseController
|
class BatteriesController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function BatteriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
return $this->renderPage($response, 'batteries', [
|
||||||
|
'batteries' => $this->getDatabase()->batteries()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('batteries'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('batteries')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function BatteriesSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'batteriessettings');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function BatteryEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['batteryId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'batteryform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('batteries')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'batteryform', [
|
||||||
|
'battery' => $this->getDatabase()->batteries($args['batteryId']),
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('batteries')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'batteriesjournal', [
|
||||||
|
'chargeCycles' => $this->getDatabase()->battery_charge_cycles()->orderBy('tracked_time', 'DESC'),
|
||||||
|
'batteries' => $this->getDatabase()->batteries()->orderBy('name')
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -26,48 +63,13 @@ class BatteriesController extends BaseController
|
|||||||
public function TrackChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function TrackChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'batterytracking', [
|
return $this->renderPage($response, 'batterytracking', [
|
||||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function BatteriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'batteries', [
|
|
||||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('batteries'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('batteries')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function BatteryEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['batteryId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'batteryform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('batteries')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'batteryform', [
|
|
||||||
'battery' => $this->getDatabase()->batteries($args['batteryId']),
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('batteries')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'batteriesjournal', [
|
|
||||||
'chargeCycles' => $this->getDatabase()->battery_charge_cycles()->orderBy('tracked_time', 'DESC'),
|
|
||||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name')
|
'batteries' => $this->getDatabase()->batteries()->orderBy('name')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function BatteriesSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'batteriessettings');
|
parent::__construct($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,11 +4,6 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class CalendarApiController extends BaseApiController
|
class CalendarApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Ical(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Ical(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -16,7 +11,8 @@ class CalendarApiController extends BaseApiController
|
|||||||
$vCalendar = new \Eluceo\iCal\Component\Calendar('grocy');
|
$vCalendar = new \Eluceo\iCal\Component\Calendar('grocy');
|
||||||
|
|
||||||
$events = $this->getCalendarService()->GetEvents();
|
$events = $this->getCalendarService()->GetEvents();
|
||||||
foreach($events as $event)
|
|
||||||
|
foreach ($events as $event)
|
||||||
{
|
{
|
||||||
$date = new \DateTime($event['start']);
|
$date = new \DateTime($event['start']);
|
||||||
$date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
|
$date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
|
||||||
@@ -45,19 +41,27 @@ class CalendarApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function IcalSharingLink(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function IcalSharingLink(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $this->ApiResponse($response, array(
|
return $this->ApiResponse($response, [
|
||||||
'url' => $this->AppContainer->get('UrlManager')->ConstructUrl('/api/calendar/ical?secret=' . $this->getApiKeyService()->GetOrCreateApiKey(\Grocy\Services\ApiKeyService::API_KEY_TYPE_SPECIAL_PURPOSE_CALENDAR_ICAL))
|
'url' => $this->AppContainer->get('UrlManager')->ConstructUrl('/api/calendar/ical?secret=' . $this->getApiKeyService()->GetOrCreateApiKey(\Grocy\Services\ApiKeyService::API_KEY_TYPE_SPECIAL_PURPOSE_CALENDAR_ICAL))
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,15 +4,15 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class CalendarController extends BaseController
|
class CalendarController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'calendar', [
|
return $this->renderPage($response, 'calendar', [
|
||||||
'fullcalendarEventSources' => $this->getCalendarService()->GetEvents()
|
'fullcalendarEventSources' => $this->getCalendarService()->GetEvents()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,40 +6,41 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class ChoresApiController extends BaseApiController
|
class ChoresApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function CalculateNextExecutionAssignments(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function TrackChoreExecution(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$requestBody = $request->getParsedBody();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_CHORE_TRACK_EXECUTION);
|
$requestBody = $request->getParsedBody();
|
||||||
|
|
||||||
$trackedTime = date('Y-m-d H:i:s');
|
$choreId = null;
|
||||||
if (array_key_exists('tracked_time', $requestBody) && (IsIsoDateTime($requestBody['tracked_time']) || IsIsoDate($requestBody['tracked_time'])))
|
|
||||||
|
if (array_key_exists('chore_id', $requestBody) && !empty($requestBody['chore_id']) && is_numeric($requestBody['chore_id']))
|
||||||
{
|
{
|
||||||
$trackedTime = $requestBody['tracked_time'];
|
$choreId = intval($requestBody['chore_id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$doneBy = GROCY_USER_ID;
|
if ($choreId === null)
|
||||||
if (array_key_exists('done_by', $requestBody) && !empty($requestBody['done_by']))
|
|
||||||
{
|
{
|
||||||
$doneBy = $requestBody['done_by'];
|
$chores = $this->getDatabase()->chores();
|
||||||
}
|
|
||||||
if($doneBy != GROCY_USER_ID)
|
|
||||||
User::checkPermission($request, User::PERMISSION_CHORE_TRACK_EXECUTION_EXECUTION);
|
|
||||||
|
|
||||||
$choreExecutionId = $this->getChoresService()->TrackChore($args['choreId'], $trackedTime, $doneBy);
|
foreach ($chores as $chore)
|
||||||
return $this->ApiResponse($response, $this->getDatabase()->chores_log($choreExecutionId));
|
{
|
||||||
|
$this->getChoresService()->CalculateNextExecutionAssignment($chore->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->getChoresService()->CalculateNextExecutionAssignment($choreId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->EmptyApiResponse($response);
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ChoreDetails(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function ChoreDetails(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -52,6 +53,7 @@ class ChoresApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -59,6 +61,43 @@ class ChoresApiController extends BaseApiController
|
|||||||
return $this->ApiResponse($response, $this->getChoresService()->GetCurrent());
|
return $this->ApiResponse($response, $this->getChoresService()->GetCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function TrackChoreExecution(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$requestBody = $request->getParsedBody();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($doneBy != GROCY_USER_ID)
|
||||||
|
{
|
||||||
|
User::checkPermission($request, User::PERMISSION_CHORE_TRACK_EXECUTION_EXECUTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
$choreExecutionId = $this->getChoresService()->TrackChore($args['choreId'], $trackedTime, $doneBy);
|
||||||
|
return $this->ApiResponse($response, $this->getDatabase()->chores_log($choreExecutionId));
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function UndoChoreExecution(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UndoChoreExecution(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -72,38 +111,12 @@ class ChoresApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CalculateNextExecutionAssignments(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
try
|
parent::__construct($container);
|
||||||
{
|
|
||||||
$requestBody = $request->getParsedBody();
|
|
||||||
|
|
||||||
$choreId = null;
|
|
||||||
if (array_key_exists('chore_id', $requestBody) && !empty($requestBody['chore_id']) && is_numeric($requestBody['chore_id']))
|
|
||||||
{
|
|
||||||
$choreId = intval($requestBody['chore_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($choreId === null)
|
|
||||||
{
|
|
||||||
$chores = $this->getDatabase()->chores();
|
|
||||||
foreach ($chores as $chore)
|
|
||||||
{
|
|
||||||
$this->getChoresService()->CalculateNextExecutionAssignment($chore->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->getChoresService()->CalculateNextExecutionAssignment($choreId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->EmptyApiResponse($response);
|
|
||||||
}
|
|
||||||
catch (\Exception $ex)
|
|
||||||
{
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,9 +4,58 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class ChoresController extends BaseController
|
class ChoresController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function ChoreEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
$usersService = $this->getUsersService();
|
||||||
|
$users = $usersService->GetUsersAsDto();
|
||||||
|
|
||||||
|
if ($args['choreId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'choreform', [
|
||||||
|
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_PERIOD_TYPE_'),
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||||
|
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
|
||||||
|
'users' => $users,
|
||||||
|
'products' => $this->getDatabase()->products()->orderBy('name')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'choreform', [
|
||||||
|
'chore' => $this->getDatabase()->chores($args['choreId']),
|
||||||
|
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_PERIOD_TYPE_'),
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||||
|
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
|
||||||
|
'users' => $users,
|
||||||
|
'products' => $this->getDatabase()->products()->orderBy('name')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ChoresList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'chores', [
|
||||||
|
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('chores')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ChoresSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'choressettings');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'choresjournal', [
|
||||||
|
'choresLog' => $this->getDatabase()->chores_log()->orderBy('tracked_time', 'DESC'),
|
||||||
|
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
||||||
|
'users' => $this->getDatabase()->users()->orderBy('username')
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -32,56 +81,9 @@ class ChoresController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ChoresList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'chores', [
|
parent::__construct($container);
|
||||||
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('chores')
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'choresjournal', [
|
|
||||||
'choresLog' => $this->getDatabase()->chores_log()->orderBy('tracked_time', 'DESC'),
|
|
||||||
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
|
||||||
'users' => $this->getDatabase()->users()->orderBy('username')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ChoreEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$usersService = $this->getUsersService();
|
|
||||||
$users = $usersService->GetUsersAsDto();
|
|
||||||
|
|
||||||
if ($args['choreId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'choreform', [
|
|
||||||
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_PERIOD_TYPE_'),
|
|
||||||
'mode' => 'create',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
|
||||||
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
|
|
||||||
'users' => $users,
|
|
||||||
'products' => $this->getDatabase()->products()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'choreform', [
|
|
||||||
'chore' => $this->getDatabase()->chores($args['choreId']),
|
|
||||||
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_PERIOD_TYPE_'),
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
|
||||||
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
|
|
||||||
'users' => $users,
|
|
||||||
'products' => $this->getDatabase()->products()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ChoresSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'choressettings');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -4,22 +4,8 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class EquipmentController extends BaseController
|
class EquipmentController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected $UserfieldsService;
|
protected $UserfieldsService;
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'equipment', [
|
|
||||||
'equipment' => $this->getDatabase()->equipment()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('equipment'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('equipment')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function EditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function EditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
if ($args['equipmentId'] == 'new')
|
if ($args['equipmentId'] == 'new')
|
||||||
@@ -32,10 +18,26 @@ class EquipmentController extends BaseController
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'equipmentform', [
|
return $this->renderPage($response, 'equipmentform', [
|
||||||
'equipment' => $this->getDatabase()->equipment($args['equipmentId']),
|
'equipment' => $this->getDatabase()->equipment($args['equipmentId']),
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('equipment')
|
'userfields' => $this->getUserfieldsService()->GetFields('equipment')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'equipment', [
|
||||||
|
'equipment' => $this->getDatabase()->equipment()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('equipment'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('equipment')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -27,16 +27,18 @@ class ExceptionController extends BaseApiController
|
|||||||
$response = $this->app->getResponseFactory()->createResponse();
|
$response = $this->app->getResponseFactory()->createResponse();
|
||||||
|
|
||||||
$isApiRoute = string_starts_with($request->getUri()->getPath(), '/api/');
|
$isApiRoute = string_starts_with($request->getUri()->getPath(), '/api/');
|
||||||
|
|
||||||
if ($isApiRoute)
|
if ($isApiRoute)
|
||||||
{
|
{
|
||||||
$status = 500;
|
$status = 500;
|
||||||
|
|
||||||
if ($exception instanceof HttpException)
|
if ($exception instanceof HttpException)
|
||||||
{
|
{
|
||||||
$status = $exception->getCode();
|
$status = $exception->getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'error_message' => $exception->getMessage(),
|
'error_message' => $exception->getMessage()
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($displayErrorDetails)
|
if ($displayErrorDetails)
|
||||||
@@ -44,7 +46,7 @@ class ExceptionController extends BaseApiController
|
|||||||
$data['error_details'] = [
|
$data['error_details'] = [
|
||||||
'stack_trace' => $exception->getTraceAsString(),
|
'stack_trace' => $exception->getTraceAsString(),
|
||||||
'file' => $exception->getFile(),
|
'file' => $exception->getFile(),
|
||||||
'line' => $exception->getLine(),
|
'line' => $exception->getLine()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,4 +73,5 @@ class ExceptionController extends BaseApiController
|
|||||||
'exception' => $exception
|
'exception' => $exception
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,24 +2,30 @@
|
|||||||
|
|
||||||
namespace Grocy\Controllers;
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
use \Grocy\Services\FilesService;
|
use Grocy\Services\FilesService;
|
||||||
use Slim\Exception\HttpNotFoundException;
|
use Slim\Exception\HttpNotFoundException;
|
||||||
|
|
||||||
class FilesApiController extends BaseApiController
|
class FilesApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function DeleteFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function UploadFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$fileName = $this->checkFileName($args['fileName']);
|
if (IsValidFileName(base64_decode($args['fileName'])))
|
||||||
|
{
|
||||||
|
$fileName = base64_decode($args['fileName']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new \Exception('Invalid filename');
|
||||||
|
}
|
||||||
|
|
||||||
$data = $request->getBody()->getContents();
|
$filePath = $this->getFilesService()->GetFilePath($args['group'], $fileName);
|
||||||
file_put_contents($this->getFilesService()->GetFilePath($args['group'], $fileName), $data);
|
|
||||||
|
if (file_exists($filePath))
|
||||||
|
{
|
||||||
|
unlink($filePath);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->EmptyApiResponse($response);
|
return $this->EmptyApiResponse($response);
|
||||||
}
|
}
|
||||||
@@ -27,6 +33,7 @@ class FilesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ServeFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function ServeFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -46,13 +53,15 @@ class FilesApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new HttpNotFoundException($request, 'File not found');
|
throw new HttpNotFoundException($request, 'File not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
throw new HttpNotFoundException($request, $ex->getMessage(), $ex);
|
throw new HttpNotFoundException($request, $ex->getMessage(), $ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ShowFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function ShowFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -75,31 +84,23 @@ class FilesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
throw new HttpNotFoundException($request, 'File not found');
|
throw new HttpNotFoundException($request, 'File not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
throw new HttpNotFoundException($request, $ex->getMessage(), $ex);
|
throw new HttpNotFoundException($request, $ex->getMessage(), $ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DeleteFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UploadFile(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (IsValidFileName(base64_decode($args['fileName'])))
|
$fileName = $this->checkFileName($args['fileName']);
|
||||||
{
|
|
||||||
$fileName = base64_decode($args['fileName']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new \Exception('Invalid filename');
|
|
||||||
}
|
|
||||||
|
|
||||||
$filePath = $this->getFilesService()->GetFilePath($args['group'], $fileName);
|
$data = $request->getBody()->getContents();
|
||||||
if (file_exists($filePath))
|
file_put_contents($this->getFilesService()->GetFilePath($args['group'], $fileName), $data);
|
||||||
{
|
|
||||||
unlink($filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->EmptyApiResponse($response);
|
return $this->EmptyApiResponse($response);
|
||||||
}
|
}
|
||||||
@@ -107,6 +108,31 @@ class FilesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fileName base64-encoded file-name
|
||||||
|
* @return false|string the decoded file-name
|
||||||
|
* @throws \Exception if the file-name is invalid.
|
||||||
|
*/
|
||||||
|
protected function checkFileName(string $fileName)
|
||||||
|
{
|
||||||
|
if (IsValidFileName(base64_decode($fileName)))
|
||||||
|
{
|
||||||
|
$fileName = base64_decode($fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new \Exception('Invalid filename');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,40 +144,36 @@ class FilesApiController extends BaseApiController
|
|||||||
protected function getFilePath(string $group, string $fileName, array $queryParams = [])
|
protected function getFilePath(string $group, string $fileName, array $queryParams = [])
|
||||||
{
|
{
|
||||||
$forceServeAs = null;
|
$forceServeAs = null;
|
||||||
if (isset($queryParams['force_serve_as']) && !empty($queryParams['force_serve_as'])) {
|
|
||||||
|
if (isset($queryParams['force_serve_as']) && !empty($queryParams['force_serve_as']))
|
||||||
|
{
|
||||||
$forceServeAs = $queryParams['force_serve_as'];
|
$forceServeAs = $queryParams['force_serve_as'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($forceServeAs == FilesService::FILE_SERVE_TYPE_PICTURE) {
|
if ($forceServeAs == FilesService::FILE_SERVE_TYPE_PICTURE)
|
||||||
|
{
|
||||||
$bestFitHeight = null;
|
$bestFitHeight = null;
|
||||||
if (isset($queryParams['best_fit_height']) && !empty($queryParams['best_fit_height']) && is_numeric($queryParams['best_fit_height'])) {
|
|
||||||
|
if (isset($queryParams['best_fit_height']) && !empty($queryParams['best_fit_height']) && is_numeric($queryParams['best_fit_height']))
|
||||||
|
{
|
||||||
$bestFitHeight = $queryParams['best_fit_height'];
|
$bestFitHeight = $queryParams['best_fit_height'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$bestFitWidth = null;
|
$bestFitWidth = null;
|
||||||
if (isset($queryParams['best_fit_width']) && !empty($queryParams['best_fit_width']) && is_numeric($queryParams['best_fit_width'])) {
|
|
||||||
|
if (isset($queryParams['best_fit_width']) && !empty($queryParams['best_fit_width']) && is_numeric($queryParams['best_fit_width']))
|
||||||
|
{
|
||||||
$bestFitWidth = $queryParams['best_fit_width'];
|
$bestFitWidth = $queryParams['best_fit_width'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$filePath = $this->getFilesService()->DownscaleImage($group, $fileName, $bestFitHeight, $bestFitWidth);
|
$filePath = $this->getFilesService()->DownscaleImage($group, $fileName, $bestFitHeight, $bestFitWidth);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$filePath = $this->getFilesService()->GetFilePath($group, $fileName);
|
$filePath = $this->getFilesService()->GetFilePath($group, $fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $filePath;
|
return $filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $fileName base64-encoded file-name
|
|
||||||
* @return false|string the decoded file-name
|
|
||||||
* @throws \Exception if the file-name is invalid.
|
|
||||||
*/
|
|
||||||
protected function checkFileName(string $fileName)
|
|
||||||
{
|
|
||||||
if (IsValidFileName(base64_decode($fileName))) {
|
|
||||||
$fileName = base64_decode($fileName);
|
|
||||||
} else {
|
|
||||||
throw new \Exception('Invalid filename');
|
|
||||||
}
|
|
||||||
return $fileName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -6,66 +6,6 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class GenericEntityApiController extends BaseApiController
|
class GenericEntityApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetObjects(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$objects = $this->getDatabase()->{$args['entity']}();
|
|
||||||
$allUserfields = $this->getUserfieldsService()->GetAllValues($args['entity']);
|
|
||||||
|
|
||||||
foreach ($objects as $object)
|
|
||||||
{
|
|
||||||
$userfields = FindAllObjectsInArrayByPropertyValue($allUserfields, 'object_id', $object->id);
|
|
||||||
$userfieldKeyValuePairs = null;
|
|
||||||
if (count($userfields) > 0)
|
|
||||||
{
|
|
||||||
foreach ($userfields as $userfield)
|
|
||||||
{
|
|
||||||
$userfieldKeyValuePairs[$userfield->name] = $userfield->value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$object->userfields = $userfieldKeyValuePairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
|
||||||
{
|
|
||||||
return $this->ApiResponse($response, $objects);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
|
||||||
{
|
|
||||||
$userfields = $this->getUserfieldsService()->GetValues($args['entity'], $args['objectId']);
|
|
||||||
if (count($userfields) === 0)
|
|
||||||
{
|
|
||||||
$userfields = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$object = $this->getDatabase()->{$args['entity']}($args['objectId']);
|
|
||||||
if ($object == null) {
|
|
||||||
return $this->GenericErrorResponse($response, 'Object not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
$object['userfields'] = $userfields;
|
|
||||||
|
|
||||||
return $this->ApiResponse($response, $object);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function AddObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function AddObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_MASTER_DATA_EDIT);
|
User::checkPermission($request, User::PERMISSION_MASTER_DATA_EDIT);
|
||||||
@@ -81,22 +21,44 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
|
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
|
||||||
}
|
}
|
||||||
|
|
||||||
$newRow = $this->getDatabase()->{$args['entity']}()->createRow($requestBody);
|
$newRow = $this->getDatabase()->{$args['entity']}
|
||||||
|
()->createRow($requestBody);
|
||||||
$newRow->save();
|
$newRow->save();
|
||||||
$success = $newRow->isClean();
|
$success = $newRow->isClean();
|
||||||
return $this->ApiResponse($response, array(
|
return $this->ApiResponse($response, [
|
||||||
'created_object_id' => $this->getDatabase()->lastInsertId()
|
'created_object_id' => $this->getDatabase()->lastInsertId()
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DeleteObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
User::checkPermission($request, User::PERMISSION_MASTER_DATA_EDIT);
|
||||||
|
|
||||||
|
if ($this->IsValidEntity($args['entity']))
|
||||||
|
{
|
||||||
|
$row = $this->getDatabase()->{$args['entity']}
|
||||||
|
($args['objectId']);
|
||||||
|
$row->delete();
|
||||||
|
$success = $row->isClean();
|
||||||
|
return $this->EmptyApiResponse($response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function EditObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function EditObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -114,7 +76,8 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
|
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = $this->getDatabase()->{$args['entity']}($args['objectId']);
|
$row = $this->getDatabase()->{$args['entity']}
|
||||||
|
($args['objectId']);
|
||||||
$row->update($requestBody);
|
$row->update($requestBody);
|
||||||
$success = $row->isClean();
|
$success = $row->isClean();
|
||||||
return $this->EmptyApiResponse($response);
|
return $this->EmptyApiResponse($response);
|
||||||
@@ -123,48 +86,77 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DeleteObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetObject(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_MASTER_DATA_EDIT);
|
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
||||||
|
|
||||||
if ($this->IsValidEntity($args['entity']))
|
|
||||||
{
|
{
|
||||||
$row = $this->getDatabase()->{$args['entity']}($args['objectId']);
|
$userfields = $this->getUserfieldsService()->GetValues($args['entity'], $args['objectId']);
|
||||||
$row->delete();
|
|
||||||
$success = $row->isClean();
|
if (count($userfields) === 0)
|
||||||
return $this->EmptyApiResponse($response);
|
{
|
||||||
|
$userfields = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = $this->getDatabase()->{$args['entity']}
|
||||||
|
($args['objectId']);
|
||||||
|
|
||||||
|
if ($object == null)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, 'Object not found', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$object['userfields'] = $userfields;
|
||||||
|
|
||||||
|
return $this->ApiResponse($response, $object);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SearchObjects(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetObjects(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
|
$objects = $this->getDatabase()->{$args['entity']}
|
||||||
|
();
|
||||||
|
$allUserfields = $this->getUserfieldsService()->GetAllValues($args['entity']);
|
||||||
|
|
||||||
|
foreach ($objects as $object)
|
||||||
|
{
|
||||||
|
$userfields = FindAllObjectsInArrayByPropertyValue($allUserfields, 'object_id', $object->id);
|
||||||
|
$userfieldKeyValuePairs = null;
|
||||||
|
|
||||||
|
if (count($userfields) > 0)
|
||||||
|
{
|
||||||
|
foreach ($userfields as $userfield)
|
||||||
|
{
|
||||||
|
$userfieldKeyValuePairs[$userfield->name] = $userfield->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$object->userfields = $userfieldKeyValuePairs;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
||||||
{
|
{
|
||||||
try
|
return $this->ApiResponse($response, $objects);
|
||||||
{
|
|
||||||
return $this->ApiResponse($response, $this->getDatabase()->{$args['entity']}()->where('name LIKE ?', '%' . $args['searchString'] . '%'));
|
|
||||||
}
|
|
||||||
catch (\PDOException $ex)
|
|
||||||
{
|
|
||||||
return $this->GenericErrorResponse($response, 'The given entity has no field "name"');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetUserfields(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetUserfields(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -177,6 +169,29 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SearchObjects(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return $this->ApiResponse($response, $this->getDatabase()->{$args['entity']}
|
||||||
|
()->where('name LIKE ?', '%' . $args['searchString'] . '%'));
|
||||||
|
}
|
||||||
|
catch (\PDOException $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, 'The given entity has no field "name"');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, 'Entity does not exist or is not exposed');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetUserfields(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function SetUserfields(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -199,6 +214,17 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function IsEntityWithPreventedListing($entity)
|
||||||
|
{
|
||||||
|
return !in_array($entity, $this->getOpenApiSpec()->components->internalSchemas->ExposedEntityButNoListing->enum);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function IsValidEntity($entity)
|
private function IsValidEntity($entity)
|
||||||
@@ -206,8 +232,4 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
return in_array($entity, $this->getOpenApiSpec()->components->internalSchemas->ExposedEntity->enum);
|
return in_array($entity, $this->getOpenApiSpec()->components->internalSchemas->ExposedEntity->enum);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function IsEntityWithPreventedListing($entity)
|
|
||||||
{
|
|
||||||
return !in_array($entity, $this->getOpenApiSpec()->components->internalSchemas->ExposedEntityButNoListing->enum);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -4,19 +4,6 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class GenericEntityController extends BaseController
|
class GenericEntityController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function UserfieldsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'userfields', [
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetAllFields(),
|
|
||||||
'entities' => $this->getUserfieldsService()->GetEntities()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function UserentitiesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UserentitiesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'userentities', [
|
return $this->renderPage($response, 'userentities', [
|
||||||
@@ -24,16 +11,22 @@ class GenericEntityController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UserobjectsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UserentityEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
$userentity = $this->getDatabase()->userentities()->where('name = :1', $args['userentityName'])->fetch();
|
if ($args['userentityId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'userentityform', [
|
||||||
|
'mode' => 'create'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'userentityform', [
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userentity' => $this->getDatabase()->userentities($args['userentityId'])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->renderPage($response, 'userobjects', [
|
|
||||||
'userentity' => $userentity,
|
|
||||||
'userobjects' => $this->getDatabase()->userobjects()->where('userentity_id = :1', $userentity->id),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('userentity-' . $args['userentityName']),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('userentity-' . $args['userentityName'])
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UserfieldEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UserfieldEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -50,28 +43,20 @@ class GenericEntityController extends BaseController
|
|||||||
{
|
{
|
||||||
return $this->renderPage($response, 'userfieldform', [
|
return $this->renderPage($response, 'userfieldform', [
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'userfield' => $this->getUserfieldsService()->GetField($args['userfieldId']),
|
'userfield' => $this->getUserfieldsService()->GetField($args['userfieldId']),
|
||||||
'userfieldTypes' => $this->getUserfieldsService()->GetFieldTypes(),
|
'userfieldTypes' => $this->getUserfieldsService()->GetFieldTypes(),
|
||||||
'entities' => $this->getUserfieldsService()->GetEntities()
|
'entities' => $this->getUserfieldsService()->GetEntities()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UserentityEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UserfieldsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
if ($args['userentityId'] == 'new')
|
return $this->renderPage($response, 'userfields', [
|
||||||
{
|
'userfields' => $this->getUserfieldsService()->GetAllFields(),
|
||||||
return $this->renderPage($response, 'userentityform', [
|
'entities' => $this->getUserfieldsService()->GetEntities()
|
||||||
'mode' => 'create'
|
]);
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'userentityform', [
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userentity' => $this->getDatabase()->userentities($args['userentityId'])
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UserobjectEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UserobjectEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -91,9 +76,28 @@ class GenericEntityController extends BaseController
|
|||||||
return $this->renderPage($response, 'userobjectform', [
|
return $this->renderPage($response, 'userobjectform', [
|
||||||
'userentity' => $userentity,
|
'userentity' => $userentity,
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'userobject' => $this->getDatabase()->userobjects($args['userobjectId']),
|
'userobject' => $this->getDatabase()->userobjects($args['userobjectId']),
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('userentity-' . $args['userentityName'])
|
'userfields' => $this->getUserfieldsService()->GetFields('userentity-' . $args['userentityName'])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function UserobjectsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$userentity = $this->getDatabase()->userentities()->where('name = :1', $args['userentityName'])->fetch();
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'userobjects', [
|
||||||
|
'userentity' => $userentity,
|
||||||
|
'userobjects' => $this->getDatabase()->userobjects()->where('userentity_id = :1', $userentity->id),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('userentity-' . $args['userentityName']),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('userentity-' . $args['userentityName'])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,45 +4,11 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class LoginController extends BaseController
|
class LoginController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container, string $sessionCookieName)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
$this->SessionCookieName = $sessionCookieName;
|
|
||||||
}
|
|
||||||
protected $SessionCookieName;
|
protected $SessionCookieName;
|
||||||
|
|
||||||
public function ProcessLogin(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetSessionCookieName()
|
||||||
{
|
{
|
||||||
$postParams = $request->getParsedBody();
|
return $this->SessionCookieName;
|
||||||
if (isset($postParams['username']) && isset($postParams['password']))
|
|
||||||
{
|
|
||||||
$user = $this->getDatabase()->users()->where('username', $postParams['username'])->fetch();
|
|
||||||
$inputPassword = $postParams['password'];
|
|
||||||
$stayLoggedInPermanently = $postParams['stay_logged_in'] == 'on';
|
|
||||||
|
|
||||||
if ($user !== null && password_verify($inputPassword, $user->password))
|
|
||||||
{
|
|
||||||
$sessionKey = $this->getSessionService()->CreateSession($user->id, $stayLoggedInPermanently);
|
|
||||||
setcookie($this->SessionCookieName, $sessionKey, PHP_INT_SIZE == 4 ? PHP_INT_MAX : PHP_INT_MAX>>32); // Cookie expires never, but session validity is up to SessionService
|
|
||||||
|
|
||||||
if (password_needs_rehash($user->password, PASSWORD_DEFAULT))
|
|
||||||
{
|
|
||||||
$user->update(array(
|
|
||||||
'password' => password_hash($inputPassword, PASSWORD_DEFAULT)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/login?invalid=true'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/login?invalid=true'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function LoginPage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function LoginPage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -56,8 +22,49 @@ class LoginController extends BaseController
|
|||||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSessionCookieName()
|
public function ProcessLogin(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->SessionCookieName;
|
$postParams = $request->getParsedBody();
|
||||||
|
|
||||||
|
if (isset($postParams['username']) && isset($postParams['password']))
|
||||||
|
{
|
||||||
|
$user = $this->getDatabase()->users()->where('username', $postParams['username'])->fetch();
|
||||||
|
$inputPassword = $postParams['password'];
|
||||||
|
$stayLoggedInPermanently = $postParams['stay_logged_in'] == 'on';
|
||||||
|
|
||||||
|
if ($user !== null && password_verify($inputPassword, $user->password))
|
||||||
|
{
|
||||||
|
$sessionKey = $this->getSessionService()->CreateSession($user->id, $stayLoggedInPermanently);
|
||||||
|
setcookie($this->SessionCookieName, $sessionKey, PHP_INT_SIZE == 4 ? PHP_INT_MAX : PHP_INT_MAX >> 32);
|
||||||
|
|
||||||
|
// Cookie expires never, but session validity is up to SessionService
|
||||||
|
|
||||||
|
if (password_needs_rehash($user->password, PASSWORD_DEFAULT))
|
||||||
|
{
|
||||||
|
$user->update([
|
||||||
|
'password' => password_hash($inputPassword, PASSWORD_DEFAULT)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/login?invalid=true'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl('/login?invalid=true'));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container, string $sessionCookieName)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
$this->SessionCookieName = $sessionCookieName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,28 +4,6 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class OpenApiController extends BaseApiController
|
class OpenApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function DocumentationUi(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->render($response, 'openapiui');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function DocumentationSpec(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$applicationService = $this->getApplicationService();
|
|
||||||
|
|
||||||
$versionInfo = $applicationService->GetInstalledVersion();
|
|
||||||
$this->getOpenApiSpec()->info->version = $versionInfo->Version;
|
|
||||||
$this->getOpenApiSpec()->info->description = str_replace('PlaceHolderManageApiKeysUrl', $this->AppContainer->get('UrlManager')->ConstructUrl('/manageapikeys'), $this->getOpenApiSpec()->info->description);
|
|
||||||
$this->getOpenApiSpec()->servers[0]->url = $this->AppContainer->get('UrlManager')->ConstructUrl('/api');
|
|
||||||
|
|
||||||
return $this->ApiResponse($response, $this->getOpenApiSpec());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ApiKeysList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function ApiKeysList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'manageapikeys', [
|
return $this->renderPage($response, 'manageapikeys', [
|
||||||
@@ -40,4 +18,26 @@ class OpenApiController extends BaseApiController
|
|||||||
$newApiKeyId = $this->getApiKeyService()->GetApiKeyId($newApiKey);
|
$newApiKeyId = $this->getApiKeyService()->GetApiKeyId($newApiKey);
|
||||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl("/manageapikeys?CreatedApiKeyId=$newApiKeyId"));
|
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl("/manageapikeys?CreatedApiKeyId=$newApiKeyId"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function DocumentationSpec(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$applicationService = $this->getApplicationService();
|
||||||
|
|
||||||
|
$versionInfo = $applicationService->GetInstalledVersion();
|
||||||
|
$this->getOpenApiSpec()->info->version = $versionInfo->Version;
|
||||||
|
$this->getOpenApiSpec()->info->description = str_replace('PlaceHolderManageApiKeysUrl', $this->AppContainer->get('UrlManager')->ConstructUrl('/manageapikeys'), $this->getOpenApiSpec()->info->description);
|
||||||
|
$this->getOpenApiSpec()->servers[0]->url = $this->AppContainer->get('UrlManager')->ConstructUrl('/api');
|
||||||
|
|
||||||
|
return $this->ApiResponse($response, $this->getOpenApiSpec());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DocumentationUi(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->render($response, 'openapiui');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,11 +6,6 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class RecipesApiController extends BaseApiController
|
class RecipesApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function AddNotFulfilledProductsToShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function AddNotFulfilledProductsToShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_SHOPPINGLIST_ITEMS_ADD);
|
User::checkPermission($request, User::PERMISSION_SHOPPINGLIST_ITEMS_ADD);
|
||||||
@@ -40,19 +35,21 @@ class RecipesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetRecipeFulfillment(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetRecipeFulfillment(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(!isset($args['recipeId']))
|
if (!isset($args['recipeId']))
|
||||||
{
|
{
|
||||||
return $this->ApiResponse($response, $this->getRecipesService()->GetRecipesResolved());
|
return $this->ApiResponse($response, $this->getRecipesService()->GetRecipesResolved());
|
||||||
}
|
}
|
||||||
|
|
||||||
$recipeResolved = FindObjectInArrayByPropertyValue($this->getRecipesService()->GetRecipesResolved(), 'recipe_id', $args['recipeId']);
|
$recipeResolved = FindObjectInArrayByPropertyValue($this->getRecipesService()->GetRecipesResolved(), 'recipe_id', $args['recipeId']);
|
||||||
if(!$recipeResolved)
|
|
||||||
|
if (!$recipeResolved)
|
||||||
{
|
{
|
||||||
throw new \Exception('Recipe does not exist');
|
throw new \Exception('Recipe does not exist');
|
||||||
}
|
}
|
||||||
@@ -60,10 +57,18 @@ class RecipesApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->ApiResponse($response, $recipeResolved);
|
return $this->ApiResponse($response, $recipeResolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,13 +2,54 @@
|
|||||||
|
|
||||||
namespace Grocy\Controllers;
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
use \Grocy\Services\RecipesService;
|
use Grocy\Services\RecipesService;
|
||||||
|
|
||||||
class RecipesController extends BaseController
|
class RecipesController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function MealPlan(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
$recipes = $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll();
|
||||||
|
|
||||||
|
$events = [];
|
||||||
|
|
||||||
|
foreach ($this->getDatabase()->meal_plan() as $mealPlanEntry)
|
||||||
|
{
|
||||||
|
$recipe = FindObjectInArrayByPropertyValue($recipes, 'id', $mealPlanEntry['recipe_id']);
|
||||||
|
$title = '';
|
||||||
|
|
||||||
|
if ($recipe !== null)
|
||||||
|
{
|
||||||
|
$title = $recipe->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$productDetails = null;
|
||||||
|
|
||||||
|
if ($mealPlanEntry['product_id'] !== null)
|
||||||
|
{
|
||||||
|
$productDetails = $this->getStockService()->GetProductDetails($mealPlanEntry['product_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$events[] = [
|
||||||
|
'id' => $mealPlanEntry['id'],
|
||||||
|
'title' => $title,
|
||||||
|
'start' => $mealPlanEntry['day'],
|
||||||
|
'date_format' => 'date',
|
||||||
|
'recipe' => json_encode($recipe),
|
||||||
|
'mealPlanEntry' => json_encode($mealPlanEntry),
|
||||||
|
'type' => $mealPlanEntry['type'],
|
||||||
|
'productDetails' => json_encode($productDetails)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'mealplan', [
|
||||||
|
'fullcalendarEventSources' => $events,
|
||||||
|
'recipes' => $recipes,
|
||||||
|
'internalRecipes' => $this->getDatabase()->recipes()->whereNot('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll(),
|
||||||
|
'recipesResolved' => $this->getRecipesService()->GetRecipesResolved(),
|
||||||
|
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||||
|
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -27,8 +68,9 @@ class RecipesController extends BaseController
|
|||||||
foreach ($recipes as $recipe)
|
foreach ($recipes as $recipe)
|
||||||
{
|
{
|
||||||
$selectedRecipe = $recipe;
|
$selectedRecipe = $recipe;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$selectedRecipePositionsResolved = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id = :1 AND is_nested_recipe_pos = 0', $selectedRecipe->id)->orderBy('ingredient_group', 'ASC', 'product_group', 'ASC');
|
$selectedRecipePositionsResolved = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id = :1 AND is_nested_recipe_pos = 0', $selectedRecipe->id)->orderBy('ingredient_group', 'ASC', 'product_group', 'ASC');
|
||||||
@@ -52,15 +94,17 @@ class RecipesController extends BaseController
|
|||||||
{
|
{
|
||||||
$selectedRecipeSubRecipes = $this->getDatabase()->recipes()->where('id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved WHERE recipe_id = :1 AND includes_recipe_id != :1)', $selectedRecipe->id)->orderBy('name')->fetchAll();
|
$selectedRecipeSubRecipes = $this->getDatabase()->recipes()->where('id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved WHERE recipe_id = :1 AND includes_recipe_id != :1)', $selectedRecipe->id)->orderBy('name')->fetchAll();
|
||||||
|
|
||||||
$includedRecipeIdsAbsolute = array();
|
$includedRecipeIdsAbsolute = [];
|
||||||
$includedRecipeIdsAbsolute[] = $selectedRecipe->id;
|
$includedRecipeIdsAbsolute[] = $selectedRecipe->id;
|
||||||
foreach($selectedRecipeSubRecipes as $subRecipe)
|
|
||||||
|
foreach ($selectedRecipeSubRecipes as $subRecipe)
|
||||||
{
|
{
|
||||||
$includedRecipeIdsAbsolute[] = $subRecipe->id;
|
$includedRecipeIdsAbsolute[] = $subRecipe->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$allRecipePositions = array();
|
$allRecipePositions = [];
|
||||||
foreach($includedRecipeIdsAbsolute as $id)
|
|
||||||
|
foreach ($includedRecipeIdsAbsolute as $id)
|
||||||
{
|
{
|
||||||
$allRecipePositions[$id] = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id = :1 AND is_nested_recipe_pos = 0', $id)->orderBy('ingredient_group', 'ASC', 'product_group', 'ASC');
|
$allRecipePositions[$id] = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id = :1 AND is_nested_recipe_pos = 0', $id)->orderBy('ingredient_group', 'ASC', 'product_group', 'ASC');
|
||||||
}
|
}
|
||||||
@@ -78,15 +122,15 @@ class RecipesController extends BaseController
|
|||||||
$recipeId = $args['recipeId'];
|
$recipeId = $args['recipeId'];
|
||||||
|
|
||||||
return $this->renderPage($response, 'recipeform', [
|
return $this->renderPage($response, 'recipeform', [
|
||||||
'recipe' => $this->getDatabase()->recipes($recipeId),
|
'recipe' => $this->getDatabase()->recipes($recipeId),
|
||||||
'recipePositions' => $this->getDatabase()->recipes_pos()->where('recipe_id', $recipeId),
|
'recipePositions' => $this->getDatabase()->recipes_pos()->where('recipe_id', $recipeId),
|
||||||
'mode' => $recipeId == 'new' ? "create" : "edit",
|
'mode' => $recipeId == 'new' ? 'create' : 'edit',
|
||||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units(),
|
'quantityunits' => $this->getDatabase()->quantity_units(),
|
||||||
'recipePositionsResolved' => $this->getRecipesService()->GetRecipesPosResolved(),
|
'recipePositionsResolved' => $this->getRecipesService()->GetRecipesPosResolved(),
|
||||||
'recipesResolved' => $this->getRecipesService()->GetRecipesResolved(),
|
'recipesResolved' => $this->getRecipesService()->GetRecipesResolved(),
|
||||||
'recipes' => $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name'),
|
'recipes' => $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name'),
|
||||||
'recipeNestings' => $this->getDatabase()->recipes_nestings()->where('recipe_id', $recipeId),
|
'recipeNestings' => $this->getDatabase()->recipes_nestings()->where('recipe_id', $recipeId),
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('recipes'),
|
'userfields' => $this->getUserfieldsService()->GetFields('recipes'),
|
||||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||||
]);
|
]);
|
||||||
@@ -109,13 +153,14 @@ class RecipesController extends BaseController
|
|||||||
{
|
{
|
||||||
return $this->renderPage($response, 'recipeposform', [
|
return $this->renderPage($response, 'recipeposform', [
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'recipe' => $this->getDatabase()->recipes($args['recipeId']),
|
'recipe' => $this->getDatabase()->recipes($args['recipeId']),
|
||||||
'recipePos' => $this->getDatabase()->recipes_pos($args['recipePosId']),
|
'recipePos' => $this->getDatabase()->recipes_pos($args['recipePosId']),
|
||||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RecipesSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function RecipesSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -123,46 +168,9 @@ class RecipesController extends BaseController
|
|||||||
return $this->renderPage($response, 'recipessettings');
|
return $this->renderPage($response, 'recipessettings');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function MealPlan(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
$recipes = $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll();
|
parent::__construct($container);
|
||||||
|
|
||||||
$events = array();
|
|
||||||
foreach($this->getDatabase()->meal_plan() as $mealPlanEntry)
|
|
||||||
{
|
|
||||||
$recipe = FindObjectInArrayByPropertyValue($recipes, 'id', $mealPlanEntry['recipe_id']);
|
|
||||||
$title = '';
|
|
||||||
if ($recipe !== null)
|
|
||||||
{
|
|
||||||
$title = $recipe->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
$productDetails = null;
|
|
||||||
if ($mealPlanEntry['product_id'] !== null)
|
|
||||||
{
|
|
||||||
$productDetails = $this->getStockService()->GetProductDetails($mealPlanEntry['product_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$events[] = array(
|
|
||||||
'id' => $mealPlanEntry['id'],
|
|
||||||
'title' => $title,
|
|
||||||
'start' => $mealPlanEntry['day'],
|
|
||||||
'date_format' => 'date',
|
|
||||||
'recipe' => json_encode($recipe),
|
|
||||||
'mealPlanEntry' => json_encode($mealPlanEntry),
|
|
||||||
'type' => $mealPlanEntry['type'],
|
|
||||||
'productDetails' => json_encode($productDetails)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'mealplan', [
|
|
||||||
'fullcalendarEventSources' => $events,
|
|
||||||
'recipes' => $recipes,
|
|
||||||
'internalRecipes' => $this->getDatabase()->recipes()->whereNot('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll(),
|
|
||||||
'recipesResolved' => $this->getRecipesService()->GetRecipesResolved(),
|
|
||||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
|
||||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,59 +4,6 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class StockController extends BaseController
|
class StockController extends BaseController
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$usersService = $this->getUsersService();
|
|
||||||
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['stock_expring_soon_days'];
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'stockoverview', [
|
|
||||||
'currentStock' => $this->getStockService()->GetCurrentStockOverview(),
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'currentStockLocations' => $this->getStockService()->GetCurrentStockLocations(),
|
|
||||||
'nextXDays' => $nextXDays,
|
|
||||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Stockentries(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$usersService = $this->getUsersService();
|
|
||||||
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['stock_expring_soon_days'];
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'stockentries', [
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
|
||||||
'stockEntries' => $this->getDatabase()->stock()->orderBy('product_id'),
|
|
||||||
'currentStockLocations' => $this->getStockService()->GetCurrentStockLocations(),
|
|
||||||
'nextXDays' => $nextXDays,
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Purchase(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id';
|
|
||||||
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'purchase', [
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'barcodes' => $productBarcodes,
|
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Consume(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Consume(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
$sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id';
|
$sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id';
|
||||||
@@ -64,20 +11,7 @@ class StockController extends BaseController
|
|||||||
|
|
||||||
return $this->renderPage($response, 'consume', [
|
return $this->renderPage($response, 'consume', [
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
'barcodes' => $productBarcodes,
|
'barcodes' => $productBarcodes,
|
||||||
'recipes' => $this->getDatabase()->recipes()->orderBy('name'),
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Transfer(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id';
|
|
||||||
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'transfer', [
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'barcodes' => $productBarcodes,
|
|
||||||
'recipes' => $this->getDatabase()->recipes()->orderBy('name'),
|
'recipes' => $this->getDatabase()->recipes()->orderBy('name'),
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
||||||
]);
|
]);
|
||||||
@@ -90,264 +24,12 @@ class StockController extends BaseController
|
|||||||
|
|
||||||
return $this->renderPage($response, 'inventory', [
|
return $this->renderPage($response, 'inventory', [
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
'barcodes' => $productBarcodes,
|
'barcodes' => $productBarcodes,
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function StockEntryEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'stockentryform', [
|
|
||||||
'stockEntry' => $this->getDatabase()->stock()->where('id', $args['entryId'])->fetch(),
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
$listId = 1;
|
|
||||||
if (isset($request->getQueryParams()['list']))
|
|
||||||
{
|
|
||||||
$listId = $request->getQueryParams()['list'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'shoppinglist', [
|
|
||||||
'listItems' => $this->getDatabase()->shopping_list()->where('shopping_list_id = :1', $listId),
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'missingProducts' => $this->getStockService()->GetMissingProducts(),
|
|
||||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
|
||||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
|
||||||
'selectedShoppingListId' => $listId,
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ProductsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'products', [
|
|
||||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function StockSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'stocksettings', [
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function LocationsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'locations', [
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('locations'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('locations')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ShoppingLocationsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglocations', [
|
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('shopping_locations')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ProductGroupsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'productgroups', [
|
|
||||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('product_groups'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('product_groups')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function QuantityUnitsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'quantityunits', [
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
|
||||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('quantity_units')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ProductEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['productId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'productform', [
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
|
||||||
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
|
||||||
'products' => $this->getDatabase()->products()->where('parent_product_id IS NULL and active = 1')->orderBy('name'),
|
|
||||||
'isSubProductOfOthers' => false,
|
|
||||||
'mode' => 'create'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$product = $this->getDatabase()->products($args['productId']);
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'productform', [
|
|
||||||
'product' => $product,
|
|
||||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
|
||||||
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
|
||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
|
||||||
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
|
||||||
'products' => $this->getDatabase()->products()->where('id != :1 AND parent_product_id IS NULL and active = 1', $product->id)->orderBy('name'),
|
|
||||||
'isSubProductOfOthers' => $this->getDatabase()->products()->where('parent_product_id = :1', $product->id)->count() !== 0,
|
|
||||||
'mode' => 'edit',
|
|
||||||
'quConversions' => $this->getDatabase()->quantity_unit_conversions()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function LocationEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['locationId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'locationform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('locations')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'locationform', [
|
|
||||||
'location' => $this->getDatabase()->locations($args['locationId']),
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('locations')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ShoppingLocationEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['shoppingLocationId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglocationform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglocationform', [
|
|
||||||
'shoppinglocation' => $this->getDatabase()->shopping_locations($args['shoppingLocationId']),
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ProductGroupEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['productGroupId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'productgroupform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('product_groups')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'productgroupform', [
|
|
||||||
'group' => $this->getDatabase()->product_groups($args['productGroupId']),
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('product_groups')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function QuantityUnitEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['quantityunitId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'quantityunitform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
|
||||||
'pluralCount' => $this->getLocalizationService()->GetPluralCount(),
|
|
||||||
'pluralRule' => $this->getLocalizationService()->GetPluralDefinition()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$quantityUnit = $this->getDatabase()->quantity_units($args['quantityunitId']);
|
|
||||||
|
|
||||||
return $this->renderPage($response, 'quantityunitform', [
|
|
||||||
'quantityUnit' => $quantityUnit,
|
|
||||||
'mode' => 'edit',
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
|
||||||
'pluralCount' => $this->getLocalizationService()->GetPluralCount(),
|
|
||||||
'pluralRule' => $this->getLocalizationService()->GetPluralDefinition(),
|
|
||||||
'defaultQuConversions' => $this->getDatabase()->quantity_unit_conversions()->where('from_qu_id = :1 AND product_id IS NULL', $quantityUnit->id),
|
|
||||||
'quantityUnits' => $this->getDatabase()->quantity_units()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ShoppingListItemEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['itemId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglistitemform', [
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
|
||||||
'mode' => 'create'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglistitemform', [
|
|
||||||
'listItem' => $this->getDatabase()->shopping_list($args['itemId']),
|
|
||||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
|
||||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
|
||||||
'mode' => 'edit'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ShoppingListEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['listId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglistform', [
|
|
||||||
'mode' => 'create'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglistform', [
|
|
||||||
'shoppingList' => $this->getDatabase()->shopping_lists($args['listId']),
|
|
||||||
'mode' => 'edit'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ShoppingListSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'shoppinglistsettings');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'stockjournal', [
|
return $this->renderPage($response, 'stockjournal', [
|
||||||
@@ -368,9 +50,55 @@ class StockController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function LocationEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['locationId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'locationform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('locations')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'locationform', [
|
||||||
|
'location' => $this->getDatabase()->locations($args['locationId']),
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('locations')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function LocationsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'locations', [
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('locations'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('locations')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$usersService = $this->getUsersService();
|
||||||
|
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['stock_expring_soon_days'];
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'stockoverview', [
|
||||||
|
'currentStock' => $this->getStockService()->GetCurrentStockOverview(),
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'currentStockLocations' => $this->getStockService()->GetCurrentStockLocations(),
|
||||||
|
'nextXDays' => $nextXDays,
|
||||||
|
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function ProductBarcodesEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function ProductBarcodesEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
$product = null;
|
$product = null;
|
||||||
|
|
||||||
if (isset($request->getQueryParams()['product']))
|
if (isset($request->getQueryParams()['product']))
|
||||||
{
|
{
|
||||||
$product = $this->getDatabase()->products($request->getQueryParams()['product']);
|
$product = $this->getDatabase()->products($request->getQueryParams()['product']);
|
||||||
@@ -394,17 +122,112 @@ class StockController extends BaseController
|
|||||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name')
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ProductEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['productId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'productform', [
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
|
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||||
|
'products' => $this->getDatabase()->products()->where('parent_product_id IS NULL and active = 1')->orderBy('name'),
|
||||||
|
'isSubProductOfOthers' => false,
|
||||||
|
'mode' => 'create'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$product = $this->getDatabase()->products($args['productId']);
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'productform', [
|
||||||
|
'product' => $product,
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
|
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||||
|
'products' => $this->getDatabase()->products()->where('id != :1 AND parent_product_id IS NULL and active = 1', $product->id)->orderBy('name'),
|
||||||
|
'isSubProductOfOthers' => $this->getDatabase()->products()->where('parent_product_id = :1', $product->id)->count() !== 0,
|
||||||
|
'mode' => 'edit',
|
||||||
|
'quConversions' => $this->getDatabase()->quantity_unit_conversions()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ProductGroupEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['productGroupId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'productgroupform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('product_groups')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'productgroupform', [
|
||||||
|
'group' => $this->getDatabase()->product_groups($args['productGroupId']),
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('product_groups')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ProductGroupsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'productgroups', [
|
||||||
|
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('product_groups'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('product_groups')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ProductsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'products', [
|
||||||
|
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Purchase(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id';
|
||||||
|
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'purchase', [
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'barcodes' => $productBarcodes,
|
||||||
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function QuantityUnitConversionEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function QuantityUnitConversionEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
$product = null;
|
$product = null;
|
||||||
|
|
||||||
if (isset($request->getQueryParams()['product']))
|
if (isset($request->getQueryParams()['product']))
|
||||||
{
|
{
|
||||||
$product = $this->getDatabase()->products($request->getQueryParams()['product']);
|
$product = $this->getDatabase()->products($request->getQueryParams()['product']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultQuUnit = null;
|
$defaultQuUnit = null;
|
||||||
|
|
||||||
if (isset($request->getQueryParams()['qu-unit']))
|
if (isset($request->getQueryParams()['qu-unit']))
|
||||||
{
|
{
|
||||||
$defaultQuUnit = $this->getDatabase()->quantity_units($request->getQueryParams()['qu-unit']);
|
$defaultQuUnit = $this->getDatabase()->quantity_units($request->getQueryParams()['qu-unit']);
|
||||||
@@ -423,7 +246,7 @@ class StockController extends BaseController
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'quantityunitconversionform', [
|
return $this->renderPage($response, 'quantityunitconversionform', [
|
||||||
'quConversion' => $this->getDatabase()->quantity_unit_conversions($args['quConversionId']),
|
'quConversion' => $this->getDatabase()->quantity_unit_conversions($args['quConversionId']),
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_unit_conversions'),
|
'userfields' => $this->getUserfieldsService()->GetFields('quantity_unit_conversions'),
|
||||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
@@ -431,6 +254,35 @@ class StockController extends BaseController
|
|||||||
'defaultQuUnit' => $defaultQuUnit
|
'defaultQuUnit' => $defaultQuUnit
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function QuantityUnitEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['quantityunitId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'quantityunitform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
||||||
|
'pluralCount' => $this->getLocalizationService()->GetPluralCount(),
|
||||||
|
'pluralRule' => $this->getLocalizationService()->GetPluralDefinition()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$quantityUnit = $this->getDatabase()->quantity_units($args['quantityunitId']);
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'quantityunitform', [
|
||||||
|
'quantityUnit' => $quantityUnit,
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
||||||
|
'pluralCount' => $this->getLocalizationService()->GetPluralCount(),
|
||||||
|
'pluralRule' => $this->getLocalizationService()->GetPluralDefinition(),
|
||||||
|
'defaultQuConversions' => $this->getDatabase()->quantity_unit_conversions()->where('from_qu_id = :1 AND product_id IS NULL', $quantityUnit->id),
|
||||||
|
'quantityUnits' => $this->getDatabase()->quantity_units()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function QuantityUnitPluralFormTesting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function QuantityUnitPluralFormTesting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -439,4 +291,165 @@ class StockController extends BaseController
|
|||||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name')
|
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function QuantityUnitsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'quantityunits', [
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('quantity_units')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$listId = 1;
|
||||||
|
|
||||||
|
if (isset($request->getQueryParams()['list']))
|
||||||
|
{
|
||||||
|
$listId = $request->getQueryParams()['list'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'shoppinglist', [
|
||||||
|
'listItems' => $this->getDatabase()->shopping_list()->where('shopping_list_id = :1', $listId),
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'missingProducts' => $this->getStockService()->GetMissingProducts(),
|
||||||
|
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||||
|
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
||||||
|
'selectedShoppingListId' => $listId,
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ShoppingListEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['listId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglistform', [
|
||||||
|
'mode' => 'create'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglistform', [
|
||||||
|
'shoppingList' => $this->getDatabase()->shopping_lists($args['listId']),
|
||||||
|
'mode' => 'edit'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ShoppingListItemEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['itemId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglistitemform', [
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
||||||
|
'mode' => 'create'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglistitemform', [
|
||||||
|
'listItem' => $this->getDatabase()->shopping_list($args['itemId']),
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
||||||
|
'mode' => 'edit'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ShoppingListSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglistsettings');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ShoppingLocationEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['shoppingLocationId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglocationform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglocationform', [
|
||||||
|
'shoppinglocation' => $this->getDatabase()->shopping_locations($args['shoppingLocationId']),
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ShoppingLocationsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'shoppinglocations', [
|
||||||
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('shopping_locations')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function StockEntryEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'stockentryform', [
|
||||||
|
'stockEntry' => $this->getDatabase()->stock()->where('id', $args['entryId'])->fetch(),
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function StockSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'stocksettings', [
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Stockentries(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$usersService = $this->getUsersService();
|
||||||
|
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['stock_expring_soon_days'];
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'stockentries', [
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||||
|
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||||
|
'stockEntries' => $this->getDatabase()->stock()->orderBy('product_id'),
|
||||||
|
'currentStockLocations' => $this->getStockService()->GetCurrentStockLocations(),
|
||||||
|
'nextXDays' => $nextXDays,
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||||
|
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Transfer(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
$sql = 'select group_concat(barcode) barcodes, product_id from product_barcodes group by product_id';
|
||||||
|
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||||
|
|
||||||
|
return $this->renderPage($response, 'transfer', [
|
||||||
|
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||||
|
'barcodes' => $productBarcodes,
|
||||||
|
'recipes' => $this->getDatabase()->recipes()->orderBy('name'),
|
||||||
|
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,18 +4,6 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class SystemApiController extends BaseApiController
|
class SystemApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetDbChangedTime(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->ApiResponse($response, array(
|
|
||||||
'changed_time' => $this->getDatabaseService()->GetDbChangedTime()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetConfig(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetConfig(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -28,13 +16,15 @@ class SystemApiController extends BaseApiController
|
|||||||
unset($constants['GROCY_IS_EMBEDDED_INSTALL']);
|
unset($constants['GROCY_IS_EMBEDDED_INSTALL']);
|
||||||
unset($constants['GROCY_USER_ID']);
|
unset($constants['GROCY_USER_ID']);
|
||||||
|
|
||||||
$returnArray = array();
|
$returnArray = [];
|
||||||
|
|
||||||
foreach ($constants as $constant => $value)
|
foreach ($constants as $constant => $value)
|
||||||
{
|
{
|
||||||
if (substr($constant, 0, 6) === 'GROCY_')
|
if (substr($constant, 0, 6) === 'GROCY_')
|
||||||
{
|
{
|
||||||
$returnArray[substr($constant, 6)] = $value;
|
$returnArray[substr($constant, 6)] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->ApiResponse($response, $returnArray);
|
return $this->ApiResponse($response, $returnArray);
|
||||||
@@ -43,6 +33,19 @@ class SystemApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDbChangedTime(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->ApiResponse($response, [
|
||||||
|
'changed_time' => $this->getDatabaseService()->GetDbChangedTime()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetSystemInfo(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->ApiResponse($response, $this->getApplicationService()->GetSystemInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function LogMissingLocalization(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function LogMissingLocalization(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -60,11 +63,14 @@ class SystemApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetSystemInfo(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
return $this->ApiResponse($response, $this->getApplicationService()->GetSystemInfo());
|
parent::__construct($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,15 +2,22 @@
|
|||||||
|
|
||||||
namespace Grocy\Controllers;
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
use \Grocy\Services\DatabaseMigrationService;
|
use Grocy\Services\DatabaseMigrationService;
|
||||||
use \Grocy\Services\DemoDataGeneratorService;
|
use Grocy\Services\DemoDataGeneratorService;
|
||||||
|
|
||||||
class SystemController extends BaseController
|
class SystemController extends BaseController
|
||||||
{
|
{
|
||||||
|
public function About(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
return $this->renderPage($response, 'about', [
|
||||||
|
'system_info' => $this->getApplicationService()->GetSystemInfo(),
|
||||||
|
'changelog' => $this->getApplicationService()->GetChangelog()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function BarcodeScannerTesting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'barcodescannertesting');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Root(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Root(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -28,6 +35,11 @@ class SystemController extends BaseController
|
|||||||
return $response->withRedirect($this->AppContainer->get('UrlManager')->ConstructUrl($this->GetEntryPageRelative()));
|
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.
|
* Get the entry page of the application based on the value of the entry page setting.
|
||||||
*
|
*
|
||||||
@@ -38,69 +50,69 @@ class SystemController extends BaseController
|
|||||||
*/
|
*/
|
||||||
private function GetEntryPageRelative()
|
private function GetEntryPageRelative()
|
||||||
{
|
{
|
||||||
if (defined('GROCY_ENTRY_PAGE')) {
|
if (defined('GROCY_ENTRY_PAGE'))
|
||||||
|
{
|
||||||
$entryPage = constant('GROCY_ENTRY_PAGE');
|
$entryPage = constant('GROCY_ENTRY_PAGE');
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$entryPage = 'stock';
|
$entryPage = 'stock';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stock
|
// Stock
|
||||||
if ($entryPage === 'stock' && constant('GROCY_FEATURE_FLAG_STOCK')) {
|
if ($entryPage === 'stock' && constant('GROCY_FEATURE_FLAG_STOCK'))
|
||||||
|
{
|
||||||
return '/stockoverview';
|
return '/stockoverview';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shoppinglist
|
// Shoppinglist
|
||||||
if ($entryPage === 'shoppinglist' && constant('GROCY_FEATURE_FLAG_SHOPPINGLIST')) {
|
if ($entryPage === 'shoppinglist' && constant('GROCY_FEATURE_FLAG_SHOPPINGLIST'))
|
||||||
|
{
|
||||||
return '/shoppinglist';
|
return '/shoppinglist';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recipes
|
// Recipes
|
||||||
if ($entryPage === 'recipes' && constant('GROCY_FEATURE_FLAG_RECIPES')) {
|
if ($entryPage === 'recipes' && constant('GROCY_FEATURE_FLAG_RECIPES'))
|
||||||
|
{
|
||||||
return '/recipes';
|
return '/recipes';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chores
|
// Chores
|
||||||
if ($entryPage === 'chores' && constant('GROCY_FEATURE_FLAG_CHORES')) {
|
if ($entryPage === 'chores' && constant('GROCY_FEATURE_FLAG_CHORES'))
|
||||||
|
{
|
||||||
return '/choresoverview';
|
return '/choresoverview';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tasks
|
// Tasks
|
||||||
if ($entryPage === 'tasks' && constant('GROCY_FEATURE_FLAG_TASKS')) {
|
if ($entryPage === 'tasks' && constant('GROCY_FEATURE_FLAG_TASKS'))
|
||||||
|
{
|
||||||
return '/tasks';
|
return '/tasks';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Batteries
|
// Batteries
|
||||||
if ($entryPage === 'batteries' && constant('GROCY_FEATURE_FLAG_BATTERIES')) {
|
if ($entryPage === 'batteries' && constant('GROCY_FEATURE_FLAG_BATTERIES'))
|
||||||
|
{
|
||||||
return '/batteriesoverview';
|
return '/batteriesoverview';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($entryPage === 'equipment' && constant('GROCY_FEATURE_FLAG_EQUIPMENT')) {
|
if ($entryPage === 'equipment' && constant('GROCY_FEATURE_FLAG_EQUIPMENT'))
|
||||||
|
{
|
||||||
return '/equipment';
|
return '/equipment';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calendar
|
// Calendar
|
||||||
if ($entryPage === 'calendar' && constant('GROCY_FEATURE_FLAG_CALENDAR')) {
|
if ($entryPage === 'calendar' && constant('GROCY_FEATURE_FLAG_CALENDAR'))
|
||||||
|
{
|
||||||
return '/calendar';
|
return '/calendar';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meal Plan
|
// Meal Plan
|
||||||
if ($entryPage === 'mealplan' && constant('GROCY_FEATURE_FLAG_RECIPES')) {
|
if ($entryPage === 'mealplan' && constant('GROCY_FEATURE_FLAG_RECIPES'))
|
||||||
|
{
|
||||||
return '/mealplan';
|
return '/mealplan';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '/about';
|
return '/about';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function About(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'about', [
|
|
||||||
'system_info' => $this->getApplicationService()->GetSystemInfo(),
|
|
||||||
'changelog' => $this->getApplicationService()->GetChangelog()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function BarcodeScannerTesting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'barcodescannertesting');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -6,11 +6,6 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class TasksApiController extends BaseApiController
|
class TasksApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->ApiResponse($response, $this->getTasksService()->GetCurrent());
|
return $this->ApiResponse($response, $this->getTasksService()->GetCurrent());
|
||||||
@@ -25,6 +20,7 @@ class TasksApiController extends BaseApiController
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$doneTime = date('Y-m-d H:i:s');
|
$doneTime = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
if (array_key_exists('done_time', $requestBody) && IsIsoDateTime($requestBody['done_time']))
|
if (array_key_exists('done_time', $requestBody) && IsIsoDateTime($requestBody['done_time']))
|
||||||
{
|
{
|
||||||
$doneTime = $requestBody['done_time'];
|
$doneTime = $requestBody['done_time'];
|
||||||
@@ -37,6 +33,7 @@ class TasksApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UndoTask(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UndoTask(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -52,5 +49,12 @@ class TasksApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,11 +4,6 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
class TasksController extends BaseController
|
class TasksController extends BaseController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
|
||||||
{
|
|
||||||
parent::__construct($container);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
if (isset($request->getQueryParams()['include_done']))
|
if (isset($request->getQueryParams()['include_done']))
|
||||||
@@ -33,29 +28,6 @@ class TasksController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function TaskEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
if ($args['taskId'] == 'new')
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'taskform', [
|
|
||||||
'mode' => 'create',
|
|
||||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
|
||||||
'users' => $this->getDatabase()->users()->orderBy('username'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('tasks')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->renderPage($response, 'taskform', [
|
|
||||||
'task' => $this->getDatabase()->tasks($args['taskId']),
|
|
||||||
'mode' => 'edit',
|
|
||||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
|
||||||
'users' => $this->getDatabase()->users()->orderBy('username'),
|
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('tasks')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function TaskCategoriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function TaskCategoriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'taskcategories', [
|
return $this->renderPage($response, 'taskcategories', [
|
||||||
@@ -77,15 +49,46 @@ class TasksController extends BaseController
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'taskcategoryform', [
|
return $this->renderPage($response, 'taskcategoryform', [
|
||||||
'category' => $this->getDatabase()->task_categories($args['categoryId']),
|
'category' => $this->getDatabase()->task_categories($args['categoryId']),
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'userfields' => $this->getUserfieldsService()->GetFields('task_categories')
|
'userfields' => $this->getUserfieldsService()->GetFields('task_categories')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function TaskEditForm(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['taskId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'taskform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
||||||
|
'users' => $this->getDatabase()->users()->orderBy('username'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('tasks')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->renderPage($response, 'taskform', [
|
||||||
|
'task' => $this->getDatabase()->tasks($args['taskId']),
|
||||||
|
'mode' => 'edit',
|
||||||
|
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
||||||
|
'users' => $this->getDatabase()->users()->orderBy('username'),
|
||||||
|
'userfields' => $this->getUserfieldsService()->GetFields('tasks')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function TasksSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function TasksSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'taskssettings');
|
return $this->renderPage($response, 'taskssettings');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct(\DI\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -9,76 +9,92 @@ class User
|
|||||||
{
|
{
|
||||||
const PERMISSION_ADMIN = 'ADMIN';
|
const PERMISSION_ADMIN = 'ADMIN';
|
||||||
|
|
||||||
const PERMISSION_USERS = 'USERS';
|
|
||||||
const PERMISSION_USERS_CREATE = 'USERS_CREATE';
|
|
||||||
const PERMISSION_USERS_EDIT = 'USERS_EDIT';
|
|
||||||
const PERMISSION_USERS_READ = 'USERS_READ';
|
|
||||||
const PERMISSION_USERS_EDIT_SELF = 'USERS_EDIT_SELF';
|
|
||||||
|
|
||||||
const PERMISSION_STOCK = 'STOCK';
|
|
||||||
const PERMISSION_STOCK_PURCHASE = 'STOCK_PURCHASE';
|
|
||||||
const PERMISSION_STOCK_CONSUME = 'STOCK_CONSUME';
|
|
||||||
const PERMISSION_STOCK_INVENTORY = 'STOCK_INVENTORY';
|
|
||||||
const PERMISSION_STOCK_TRANSFER = 'STOCK_TRANSFER';
|
|
||||||
const PERMISSION_STOCK_OPEN = 'STOCK_OPEN';
|
|
||||||
const PERMISSION_STOCK_EDIT = 'STOCK_EDIT';
|
|
||||||
|
|
||||||
const PERMISSION_RECIPES = 'RECIPES';
|
|
||||||
const PERMISSION_RECIPES_MEALPLAN = 'RECIPES_MEALPLAN';
|
|
||||||
|
|
||||||
const PERMISSION_SHOPPINGLIST = 'SHOPPINGLIST';
|
|
||||||
const PERMISSION_SHOPPINGLIST_ITEMS_ADD = 'SHOPPINGLIST_ITEMS_ADD';
|
|
||||||
const PERMISSION_SHOPPINGLIST_ITEMS_DELETE = 'SHOPPINGLIST_ITEMS_DELETE';
|
|
||||||
|
|
||||||
const PERMISSION_CHORES = 'CHORES';
|
|
||||||
const PERMISSION_CHORE_TRACK_EXECUTION = 'CHORE_TRACK_EXECUTION';
|
|
||||||
const PERMISSION_CHORE_UNDO_EXECUTION = 'CHORE_UNDO_EXECUTION';
|
|
||||||
|
|
||||||
const PERMISSION_BATTERIES = 'BATTERIES';
|
const PERMISSION_BATTERIES = 'BATTERIES';
|
||||||
|
|
||||||
const PERMISSION_BATTERIES_TRACK_CHARGE_CYCLE = 'BATTERIES_TRACK_CHARGE_CYCLE';
|
const PERMISSION_BATTERIES_TRACK_CHARGE_CYCLE = 'BATTERIES_TRACK_CHARGE_CYCLE';
|
||||||
|
|
||||||
const PERMISSION_BATTERIES_UNDO_CHARGE_CYCLE = 'BATTERIES_UNDO_CHARGE_CYCLE';
|
const PERMISSION_BATTERIES_UNDO_CHARGE_CYCLE = 'BATTERIES_UNDO_CHARGE_CYCLE';
|
||||||
|
|
||||||
const PERMISSION_TASKS = 'TASKS';
|
|
||||||
const PERMISSION_TASKS_UNDO_EXECUTION = 'TASKS_UNDO_EXECUTION';
|
|
||||||
const PERMISSION_TASKS_MARK_COMPLETED = 'TASKS_MARK_COMPLETED';
|
|
||||||
|
|
||||||
const PERMISSION_EQUIPMENT = 'EQUIPMENT';
|
|
||||||
|
|
||||||
const PERMISSION_CALENDAR = 'CALENDAR';
|
const PERMISSION_CALENDAR = 'CALENDAR';
|
||||||
|
|
||||||
|
const PERMISSION_CHORES = 'CHORES';
|
||||||
|
|
||||||
|
const PERMISSION_CHORE_TRACK_EXECUTION = 'CHORE_TRACK_EXECUTION';
|
||||||
|
|
||||||
|
const PERMISSION_CHORE_UNDO_EXECUTION = 'CHORE_UNDO_EXECUTION';
|
||||||
|
|
||||||
|
const PERMISSION_EQUIPMENT = 'EQUIPMENT';
|
||||||
|
|
||||||
const PERMISSION_MASTER_DATA_EDIT = 'MASTER_DATA_EDIT';
|
const PERMISSION_MASTER_DATA_EDIT = 'MASTER_DATA_EDIT';
|
||||||
|
|
||||||
|
const PERMISSION_RECIPES = 'RECIPES';
|
||||||
|
|
||||||
|
const PERMISSION_RECIPES_MEALPLAN = 'RECIPES_MEALPLAN';
|
||||||
|
|
||||||
|
const PERMISSION_SHOPPINGLIST = 'SHOPPINGLIST';
|
||||||
|
|
||||||
|
const PERMISSION_SHOPPINGLIST_ITEMS_ADD = 'SHOPPINGLIST_ITEMS_ADD';
|
||||||
|
|
||||||
|
const PERMISSION_SHOPPINGLIST_ITEMS_DELETE = 'SHOPPINGLIST_ITEMS_DELETE';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK = 'STOCK';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK_CONSUME = 'STOCK_CONSUME';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK_EDIT = 'STOCK_EDIT';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK_INVENTORY = 'STOCK_INVENTORY';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK_OPEN = 'STOCK_OPEN';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK_PURCHASE = 'STOCK_PURCHASE';
|
||||||
|
|
||||||
|
const PERMISSION_STOCK_TRANSFER = 'STOCK_TRANSFER';
|
||||||
|
|
||||||
|
const PERMISSION_TASKS = 'TASKS';
|
||||||
|
|
||||||
|
const PERMISSION_TASKS_MARK_COMPLETED = 'TASKS_MARK_COMPLETED';
|
||||||
|
|
||||||
|
const PERMISSION_TASKS_UNDO_EXECUTION = 'TASKS_UNDO_EXECUTION';
|
||||||
|
|
||||||
|
const PERMISSION_USERS = 'USERS';
|
||||||
|
|
||||||
|
const PERMISSION_USERS_CREATE = 'USERS_CREATE';
|
||||||
|
|
||||||
|
const PERMISSION_USERS_EDIT = 'USERS_EDIT';
|
||||||
|
|
||||||
|
const PERMISSION_USERS_EDIT_SELF = 'USERS_EDIT_SELF';
|
||||||
|
|
||||||
|
const PERMISSION_USERS_READ = 'USERS_READ';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \LessQL\Database|null
|
* @var \LessQL\Database|null
|
||||||
*/
|
*/
|
||||||
protected $db;
|
protected $db;
|
||||||
|
|
||||||
|
public static function PermissionList()
|
||||||
|
{
|
||||||
|
$user = new self();
|
||||||
|
return $user->getPermissionList();
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->db = DatabaseService::getInstance()->GetDbConnection();
|
$this->db = DatabaseService::getInstance()->GetDbConnection();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPermissions(): Result
|
public static function checkPermission($request, string...$permissions): void
|
||||||
{
|
{
|
||||||
return $this->db->user_permissions_resolved()->where('user_id', GROCY_USER_ID);
|
$user = new self();
|
||||||
}
|
|
||||||
|
|
||||||
public function hasPermission(string $permission): bool
|
foreach ($permissions as $permission)
|
||||||
{
|
{
|
||||||
// global $PERMISSION_CACHE;
|
if (!$user->hasPermission($permission))
|
||||||
// if(isset($PERMISSION_CACHE[$permission]))
|
{
|
||||||
// return $PERMISSION_CACHE[$permission];
|
|
||||||
return $this->getPermissions()->where('permission_name', $permission)->fetch() !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function checkPermission($request, string ...$permissions): void
|
|
||||||
{
|
|
||||||
$user = new User();
|
|
||||||
foreach ($permissions as $permission) {
|
|
||||||
if (!$user->hasPermission($permission)) {
|
|
||||||
throw new PermissionMissingException($request, $permission);
|
throw new PermissionMissingException($request, $permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -88,20 +104,34 @@ class User
|
|||||||
return $this->db->uihelper_user_permissions()->where('user_id', GROCY_USER_ID);
|
return $this->db->uihelper_user_permissions()->where('user_id', GROCY_USER_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function hasPermissions(string ...$permissions)
|
public function hasPermission(string $permission): bool
|
||||||
{
|
{
|
||||||
$user = new User();
|
// global $PERMISSION_CACHE;
|
||||||
foreach ($permissions as $permission) {
|
|
||||||
if (!$user->hasPermission($permission)) {
|
// if(isset($PERMISSION_CACHE[$permission]))
|
||||||
|
// return $PERMISSION_CACHE[$permission];
|
||||||
|
return $this->getPermissions()->where('permission_name', $permission)->fetch() !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function hasPermissions(string...$permissions)
|
||||||
|
{
|
||||||
|
$user = new self();
|
||||||
|
|
||||||
|
foreach ($permissions as $permission)
|
||||||
|
{
|
||||||
|
if (!$user->hasPermission($permission))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function PermissionList()
|
protected function getPermissions(): Result
|
||||||
{
|
{
|
||||||
$user = new User();
|
return $this->db->user_permissions_resolved()->where('user_id', GROCY_USER_ID);
|
||||||
return $user->getPermissionList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,22 +6,27 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class UsersApiController extends BaseApiController
|
class UsersApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
public function __construct(\DI\Container $container)
|
public function AddPermission(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
try {
|
||||||
}
|
User::checkPermission($request, User::PERMISSION_ADMIN);
|
||||||
|
$requestBody = $request->getParsedBody();
|
||||||
|
|
||||||
public function GetUsers(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
$this->getDatabase()->user_permissions()->createRow([
|
||||||
{
|
'user_id' => $args['userId'],
|
||||||
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
'permission_id' => $requestBody['permission_id']
|
||||||
try
|
])->save();
|
||||||
|
return $this->EmptyApiResponse($response);
|
||||||
|
}
|
||||||
|
catch (\Slim\Exception\HttpSpecializedException $ex)
|
||||||
{
|
{
|
||||||
return $this->ApiResponse($response, $this->getUsersService()->GetUsersAsDto());
|
return $this->GenericErrorResponse($response, $ex->getMessage(), $ex->getCode());
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CreateUser(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function CreateUser(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -43,6 +48,7 @@ class UsersApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function DeleteUser(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function DeleteUser(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -57,15 +63,20 @@ class UsersApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function EditUser(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function EditUser(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
if ($args['userId'] == GROCY_USER_ID) {
|
if ($args['userId'] == GROCY_USER_ID)
|
||||||
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_USERS_EDIT_SELF);
|
User::checkPermission($request, User::PERMISSION_USERS_EDIT_SELF);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_USERS_EDIT);
|
User::checkPermission($request, User::PERMISSION_USERS_EDIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
$requestBody = $request->getParsedBody();
|
$requestBody = $request->getParsedBody();
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -77,6 +88,21 @@ class UsersApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetUserSetting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$value = $this->getUsersService()->GetUserSetting(GROCY_USER_ID, $args['settingKey']);
|
||||||
|
return $this->ApiResponse($response, ['value' => $value]);
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetUserSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetUserSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -89,19 +115,76 @@ class UsersApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetUserSetting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function GetUsers(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
|
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$value = $this->getUsersService()->GetUserSetting(GROCY_USER_ID, $args['settingKey']);
|
return $this->ApiResponse($response, $this->getUsersService()->GetUsersAsDto());
|
||||||
return $this->ApiResponse($response, array('value' => $value));
|
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ListPermissions(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
User::checkPermission($request, User::PERMISSION_ADMIN);
|
||||||
|
|
||||||
|
return $this->ApiResponse($response,
|
||||||
|
$this->getDatabase()->user_permissions()->where($args['userId'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (\Slim\Exception\HttpSpecializedException $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage(), $ex->getCode());
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetPermissions(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
User::checkPermission($request, User::PERMISSION_ADMIN);
|
||||||
|
$requestBody = $request->getParsedBody();
|
||||||
|
$db = $this->getDatabase();
|
||||||
|
$db->user_permissions()
|
||||||
|
->where('user_id', $args['userId'])
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
$perms = [];
|
||||||
|
|
||||||
|
foreach ($requestBody['permissions'] as $perm_id)
|
||||||
|
{
|
||||||
|
$perms[] = [
|
||||||
|
'user_id' => $args['userId'],
|
||||||
|
'permission_id' => $perm_id
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->insert('user_permissions', $perms, 'batch');
|
||||||
|
|
||||||
|
return $this->EmptyApiResponse($response);
|
||||||
|
}
|
||||||
|
catch (\Slim\Exception\HttpSpecializedException $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage(), $ex->getCode());
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetUserSetting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function SetUserSetting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
@@ -117,67 +200,12 @@ class UsersApiController extends BaseApiController
|
|||||||
{
|
{
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AddPermission(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
try {
|
parent::__construct($container);
|
||||||
User::checkPermission($request, User::PERMISSION_ADMIN);
|
|
||||||
$requestBody = $request->getParsedBody();
|
|
||||||
|
|
||||||
$this->getDatabase()->user_permissions()->createRow(array(
|
|
||||||
'user_id' => $args['userId'],
|
|
||||||
'permission_id' => $requestBody['permission_id'],
|
|
||||||
))->save();
|
|
||||||
return $this->EmptyApiResponse($response);
|
|
||||||
} catch (\Slim\Exception\HttpSpecializedException $ex) {
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage(), $ex->getCode());
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function ListPermissions(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
User::checkPermission($request, User::PERMISSION_ADMIN);
|
|
||||||
|
|
||||||
return $this->ApiResponse($response,
|
|
||||||
$this->getDatabase()->user_permissions()->where($args['userId'])
|
|
||||||
);
|
|
||||||
} catch (\Slim\Exception\HttpSpecializedException $ex) {
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage(), $ex->getCode());
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function SetPermissions(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
User::checkPermission($request, User::PERMISSION_ADMIN);
|
|
||||||
$requestBody = $request->getParsedBody();
|
|
||||||
$db = $this->getDatabase();
|
|
||||||
$db->user_permissions()
|
|
||||||
->where('user_id', $args['userId'])
|
|
||||||
->delete();
|
|
||||||
|
|
||||||
$perms = [];
|
|
||||||
|
|
||||||
foreach ($requestBody['permissions'] as $perm_id) {
|
|
||||||
$perms[] = array(
|
|
||||||
'user_id' => $args['userId'],
|
|
||||||
'permission_id' => $perm_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$db->insert('user_permissions', $perms, 'batch');
|
|
||||||
|
|
||||||
return $this->EmptyApiResponse($response);
|
|
||||||
} catch (\Slim\Exception\HttpSpecializedException $ex) {
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage(), $ex->getCode());
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -6,11 +6,13 @@ use Grocy\Controllers\Users\User;
|
|||||||
|
|
||||||
class UsersController extends BaseController
|
class UsersController extends BaseController
|
||||||
{
|
{
|
||||||
public function UsersList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function PermissionList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
||||||
return $this->renderPage($response, 'users', [
|
return $this->renderPage($response, 'userpermissions', [
|
||||||
'users' => $this->getDatabase()->users()->orderBy('username')
|
'user' => $this->getDatabase()->users($args['userId']),
|
||||||
|
'permissions' => $this->getDatabase()->uihelper_user_permissions()
|
||||||
|
->where('parent IS NULL')->where('user_id', $args['userId'])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,35 +27,45 @@ class UsersController extends BaseController
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if($args['userId'] == GROCY_USER_ID)
|
if ($args['userId'] == GROCY_USER_ID)
|
||||||
|
{
|
||||||
User::checkPermission($request, User::PERMISSION_USERS_EDIT_SELF);
|
User::checkPermission($request, User::PERMISSION_USERS_EDIT_SELF);
|
||||||
else User::checkPermission($request, User::PERMISSION_USERS_EDIT);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
User::checkPermission($request, User::PERMISSION_USERS_EDIT);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->renderPage($response, 'userform', [
|
return $this->renderPage($response, 'userform', [
|
||||||
'user' => $this->getDatabase()->users($args['userId']),
|
'user' => $this->getDatabase()->users($args['userId']),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function PermissionList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
|
||||||
{
|
|
||||||
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
|
||||||
return $this->renderPage($response, 'userpermissions', [
|
|
||||||
'user' => $this->getDatabase()->users($args['userId']),
|
|
||||||
'permissions' => $this->getDatabase()->uihelper_user_permissions()
|
|
||||||
->where('parent IS NULL')->where('user_id', $args['userId']),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UserSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
public function UserSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->renderPage($response, 'usersettings', [
|
return $this->renderPage($response, 'usersettings', [
|
||||||
'languages' => array_filter(scandir(__DIR__.'/../localization'), function ($item){
|
'languages' => array_filter(scandir(__DIR__ . '/../localization'), function ($item)
|
||||||
if($item == "." || $item == "..")
|
{
|
||||||
|
if ($item == '.' || $item == '..')
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
return is_dir(__DIR__.'/../localization/'.$item);
|
}
|
||||||
|
|
||||||
|
return is_dir(__DIR__ . '/../localization/' . $item);
|
||||||
})
|
})
|
||||||
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function UsersList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||||
|
{
|
||||||
|
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
||||||
|
return $this->renderPage($response, 'users', [
|
||||||
|
'users' => $this->getDatabase()->users()->orderBy('username')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,16 +4,9 @@ namespace Grocy\Helpers;
|
|||||||
|
|
||||||
abstract class BaseBarcodeLookupPlugin
|
abstract class BaseBarcodeLookupPlugin
|
||||||
{
|
{
|
||||||
final public function __construct($locations, $quantityUnits)
|
|
||||||
{
|
|
||||||
$this->Locations = $locations;
|
|
||||||
$this->QuantityUnits = $quantityUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected $Locations;
|
protected $Locations;
|
||||||
protected $QuantityUnits;
|
|
||||||
|
|
||||||
abstract protected function ExecuteLookup($barcode);
|
protected $QuantityUnits;
|
||||||
|
|
||||||
final public function Lookup($barcode)
|
final public function Lookup($barcode)
|
||||||
{
|
{
|
||||||
@@ -24,52 +17,62 @@ abstract class BaseBarcodeLookupPlugin
|
|||||||
return $pluginOutput;
|
return $pluginOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin must return an associative array
|
// Plugin must return an associative array
|
||||||
if (!is_array($pluginOutput))
|
if (!is_array($pluginOutput))
|
||||||
{
|
{
|
||||||
throw new \Exception('Plugin output must be an associative array');
|
throw new \Exception('Plugin output must be an associative array');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsAssociativeArray($pluginOutput)) // $pluginOutput is at least an indexed array here
|
if (!IsAssociativeArray($pluginOutput)) // $pluginOutput is at least an indexed array here
|
||||||
{
|
{
|
||||||
throw new \Exception('Plugin output must be an associative array');
|
throw new \Exception('Plugin output must be an associative array');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for minimum needed properties
|
// Check for minimum needed properties
|
||||||
$minimunNeededProperties = array(
|
$minimunNeededProperties = [
|
||||||
'name',
|
'name',
|
||||||
'location_id',
|
'location_id',
|
||||||
'qu_id_purchase',
|
'qu_id_purchase',
|
||||||
'qu_id_stock',
|
'qu_id_stock',
|
||||||
'qu_factor_purchase_to_stock',
|
'qu_factor_purchase_to_stock',
|
||||||
'barcode'
|
'barcode'
|
||||||
);
|
];
|
||||||
|
|
||||||
foreach ($minimunNeededProperties as $prop)
|
foreach ($minimunNeededProperties as $prop)
|
||||||
{
|
{
|
||||||
if (!array_key_exists($prop, $pluginOutput))
|
if (!array_key_exists($prop, $pluginOutput))
|
||||||
{
|
{
|
||||||
throw new \Exception("Plugin output does not provide needed property $prop");
|
throw new \Exception("Plugin output does not provide needed property $prop");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// $pluginOutput contains all needed properties here
|
// $pluginOutput contains all needed properties here
|
||||||
|
|
||||||
// Check referenced entity ids are valid
|
// Check referenced entity ids are valid
|
||||||
$locationId = $pluginOutput['location_id'];
|
$locationId = $pluginOutput['location_id'];
|
||||||
|
|
||||||
if (FindObjectInArrayByPropertyValue($this->Locations, 'id', $locationId) === null)
|
if (FindObjectInArrayByPropertyValue($this->Locations, 'id', $locationId) === null)
|
||||||
{
|
{
|
||||||
throw new \Exception("Location $locationId is not a valid location id");
|
throw new \Exception("Location $locationId is not a valid location id");
|
||||||
}
|
}
|
||||||
|
|
||||||
$quIdPurchase = $pluginOutput['qu_id_purchase'];
|
$quIdPurchase = $pluginOutput['qu_id_purchase'];
|
||||||
|
|
||||||
if (FindObjectInArrayByPropertyValue($this->QuantityUnits, 'id', $quIdPurchase) === null)
|
if (FindObjectInArrayByPropertyValue($this->QuantityUnits, 'id', $quIdPurchase) === null)
|
||||||
{
|
{
|
||||||
throw new \Exception("Location $quIdPurchase is not a valid quantity unit id");
|
throw new \Exception("Location $quIdPurchase is not a valid quantity unit id");
|
||||||
}
|
}
|
||||||
|
|
||||||
$quIdStock = $pluginOutput['qu_id_stock'];
|
$quIdStock = $pluginOutput['qu_id_stock'];
|
||||||
|
|
||||||
if (FindObjectInArrayByPropertyValue($this->QuantityUnits, 'id', $quIdStock) === null)
|
if (FindObjectInArrayByPropertyValue($this->QuantityUnits, 'id', $quIdStock) === null)
|
||||||
{
|
{
|
||||||
throw new \Exception("Location $quIdStock is not a valid quantity unit id");
|
throw new \Exception("Location $quIdStock is not a valid quantity unit id");
|
||||||
}
|
}
|
||||||
|
|
||||||
$quFactor = $pluginOutput['qu_factor_purchase_to_stock'];
|
$quFactor = $pluginOutput['qu_factor_purchase_to_stock'];
|
||||||
|
|
||||||
if (empty($quFactor) || !is_numeric($quFactor))
|
if (empty($quFactor) || !is_numeric($quFactor))
|
||||||
{
|
{
|
||||||
throw new \Exception('Quantity unit factor is empty or not a number');
|
throw new \Exception('Quantity unit factor is empty or not a number');
|
||||||
@@ -77,4 +80,12 @@ abstract class BaseBarcodeLookupPlugin
|
|||||||
|
|
||||||
return $pluginOutput;
|
return $pluginOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final public function __construct($locations, $quantityUnits)
|
||||||
|
{
|
||||||
|
$this->Locations = $locations;
|
||||||
|
$this->QuantityUnits = $quantityUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function ExecuteLookup($barcode);
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class ERequirementNotMet extends Exception { }
|
class ERequirementNotMet extends Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
const REQUIRED_PHP_EXTENSIONS = array('fileinfo', 'pdo_sqlite', 'gd');
|
const REQUIRED_PHP_EXTENSIONS = ['fileinfo', 'pdo_sqlite', 'gd'];
|
||||||
const REQUIRED_SQLITE_VERSION = "3.8.3";
|
const REQUIRED_SQLITE_VERSION = '3.8.3';
|
||||||
|
|
||||||
class PrerequisiteChecker
|
class PrerequisiteChecker
|
||||||
{
|
{
|
||||||
@@ -16,13 +18,13 @@ class PrerequisiteChecker
|
|||||||
self::checkForSqliteVersion();
|
self::checkForSqliteVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function checkForComposer()
|
||||||
private function checkForConfigFile()
|
|
||||||
{
|
{
|
||||||
if (!file_exists(GROCY_DATAPATH . '/config.php'))
|
if (!file_exists(__DIR__ . '/../vendor/autoload.php'))
|
||||||
{
|
{
|
||||||
throw new ERequirementNotMet('config.php in data directory (' . GROCY_DATAPATH . ') not found. Have you copied config-dist.php to the data directory and renamed it to config.php?');
|
throw new ERequirementNotMet('/vendor/autoload.php not found. Have you run Composer?');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkForConfigDistFile()
|
private function checkForConfigDistFile()
|
||||||
@@ -31,42 +33,48 @@ class PrerequisiteChecker
|
|||||||
{
|
{
|
||||||
throw new ERequirementNotMet('config-dist.php not found. Please do not remove this file.');
|
throw new ERequirementNotMet('config-dist.php not found. Please do not remove this file.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkForComposer()
|
private function checkForConfigFile()
|
||||||
{
|
{
|
||||||
if (!file_exists(__DIR__ . '/../vendor/autoload.php'))
|
if (!file_exists(GROCY_DATAPATH . '/config.php'))
|
||||||
{
|
{
|
||||||
throw new ERequirementNotMet('/vendor/autoload.php not found. Have you run Composer?');
|
throw new ERequirementNotMet('config.php in data directory (' . GROCY_DATAPATH . ') not found. Have you copied config-dist.php to the data directory and renamed it to config.php?');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkForPhpExtensions()
|
private function checkForPhpExtensions()
|
||||||
{
|
{
|
||||||
$loadedExtensions = get_loaded_extensions();
|
$loadedExtensions = get_loaded_extensions();
|
||||||
|
|
||||||
foreach (REQUIRED_PHP_EXTENSIONS as $extension)
|
foreach (REQUIRED_PHP_EXTENSIONS as $extension)
|
||||||
{
|
{
|
||||||
if (!in_array($extension, $loadedExtensions))
|
if (!in_array($extension, $loadedExtensions))
|
||||||
{
|
{
|
||||||
throw new ERequirementNotMet("PHP module '{$extension}' not installed, but required.");
|
throw new ERequirementNotMet("PHP module '{$extension}' not installed, but required.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private function checkForSqliteVersion()
|
private function checkForSqliteVersion()
|
||||||
{
|
{
|
||||||
$sqliteVersion = self::getSqlVersionAsString();
|
$sqliteVersion = self::getSqlVersionAsString();
|
||||||
|
|
||||||
if (version_compare($sqliteVersion, REQUIRED_SQLITE_VERSION, '<'))
|
if (version_compare($sqliteVersion, REQUIRED_SQLITE_VERSION, '<'))
|
||||||
{
|
{
|
||||||
throw new ERequirementNotMet('SQLite ' . REQUIRED_SQLITE_VERSION . ' is required, however you are running ' . $sqliteVersion);
|
throw new ERequirementNotMet('SQLite ' . REQUIRED_SQLITE_VERSION . ' is required, however you are running ' . $sqliteVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getSqlVersionAsString()
|
private function getSqlVersionAsString()
|
||||||
{
|
{
|
||||||
$dbh = new PDO('sqlite::memory:');
|
$dbh = new PDO('sqlite::memory:');
|
||||||
return $dbh->query('select sqlite_version()')->fetch()[0];
|
return $dbh->query('select sqlite_version()')->fetch()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,18 +4,6 @@ namespace Grocy\Helpers;
|
|||||||
|
|
||||||
class UrlManager
|
class UrlManager
|
||||||
{
|
{
|
||||||
public function __construct(string $basePath)
|
|
||||||
{
|
|
||||||
if ($basePath === '/')
|
|
||||||
{
|
|
||||||
$this->BasePath = $this->GetBaseUrl();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->BasePath = $basePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected $BasePath;
|
protected $BasePath;
|
||||||
|
|
||||||
public function ConstructUrl($relativePath, $isResource = false)
|
public function ConstructUrl($relativePath, $isResource = false)
|
||||||
@@ -28,6 +16,20 @@ class UrlManager
|
|||||||
{
|
{
|
||||||
return rtrim($this->BasePath, '/') . '/index.php' . $relativePath;
|
return rtrim($this->BasePath, '/') . '/index.php' . $relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(string $basePath)
|
||||||
|
{
|
||||||
|
if ($basePath === '/')
|
||||||
|
{
|
||||||
|
$this->BasePath = $this->GetBaseUrl();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->BasePath = $basePath;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function GetBaseUrl()
|
private function GetBaseUrl()
|
||||||
@@ -37,6 +39,7 @@ class UrlManager
|
|||||||
$_SERVER['HTTPS'] = 'on';
|
$_SERVER['HTTPS'] = 'on';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]";
|
return (isset($_SERVER['HTTPS']) ? 'https' : 'http') . "://$_SERVER[HTTP_HOST]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
function FindObjectInArrayByPropertyValue($array, $propertyName, $propertyValue)
|
function FindObjectInArrayByPropertyValue($array, $propertyName, $propertyValue)
|
||||||
{
|
{
|
||||||
foreach($array as $object)
|
foreach ($array as $object)
|
||||||
{
|
{
|
||||||
if($object->{$propertyName} == $propertyValue)
|
if ($object->{$propertyName}
|
||||||
|
== $propertyValue)
|
||||||
{
|
{
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -15,31 +17,41 @@ function FindObjectInArrayByPropertyValue($array, $propertyName, $propertyValue)
|
|||||||
|
|
||||||
function FindAllObjectsInArrayByPropertyValue($array, $propertyName, $propertyValue, $operator = '==')
|
function FindAllObjectsInArrayByPropertyValue($array, $propertyName, $propertyValue, $operator = '==')
|
||||||
{
|
{
|
||||||
$returnArray = array();
|
$returnArray = [];
|
||||||
|
|
||||||
foreach($array as $object)
|
foreach ($array as $object)
|
||||||
{
|
{
|
||||||
switch($operator)
|
switch ($operator)
|
||||||
{
|
{
|
||||||
case '==':
|
case '==':
|
||||||
if($object->{$propertyName} == $propertyValue)
|
|
||||||
|
if ($object-> {$propertyName}
|
||||||
|
== $propertyValue)
|
||||||
{
|
{
|
||||||
$returnArray[] = $object;
|
$returnArray[] = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
if($object->{$propertyName} > $propertyValue)
|
|
||||||
|
if ($object-> {$propertyName}
|
||||||
|
> $propertyValue)
|
||||||
{
|
{
|
||||||
$returnArray[] = $object;
|
$returnArray[] = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
if($object->{$propertyName} < $propertyValue)
|
|
||||||
|
if ($object-> {$propertyName}
|
||||||
|
< $propertyValue)
|
||||||
{
|
{
|
||||||
$returnArray[] = $object;
|
$returnArray[] = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $returnArray;
|
return $returnArray;
|
||||||
@@ -47,31 +59,38 @@ function FindAllObjectsInArrayByPropertyValue($array, $propertyName, $propertyVa
|
|||||||
|
|
||||||
function FindAllItemsInArrayByValue($array, $value, $operator = '==')
|
function FindAllItemsInArrayByValue($array, $value, $operator = '==')
|
||||||
{
|
{
|
||||||
$returnArray = array();
|
$returnArray = [];
|
||||||
|
|
||||||
foreach($array as $item)
|
foreach ($array as $item)
|
||||||
{
|
{
|
||||||
switch($operator)
|
switch ($operator)
|
||||||
{
|
{
|
||||||
case '==':
|
case '==':
|
||||||
if($item == $value)
|
|
||||||
|
if ($item == $value)
|
||||||
{
|
{
|
||||||
$returnArray[] = $item;
|
$returnArray[] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
if($item > $value)
|
|
||||||
|
if ($item > $value)
|
||||||
{
|
{
|
||||||
$returnArray[] = $item;
|
$returnArray[] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
if($item < $value)
|
|
||||||
|
if ($item < $value)
|
||||||
{
|
{
|
||||||
$returnArray[] = $item;
|
$returnArray[] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $returnArray;
|
return $returnArray;
|
||||||
@@ -80,7 +99,8 @@ function FindAllItemsInArrayByValue($array, $value, $operator = '==')
|
|||||||
function SumArrayValue($array, $propertyName)
|
function SumArrayValue($array, $propertyName)
|
||||||
{
|
{
|
||||||
$sum = 0;
|
$sum = 0;
|
||||||
foreach($array as $object)
|
|
||||||
|
foreach ($array as $object)
|
||||||
{
|
{
|
||||||
$sum += floatval($object->{$propertyName});
|
$sum += floatval($object->{$propertyName});
|
||||||
}
|
}
|
||||||
@@ -102,11 +122,13 @@ function GetClassConstants($className, $prefix = null)
|
|||||||
$matchingKeys = preg_grep('!^' . $prefix . '!', array_keys($constants));
|
$matchingKeys = preg_grep('!^' . $prefix . '!', array_keys($constants));
|
||||||
return array_intersect_key($constants, array_flip($matchingKeys));
|
return array_intersect_key($constants, array_flip($matchingKeys));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function RandomString($length, $allowedChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
|
function RandomString($length, $allowedChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
|
||||||
{
|
{
|
||||||
$randomString = '';
|
$randomString = '';
|
||||||
|
|
||||||
for ($i = 0; $i < $length; $i++)
|
for ($i = 0; $i < $length; $i++)
|
||||||
{
|
{
|
||||||
$randomString .= $allowedChars[rand(0, strlen($allowedChars) - 1)];
|
$randomString .= $allowedChars[rand(0, strlen($allowedChars) - 1)];
|
||||||
@@ -142,13 +164,16 @@ function ExternalSettingValue(string $value)
|
|||||||
{
|
{
|
||||||
$tvalue = rtrim($value, "\r\n");
|
$tvalue = rtrim($value, "\r\n");
|
||||||
$lvalue = strtolower($tvalue);
|
$lvalue = strtolower($tvalue);
|
||||||
if ($lvalue === "true"){
|
|
||||||
|
if ($lvalue === 'true')
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
elseif ($lvalue === "false")
|
elseif ($lvalue === 'false')
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tvalue;
|
return $tvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,30 +183,35 @@ function Setting(string $name, $value)
|
|||||||
{
|
{
|
||||||
// The content of a $name.txt file in /data/settingoverrides can overwrite the given setting (for embedded mode)
|
// The content of a $name.txt file in /data/settingoverrides can overwrite the given setting (for embedded mode)
|
||||||
$settingOverrideFile = GROCY_DATAPATH . '/settingoverrides/' . $name . '.txt';
|
$settingOverrideFile = GROCY_DATAPATH . '/settingoverrides/' . $name . '.txt';
|
||||||
|
|
||||||
if (file_exists($settingOverrideFile))
|
if (file_exists($settingOverrideFile))
|
||||||
{
|
{
|
||||||
define('GROCY_' . $name, ExternalSettingValue(file_get_contents($settingOverrideFile)));
|
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
|
elseif (getenv('GROCY_' . $name) !== false) // An environment variable with the same name and prefix GROCY_ overwrites the given setting
|
||||||
{
|
{
|
||||||
define('GROCY_' . $name, ExternalSettingValue(getenv('GROCY_'. $name)));
|
define('GROCY_' . $name, ExternalSettingValue(getenv('GROCY_' . $name)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
define('GROCY_' . $name, $value);
|
define('GROCY_' . $name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global $GROCY_DEFAULT_USER_SETTINGS;
|
global $GROCY_DEFAULT_USER_SETTINGS;
|
||||||
$GROCY_DEFAULT_USER_SETTINGS = array();
|
$GROCY_DEFAULT_USER_SETTINGS = [];
|
||||||
function DefaultUserSetting(string $name, $value)
|
function DefaultUserSetting(string $name, $value)
|
||||||
{
|
{
|
||||||
global $GROCY_DEFAULT_USER_SETTINGS;
|
global $GROCY_DEFAULT_USER_SETTINGS;
|
||||||
|
|
||||||
if (!array_key_exists($name, $GROCY_DEFAULT_USER_SETTINGS))
|
if (!array_key_exists($name, $GROCY_DEFAULT_USER_SETTINGS))
|
||||||
{
|
{
|
||||||
$GROCY_DEFAULT_USER_SETTINGS[$name] = $value;
|
$GROCY_DEFAULT_USER_SETTINGS[$name] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetUserDisplayName($user)
|
function GetUserDisplayName($user)
|
||||||
@@ -210,7 +240,7 @@ function GetUserDisplayName($user)
|
|||||||
|
|
||||||
function IsValidFileName($fileName)
|
function IsValidFileName($fileName)
|
||||||
{
|
{
|
||||||
if(preg_match('=^[^/?*;:{}\\\\]+\.[^/?*;:{}\\\\]+$=', $fileName))
|
if (preg_match('=^[^/?*;:{}\\\\]+\.[^/?*;:{}\\\\]+$=', $fileName))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -232,6 +262,7 @@ function string_starts_with($haystack, $needle)
|
|||||||
function string_ends_with($haystack, $needle)
|
function string_ends_with($haystack, $needle)
|
||||||
{
|
{
|
||||||
$length = strlen($needle);
|
$length = strlen($needle);
|
||||||
|
|
||||||
if ($length == 0)
|
if ($length == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@@ -2,22 +2,21 @@
|
|||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
|
use Grocy\Services\ApiKeyService;
|
||||||
use Psr\Http\Message\ResponseFactoryInterface;
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Slim\Routing\RouteContext;
|
use Slim\Routing\RouteContext;
|
||||||
|
|
||||||
use Grocy\Services\ApiKeyService;
|
|
||||||
|
|
||||||
class ApiKeyAuthMiddleware extends AuthMiddleware
|
class ApiKeyAuthMiddleware extends AuthMiddleware
|
||||||
{
|
{
|
||||||
|
protected $ApiKeyHeaderName;
|
||||||
|
|
||||||
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
||||||
{
|
{
|
||||||
parent::__construct($container, $responseFactory);
|
parent::__construct($container, $responseFactory);
|
||||||
$this->ApiKeyHeaderName = $this->AppContainer->get('ApiKeyHeaderName');
|
$this->ApiKeyHeaderName = $this->AppContainer->get('ApiKeyHeaderName');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $ApiKeyHeaderName;
|
|
||||||
|
|
||||||
function authenticate(Request $request)
|
function authenticate(Request $request)
|
||||||
{
|
{
|
||||||
if (!defined('GROCY_SHOW_AUTH_VIEWS'))
|
if (!defined('GROCY_SHOW_AUTH_VIEWS'))
|
||||||
@@ -34,7 +33,7 @@ class ApiKeyAuthMiddleware extends AuthMiddleware
|
|||||||
|
|
||||||
$apiKeyService = new ApiKeyService();
|
$apiKeyService = new ApiKeyService();
|
||||||
|
|
||||||
// First check of the API key in the configured header
|
// First check of the API key in the configured header
|
||||||
if (!$request->hasHeader($this->ApiKeyHeaderName) || !$apiKeyService->IsValidApiKey($request->getHeaderLine($this->ApiKeyHeaderName)))
|
if (!$request->hasHeader($this->ApiKeyHeaderName) || !$apiKeyService->IsValidApiKey($request->getHeaderLine($this->ApiKeyHeaderName)))
|
||||||
{
|
{
|
||||||
$validApiKey = false;
|
$validApiKey = false;
|
||||||
@@ -44,14 +43,14 @@ class ApiKeyAuthMiddleware extends AuthMiddleware
|
|||||||
$usedApiKey = $request->getHeaderLine($this->ApiKeyHeaderName);
|
$usedApiKey = $request->getHeaderLine($this->ApiKeyHeaderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not recommended, but it's also possible to provide the API key via a query parameter (same name as the configured header)
|
// Not recommended, but it's also possible to provide the API key via a query parameter (same name as the configured header)
|
||||||
if (!$validApiKey && !empty($request->getQueryParam($this->ApiKeyHeaderName)) && $apiKeyService->IsValidApiKey($request->getQueryParam($this->ApiKeyHeaderName)))
|
if (!$validApiKey && !empty($request->getQueryParam($this->ApiKeyHeaderName)) && $apiKeyService->IsValidApiKey($request->getQueryParam($this->ApiKeyHeaderName)))
|
||||||
{
|
{
|
||||||
$validApiKey = true;
|
$validApiKey = true;
|
||||||
$usedApiKey = $request->getQueryParam($this->ApiKeyHeaderName);
|
$usedApiKey = $request->getQueryParam($this->ApiKeyHeaderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handling of special purpose API keys
|
// Handling of special purpose API keys
|
||||||
if (!$validApiKey)
|
if (!$validApiKey)
|
||||||
{
|
{
|
||||||
if ($routeName === 'calendar-ical')
|
if ($routeName === 'calendar-ical')
|
||||||
@@ -60,7 +59,9 @@ class ApiKeyAuthMiddleware extends AuthMiddleware
|
|||||||
{
|
{
|
||||||
$validApiKey = true;
|
$validApiKey = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($validApiKey)
|
if ($validApiKey)
|
||||||
@@ -72,5 +73,7 @@ class ApiKeyAuthMiddleware extends AuthMiddleware
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,24 +2,23 @@
|
|||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
|
use Grocy\Services\SessionService;
|
||||||
use Psr\Http\Message\ResponseFactoryInterface;
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||||
use Slim\Routing\RouteContext;
|
use Slim\Routing\RouteContext;
|
||||||
|
|
||||||
use Grocy\Services\SessionService;
|
|
||||||
|
|
||||||
abstract class AuthMiddleware extends BaseMiddleware
|
abstract class AuthMiddleware extends BaseMiddleware
|
||||||
{
|
{
|
||||||
|
protected $ResponseFactory;
|
||||||
|
|
||||||
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
$this->ResponseFactory = $responseFactory;
|
$this->ResponseFactory = $responseFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $ResponseFactory;
|
|
||||||
|
|
||||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||||
{
|
{
|
||||||
$routeContext = RouteContext::fromRequest($request);
|
$routeContext = RouteContext::fromRequest($request);
|
||||||
@@ -31,11 +30,14 @@ abstract class AuthMiddleware extends BaseMiddleware
|
|||||||
{
|
{
|
||||||
return $handler->handle($request);
|
return $handler->handle($request);
|
||||||
}
|
}
|
||||||
else if ($routeName === 'login')
|
else
|
||||||
|
|
||||||
|
if ($routeName === 'login')
|
||||||
{
|
{
|
||||||
define('GROCY_AUTHENTICATED', false);
|
define('GROCY_AUTHENTICATED', false);
|
||||||
return $handler->handle($request);
|
return $handler->handle($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GROCY_MODE === 'dev' || GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease' || GROCY_IS_EMBEDDED_INSTALL || GROCY_DISABLE_AUTH)
|
if (GROCY_MODE === 'dev' || GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease' || GROCY_IS_EMBEDDED_INSTALL || GROCY_DISABLE_AUTH)
|
||||||
{
|
{
|
||||||
$sessionService = SessionService::getInstance();
|
$sessionService = SessionService::getInstance();
|
||||||
@@ -55,6 +57,7 @@ abstract class AuthMiddleware extends BaseMiddleware
|
|||||||
define('GROCY_AUTHENTICATED', false);
|
define('GROCY_AUTHENTICATED', false);
|
||||||
|
|
||||||
$response = $this->ResponseFactory->createResponse();
|
$response = $this->ResponseFactory->createResponse();
|
||||||
|
|
||||||
if ($isApiRoute)
|
if ($isApiRoute)
|
||||||
{
|
{
|
||||||
return $response->withStatus(401);
|
return $response->withStatus(401);
|
||||||
@@ -63,6 +66,7 @@ abstract class AuthMiddleware extends BaseMiddleware
|
|||||||
{
|
{
|
||||||
return $response->withHeader('Location', $this->AppContainer->get('UrlManager')->ConstructUrl('/login'));
|
return $response->withHeader('Location', $this->AppContainer->get('UrlManager')->ConstructUrl('/login'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -72,7 +76,9 @@ abstract class AuthMiddleware extends BaseMiddleware
|
|||||||
|
|
||||||
return $response = $handler->handle($request);
|
return $response = $handler->handle($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2,16 +2,17 @@
|
|||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
use \Grocy\Services\ApplicationService;
|
use Grocy\Services\ApplicationService;
|
||||||
|
|
||||||
class BaseMiddleware
|
class BaseMiddleware
|
||||||
{
|
{
|
||||||
|
protected $AppContainer;
|
||||||
|
|
||||||
|
protected $ApplicationService;
|
||||||
|
|
||||||
public function __construct(\DI\Container $container)
|
public function __construct(\DI\Container $container)
|
||||||
{
|
{
|
||||||
$this->AppContainer = $container;
|
$this->AppContainer = $container;
|
||||||
$this->ApplicationService = ApplicationService::getInstance();
|
$this->ApplicationService = ApplicationService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $AppContainer;
|
|
||||||
protected $ApplicationService;
|
|
||||||
}
|
}
|
||||||
|
@@ -3,10 +3,9 @@
|
|||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
use Psr\Http\Message\ResponseFactoryInterface;
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
|
||||||
use Slim\Routing\RouteContext;
|
|
||||||
|
|
||||||
class CorsMiddleware
|
class CorsMiddleware
|
||||||
{
|
{
|
||||||
@@ -22,15 +21,21 @@ class CorsMiddleware
|
|||||||
|
|
||||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||||
{
|
{
|
||||||
if ($request->getMethod() == "OPTIONS")
|
if ($request->getMethod() == 'OPTIONS')
|
||||||
|
{
|
||||||
$response = $this->responseFactory->createResponse(200);
|
$response = $this->responseFactory->createResponse(200);
|
||||||
else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$response = $handler->handle($request);
|
$response = $handler->handle($request);
|
||||||
|
|
||||||
}
|
}
|
||||||
//$routeContext = RouteContext::fromRequest($request);
|
|
||||||
//$routingResults = $routeContext->getRoutingResults();
|
//$routeContext = RouteContext::fromRequest($request);
|
||||||
//$methods = $routingResults->getAllowedMethods();
|
|
||||||
|
//$routingResults = $routeContext->getRoutingResults();
|
||||||
|
|
||||||
|
//$methods = $routingResults->getAllowedMethods();
|
||||||
//$requestHeaders = $request->getHeaderLine('Access-Control-Request-Headers');
|
//$requestHeaders = $request->getHeaderLine('Access-Control-Request-Headers');
|
||||||
|
|
||||||
$response = $response->withHeader('Access-Control-Allow-Origin', '*');
|
$response = $response->withHeader('Access-Control-Allow-Origin', '*');
|
||||||
@@ -39,4 +44,5 @@ class CorsMiddleware
|
|||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ class DefaultAuthMiddleware extends AuthMiddleware
|
|||||||
// First try to authenticate by API key
|
// First try to authenticate by API key
|
||||||
$auth = new ApiKeyAuthMiddleware($this->AppContainer, $this->ResponseFactory);
|
$auth = new ApiKeyAuthMiddleware($this->AppContainer, $this->ResponseFactory);
|
||||||
$user = $auth->authenticate($request);
|
$user = $auth->authenticate($request);
|
||||||
|
|
||||||
if ($user !== null)
|
if ($user !== null)
|
||||||
{
|
{
|
||||||
return $user;
|
return $user;
|
||||||
@@ -21,4 +22,5 @@ class DefaultAuthMiddleware extends AuthMiddleware
|
|||||||
$user = $auth->authenticate($request);
|
$user = $auth->authenticate($request);
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
|
||||||
|
|
||||||
class JsonMiddleware extends BaseMiddleware
|
class JsonMiddleware extends BaseMiddleware
|
||||||
{
|
{
|
||||||
@@ -25,5 +25,7 @@ class JsonMiddleware extends BaseMiddleware
|
|||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
|
|
||||||
use Grocy\Services\UsersService;
|
use Grocy\Services\UsersService;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
@@ -11,7 +9,6 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
|||||||
|
|
||||||
class LocaleMiddleware extends BaseMiddleware
|
class LocaleMiddleware extends BaseMiddleware
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||||
{
|
{
|
||||||
$locale = $this->getLocale($request);
|
$locale = $this->getLocale($request);
|
||||||
@@ -21,22 +18,28 @@ class LocaleMiddleware extends BaseMiddleware
|
|||||||
|
|
||||||
protected function getLocale(Request $request)
|
protected function getLocale(Request $request)
|
||||||
{
|
{
|
||||||
if(GROCY_AUTHENTICATED)
|
if (GROCY_AUTHENTICATED)
|
||||||
{
|
{
|
||||||
$locale = UsersService::getInstance()->GetUserSetting(GROCY_USER_ID, 'locale');
|
$locale = UsersService::getInstance()->GetUserSetting(GROCY_USER_ID, 'locale');
|
||||||
if (isset($locale) && !empty($locale)) {
|
|
||||||
if (in_array($locale, scandir(__DIR__ . '/../localization'))) {
|
if (isset($locale) && !empty($locale))
|
||||||
|
{
|
||||||
|
if (in_array($locale, scandir(__DIR__ . '/../localization')))
|
||||||
|
{
|
||||||
return $locale;
|
return $locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$langs = join(',', $request->getHeader('Accept-Language'));
|
$langs = implode(',', $request->getHeader('Accept-Language'));
|
||||||
|
|
||||||
// src: https://gist.github.com/spolischook/0cde9c6286415cddc088
|
// src: https://gist.github.com/spolischook/0cde9c6286415cddc088
|
||||||
$prefLocales = array_reduce(
|
$prefLocales = array_reduce(
|
||||||
explode(',', $langs),
|
explode(',', $langs),
|
||||||
function ($res, $el) {
|
function ($res, $el)
|
||||||
|
{
|
||||||
list($l, $q) = array_merge(explode(';q=', $el), [1]);
|
list($l, $q) = array_merge(explode(';q=', $el), [1]);
|
||||||
$res[$l] = (float) $q;
|
$res[$l] = (float) $q;
|
||||||
return $res;
|
return $res;
|
||||||
@@ -44,24 +47,33 @@ class LocaleMiddleware extends BaseMiddleware
|
|||||||
arsort($prefLocales);
|
arsort($prefLocales);
|
||||||
|
|
||||||
$availableLocales = scandir(__DIR__ . '/../localization');
|
$availableLocales = scandir(__DIR__ . '/../localization');
|
||||||
foreach ($prefLocales as $locale => $q) {
|
|
||||||
if(in_array($locale, $availableLocales))
|
foreach ($prefLocales as $locale => $q)
|
||||||
|
{
|
||||||
|
if (in_array($locale, $availableLocales))
|
||||||
{
|
{
|
||||||
return $locale;
|
return $locale;
|
||||||
}
|
}
|
||||||
// e.g. en_GB
|
|
||||||
if(in_array(substr($locale, 0, 5), $availableLocales))
|
// e.g. en_GB
|
||||||
|
if (in_array(substr($locale, 0, 5), $availableLocales))
|
||||||
{
|
{
|
||||||
return substr($locale, 0, 5);
|
return substr($locale, 0, 5);
|
||||||
}
|
}
|
||||||
// e.g: cs
|
|
||||||
// or en
|
// e.g: cs
|
||||||
// or de
|
|
||||||
if(in_array(substr($locale, 0, 2), $availableLocales))
|
// or en
|
||||||
|
|
||||||
|
// or de
|
||||||
|
if (in_array(substr($locale, 0, 2), $availableLocales))
|
||||||
{
|
{
|
||||||
return substr($locale, 0, 2);
|
return substr($locale, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GROCY_DEFAULT_LOCALE;
|
return GROCY_DEFAULT_LOCALE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
||||||
|
|
||||||
use Grocy\Services\DatabaseService;
|
use Grocy\Services\DatabaseService;
|
||||||
use Grocy\Services\UsersService;
|
use Grocy\Services\UsersService;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
class ReverseProxyAuthMiddleware extends AuthMiddleware
|
class ReverseProxyAuthMiddleware extends AuthMiddleware
|
||||||
{
|
{
|
||||||
@@ -23,7 +22,7 @@ class ReverseProxyAuthMiddleware extends AuthMiddleware
|
|||||||
if (count($username) !== 1)
|
if (count($username) !== 1)
|
||||||
{
|
{
|
||||||
// Invalid configuration of Proxy
|
// Invalid configuration of Proxy
|
||||||
throw new \Exception("ReverseProxyAuthMiddleware: Invalid username from proxy: " . var_dump($username));
|
throw new \Exception('ReverseProxyAuthMiddleware: Invalid username from proxy: ' . var_dump($username));
|
||||||
}
|
}
|
||||||
|
|
||||||
$username = $username[0];
|
$username = $username[0];
|
||||||
@@ -37,4 +36,5 @@ class ReverseProxyAuthMiddleware extends AuthMiddleware
|
|||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,23 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace Grocy\Middleware;
|
namespace Grocy\Middleware;
|
||||||
|
|
||||||
|
use Grocy\Services\SessionService;
|
||||||
use Psr\Http\Message\ResponseFactoryInterface;
|
use Psr\Http\Message\ResponseFactoryInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
use Grocy\Services\SessionService;
|
|
||||||
|
|
||||||
class SessionAuthMiddleware extends AuthMiddleware
|
class SessionAuthMiddleware extends AuthMiddleware
|
||||||
{
|
{
|
||||||
|
protected $SessionCookieName;
|
||||||
|
|
||||||
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
public function __construct(\DI\Container $container, ResponseFactoryInterface $responseFactory)
|
||||||
{
|
{
|
||||||
parent::__construct($container, $responseFactory);
|
parent::__construct($container, $responseFactory);
|
||||||
$this->SessionCookieName = $this->AppContainer->get('LoginControllerInstance')->GetSessionCookieName();
|
$this->SessionCookieName = $this->AppContainer->get('LoginControllerInstance')->GetSessionCookieName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $SessionCookieName;
|
|
||||||
|
|
||||||
function authenticate(Request $request)
|
function authenticate(Request $request)
|
||||||
{
|
{
|
||||||
if (!defined('GROCY_SHOW_AUTH_VIEWS'))
|
if (!defined('GROCY_SHOW_AUTH_VIEWS'))
|
||||||
@@ -26,6 +24,7 @@ class SessionAuthMiddleware extends AuthMiddleware
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sessionService = SessionService::getInstance();
|
$sessionService = SessionService::getInstance();
|
||||||
|
|
||||||
if (!isset($_COOKIE[$this->SessionCookieName]) || !$sessionService->IsValidSession($_COOKIE[$this->SessionCookieName]))
|
if (!isset($_COOKIE[$this->SessionCookieName]) || !$sessionService->IsValidSession($_COOKIE[$this->SessionCookieName]))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@@ -34,5 +33,7 @@ class SessionAuthMiddleware extends AuthMiddleware
|
|||||||
{
|
{
|
||||||
return $sessionService->GetUserBySessionKey($_COOKIE[$this->SessionCookieName]);
|
return $sessionService->GetUserBySessionKey($_COOKIE[$this->SessionCookieName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// Definitions for embedded mode
|
// Definitions for embedded mode
|
||||||
|
|
||||||
if (file_exists(__DIR__ . '/../embedded.txt'))
|
if (file_exists(__DIR__ . '/../embedded.txt'))
|
||||||
{
|
{
|
||||||
define('GROCY_IS_EMBEDDED_INSTALL', true);
|
define('GROCY_IS_EMBEDDED_INSTALL', true);
|
||||||
@@ -12,6 +13,7 @@ else
|
|||||||
define('GROCY_IS_EMBEDDED_INSTALL', false);
|
define('GROCY_IS_EMBEDDED_INSTALL', false);
|
||||||
|
|
||||||
$datapath = 'data';
|
$datapath = 'data';
|
||||||
|
|
||||||
if (getenv('GROCY_DATAPATH') !== false)
|
if (getenv('GROCY_DATAPATH') !== false)
|
||||||
{
|
{
|
||||||
$datapath = getenv('GROCY_DATAPATH');
|
$datapath = getenv('GROCY_DATAPATH');
|
||||||
@@ -25,6 +27,7 @@ else
|
|||||||
{
|
{
|
||||||
$datapath = __DIR__ . '/../' . $datapath;
|
$datapath = __DIR__ . '/../' . $datapath;
|
||||||
}
|
}
|
||||||
|
|
||||||
define('GROCY_DATAPATH', $datapath);
|
define('GROCY_DATAPATH', $datapath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,11 +35,11 @@ require_once __DIR__ . '/../helpers/PrerequisiteChecker.php';
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
(new PrerequisiteChecker)->checkRequirements();
|
(new PrerequisiteChecker())->checkRequirements();
|
||||||
}
|
}
|
||||||
catch (ERequirementNotMet $ex)
|
catch (ERequirementNotMet $ex)
|
||||||
{
|
{
|
||||||
die('Unable to run grocy: ' . $ex->getMessage());
|
exit('Unable to run grocy: ' . $ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/../app.php';
|
require_once __DIR__ . '/../app.php';
|
||||||
|
@@ -5,8 +5,70 @@ namespace Grocy\Services;
|
|||||||
class ApiKeyService extends BaseService
|
class ApiKeyService extends BaseService
|
||||||
{
|
{
|
||||||
const API_KEY_TYPE_DEFAULT = 'default';
|
const API_KEY_TYPE_DEFAULT = 'default';
|
||||||
|
|
||||||
const API_KEY_TYPE_SPECIAL_PURPOSE_CALENDAR_ICAL = 'special-purpose-calendar-ical';
|
const API_KEY_TYPE_SPECIAL_PURPOSE_CALENDAR_ICAL = 'special-purpose-calendar-ical';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function CreateApiKey($keyType = self::API_KEY_TYPE_DEFAULT)
|
||||||
|
{
|
||||||
|
$newApiKey = $this->GenerateApiKey();
|
||||||
|
|
||||||
|
$apiKeyRow = $this->getDatabase()->api_keys()->createRow([
|
||||||
|
'api_key' => $newApiKey,
|
||||||
|
'user_id' => GROCY_USER_ID,
|
||||||
|
'expires' => '2999-12-31 23:59:59', // Default is that API keys expire never
|
||||||
|
'key_type' => $keyType
|
||||||
|
]);
|
||||||
|
$apiKeyRow->save();
|
||||||
|
|
||||||
|
return $newApiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetApiKeyId($apiKey)
|
||||||
|
{
|
||||||
|
$apiKey = $this->getDatabase()->api_keys()->where('api_key', $apiKey)->fetch();
|
||||||
|
return $apiKey->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns any valid key for $keyType,
|
||||||
|
// not allowed for key type "default"
|
||||||
|
public function GetOrCreateApiKey($keyType)
|
||||||
|
{
|
||||||
|
if ($keyType === self::API_KEY_TYPE_DEFAULT)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$apiKeyRow = $this->getDatabase()->api_keys()->where('key_type = :1 AND expires > :2', $keyType, date('Y-m-d H:i:s', time()))->fetch();
|
||||||
|
|
||||||
|
if ($apiKeyRow !== null)
|
||||||
|
{
|
||||||
|
return $apiKeyRow->api_key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->CreateApiKey($keyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetUserByApiKey($apiKey)
|
||||||
|
{
|
||||||
|
$apiKeyRow = $this->getDatabase()->api_keys()->where('api_key', $apiKey)->fetch();
|
||||||
|
|
||||||
|
if ($apiKeyRow !== null)
|
||||||
|
{
|
||||||
|
return $this->getDatabase()->users($apiKeyRow->user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
@@ -19,14 +81,15 @@ class ApiKeyService extends BaseService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$apiKeyRow = $this->getDatabase()->api_keys()->where('api_key = :1 AND expires > :2 AND key_type = :3', $apiKey, date('Y-m-d H:i:s', time()), $keyType)->fetch();
|
$apiKeyRow = $this->getDatabase()->api_keys()->where('api_key = :1 AND expires > :2 AND key_type = :3', $apiKey, date('Y-m-d H:i:s', time()), $keyType)->fetch();
|
||||||
|
|
||||||
if ($apiKeyRow !== null)
|
if ($apiKeyRow !== null)
|
||||||
{
|
{
|
||||||
// This should not change the database file modification time as this is used
|
// This should not change the database file modification time as this is used
|
||||||
// to determine if REALLY something has changed
|
// to determine if REALLY something has changed
|
||||||
$dbModTime = $this->getDatabaseService()->GetDbChangedTime();
|
$dbModTime = $this->getDatabaseService()->GetDbChangedTime();
|
||||||
$apiKeyRow->update(array(
|
$apiKeyRow->update([
|
||||||
'last_used' => date('Y-m-d H:i:s', time())
|
'last_used' => date('Y-m-d H:i:s', time())
|
||||||
));
|
]);
|
||||||
$this->getDatabaseService()->SetDbChangedTime($dbModTime);
|
$this->getDatabaseService()->SetDbChangedTime($dbModTime);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -35,25 +98,9 @@ class ApiKeyService extends BaseService
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function CreateApiKey($keyType = self::API_KEY_TYPE_DEFAULT)
|
|
||||||
{
|
|
||||||
$newApiKey = $this->GenerateApiKey();
|
|
||||||
|
|
||||||
$apiKeyRow = $this->getDatabase()->api_keys()->createRow(array(
|
|
||||||
'api_key' => $newApiKey,
|
|
||||||
'user_id' => GROCY_USER_ID,
|
|
||||||
'expires' => '2999-12-31 23:59:59', // Default is that API keys expire never
|
|
||||||
'key_type' => $keyType
|
|
||||||
));
|
|
||||||
$apiKeyRow->save();
|
|
||||||
|
|
||||||
return $newApiKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RemoveApiKey($apiKey)
|
public function RemoveApiKey($apiKey)
|
||||||
@@ -61,46 +108,9 @@ class ApiKeyService extends BaseService
|
|||||||
$this->getDatabase()->api_keys()->where('api_key', $apiKey)->delete();
|
$this->getDatabase()->api_keys()->where('api_key', $apiKey)->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetApiKeyId($apiKey)
|
|
||||||
{
|
|
||||||
$apiKey = $this->getDatabase()->api_keys()->where('api_key', $apiKey)->fetch();
|
|
||||||
return $apiKey->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetUserByApiKey($apiKey)
|
|
||||||
{
|
|
||||||
$apiKeyRow = $this->getDatabase()->api_keys()->where('api_key', $apiKey)->fetch();
|
|
||||||
if ($apiKeyRow !== null)
|
|
||||||
{
|
|
||||||
return $this->getDatabase()->users($apiKeyRow->user_id);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns any valid key for $keyType,
|
|
||||||
// not allowed for key type "default"
|
|
||||||
public function GetOrCreateApiKey($keyType)
|
|
||||||
{
|
|
||||||
if ($keyType === self::API_KEY_TYPE_DEFAULT)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$apiKeyRow = $this->getDatabase()->api_keys()->where('key_type = :1 AND expires > :2', $keyType, date('Y-m-d H:i:s', time()))->fetch();
|
|
||||||
if ($apiKeyRow !== null)
|
|
||||||
{
|
|
||||||
return $apiKeyRow->api_key;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $this->CreateApiKey($keyType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function GenerateApiKey()
|
private function GenerateApiKey()
|
||||||
{
|
{
|
||||||
return RandomString(50);
|
return RandomString(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,45 @@ class ApplicationService extends BaseService
|
|||||||
{
|
{
|
||||||
private $InstalledVersion;
|
private $InstalledVersion;
|
||||||
|
|
||||||
|
public function GetChangelog()
|
||||||
|
{
|
||||||
|
$changelogItems = [];
|
||||||
|
|
||||||
|
foreach (glob(__DIR__ . '/../changelog/*.md') as $file)
|
||||||
|
{
|
||||||
|
$fileName = basename($file);
|
||||||
|
$fileNameParts = explode('_', $fileName);
|
||||||
|
|
||||||
|
$fileContent = file_get_contents($file);
|
||||||
|
$version = $fileNameParts[1];
|
||||||
|
$releaseDate = explode('.', $fileNameParts[2])[0];
|
||||||
|
$releaseNumber = intval($fileNameParts[0]);
|
||||||
|
|
||||||
|
$changelogItems[] = [
|
||||||
|
'version' => $version,
|
||||||
|
'release_date' => $releaseDate,
|
||||||
|
'body' => $fileContent,
|
||||||
|
'release_number' => $releaseNumber
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort changelog items to have the changelog descending by newest version
|
||||||
|
usort($changelogItems, function ($a, $b)
|
||||||
|
{
|
||||||
|
if ($a['release_number'] == $b['release_number'])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($a['release_number'] < $b['release_number']) ? 1 : -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
'changelog_items' => $changelogItems,
|
||||||
|
'newest_release_number' => $changelogItems[0]['release_number']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function GetInstalledVersion()
|
public function GetInstalledVersion()
|
||||||
{
|
{
|
||||||
if ($this->InstalledVersion == null)
|
if ($this->InstalledVersion == null)
|
||||||
@@ -20,6 +59,7 @@ class ApplicationService extends BaseService
|
|||||||
$this->InstalledVersion->Version = "pre-release-$commitHash";
|
$this->InstalledVersion->Version = "pre-release-$commitHash";
|
||||||
$this->InstalledVersion->ReleaseDate = substr($commitDate, 0, 19);
|
$this->InstalledVersion->ReleaseDate = substr($commitDate, 0, 19);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->InstalledVersion;
|
return $this->InstalledVersion;
|
||||||
@@ -31,48 +71,11 @@ class ApplicationService extends BaseService
|
|||||||
$sqliteVersion = $pdo->query('SELECT sqlite_version()')->fetch()[0];
|
$sqliteVersion = $pdo->query('SELECT sqlite_version()')->fetch()[0];
|
||||||
$pdo = null;
|
$pdo = null;
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'grocy_version' => $this->GetInstalledVersion(),
|
'grocy_version' => $this->GetInstalledVersion(),
|
||||||
'php_version' => phpversion(),
|
'php_version' => phpversion(),
|
||||||
'sqlite_version' => $sqliteVersion
|
'sqlite_version' => $sqliteVersion
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetChangelog()
|
|
||||||
{
|
|
||||||
$changelogItems = array();
|
|
||||||
foreach(glob(__DIR__ . '/../changelog/*.md') as $file)
|
|
||||||
{
|
|
||||||
$fileName = basename($file);
|
|
||||||
$fileNameParts = explode('_', $fileName);
|
|
||||||
|
|
||||||
$fileContent = file_get_contents($file);
|
|
||||||
$version = $fileNameParts[1];
|
|
||||||
$releaseDate = explode('.', $fileNameParts[2])[0];
|
|
||||||
$releaseNumber = intval($fileNameParts[0]);
|
|
||||||
|
|
||||||
$changelogItems[] = array(
|
|
||||||
'version' => $version,
|
|
||||||
'release_date' => $releaseDate,
|
|
||||||
'body' => $fileContent,
|
|
||||||
'release_number' => $releaseNumber
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort changelog items to have the changelog descending by newest version
|
|
||||||
usort($changelogItems, function($a, $b)
|
|
||||||
{
|
|
||||||
if ($a['release_number'] == $b['release_number'])
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ($a['release_number'] < $b['release_number']) ? 1 : -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'changelog_items' => $changelogItems,
|
|
||||||
'newest_release_number' => $changelogItems[0]['release_number']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,19 @@
|
|||||||
|
|
||||||
namespace Grocy\Services;
|
namespace Grocy\Services;
|
||||||
|
|
||||||
#use \Grocy\Services\DatabaseService;
|
|
||||||
#use \Grocy\Services\LocalizationService;
|
|
||||||
|
|
||||||
class BaseService
|
class BaseService
|
||||||
{
|
{
|
||||||
public function __construct() {
|
private static $instances = [];
|
||||||
}
|
|
||||||
|
|
||||||
private static $instances = array();
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public static function getInstance()
|
public static function getInstance()
|
||||||
{
|
{
|
||||||
$className = get_called_class();
|
$className = get_called_class();
|
||||||
if(!isset(self::$instances[$className]))
|
|
||||||
|
if (!isset(self::$instances[$className]))
|
||||||
{
|
{
|
||||||
self::$instances[$className] = new $className();
|
self::$instances[$className] = new $className();
|
||||||
}
|
}
|
||||||
@@ -23,9 +22,14 @@ class BaseService
|
|||||||
return self::$instances[$className];
|
return self::$instances[$className];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getDatabaseService()
|
protected function getBatteriesService()
|
||||||
{
|
{
|
||||||
return DatabaseService::getInstance();
|
return BatteriesService::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getChoresService()
|
||||||
|
{
|
||||||
|
return ChoresService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getDatabase()
|
protected function getDatabase()
|
||||||
@@ -33,7 +37,12 @@ class BaseService
|
|||||||
return $this->getDatabaseService()->GetDbConnection();
|
return $this->getDatabaseService()->GetDbConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getLocalizationService()
|
protected function getDatabaseService()
|
||||||
|
{
|
||||||
|
return DatabaseService::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getLocalizationService()
|
||||||
{
|
{
|
||||||
return LocalizationService::getInstance(GROCY_LOCALE);
|
return LocalizationService::getInstance(GROCY_LOCALE);
|
||||||
}
|
}
|
||||||
@@ -48,18 +57,9 @@ class BaseService
|
|||||||
return TasksService::getInstance();
|
return TasksService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getChoresService()
|
|
||||||
{
|
|
||||||
return ChoresService::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getBatteriesService()
|
|
||||||
{
|
|
||||||
return BatteriesService::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getUsersService()
|
protected function getUsersService()
|
||||||
{
|
{
|
||||||
return UsersService::getInstance();
|
return UsersService::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,12 +4,6 @@ namespace Grocy\Services;
|
|||||||
|
|
||||||
class BatteriesService extends BaseService
|
class BatteriesService extends BaseService
|
||||||
{
|
{
|
||||||
public function GetCurrent()
|
|
||||||
{
|
|
||||||
$sql = 'SELECT * from batteries_current';
|
|
||||||
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetBatteryDetails(int $batteryId)
|
public function GetBatteryDetails(int $batteryId)
|
||||||
{
|
{
|
||||||
if (!$this->BatteryExists($batteryId))
|
if (!$this->BatteryExists($batteryId))
|
||||||
@@ -22,12 +16,18 @@ class BatteriesService extends BaseService
|
|||||||
$batteryLastChargedTime = $this->getDatabase()->battery_charge_cycles()->where('battery_id = :1 AND undone = 0', $batteryId)->max('tracked_time');
|
$batteryLastChargedTime = $this->getDatabase()->battery_charge_cycles()->where('battery_id = :1 AND undone = 0', $batteryId)->max('tracked_time');
|
||||||
$nextChargeTime = $this->getDatabase()->batteries_current()->where('battery_id', $batteryId)->min('next_estimated_charge_time');
|
$nextChargeTime = $this->getDatabase()->batteries_current()->where('battery_id', $batteryId)->min('next_estimated_charge_time');
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'battery' => $battery,
|
'battery' => $battery,
|
||||||
'last_charged' => $batteryLastChargedTime,
|
'last_charged' => $batteryLastChargedTime,
|
||||||
'charge_cycles_count' => $batteryChargeCyclesCount,
|
'charge_cycles_count' => $batteryChargeCyclesCount,
|
||||||
'next_estimated_charge_time' => $nextChargeTime
|
'next_estimated_charge_time' => $nextChargeTime
|
||||||
);
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetCurrent()
|
||||||
|
{
|
||||||
|
$sql = 'SELECT * from batteries_current';
|
||||||
|
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function TrackChargeCycle(int $batteryId, string $trackedTime)
|
public function TrackChargeCycle(int $batteryId, string $trackedTime)
|
||||||
@@ -37,33 +37,35 @@ class BatteriesService extends BaseService
|
|||||||
throw new \Exception('Battery does not exist');
|
throw new \Exception('Battery does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$logRow = $this->getDatabase()->battery_charge_cycles()->createRow(array(
|
$logRow = $this->getDatabase()->battery_charge_cycles()->createRow([
|
||||||
'battery_id' => $batteryId,
|
'battery_id' => $batteryId,
|
||||||
'tracked_time' => $trackedTime
|
'tracked_time' => $trackedTime
|
||||||
));
|
]);
|
||||||
$logRow->save();
|
$logRow->save();
|
||||||
|
|
||||||
return $this->getDatabase()->lastInsertId();
|
return $this->getDatabase()->lastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function UndoChargeCycle($chargeCycleId)
|
||||||
|
{
|
||||||
|
$logRow = $this->getDatabase()->battery_charge_cycles()->where('id = :1 AND undone = 0', $chargeCycleId)->fetch();
|
||||||
|
|
||||||
|
if ($logRow == null)
|
||||||
|
{
|
||||||
|
throw new \Exception('Charge cycle does not exist or was already undone');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update log entry
|
||||||
|
$logRow->update([
|
||||||
|
'undone' => 1,
|
||||||
|
'undone_timestamp' => date('Y-m-d H:i:s')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
private function BatteryExists($batteryId)
|
private function BatteryExists($batteryId)
|
||||||
{
|
{
|
||||||
$batteryRow = $this->getDatabase()->batteries()->where('id = :1', $batteryId)->fetch();
|
$batteryRow = $this->getDatabase()->batteries()->where('id = :1', $batteryId)->fetch();
|
||||||
return $batteryRow !== null;
|
return $batteryRow !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function UndoChargeCycle($chargeCycleId)
|
|
||||||
{
|
|
||||||
$logRow = $this->getDatabase()->battery_charge_cycles()->where('id = :1 AND undone = 0', $chargeCycleId)->fetch();
|
|
||||||
if ($logRow == null)
|
|
||||||
{
|
|
||||||
throw new \Exception('Charge cycle does not exist or was already undone');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update log entry
|
|
||||||
$logRow->update(array(
|
|
||||||
'undone' => 1,
|
|
||||||
'undone_timestamp' => date('Y-m-d H:i:s')
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -3,147 +3,171 @@
|
|||||||
namespace Grocy\Services;
|
namespace Grocy\Services;
|
||||||
|
|
||||||
#use \Grocy\Services\StockService;
|
#use \Grocy\Services\StockService;
|
||||||
|
|
||||||
#use \Grocy\Services\TasksService;
|
#use \Grocy\Services\TasksService;
|
||||||
|
|
||||||
#use \Grocy\Services\ChoresService;
|
#use \Grocy\Services\ChoresService;
|
||||||
|
|
||||||
#use \Grocy\Services\BatteriesService;
|
#use \Grocy\Services\BatteriesService;
|
||||||
#use \Grocy\Services\UsersService;
|
#use \Grocy\Services\UsersService;
|
||||||
use \Grocy\Helpers\UrlManager;
|
use Grocy\Helpers\UrlManager;
|
||||||
|
|
||||||
class CalendarService extends BaseService
|
class CalendarService extends BaseService
|
||||||
{
|
{
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->UrlManager = new UrlManager(GROCY_BASE_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetEvents()
|
public function GetEvents()
|
||||||
{
|
{
|
||||||
$stockEvents = array();
|
$stockEvents = [];
|
||||||
|
|
||||||
if (GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING)
|
if (GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING)
|
||||||
{
|
{
|
||||||
$products = $this->getDatabase()->products();
|
$products = $this->getDatabase()->products();
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Product expires') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Product expires') . ': ';
|
||||||
foreach($this->getStockService()->GetCurrentStock() as $currentStockEntry)
|
|
||||||
|
foreach ($this->getStockService()->GetCurrentStock() as $currentStockEntry)
|
||||||
{
|
{
|
||||||
if ($currentStockEntry->amount > 0)
|
if ($currentStockEntry->amount > 0)
|
||||||
{
|
{
|
||||||
$stockEvents[] = array(
|
$stockEvents[] = [
|
||||||
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name,
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name,
|
||||||
'start' => $currentStockEntry->best_before_date,
|
'start' => $currentStockEntry->best_before_date,
|
||||||
'date_format' => 'date',
|
'date_format' => 'date',
|
||||||
'link' => $this->UrlManager->ConstructUrl('/stockoverview')
|
'link' => $this->UrlManager->ConstructUrl('/stockoverview')
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$taskEvents = array();
|
$taskEvents = [];
|
||||||
|
|
||||||
if (GROCY_FEATURE_FLAG_TASKS)
|
if (GROCY_FEATURE_FLAG_TASKS)
|
||||||
{
|
{
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Task due') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Task due') . ': ';
|
||||||
foreach($this->getTasksService()->GetCurrent() as $currentTaskEntry)
|
|
||||||
|
foreach ($this->getTasksService()->GetCurrent() as $currentTaskEntry)
|
||||||
{
|
{
|
||||||
$taskEvents[] = array(
|
$taskEvents[] = [
|
||||||
'title' => $titlePrefix . $currentTaskEntry->name,
|
'title' => $titlePrefix . $currentTaskEntry->name,
|
||||||
'start' => $currentTaskEntry->due_date,
|
'start' => $currentTaskEntry->due_date,
|
||||||
'date_format' => 'date',
|
'date_format' => 'date',
|
||||||
'link' => $this->UrlManager->ConstructUrl('/tasks')
|
'link' => $this->UrlManager->ConstructUrl('/tasks')
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$choreEvents = array();
|
$choreEvents = [];
|
||||||
|
|
||||||
if (GROCY_FEATURE_FLAG_CHORES)
|
if (GROCY_FEATURE_FLAG_CHORES)
|
||||||
{
|
{
|
||||||
$users = $this->getUsersService()->GetUsersAsDto();
|
$users = $this->getUsersService()->GetUsersAsDto();
|
||||||
|
|
||||||
$chores = $this->getDatabase()->chores();
|
$chores = $this->getDatabase()->chores();
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Chore due') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Chore due') . ': ';
|
||||||
foreach($this->getChoresService()->GetCurrent() as $currentChoreEntry)
|
|
||||||
|
foreach ($this->getChoresService()->GetCurrent() as $currentChoreEntry)
|
||||||
{
|
{
|
||||||
$chore = FindObjectInArrayByPropertyValue($chores, 'id', $currentChoreEntry->chore_id);
|
$chore = FindObjectInArrayByPropertyValue($chores, 'id', $currentChoreEntry->chore_id);
|
||||||
|
|
||||||
$assignedToText = '';
|
$assignedToText = '';
|
||||||
|
|
||||||
if (!empty($currentChoreEntry->next_execution_assigned_to_user_id))
|
if (!empty($currentChoreEntry->next_execution_assigned_to_user_id))
|
||||||
{
|
{
|
||||||
$assignedToText = ' (' . $this->getLocalizationService()->__t('assigned to %s', FindObjectInArrayByPropertyValue($users, 'id', $currentChoreEntry->next_execution_assigned_to_user_id)->display_name) . ')';
|
$assignedToText = ' (' . $this->getLocalizationService()->__t('assigned to %s', FindObjectInArrayByPropertyValue($users, 'id', $currentChoreEntry->next_execution_assigned_to_user_id)->display_name) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
$choreEvents[] = array(
|
$choreEvents[] = [
|
||||||
'title' => $titlePrefix . $chore->name . $assignedToText,
|
'title' => $titlePrefix . $chore->name . $assignedToText,
|
||||||
'start' => $currentChoreEntry->next_estimated_execution_time,
|
'start' => $currentChoreEntry->next_estimated_execution_time,
|
||||||
'date_format' => 'datetime',
|
'date_format' => 'datetime',
|
||||||
'link' => $this->UrlManager->ConstructUrl('/choresoverview'),
|
'link' => $this->UrlManager->ConstructUrl('/choresoverview'),
|
||||||
'allDay' => $chore->track_date_only == 1
|
'allDay' => $chore->track_date_only == 1
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$batteryEvents = array();
|
$batteryEvents = [];
|
||||||
|
|
||||||
if (GROCY_FEATURE_FLAG_BATTERIES)
|
if (GROCY_FEATURE_FLAG_BATTERIES)
|
||||||
{
|
{
|
||||||
$batteries = $this->getDatabase()->batteries();
|
$batteries = $this->getDatabase()->batteries();
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Battery charge cycle due') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Battery charge cycle due') . ': ';
|
||||||
foreach($this->getBatteriesService()->GetCurrent() as $currentBatteryEntry)
|
|
||||||
|
foreach ($this->getBatteriesService()->GetCurrent() as $currentBatteryEntry)
|
||||||
{
|
{
|
||||||
$batteryEvents[] = array(
|
$batteryEvents[] = [
|
||||||
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->name,
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->name,
|
||||||
'start' => $currentBatteryEntry->next_estimated_charge_time,
|
'start' => $currentBatteryEntry->next_estimated_charge_time,
|
||||||
'date_format' => 'datetime',
|
'date_format' => 'datetime',
|
||||||
'link' => $this->UrlManager->ConstructUrl('/batteriesoverview')
|
'link' => $this->UrlManager->ConstructUrl('/batteriesoverview')
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$mealPlanRecipeEvents = array();
|
$mealPlanRecipeEvents = [];
|
||||||
|
|
||||||
if (GROCY_FEATURE_FLAG_RECIPES)
|
if (GROCY_FEATURE_FLAG_RECIPES)
|
||||||
{
|
{
|
||||||
$recipes = $this->getDatabase()->recipes();
|
$recipes = $this->getDatabase()->recipes();
|
||||||
$mealPlanDayRecipes = $this->getDatabase()->recipes()->where('type', 'mealplan-day');
|
$mealPlanDayRecipes = $this->getDatabase()->recipes()->where('type', 'mealplan-day');
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Meal plan recipe') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Meal plan recipe') . ': ';
|
||||||
|
|
||||||
foreach($mealPlanDayRecipes as $mealPlanDayRecipe)
|
foreach ($mealPlanDayRecipes as $mealPlanDayRecipe)
|
||||||
{
|
{
|
||||||
$recipesOfCurrentDay = $this->getDatabase()->recipes_nestings_resolved()->where('recipe_id = :1 AND includes_recipe_id != :1', $mealPlanDayRecipe->id);
|
$recipesOfCurrentDay = $this->getDatabase()->recipes_nestings_resolved()->where('recipe_id = :1 AND includes_recipe_id != :1', $mealPlanDayRecipe->id);
|
||||||
|
|
||||||
foreach ($recipesOfCurrentDay as $recipeOfCurrentDay)
|
foreach ($recipesOfCurrentDay as $recipeOfCurrentDay)
|
||||||
{
|
{
|
||||||
$mealPlanRecipeEvents[] = array(
|
$mealPlanRecipeEvents[] = [
|
||||||
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($recipes, 'id', $recipeOfCurrentDay->includes_recipe_id)->name,
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($recipes, 'id', $recipeOfCurrentDay->includes_recipe_id)->name,
|
||||||
'start' => FindObjectInArrayByPropertyValue($recipes, 'id', $recipeOfCurrentDay->recipe_id)->name,
|
'start' => FindObjectInArrayByPropertyValue($recipes, 'id', $recipeOfCurrentDay->recipe_id)->name,
|
||||||
'date_format' => 'date',
|
'date_format' => 'date',
|
||||||
'description' => $this->UrlManager->ConstructUrl('/mealplan' . '?week=' . FindObjectInArrayByPropertyValue($recipes, 'id', $recipeOfCurrentDay->recipe_id)->name),
|
'description' => $this->UrlManager->ConstructUrl('/mealplan' . '?week=' . FindObjectInArrayByPropertyValue($recipes, 'id', $recipeOfCurrentDay->recipe_id)->name),
|
||||||
'link' => $this->UrlManager->ConstructUrl('/recipes' . '?recipe=' . $recipeOfCurrentDay->includes_recipe_id . "#fullscreen")
|
'link' => $this->UrlManager->ConstructUrl('/recipes' . '?recipe=' . $recipeOfCurrentDay->includes_recipe_id . '#fullscreen')
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$mealPlanDayNotes = $this->getDatabase()->meal_plan()->where('type', 'note');
|
$mealPlanDayNotes = $this->getDatabase()->meal_plan()->where('type', 'note');
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Meal plan note') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Meal plan note') . ': ';
|
||||||
$mealPlanNotesEvents = array();
|
$mealPlanNotesEvents = [];
|
||||||
foreach($mealPlanDayNotes as $mealPlanDayNote)
|
|
||||||
|
foreach ($mealPlanDayNotes as $mealPlanDayNote)
|
||||||
{
|
{
|
||||||
$mealPlanNotesEvents[] = array(
|
$mealPlanNotesEvents[] = [
|
||||||
'title' => $titlePrefix . $mealPlanDayNote->note,
|
'title' => $titlePrefix . $mealPlanDayNote->note,
|
||||||
'start' => $mealPlanDayNote->day,
|
'start' => $mealPlanDayNote->day,
|
||||||
'date_format' => 'date'
|
'date_format' => 'date'
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$products = $this->getDatabase()->products();
|
$products = $this->getDatabase()->products();
|
||||||
$mealPlanDayProducts = $this->getDatabase()->meal_plan()->where('type', 'product');
|
$mealPlanDayProducts = $this->getDatabase()->meal_plan()->where('type', 'product');
|
||||||
$titlePrefix = $this->getLocalizationService()->__t('Meal plan product') . ': ';
|
$titlePrefix = $this->getLocalizationService()->__t('Meal plan product') . ': ';
|
||||||
$mealPlanProductEvents = array();
|
$mealPlanProductEvents = [];
|
||||||
foreach($mealPlanDayProducts as $mealPlanDayProduct)
|
|
||||||
|
foreach ($mealPlanDayProducts as $mealPlanDayProduct)
|
||||||
{
|
{
|
||||||
$mealPlanProductEvents[] = array(
|
$mealPlanProductEvents[] = [
|
||||||
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($products, 'id', $mealPlanDayProduct->product_id)->name,
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($products, 'id', $mealPlanDayProduct->product_id)->name,
|
||||||
'start' => $mealPlanDayProduct->day,
|
'start' => $mealPlanDayProduct->day,
|
||||||
'date_format' => 'date'
|
'date_format' => 'date'
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_merge($stockEvents, $taskEvents, $choreEvents, $batteryEvents, $mealPlanRecipeEvents, $mealPlanNotesEvents, $mealPlanProductEvents);
|
return array_merge($stockEvents, $taskEvents, $choreEvents, $batteryEvents, $mealPlanRecipeEvents, $mealPlanNotesEvents, $mealPlanProductEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->UrlManager = new UrlManager(GROCY_BASE_URL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,31 +2,115 @@
|
|||||||
|
|
||||||
namespace Grocy\Services;
|
namespace Grocy\Services;
|
||||||
|
|
||||||
#use \Grocy\Services\StockService;
|
|
||||||
|
|
||||||
class ChoresService extends BaseService
|
class ChoresService extends BaseService
|
||||||
{
|
{
|
||||||
const CHORE_PERIOD_TYPE_MANUALLY = 'manually';
|
|
||||||
const CHORE_PERIOD_TYPE_DYNAMIC_REGULAR = 'dynamic-regular';
|
|
||||||
const CHORE_PERIOD_TYPE_DAILY = 'daily';
|
|
||||||
const CHORE_PERIOD_TYPE_WEEKLY = 'weekly';
|
|
||||||
const CHORE_PERIOD_TYPE_MONTHLY = 'monthly';
|
|
||||||
const CHORE_PERIOD_TYPE_YEARLY = 'yearly';
|
|
||||||
|
|
||||||
const CHORE_ASSIGNMENT_TYPE_NO_ASSIGNMENT = 'no-assignment';
|
|
||||||
const CHORE_ASSIGNMENT_TYPE_WHO_LEAST_DID_FIRST = 'who-least-did-first';
|
|
||||||
const CHORE_ASSIGNMENT_TYPE_RANDOM = 'random';
|
|
||||||
const CHORE_ASSIGNMENT_TYPE_IN_ALPHABETICAL_ORDER = 'in-alphabetical-order';
|
const CHORE_ASSIGNMENT_TYPE_IN_ALPHABETICAL_ORDER = 'in-alphabetical-order';
|
||||||
|
|
||||||
public function __construct()
|
const CHORE_ASSIGNMENT_TYPE_NO_ASSIGNMENT = 'no-assignment';
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetCurrent()
|
const CHORE_ASSIGNMENT_TYPE_RANDOM = 'random';
|
||||||
|
|
||||||
|
const CHORE_ASSIGNMENT_TYPE_WHO_LEAST_DID_FIRST = 'who-least-did-first';
|
||||||
|
|
||||||
|
const CHORE_PERIOD_TYPE_DAILY = 'daily';
|
||||||
|
|
||||||
|
const CHORE_PERIOD_TYPE_DYNAMIC_REGULAR = 'dynamic-regular';
|
||||||
|
|
||||||
|
const CHORE_PERIOD_TYPE_MANUALLY = 'manually';
|
||||||
|
|
||||||
|
const CHORE_PERIOD_TYPE_MONTHLY = 'monthly';
|
||||||
|
|
||||||
|
const CHORE_PERIOD_TYPE_WEEKLY = 'weekly';
|
||||||
|
|
||||||
|
const CHORE_PERIOD_TYPE_YEARLY = 'yearly';
|
||||||
|
|
||||||
|
public function CalculateNextExecutionAssignment($choreId)
|
||||||
{
|
{
|
||||||
$sql = 'SELECT chores_current.*, chores.name AS chore_name from chores_current join chores on chores_current.chore_id = chores.id';
|
if (!$this->ChoreExists($choreId))
|
||||||
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
{
|
||||||
|
throw new \Exception('Chore does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$chore = $this->getDatabase()->chores($choreId);
|
||||||
|
$choreLastTrackedTime = $this->getDatabase()->chores_log()->where('chore_id = :1 AND undone = 0', $choreId)->max('tracked_time');
|
||||||
|
$lastChoreLogRow = $this->getDatabase()->chores_log()->where('chore_id = :1 AND tracked_time = :2 AND undone = 0', $choreId, $choreLastTrackedTime)->orderBy('row_created_timestamp', 'DESC')->fetch();
|
||||||
|
$lastDoneByUserId = $lastChoreLogRow->done_by_user_id;
|
||||||
|
|
||||||
|
$users = $this->getUsersService()->GetUsersAsDto();
|
||||||
|
$assignedUsers = [];
|
||||||
|
|
||||||
|
foreach ($users as $user)
|
||||||
|
{
|
||||||
|
if (in_array($user->id, explode(',', $chore->assignment_config)))
|
||||||
|
{
|
||||||
|
$assignedUsers[] = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$nextExecutionUserId = null;
|
||||||
|
|
||||||
|
if ($chore->assignment_type == self::CHORE_ASSIGNMENT_TYPE_RANDOM)
|
||||||
|
{
|
||||||
|
// Random assignment and only 1 user in the group? Well, ok - will be hard to guess the next one...
|
||||||
|
if (count($assignedUsers) == 1)
|
||||||
|
{
|
||||||
|
$nextExecutionUserId = array_shift($assignedUsers)->id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Randomness in small groups will likely often result in the same user, so try it as long as this is the case
|
||||||
|
while ($nextExecutionUserId == null || $nextExecutionUserId == $lastDoneByUserId)
|
||||||
|
{
|
||||||
|
$nextExecutionUserId = $assignedUsers[array_rand($assignedUsers)]->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ($chore->assignment_type == self::CHORE_ASSIGNMENT_TYPE_IN_ALPHABETICAL_ORDER)
|
||||||
|
{
|
||||||
|
usort($assignedUsers, function ($a, $b)
|
||||||
|
{
|
||||||
|
return strcmp($a->display_name, $b->display_name);
|
||||||
|
});
|
||||||
|
|
||||||
|
$nextRoundMatches = false;
|
||||||
|
foreach ($assignedUsers as $user)
|
||||||
|
{
|
||||||
|
if ($nextRoundMatches)
|
||||||
|
{
|
||||||
|
$nextExecutionUserId = $user->id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user->id == $lastDoneByUserId)
|
||||||
|
{
|
||||||
|
$nextRoundMatches = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing has matched, probably it was the last user in the sorted list -> the first one is the next one
|
||||||
|
if ($nextExecutionUserId == null)
|
||||||
|
{
|
||||||
|
$nextExecutionUserId = array_shift($assignedUsers)->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ($chore->assignment_type == self::CHORE_ASSIGNMENT_TYPE_WHO_LEAST_DID_FIRST)
|
||||||
|
{
|
||||||
|
$row = $this->getDatabase()->chores_execution_users_statistics()->where('chore_id = :1', $choreId)->orderBy('execution_count')->limit(1)->fetch();
|
||||||
|
if ($row != null)
|
||||||
|
{
|
||||||
|
$nextExecutionUserId = $row->user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$chore->update([
|
||||||
|
'next_execution_assigned_to_user_id' => $nextExecutionUserId
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetChoreDetails(int $choreId)
|
public function GetChoreDetails(int $choreId)
|
||||||
@@ -36,14 +120,14 @@ class ChoresService extends BaseService
|
|||||||
throw new \Exception('Chore does not exist');
|
throw new \Exception('Chore does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$users = $this->getUsersService()->GetUsersAsDto();
|
$users = $this->getUsersService()->GetUsersAsDto();
|
||||||
|
|
||||||
$chore = $this->getDatabase()->chores($choreId);
|
$chore = $this->getDatabase()->chores($choreId);
|
||||||
$choreTrackedCount = $this->getDatabase()->chores_log()->where('chore_id = :1 AND undone = 0', $choreId)->count();
|
$choreTrackedCount = $this->getDatabase()->chores_log()->where('chore_id = :1 AND undone = 0', $choreId)->count();
|
||||||
$choreLastTrackedTime = $this->getDatabase()->chores_log()->where('chore_id = :1 AND undone = 0', $choreId)->max('tracked_time');
|
$choreLastTrackedTime = $this->getDatabase()->chores_log()->where('chore_id = :1 AND undone = 0', $choreId)->max('tracked_time');
|
||||||
$nextExecutionTime = $this->getDatabase()->chores_current()->where('chore_id', $choreId)->min('next_estimated_execution_time');
|
$nextExecutionTime = $this->getDatabase()->chores_current()->where('chore_id', $choreId)->min('next_estimated_execution_time');
|
||||||
|
|
||||||
$lastChoreLogRow = $this->getDatabase()->chores_log()->where('chore_id = :1 AND tracked_time = :2 AND undone = 0', $choreId, $choreLastTrackedTime)->fetch();
|
$lastChoreLogRow = $this->getDatabase()->chores_log()->where('chore_id = :1 AND tracked_time = :2 AND undone = 0', $choreId, $choreLastTrackedTime)->fetch();
|
||||||
$lastDoneByUser = null;
|
$lastDoneByUser = null;
|
||||||
if ($lastChoreLogRow !== null && !empty($lastChoreLogRow))
|
if ($lastChoreLogRow !== null && !empty($lastChoreLogRow))
|
||||||
{
|
{
|
||||||
@@ -56,14 +140,20 @@ class ChoresService extends BaseService
|
|||||||
$nextExecutionAssignedUser = FindObjectInArrayByPropertyValue($users, 'id', $chore->next_execution_assigned_to_user_id);
|
$nextExecutionAssignedUser = FindObjectInArrayByPropertyValue($users, 'id', $chore->next_execution_assigned_to_user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return [
|
||||||
'chore' => $chore,
|
'chore' => $chore,
|
||||||
'last_tracked' => $choreLastTrackedTime,
|
'last_tracked' => $choreLastTrackedTime,
|
||||||
'tracked_count' => $choreTrackedCount,
|
'tracked_count' => $choreTrackedCount,
|
||||||
'last_done_by' => $lastDoneByUser,
|
'last_done_by' => $lastDoneByUser,
|
||||||
'next_estimated_execution_time' => $nextExecutionTime,
|
'next_estimated_execution_time' => $nextExecutionTime,
|
||||||
'next_execution_assigned_user' => $nextExecutionAssignedUser
|
'next_execution_assigned_user' => $nextExecutionAssignedUser
|
||||||
);
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetCurrent()
|
||||||
|
{
|
||||||
|
$sql = 'SELECT chores_current.*, chores.name AS chore_name from chores_current join chores on chores_current.chore_id = chores.id';
|
||||||
|
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function TrackChore(int $choreId, string $trackedTime, $doneBy = GROCY_USER_ID)
|
public function TrackChore(int $choreId, string $trackedTime, $doneBy = GROCY_USER_ID)
|
||||||
@@ -85,11 +175,11 @@ class ChoresService extends BaseService
|
|||||||
$trackedTime = substr($trackedTime, 0, 10) . ' 00:00:00';
|
$trackedTime = substr($trackedTime, 0, 10) . ' 00:00:00';
|
||||||
}
|
}
|
||||||
|
|
||||||
$logRow = $this->getDatabase()->chores_log()->createRow(array(
|
$logRow = $this->getDatabase()->chores_log()->createRow([
|
||||||
'chore_id' => $choreId,
|
'chore_id' => $choreId,
|
||||||
'tracked_time' => $trackedTime,
|
'tracked_time' => $trackedTime,
|
||||||
'done_by_user_id' => $doneBy
|
'done_by_user_id' => $doneBy
|
||||||
));
|
]);
|
||||||
$logRow->save();
|
$logRow->save();
|
||||||
$lastInsertId = $this->getDatabase()->lastInsertId();
|
$lastInsertId = $this->getDatabase()->lastInsertId();
|
||||||
|
|
||||||
@@ -103,12 +193,6 @@ class ChoresService extends BaseService
|
|||||||
return $lastInsertId;
|
return $lastInsertId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ChoreExists($choreId)
|
|
||||||
{
|
|
||||||
$choreRow = $this->getDatabase()->chores()->where('id = :1', $choreId)->fetch();
|
|
||||||
return $choreRow !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function UndoChoreExecution($executionId)
|
public function UndoChoreExecution($executionId)
|
||||||
{
|
{
|
||||||
$logRow = $this->getDatabase()->chores_log()->where('id = :1 AND undone = 0', $executionId)->fetch();
|
$logRow = $this->getDatabase()->chores_log()->where('id = :1 AND undone = 0', $executionId)->fetch();
|
||||||
@@ -118,90 +202,21 @@ class ChoresService extends BaseService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update log entry
|
// Update log entry
|
||||||
$logRow->update(array(
|
$logRow->update([
|
||||||
'undone' => 1,
|
'undone' => 1,
|
||||||
'undone_timestamp' => date('Y-m-d H:i:s')
|
'undone_timestamp' => date('Y-m-d H:i:s')
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function CalculateNextExecutionAssignment($choreId)
|
public function __construct()
|
||||||
{
|
{
|
||||||
if (!$this->ChoreExists($choreId))
|
parent::__construct();
|
||||||
{
|
|
||||||
throw new \Exception('Chore does not exist');
|
|
||||||
}
|
|
||||||
|
|
||||||
$chore = $this->getDatabase()->chores($choreId);
|
|
||||||
$choreLastTrackedTime = $this->getDatabase()->chores_log()->where('chore_id = :1 AND undone = 0', $choreId)->max('tracked_time');
|
|
||||||
$lastChoreLogRow = $this->getDatabase()->chores_log()->where('chore_id = :1 AND tracked_time = :2 AND undone = 0', $choreId, $choreLastTrackedTime)->orderBy('row_created_timestamp', 'DESC')->fetch();
|
|
||||||
$lastDoneByUserId = $lastChoreLogRow->done_by_user_id;
|
|
||||||
|
|
||||||
$users = $this->getUsersService()->GetUsersAsDto();
|
|
||||||
$assignedUsers = array();
|
|
||||||
foreach ($users as $user)
|
|
||||||
{
|
|
||||||
if (in_array($user->id, explode(',', $chore->assignment_config)))
|
|
||||||
{
|
|
||||||
$assignedUsers[] = $user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$nextExecutionUserId = null;
|
|
||||||
if ($chore->assignment_type == self::CHORE_ASSIGNMENT_TYPE_RANDOM)
|
|
||||||
{
|
|
||||||
// Random assignment and only 1 user in the group? Well, ok - will be hard to guess the next one...
|
|
||||||
if (count($assignedUsers) == 1)
|
|
||||||
{
|
|
||||||
$nextExecutionUserId = array_shift($assignedUsers)->id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Randomness in small groups will likely often result in the same user, so try it as long as this is the case
|
|
||||||
while ($nextExecutionUserId == null || $nextExecutionUserId == $lastDoneByUserId)
|
|
||||||
{
|
|
||||||
$nextExecutionUserId = $assignedUsers[array_rand($assignedUsers)]->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ($chore->assignment_type == self::CHORE_ASSIGNMENT_TYPE_IN_ALPHABETICAL_ORDER)
|
|
||||||
{
|
|
||||||
usort($assignedUsers, function($a, $b)
|
|
||||||
{
|
|
||||||
return strcmp($a->display_name, $b->display_name);
|
|
||||||
});
|
|
||||||
|
|
||||||
$nextRoundMatches = false;
|
|
||||||
foreach ($assignedUsers as $user)
|
|
||||||
{
|
|
||||||
if ($nextRoundMatches)
|
|
||||||
{
|
|
||||||
$nextExecutionUserId = $user->id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($user->id == $lastDoneByUserId)
|
|
||||||
{
|
|
||||||
$nextRoundMatches = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If nothing has matched, probably it was the last user in the sorted list -> the first one is the next one
|
|
||||||
if ($nextExecutionUserId == null)
|
|
||||||
{
|
|
||||||
$nextExecutionUserId = array_shift($assignedUsers)->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ($chore->assignment_type == self::CHORE_ASSIGNMENT_TYPE_WHO_LEAST_DID_FIRST)
|
|
||||||
{
|
|
||||||
$row = $this->getDatabase()->chores_execution_users_statistics()->where('chore_id = :1', $choreId)->orderBy('execution_count')->limit(1)->fetch();
|
|
||||||
if ($row != null)
|
|
||||||
{
|
|
||||||
$nextExecutionUserId = $row->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$chore->update(array(
|
|
||||||
'next_execution_assigned_to_user_id' => $nextExecutionUserId
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function ChoreExists($choreId)
|
||||||
|
{
|
||||||
|
$choreRow = $this->getDatabase()->chores()->where('id = :1', $choreId)->fetch();
|
||||||
|
return $choreRow !== null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,47 +6,58 @@ class DatabaseMigrationService extends BaseService
|
|||||||
{
|
{
|
||||||
public function MigrateDatabase()
|
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')))");
|
$this->getDatabaseService()->ExecuteDbStatement("CREATE TABLE IF NOT EXISTS migrations (migration INTEGER NOT NULL PRIMARY KEY UNIQUE, execution_time_timestamp DATETIME DEFAULT (datetime('now', 'localtime')))");
|
||||||
|
|
||||||
|
$migrationFiles = [];
|
||||||
|
|
||||||
$migrationFiles = array();
|
|
||||||
foreach (new \FilesystemIterator(__DIR__ . '/../migrations') as $file)
|
foreach (new \FilesystemIterator(__DIR__ . '/../migrations') as $file)
|
||||||
{
|
{
|
||||||
$migrationFiles[$file->getBasename()] = $file;
|
$migrationFiles[$file->getBasename()] = $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
ksort($migrationFiles);
|
ksort($migrationFiles);
|
||||||
foreach($migrationFiles as $migrationKey => $migrationFile)
|
|
||||||
{
|
|
||||||
if($migrationFile->getExtension() === 'php')
|
|
||||||
{
|
|
||||||
$migrationNumber = ltrim($migrationFile->getBasename('.php'), '0');
|
|
||||||
$this->ExecutePhpMigrationWhenNeeded($migrationNumber, $migrationFile->getPathname());
|
|
||||||
}
|
|
||||||
else if($migrationFile->getExtension() === 'sql')
|
|
||||||
{
|
|
||||||
$migrationNumber = ltrim($migrationFile->getBasename('.sql'), '0');
|
|
||||||
$this->ExecuteSqlMigrationWhenNeeded($migrationNumber, file_get_contents($migrationFile->getPathname()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
foreach ($migrationFiles as $migrationKey => $migrationFile)
|
||||||
}
|
|
||||||
|
|
||||||
private function ExecuteSqlMigrationWhenNeeded(int $migrationId, string $sql)
|
|
||||||
{
|
|
||||||
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
|
|
||||||
if (intval($rowCount) === 0)
|
|
||||||
{
|
{
|
||||||
$this->getDatabaseService()->ExecuteDbStatement($sql);
|
if ($migrationFile->getExtension() === 'php')
|
||||||
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
|
{
|
||||||
|
$migrationNumber = ltrim($migrationFile->getBasename('.php'), '0');
|
||||||
|
$this->ExecutePhpMigrationWhenNeeded($migrationNumber, $migrationFile->getPathname());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
if ($migrationFile->getExtension() === 'sql')
|
||||||
|
{
|
||||||
|
$migrationNumber = ltrim($migrationFile->getBasename('.sql'), '0');
|
||||||
|
$this->ExecuteSqlMigrationWhenNeeded($migrationNumber, file_get_contents($migrationFile->getPathname()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ExecutePhpMigrationWhenNeeded(int $migrationId, string $phpFile)
|
private function ExecutePhpMigrationWhenNeeded(int $migrationId, string $phpFile)
|
||||||
{
|
{
|
||||||
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
|
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
|
||||||
|
|
||||||
if (intval($rowCount) === 0)
|
if (intval($rowCount) === 0)
|
||||||
{
|
{
|
||||||
include $phpFile;
|
include $phpFile;
|
||||||
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
|
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function ExecuteSqlMigrationWhenNeeded(int $migrationId, string $sql)
|
||||||
|
{
|
||||||
|
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
|
||||||
|
|
||||||
|
if (intval($rowCount) === 0)
|
||||||
|
{
|
||||||
|
$this->getDatabaseService()->ExecuteDbStatement($sql);
|
||||||
|
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,80 @@ namespace Grocy\Services;
|
|||||||
|
|
||||||
class DatabaseService
|
class DatabaseService
|
||||||
{
|
{
|
||||||
|
private static $DbConnection = null;
|
||||||
|
|
||||||
|
private static $DbConnectionRaw = null;
|
||||||
|
|
||||||
private static $instance = null;
|
private static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return boolean|\PDOStatement
|
||||||
|
*/
|
||||||
|
public function ExecuteDbQuery(string $sql)
|
||||||
|
{
|
||||||
|
$pdo = $this->GetDbConnectionRaw();
|
||||||
|
|
||||||
|
if ($this->ExecuteDbStatement($sql) === true)
|
||||||
|
{
|
||||||
|
return $pdo->query($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function ExecuteDbStatement(string $sql)
|
||||||
|
{
|
||||||
|
$pdo = $this->GetDbConnectionRaw();
|
||||||
|
|
||||||
|
if ($pdo->exec($sql) === false)
|
||||||
|
{
|
||||||
|
throw new Exception($pdo->errorInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDbChangedTime()
|
||||||
|
{
|
||||||
|
return date('Y-m-d H:i:s', filemtime($this->GetDbFilePath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \LessQL\Database
|
||||||
|
*/
|
||||||
|
public function GetDbConnection()
|
||||||
|
{
|
||||||
|
if (self::$DbConnection == null)
|
||||||
|
{
|
||||||
|
self::$DbConnection = new \LessQL\Database($this->GetDbConnectionRaw());
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$DbConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \PDO
|
||||||
|
*/
|
||||||
|
public function GetDbConnectionRaw()
|
||||||
|
{
|
||||||
|
if (self::$DbConnectionRaw == null)
|
||||||
|
{
|
||||||
|
$pdo = new \PDO('sqlite:' . $this->GetDbFilePath());
|
||||||
|
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
|
self::$DbConnectionRaw = $pdo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$DbConnectionRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetDbChangedTime($dateTime)
|
||||||
|
{
|
||||||
|
touch($this->GetDbFilePath(), strtotime($dateTime));
|
||||||
|
}
|
||||||
|
|
||||||
public static function getInstance()
|
public static function getInstance()
|
||||||
{
|
{
|
||||||
if (self::$instance == null)
|
if (self::$instance == null)
|
||||||
@@ -28,71 +100,4 @@ class DatabaseService
|
|||||||
return GROCY_DATAPATH . '/grocy.db';
|
return GROCY_DATAPATH . '/grocy.db';
|
||||||
}
|
}
|
||||||
|
|
||||||
private static $DbConnectionRaw = null;
|
|
||||||
/**
|
|
||||||
* @return \PDO
|
|
||||||
*/
|
|
||||||
public function GetDbConnectionRaw()
|
|
||||||
{
|
|
||||||
if (self::$DbConnectionRaw == null)
|
|
||||||
{
|
|
||||||
$pdo = new \PDO('sqlite:' . $this->GetDbFilePath());
|
|
||||||
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
|
||||||
self::$DbConnectionRaw = $pdo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$DbConnectionRaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static $DbConnection = null;
|
|
||||||
/**
|
|
||||||
* @return \LessQL\Database
|
|
||||||
*/
|
|
||||||
public function GetDbConnection()
|
|
||||||
{
|
|
||||||
if (self::$DbConnection == null)
|
|
||||||
{
|
|
||||||
self::$DbConnection = new \LessQL\Database($this->GetDbConnectionRaw());
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$DbConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function ExecuteDbStatement(string $sql)
|
|
||||||
{
|
|
||||||
$pdo = $this->GetDbConnectionRaw();
|
|
||||||
if ($pdo->exec($sql) === false)
|
|
||||||
{
|
|
||||||
throw new Exception($pdo->errorInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return boolean|\PDOStatement
|
|
||||||
*/
|
|
||||||
public function ExecuteDbQuery(string $sql)
|
|
||||||
{
|
|
||||||
$pdo = $this->GetDbConnectionRaw();
|
|
||||||
if ($this->ExecuteDbStatement($sql) === true)
|
|
||||||
{
|
|
||||||
return $pdo->query($sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetDbChangedTime()
|
|
||||||
{
|
|
||||||
return date('Y-m-d H:i:s', filemtime($this->GetDbFilePath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function SetDbChangedTime($dateTime)
|
|
||||||
{
|
|
||||||
touch($this->GetDbFilePath(), strtotime($dateTime));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -6,17 +6,14 @@ namespace Grocy\Services;
|
|||||||
|
|
||||||
class DemoDataGeneratorService extends BaseService
|
class DemoDataGeneratorService extends BaseService
|
||||||
{
|
{
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
$this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected $LocalizationService;
|
protected $LocalizationService;
|
||||||
|
|
||||||
|
private $LastSupermarketId = 1;
|
||||||
|
|
||||||
public function PopulateDemoData()
|
public function PopulateDemoData()
|
||||||
{
|
{
|
||||||
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = -1')->fetchColumn();
|
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = -1')->fetchColumn();
|
||||||
|
|
||||||
if (intval($rowCount) === 0)
|
if (intval($rowCount) === 0)
|
||||||
{
|
{
|
||||||
$loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';
|
$loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';
|
||||||
@@ -314,14 +311,29 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
$this->DownloadFileIfNotAlreadyExists('https://releases.grocy.info/demoresources/chocolate_sauce.jpg', "$recipePicturesFolder/chocolate_sauce.jpg");
|
$this->DownloadFileIfNotAlreadyExists('https://releases.grocy.info/demoresources/chocolate_sauce.jpg', "$recipePicturesFolder/chocolate_sauce.jpg");
|
||||||
$this->DownloadFileIfNotAlreadyExists('https://releases.grocy.info/demoresources/pancakes_chocolate_sauce.jpg', "$recipePicturesFolder/pancakes_chocolate_sauce.jpg");
|
$this->DownloadFileIfNotAlreadyExists('https://releases.grocy.info/demoresources/pancakes_chocolate_sauce.jpg', "$recipePicturesFolder/pancakes_chocolate_sauce.jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function RandomPrice()
|
public function __construct()
|
||||||
{
|
{
|
||||||
return mt_rand(2 * 100, 25 * 100) / 100;
|
parent::__construct();
|
||||||
|
$this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function DownloadFileIfNotAlreadyExists($sourceUrl, $destinationPath)
|
||||||
|
{
|
||||||
|
if (!file_exists($destinationPath))
|
||||||
|
{
|
||||||
|
file_put_contents($destinationPath, file_get_contents($sourceUrl, false, stream_context_create([
|
||||||
|
'ssl' => [
|
||||||
|
'verify_peer' => false,
|
||||||
|
'verify_peer_name' => false
|
||||||
|
]
|
||||||
|
])));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private $LastSupermarketId = 1;
|
|
||||||
private function NextSupermarketId()
|
private function NextSupermarketId()
|
||||||
{
|
{
|
||||||
$returnValue = $this->LastSupermarketId;
|
$returnValue = $this->LastSupermarketId;
|
||||||
@@ -338,10 +350,9 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
return $returnValue;
|
return $returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __t_sql(string $text)
|
private function RandomPrice()
|
||||||
{
|
{
|
||||||
$localizedText = $this->getLocalizationService()->__t($text, null);
|
return mt_rand(2 * 100, 25 * 100) / 100;
|
||||||
return str_replace("'", "''", $localizedText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function __n_sql($number, string $singularForm, string $pluralForm)
|
private function __n_sql($number, string $singularForm, string $pluralForm)
|
||||||
@@ -350,16 +361,10 @@ class DemoDataGeneratorService extends BaseService
|
|||||||
return str_replace("'", "''", $localizedText);
|
return str_replace("'", "''", $localizedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function DownloadFileIfNotAlreadyExists($sourceUrl, $destinationPath)
|
private function __t_sql(string $text)
|
||||||
{
|
{
|
||||||
if (!file_exists($destinationPath))
|
$localizedText = $this->getLocalizationService()->__t($text, null);
|
||||||
{
|
return str_replace("'", "''", $localizedText);
|
||||||
file_put_contents($destinationPath, file_get_contents($sourceUrl, false, stream_context_create(array(
|
|
||||||
'ssl' => array(
|
|
||||||
'verify_peer' => false,
|
|
||||||
'verify_peer_name' => false,
|
|
||||||
),
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,37 +2,14 @@
|
|||||||
|
|
||||||
namespace Grocy\Services;
|
namespace Grocy\Services;
|
||||||
|
|
||||||
use \Gumlet\ImageResize;
|
use Gumlet\ImageResize;
|
||||||
|
|
||||||
class FilesService extends BaseService
|
class FilesService extends BaseService
|
||||||
{
|
{
|
||||||
const FILE_SERVE_TYPE_PICTURE = 'picture';
|
const FILE_SERVE_TYPE_PICTURE = 'picture';
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$this->StoragePath = GROCY_DATAPATH . '/storage';
|
|
||||||
|
|
||||||
if (!file_exists($this->StoragePath))
|
|
||||||
{
|
|
||||||
mkdir($this->StoragePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private $StoragePath;
|
private $StoragePath;
|
||||||
|
|
||||||
public function GetFilePath($group, $fileName)
|
|
||||||
{
|
|
||||||
$groupFolderPath = $this->StoragePath . '/' . $group;
|
|
||||||
if (!file_exists($groupFolderPath))
|
|
||||||
{
|
|
||||||
mkdir($groupFolderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $groupFolderPath . '/' . $fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function DownscaleImage($group, $fileName, $bestFitHeight = null, $bestFitWidth = null)
|
public function DownscaleImage($group, $fileName, $bestFitHeight = null, $bestFitWidth = null)
|
||||||
{
|
{
|
||||||
$filePath = $this->GetFilePath($group, $fileName);
|
$filePath = $this->GetFilePath($group, $fileName);
|
||||||
@@ -52,20 +29,27 @@ class FilesService extends BaseService
|
|||||||
if (!file_exists($filePathDownscaled))
|
if (!file_exists($filePathDownscaled))
|
||||||
{
|
{
|
||||||
$image = new ImageResize($filePath);
|
$image = new ImageResize($filePath);
|
||||||
|
|
||||||
if ($bestFitHeight !== null && $bestFitHeight !== null)
|
if ($bestFitHeight !== null && $bestFitHeight !== null)
|
||||||
{
|
{
|
||||||
$image->resizeToBestFit($bestFitWidth, $bestFitHeight);
|
$image->resizeToBestFit($bestFitWidth, $bestFitHeight);
|
||||||
}
|
}
|
||||||
else if ($bestFitHeight !== null)
|
else
|
||||||
|
|
||||||
|
if ($bestFitHeight !== null)
|
||||||
{
|
{
|
||||||
$image->resizeToHeight($bestFitHeight);
|
$image->resizeToHeight($bestFitHeight);
|
||||||
}
|
}
|
||||||
else if ($bestFitWidth !== null)
|
else
|
||||||
|
|
||||||
|
if ($bestFitWidth !== null)
|
||||||
{
|
{
|
||||||
$image->resizeToWidth($bestFitWidth);
|
$image->resizeToWidth($bestFitWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
$image->save($filePathDownscaled);
|
$image->save($filePathDownscaled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (ImageResizeException $ex)
|
catch (ImageResizeException $ex)
|
||||||
{
|
{
|
||||||
@@ -74,4 +58,30 @@ class FilesService extends BaseService
|
|||||||
|
|
||||||
return $filePathDownscaled;
|
return $filePathDownscaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetFilePath($group, $fileName)
|
||||||
|
{
|
||||||
|
$groupFolderPath = $this->StoragePath . '/' . $group;
|
||||||
|
|
||||||
|
if (!file_exists($groupFolderPath))
|
||||||
|
{
|
||||||
|
mkdir($groupFolderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groupFolderPath . '/' . $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->StoragePath = GROCY_DATAPATH . '/storage';
|
||||||
|
|
||||||
|
if (!file_exists($this->StoragePath))
|
||||||
|
{
|
||||||
|
mkdir($this->StoragePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -3,14 +3,69 @@
|
|||||||
namespace Grocy\Services;
|
namespace Grocy\Services;
|
||||||
|
|
||||||
#use \Grocy\Services\DatabaseService;
|
#use \Grocy\Services\DatabaseService;
|
||||||
use \Gettext\Translation;
|
use Gettext\Translation;
|
||||||
use \Gettext\Translations;
|
use Gettext\Translations;
|
||||||
use \Gettext\Translator;
|
use Gettext\Translator;
|
||||||
|
|
||||||
class LocalizationService
|
class LocalizationService
|
||||||
{
|
{
|
||||||
|
protected $Po;
|
||||||
|
|
||||||
private static $instanceMap = array();
|
protected $PoUserStrings;
|
||||||
|
|
||||||
|
protected $Pot;
|
||||||
|
|
||||||
|
protected $PotMain;
|
||||||
|
|
||||||
|
protected $Translator;
|
||||||
|
|
||||||
|
private static $instanceMap = [];
|
||||||
|
|
||||||
|
public function CheckAndAddMissingTranslationToPot($text)
|
||||||
|
{
|
||||||
|
if (GROCY_MODE === 'dev')
|
||||||
|
{
|
||||||
|
if ($this->Pot->find('', $text) === false && $this->PoUserStrings->find('', $text) === false && empty($text) === false)
|
||||||
|
{
|
||||||
|
$translation = new Translation('', $text);
|
||||||
|
$this->PotMain[] = $translation;
|
||||||
|
$this->PotMain->toPoFile(__DIR__ . '/../localization/strings.pot');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetPluralCount()
|
||||||
|
{
|
||||||
|
if ($this->Po->getHeader(Translations::HEADER_PLURAL) !== null)
|
||||||
|
{
|
||||||
|
return $this->Po->getPluralForms()[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetPluralDefinition()
|
||||||
|
{
|
||||||
|
if ($this->Po->getHeader(Translations::HEADER_PLURAL) !== null)
|
||||||
|
{
|
||||||
|
return $this->Po->getPluralForms()[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '(n != 1)';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetPoAsJsonString()
|
||||||
|
{
|
||||||
|
return $this->Po->toJsonString();
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct(string $culture)
|
public function __construct(string $culture)
|
||||||
{
|
{
|
||||||
@@ -19,15 +74,26 @@ class LocalizationService
|
|||||||
$this->LoadLocalizations($culture);
|
$this->LoadLocalizations($culture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __n($number, $singularForm, $pluralForm)
|
||||||
protected function getDatabaseService()
|
|
||||||
{
|
{
|
||||||
return DatabaseService::getInstance();
|
$this->CheckAndAddMissingTranslationToPot($singularForm);
|
||||||
|
|
||||||
|
return sprintf($this->Translator->ngettext($singularForm, $pluralForm, $number), $number);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getdatabase()
|
public function __t($text, ...$placeholderValues)
|
||||||
{
|
{
|
||||||
return $this->getDatabaseService()->GetDbConnection();
|
$this->CheckAndAddMissingTranslationToPot($text);
|
||||||
|
|
||||||
|
if (func_num_args() === 1)
|
||||||
|
{
|
||||||
|
return $this->Translator->gettext($text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return vsprintf($this->Translator->gettext($text), ...$placeholderValues);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getInstance(string $culture)
|
public static function getInstance(string $culture)
|
||||||
@@ -40,11 +106,15 @@ class LocalizationService
|
|||||||
return self::$instanceMap[$culture];
|
return self::$instanceMap[$culture];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $Pot;
|
protected function getDatabaseService()
|
||||||
protected $PotMain;
|
{
|
||||||
protected $Po;
|
return DatabaseService::getInstance();
|
||||||
protected $PoUserStrings;
|
}
|
||||||
protected $Translator;
|
|
||||||
|
protected function getdatabase()
|
||||||
|
{
|
||||||
|
return $this->getDatabaseService()->GetDbConnection();
|
||||||
|
}
|
||||||
|
|
||||||
private function LoadLocalizations()
|
private function LoadLocalizations()
|
||||||
{
|
{
|
||||||
@@ -63,45 +133,53 @@ class LocalizationService
|
|||||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/permissions.pot'));
|
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/permissions.pot'));
|
||||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/locales.pot'));
|
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/locales.pot'));
|
||||||
|
|
||||||
|
|
||||||
if (GROCY_MODE !== 'production')
|
if (GROCY_MODE !== 'production')
|
||||||
{
|
{
|
||||||
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/demo_data.pot'));
|
$this->Pot = $this->Pot->mergeWith(Translations::fromPoFile(__DIR__ . '/../localization/demo_data.pot'));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->PoUserStrings = new Translations();
|
$this->PoUserStrings = new Translations();
|
||||||
$this->PoUserStrings->setDomain('grocy/userstrings');
|
$this->PoUserStrings->setDomain('grocy/userstrings');
|
||||||
|
|
||||||
$this->Po = Translations::fromPoFile(__DIR__ . "/../localization/$culture/strings.po");
|
$this->Po = Translations::fromPoFile(__DIR__ . "/../localization/$culture/strings.po");
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/chore_assignment_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/chore_assignment_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_assignment_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_assignment_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/component_translations.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/component_translations.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/component_translations.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/component_translations.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/stock_transaction_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/stock_transaction_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/stock_transaction_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/stock_transaction_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/chore_period_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/chore_period_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_period_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/chore_period_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/userfield_types.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/userfield_types.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/userfield_types.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/userfield_types.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/permissions.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/permissions.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/permissions.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/permissions.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists(__DIR__ . "/../localization/$culture/locales.po"))
|
if (file_exists(__DIR__ . "/../localization/$culture/locales.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/locales.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/locales.po"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GROCY_MODE !== 'production' && file_exists(__DIR__ . "/../localization/$culture/demo_data.po"))
|
if (GROCY_MODE !== 'production' && file_exists(__DIR__ . "/../localization/$culture/demo_data.po"))
|
||||||
{
|
{
|
||||||
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/demo_data.po"));
|
$this->Po = $this->Po->mergeWith(Translations::fromPoFile(__DIR__ . "/../localization/$culture/demo_data.po"));
|
||||||
@@ -128,6 +206,7 @@ class LocalizationService
|
|||||||
|
|
||||||
$this->PoUserStrings[] = $translation;
|
$this->PoUserStrings[] = $translation;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Po = $this->Po->mergeWith($this->PoUserStrings);
|
$this->Po = $this->Po->mergeWith($this->PoUserStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,66 +214,4 @@ class LocalizationService
|
|||||||
$this->Translator->loadTranslations($this->Po);
|
$this->Translator->loadTranslations($this->Po);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetPoAsJsonString()
|
|
||||||
{
|
|
||||||
return $this->Po->toJsonString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetPluralCount()
|
|
||||||
{
|
|
||||||
if ($this->Po->getHeader(Translations::HEADER_PLURAL) !== null)
|
|
||||||
{
|
|
||||||
return $this->Po->getPluralForms()[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetPluralDefinition()
|
|
||||||
{
|
|
||||||
if ($this->Po->getHeader(Translations::HEADER_PLURAL) !== null)
|
|
||||||
{
|
|
||||||
return $this->Po->getPluralForms()[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return '(n != 1)';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __t($text, ...$placeholderValues)
|
|
||||||
{
|
|
||||||
$this->CheckAndAddMissingTranslationToPot($text);
|
|
||||||
|
|
||||||
if (func_num_args() === 1)
|
|
||||||
{
|
|
||||||
return $this->Translator->gettext($text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return vsprintf($this->Translator->gettext($text), ...$placeholderValues);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __n($number, $singularForm, $pluralForm)
|
|
||||||
{
|
|
||||||
$this->CheckAndAddMissingTranslationToPot($singularForm);
|
|
||||||
|
|
||||||
return sprintf($this->Translator->ngettext($singularForm, $pluralForm, $number), $number);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function CheckAndAddMissingTranslationToPot($text)
|
|
||||||
{
|
|
||||||
if (GROCY_MODE === 'dev')
|
|
||||||
{
|
|
||||||
if ($this->Pot->find('', $text) === false && $this->PoUserStrings->find('', $text) === false && empty($text) === false)
|
|
||||||
{
|
|
||||||
$translation = new Translation('', $text);
|
|
||||||
$this->PotMain[] = $translation;
|
|
||||||
$this->PotMain->toPoFile(__DIR__ . '/../localization/strings.pot');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -6,13 +6,74 @@ namespace Grocy\Services;
|
|||||||
|
|
||||||
class RecipesService extends BaseService
|
class RecipesService extends BaseService
|
||||||
{
|
{
|
||||||
const RECIPE_TYPE_NORMAL = 'normal';
|
|
||||||
const RECIPE_TYPE_MEALPLAN_DAY = 'mealplan-day';
|
const RECIPE_TYPE_MEALPLAN_DAY = 'mealplan-day';
|
||||||
|
|
||||||
const RECIPE_TYPE_MEALPLAN_WEEK = 'mealplan-week';
|
const RECIPE_TYPE_MEALPLAN_WEEK = 'mealplan-week';
|
||||||
|
|
||||||
public function __construct()
|
const RECIPE_TYPE_NORMAL = 'normal';
|
||||||
|
|
||||||
|
public function AddNotFulfilledProductsToShoppingList($recipeId, $excludedProductIds = null)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
$recipe = $this->getDataBase()->recipes($recipeId);
|
||||||
|
|
||||||
|
$recipePositions = $this->GetRecipesPosResolved();
|
||||||
|
|
||||||
|
foreach ($recipePositions as $recipePosition)
|
||||||
|
{
|
||||||
|
if ($recipePosition->recipe_id == $recipeId && !in_array($recipePosition->product_id, $excludedProductIds))
|
||||||
|
{
|
||||||
|
$product = $this->getDataBase()->products($recipePosition->product_id);
|
||||||
|
|
||||||
|
$toOrderAmount = round(($recipePosition->missing_amount - $recipePosition->amount_on_shopping_list) / $product->qu_factor_purchase_to_stock, 2);
|
||||||
|
|
||||||
|
if ($recipe->not_check_shoppinglist == 1)
|
||||||
|
{
|
||||||
|
$toOrderAmount = round($recipePosition->missing_amount / $product->qu_factor_purchase_to_stock, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($toOrderAmount > 0)
|
||||||
|
{
|
||||||
|
$shoppinglistRow = $this->getDataBase()->shopping_list()->createRow([
|
||||||
|
'product_id' => $recipePosition->product_id,
|
||||||
|
'amount' => $toOrderAmount,
|
||||||
|
'note' => $this->getLocalizationService()->__t('Added for recipe %s', $recipe->name)
|
||||||
|
]);
|
||||||
|
$shoppinglistRow->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ConsumeRecipe($recipeId)
|
||||||
|
{
|
||||||
|
if (!$this->RecipeExists($recipeId))
|
||||||
|
{
|
||||||
|
throw new \Exception('Recipe does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$transactionId = uniqid();
|
||||||
|
$recipePositions = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id', $recipeId)->fetchAll();
|
||||||
|
|
||||||
|
foreach ($recipePositions as $recipePosition)
|
||||||
|
{
|
||||||
|
if ($recipePosition->only_check_single_unit_in_stock == 0)
|
||||||
|
{
|
||||||
|
$this->getStockService()->ConsumeProduct($recipePosition->product_id, $recipePosition->recipe_amount, false, StockService::TRANSACTION_TYPE_CONSUME, 'default', $recipeId, null, $transactionId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$recipeRow = $this->getDatabase()->recipes()->where('id = :1', $recipeId)->fetch();
|
||||||
|
|
||||||
|
if (!empty($recipeRow->product_id))
|
||||||
|
{
|
||||||
|
$recipeResolvedRow = $this->getDatabase()->recipes_resolved()->where('recipe_id = :1', $recipeId)->fetch();
|
||||||
|
$this->getStockService()->AddProduct($recipeRow->product_id, floatval($recipeRow->desired_servings), null, StockService::TRANSACTION_TYPE_SELF_PRODUCTION, date('Y-m-d'), floatval($recipeResolvedRow->costs));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetRecipesPosResolved()
|
public function GetRecipesPosResolved()
|
||||||
@@ -27,59 +88,9 @@ class RecipesService extends BaseService
|
|||||||
return $this->getDataBaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
return $this->getDataBaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function AddNotFulfilledProductsToShoppingList($recipeId, $excludedProductIds = null)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$recipe = $this->getDataBase()->recipes($recipeId);
|
parent::__construct();
|
||||||
|
|
||||||
$recipePositions = $this->GetRecipesPosResolved();
|
|
||||||
foreach ($recipePositions as $recipePosition)
|
|
||||||
{
|
|
||||||
if($recipePosition->recipe_id == $recipeId && !in_array($recipePosition->product_id, $excludedProductIds))
|
|
||||||
{
|
|
||||||
$product = $this->getDataBase()->products($recipePosition->product_id);
|
|
||||||
|
|
||||||
$toOrderAmount = round(($recipePosition->missing_amount - $recipePosition->amount_on_shopping_list) / $product->qu_factor_purchase_to_stock, 2);
|
|
||||||
if ($recipe->not_check_shoppinglist == 1)
|
|
||||||
{
|
|
||||||
$toOrderAmount = round($recipePosition->missing_amount / $product->qu_factor_purchase_to_stock, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($toOrderAmount > 0)
|
|
||||||
{
|
|
||||||
$shoppinglistRow = $this->getDataBase()->shopping_list()->createRow(array(
|
|
||||||
'product_id' => $recipePosition->product_id,
|
|
||||||
'amount' => $toOrderAmount,
|
|
||||||
'note' => $this->getLocalizationService()->__t('Added for recipe %s', $recipe->name)
|
|
||||||
));
|
|
||||||
$shoppinglistRow->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function ConsumeRecipe($recipeId)
|
|
||||||
{
|
|
||||||
if (!$this->RecipeExists($recipeId))
|
|
||||||
{
|
|
||||||
throw new \Exception('Recipe does not exist');
|
|
||||||
}
|
|
||||||
|
|
||||||
$transactionId = uniqid();
|
|
||||||
$recipePositions = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id', $recipeId)->fetchAll();
|
|
||||||
foreach ($recipePositions as $recipePosition)
|
|
||||||
{
|
|
||||||
if ($recipePosition->only_check_single_unit_in_stock == 0)
|
|
||||||
{
|
|
||||||
$this->getStockService()->ConsumeProduct($recipePosition->product_id, $recipePosition->recipe_amount, false, StockService::TRANSACTION_TYPE_CONSUME, 'default', $recipeId, null, $transactionId, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$recipeRow = $this->getDatabase()->recipes()->where('id = :1', $recipeId)->fetch();
|
|
||||||
if (!empty($recipeRow->product_id))
|
|
||||||
{
|
|
||||||
$recipeResolvedRow = $this->getDatabase()->recipes_resolved()->where('recipe_id = :1', $recipeId)->fetch();
|
|
||||||
$this->getStockService()->AddProduct($recipeRow->product_id, floatval($recipeRow->desired_servings), null, StockService::TRANSACTION_TYPE_SELF_PRODUCTION, date('Y-m-d'), floatval($recipeResolvedRow->costs));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function RecipeExists($recipeId)
|
private function RecipeExists($recipeId)
|
||||||
@@ -87,4 +98,5 @@ class RecipesService extends BaseService
|
|||||||
$recipeRow = $this->getDataBase()->recipes()->where('id = :1', $recipeId)->fetch();
|
$recipeRow = $this->getDataBase()->recipes()->where('id = :1', $recipeId)->fetch();
|
||||||
return $recipeRow !== null;
|
return $recipeRow !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,47 @@ namespace Grocy\Services;
|
|||||||
|
|
||||||
class SessionService extends BaseService
|
class SessionService extends BaseService
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
if ($stayLoggedInPermanently === true)
|
||||||
|
{
|
||||||
|
$expires = date('Y-m-d H:i:s', PHP_INT_SIZE == 4 ? PHP_INT_MAX : PHP_INT_MAX >> 32); // Never
|
||||||
|
}
|
||||||
|
|
||||||
|
$sessionRow = $this->getDatabase()->sessions()->createRow([
|
||||||
|
'user_id' => $userId,
|
||||||
|
'session_key' => $newSessionKey,
|
||||||
|
'expires' => $expires
|
||||||
|
]);
|
||||||
|
$sessionRow->save();
|
||||||
|
|
||||||
|
return $newSessionKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetDefaultUser()
|
||||||
|
{
|
||||||
|
return $this->getDatabase()->users(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetUserBySessionKey($sessionKey)
|
||||||
|
{
|
||||||
|
$sessionRow = $this->getDatabase()->sessions()->where('session_key', $sessionKey)->fetch();
|
||||||
|
|
||||||
|
if ($sessionRow !== null)
|
||||||
|
{
|
||||||
|
return $this->getDatabase()->users($sessionRow->user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return boolean
|
* @return boolean
|
||||||
@@ -17,14 +58,15 @@ class SessionService extends BaseService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
$sessionRow = $this->getDatabase()->sessions()->where('session_key = :1 AND expires > :2', $sessionKey, date('Y-m-d H:i:s', time()))->fetch();
|
$sessionRow = $this->getDatabase()->sessions()->where('session_key = :1 AND expires > :2', $sessionKey, date('Y-m-d H:i:s', time()))->fetch();
|
||||||
|
|
||||||
if ($sessionRow !== null)
|
if ($sessionRow !== null)
|
||||||
{
|
{
|
||||||
// This should not change the database file modification time as this is used
|
// This should not change the database file modification time as this is used
|
||||||
// to determine if REALLY something has changed
|
// to determine if REALLY something has changed
|
||||||
$dbModTime = $this->getDatabaseService()->GetDbChangedTime();
|
$dbModTime = $this->getDatabaseService()->GetDbChangedTime();
|
||||||
$sessionRow->update(array(
|
$sessionRow->update([
|
||||||
'last_used' => date('Y-m-d H:i:s', time())
|
'last_used' => date('Y-m-d H:i:s', time())
|
||||||
));
|
]);
|
||||||
$this->getDatabaseService()->SetDbChangedTime($dbModTime);
|
$this->getDatabaseService()->SetDbChangedTime($dbModTime);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -33,30 +75,9 @@ class SessionService extends BaseService
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
if ($stayLoggedInPermanently === true)
|
|
||||||
{
|
|
||||||
$expires = date('Y-m-d H:i:s', PHP_INT_SIZE == 4 ? PHP_INT_MAX : PHP_INT_MAX>>32); // Never
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sessionRow = $this->getDatabase()->sessions()->createRow(array(
|
|
||||||
'user_id' => $userId,
|
|
||||||
'session_key' => $newSessionKey,
|
|
||||||
'expires' => $expires
|
|
||||||
));
|
|
||||||
$sessionRow->save();
|
|
||||||
|
|
||||||
return $newSessionKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function RemoveSession($sessionKey)
|
public function RemoveSession($sessionKey)
|
||||||
@@ -64,23 +85,9 @@ class SessionService extends BaseService
|
|||||||
$this->getDatabase()->sessions()->where('session_key', $sessionKey)->delete();
|
$this->getDatabase()->sessions()->where('session_key', $sessionKey)->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetUserBySessionKey($sessionKey)
|
|
||||||
{
|
|
||||||
$sessionRow = $this->getDatabase()->sessions()->where('session_key', $sessionKey)->fetch();
|
|
||||||
if ($sessionRow !== null)
|
|
||||||
{
|
|
||||||
return $this->getDatabase()->users($sessionRow->user_id);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetDefaultUser()
|
|
||||||
{
|
|
||||||
return $this->getDatabase()->users(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function GenerateSessionKey()
|
private function GenerateSessionKey()
|
||||||
{
|
{
|
||||||
return RandomString(50);
|
return RandomString(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -18,10 +18,10 @@ class TasksService extends BaseService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$taskRow = $this->getDatabase()->tasks()->where('id = :1', $taskId)->fetch();
|
$taskRow = $this->getDatabase()->tasks()->where('id = :1', $taskId)->fetch();
|
||||||
$taskRow->update(array(
|
$taskRow->update([
|
||||||
'done' => 1,
|
'done' => 1,
|
||||||
'done_timestamp' => $doneTime
|
'done_timestamp' => $doneTime
|
||||||
));
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -34,10 +34,10 @@ class TasksService extends BaseService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$taskRow = $this->getDatabase()->tasks()->where('id = :1', $taskId)->fetch();
|
$taskRow = $this->getDatabase()->tasks()->where('id = :1', $taskId)->fetch();
|
||||||
$taskRow->update(array(
|
$taskRow->update([
|
||||||
'done' => 0,
|
'done' => 0,
|
||||||
'done_timestamp' => null
|
'done_timestamp' => null
|
||||||
));
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -47,4 +47,5 @@ class TasksService extends BaseService
|
|||||||
$taskRow = $this->getDatabase()->tasks()->where('id = :1', $taskId)->fetch();
|
$taskRow = $this->getDatabase()->tasks()->where('id = :1', $taskId)->fetch();
|
||||||
return $taskRow !== null;
|
return $taskRow !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,33 +4,69 @@ namespace Grocy\Services;
|
|||||||
|
|
||||||
class UserfieldsService extends BaseService
|
class UserfieldsService extends BaseService
|
||||||
{
|
{
|
||||||
const USERFIELD_TYPE_SINGLE_LINE_TEXT = 'text-single-line';
|
|
||||||
const USERFIELD_TYPE_SINGLE_MULTILINE_TEXT = 'text-multi-line';
|
|
||||||
const USERFIELD_TYPE_INTEGRAL_NUMBER = 'number-integral';
|
|
||||||
const USERFIELD_TYPE_DECIMAL_NUMBER = 'number-decimal';
|
|
||||||
const USERFIELD_TYPE_DATE = 'date';
|
|
||||||
const USERFIELD_TYPE_DATETIME = 'datetime';
|
|
||||||
const USERFIELD_TYPE_CHECKBOX = 'checkbox';
|
const USERFIELD_TYPE_CHECKBOX = 'checkbox';
|
||||||
const USERFIELD_TYPE_PRESET_LIST = 'preset-list';
|
|
||||||
const USERFIELD_TYPE_PRESET_CHECKLIST = 'preset-checklist';
|
|
||||||
const USERFIELD_TYPE_LINK = 'link';
|
|
||||||
const USERFIELD_TYPE_FILE = 'file';
|
|
||||||
const USERFIELD_TYPE_IMAGE = 'image';
|
|
||||||
|
|
||||||
public function __construct()
|
const USERFIELD_TYPE_DATE = 'date';
|
||||||
{
|
|
||||||
parent::__construct();
|
const USERFIELD_TYPE_DATETIME = 'datetime';
|
||||||
}
|
|
||||||
|
const USERFIELD_TYPE_DECIMAL_NUMBER = 'number-decimal';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_FILE = 'file';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_IMAGE = 'image';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_INTEGRAL_NUMBER = 'number-integral';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_LINK = 'link';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_PRESET_CHECKLIST = 'preset-checklist';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_PRESET_LIST = 'preset-list';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_SINGLE_LINE_TEXT = 'text-single-line';
|
||||||
|
|
||||||
|
const USERFIELD_TYPE_SINGLE_MULTILINE_TEXT = 'text-multi-line';
|
||||||
|
|
||||||
protected $OpenApiSpec = null;
|
protected $OpenApiSpec = null;
|
||||||
|
|
||||||
protected function getOpenApispec()
|
public function GetAllFields()
|
||||||
{
|
{
|
||||||
if($this->OpenApiSpec == null)
|
return $this->getDatabase()->userfields()->orderBy('name')->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAllValues($entity)
|
||||||
|
{
|
||||||
|
if (!$this->IsValidEntity($entity))
|
||||||
{
|
{
|
||||||
$this->OpenApiSpec = json_decode(file_get_contents(__DIR__ . '/../grocy.openapi.json'));
|
throw new \Exception('Entity does not exist or is not exposed');
|
||||||
}
|
}
|
||||||
return $this->OpenApiSpec;
|
|
||||||
|
return $this->getDatabase()->userfield_values_resolved()->where('entity', $entity)->orderBy('name')->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetEntities()
|
||||||
|
{
|
||||||
|
$exposedDefaultEntities = $this->getOpenApiSpec()->components->internalSchemas->ExposedEntity->enum;
|
||||||
|
|
||||||
|
$userentities = [];
|
||||||
|
|
||||||
|
foreach ($this->getDatabase()->userentities()->orderBy('name') as $userentity)
|
||||||
|
{
|
||||||
|
$userentities[] = 'userentity-' . $userentity->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_merge($exposedDefaultEntities, $userentities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetField($fieldId)
|
||||||
|
{
|
||||||
|
return $this->getDatabase()->userfields($fieldId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetFieldTypes()
|
||||||
|
{
|
||||||
|
return GetClassConstants('\Grocy\Services\UserfieldsService');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFields($entity)
|
public function GetFields($entity)
|
||||||
@@ -43,16 +79,6 @@ class UserfieldsService extends BaseService
|
|||||||
return $this->getDatabase()->userfields()->where('entity', $entity)->orderBy('name')->fetchAll();
|
return $this->getDatabase()->userfields()->where('entity', $entity)->orderBy('name')->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetField($fieldId)
|
|
||||||
{
|
|
||||||
return $this->getDatabase()->userfields($fieldId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetAllFields()
|
|
||||||
{
|
|
||||||
return $this->getDatabase()->userfields()->orderBy('name')->fetchAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetValues($entity, $objectId)
|
public function GetValues($entity, $objectId)
|
||||||
{
|
{
|
||||||
if (!$this->IsValidEntity($entity))
|
if (!$this->IsValidEntity($entity))
|
||||||
@@ -61,7 +87,8 @@ class UserfieldsService extends BaseService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$userfields = $this->getDatabase()->userfield_values_resolved()->where('entity = :1 AND object_id = :2', $entity, $objectId)->orderBy('name')->fetchAll();
|
$userfields = $this->getDatabase()->userfield_values_resolved()->where('entity = :1 AND object_id = :2', $entity, $objectId)->orderBy('name')->fetchAll();
|
||||||
$userfieldKeyValuePairs = array();
|
$userfieldKeyValuePairs = [];
|
||||||
|
|
||||||
foreach ($userfields as $userfield)
|
foreach ($userfields as $userfield)
|
||||||
{
|
{
|
||||||
$userfieldKeyValuePairs[$userfield->name] = $userfield->value;
|
$userfieldKeyValuePairs[$userfield->name] = $userfield->value;
|
||||||
@@ -70,16 +97,6 @@ class UserfieldsService extends BaseService
|
|||||||
return $userfieldKeyValuePairs;
|
return $userfieldKeyValuePairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetAllValues($entity)
|
|
||||||
{
|
|
||||||
if (!$this->IsValidEntity($entity))
|
|
||||||
{
|
|
||||||
throw new \Exception('Entity does not exist or is not exposed');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getDatabase()->userfield_values_resolved()->where('entity', $entity)->orderBy('name')->fetchAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function SetValues($entity, $objectId, $userfields)
|
public function SetValues($entity, $objectId, $userfields)
|
||||||
{
|
{
|
||||||
if (!$this->IsValidEntity($entity))
|
if (!$this->IsValidEntity($entity))
|
||||||
@@ -99,44 +116,45 @@ class UserfieldsService extends BaseService
|
|||||||
$fieldId = $fieldRow->id;
|
$fieldId = $fieldRow->id;
|
||||||
|
|
||||||
$alreadyExistingEntry = $this->getDatabase()->userfield_values()->where('field_id = :1 AND object_id = :2', $fieldId, $objectId)->fetch();
|
$alreadyExistingEntry = $this->getDatabase()->userfield_values()->where('field_id = :1 AND object_id = :2', $fieldId, $objectId)->fetch();
|
||||||
|
|
||||||
if ($alreadyExistingEntry) // Update
|
if ($alreadyExistingEntry) // Update
|
||||||
{
|
{
|
||||||
$alreadyExistingEntry->update(array(
|
$alreadyExistingEntry->update([
|
||||||
'value' => $value
|
'value' => $value
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
else // Insert
|
else // Insert
|
||||||
{
|
{
|
||||||
$newRow = $this->getDatabase()->userfield_values()->createRow(array(
|
$newRow = $this->getDatabase()->userfield_values()->createRow([
|
||||||
'field_id' => $fieldId,
|
'field_id' => $fieldId,
|
||||||
'object_id' => $objectId,
|
'object_id' => $objectId,
|
||||||
'value' => $value
|
'value' => $value
|
||||||
));
|
]);
|
||||||
$newRow->save();
|
$newRow->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetEntities()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$exposedDefaultEntities = $this->getOpenApiSpec()->components->internalSchemas->ExposedEntity->enum;
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
$userentities = array();
|
protected function getOpenApispec()
|
||||||
foreach ($this->getDatabase()->userentities()->orderBy('name') as $userentity)
|
{
|
||||||
|
if ($this->OpenApiSpec == null)
|
||||||
{
|
{
|
||||||
$userentities[] = 'userentity-' . $userentity->name;
|
$this->OpenApiSpec = json_decode(file_get_contents(__DIR__ . '/../grocy.openapi.json'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_merge($exposedDefaultEntities, $userentities);
|
return $this->OpenApiSpec;
|
||||||
}
|
|
||||||
|
|
||||||
public function GetFieldTypes()
|
|
||||||
{
|
|
||||||
return GetClassConstants('\Grocy\Services\UserfieldsService');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function IsValidEntity($entity)
|
private function IsValidEntity($entity)
|
||||||
{
|
{
|
||||||
return in_array($entity, $this->GetEntities());
|
return in_array($entity, $this->GetEntities());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,25 +6,34 @@ class UsersService extends BaseService
|
|||||||
{
|
{
|
||||||
public function CreateUser(string $username, string $firstName, string $lastName, string $password)
|
public function CreateUser(string $username, string $firstName, string $lastName, string $password)
|
||||||
{
|
{
|
||||||
$newUserRow = $this->getDatabase()->users()->createRow(array(
|
$newUserRow = $this->getDatabase()->users()->createRow([
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'first_name' => $firstName,
|
'first_name' => $firstName,
|
||||||
'last_name' => $lastName,
|
'last_name' => $lastName,
|
||||||
'password' => password_hash($password, PASSWORD_DEFAULT)
|
'password' => password_hash($password, PASSWORD_DEFAULT)
|
||||||
));
|
]);
|
||||||
$newUserRow = $newUserRow->save();
|
$newUserRow = $newUserRow->save();
|
||||||
$permList = array();
|
$permList = [];
|
||||||
foreach ($this->getDatabase()->permission_hierarchy()->where('name', GROCY_DEFAULT_PERMISSIONS)->fetchAll() as $perm) {
|
|
||||||
$permList[] = array(
|
foreach ($this->getDatabase()->permission_hierarchy()->where('name', GROCY_DEFAULT_PERMISSIONS)->fetchAll() as $perm)
|
||||||
|
{
|
||||||
|
$permList[] = [
|
||||||
'user_id' => $newUserRow->id,
|
'user_id' => $newUserRow->id,
|
||||||
'permission_id' => $perm->id
|
'permission_id' => $perm->id
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->getDatabase()->user_permissions()->insert($permList);
|
$this->getDatabase()->user_permissions()->insert($permList);
|
||||||
|
|
||||||
return $newUserRow;
|
return $newUserRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function DeleteUser($userId)
|
||||||
|
{
|
||||||
|
$row = $this->getDatabase()->users($userId);
|
||||||
|
$row->delete();
|
||||||
|
}
|
||||||
|
|
||||||
public function EditUser(int $userId, string $username, string $firstName, string $lastName, string $password)
|
public function EditUser(int $userId, string $username, string $firstName, string $lastName, string $password)
|
||||||
{
|
{
|
||||||
if (!$this->UserExists($userId))
|
if (!$this->UserExists($userId))
|
||||||
@@ -33,36 +42,18 @@ class UsersService extends BaseService
|
|||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->getDatabase()->users($userId);
|
$user = $this->getDatabase()->users($userId);
|
||||||
$user->update(array(
|
$user->update([
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'first_name' => $firstName,
|
'first_name' => $firstName,
|
||||||
'last_name' => $lastName,
|
'last_name' => $lastName,
|
||||||
'password' => password_hash($password, PASSWORD_DEFAULT)
|
'password' => password_hash($password, PASSWORD_DEFAULT)
|
||||||
));
|
]);
|
||||||
}
|
|
||||||
|
|
||||||
public function DeleteUser($userId)
|
|
||||||
{
|
|
||||||
$row = $this->getDatabase()->users($userId);
|
|
||||||
$row->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function GetUsersAsDto()
|
|
||||||
{
|
|
||||||
$users = $this->getDatabase()->users();
|
|
||||||
$returnUsers = array();
|
|
||||||
foreach ($users as $user)
|
|
||||||
{
|
|
||||||
unset($user->password);
|
|
||||||
$user->display_name = GetUserDisplayName($user);
|
|
||||||
$returnUsers[] = $user;
|
|
||||||
}
|
|
||||||
return $returnUsers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetUserSetting($userId, $settingKey)
|
public function GetUserSetting($userId, $settingKey)
|
||||||
{
|
{
|
||||||
$settingRow = $this->getDatabase()->user_settings()->where('user_id = :1 AND key = :2', $userId, $settingKey)->fetch();
|
$settingRow = $this->getDatabase()->user_settings()->where('user_id = :1 AND key = :2', $userId, $settingKey)->fetch();
|
||||||
|
|
||||||
if ($settingRow !== null)
|
if ($settingRow !== null)
|
||||||
{
|
{
|
||||||
return $settingRow->value;
|
return $settingRow->value;
|
||||||
@@ -71,13 +62,15 @@ class UsersService extends BaseService
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetUserSettings($userId)
|
public function GetUserSettings($userId)
|
||||||
{
|
{
|
||||||
$settings = array();
|
$settings = [];
|
||||||
|
|
||||||
$settingRows = $this->getDatabase()->user_settings()->where('user_id = :1', $userId)->fetchAll();
|
$settingRows = $this->getDatabase()->user_settings()->where('user_id = :1', $userId)->fetchAll();
|
||||||
|
|
||||||
foreach ($settingRows as $settingRow)
|
foreach ($settingRows as $settingRow)
|
||||||
{
|
{
|
||||||
$settings[$settingRow->key] = $settingRow->value;
|
$settings[$settingRow->key] = $settingRow->value;
|
||||||
@@ -88,25 +81,42 @@ class UsersService extends BaseService
|
|||||||
return array_merge($GROCY_DEFAULT_USER_SETTINGS, $settings);
|
return array_merge($GROCY_DEFAULT_USER_SETTINGS, $settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetUsersAsDto()
|
||||||
|
{
|
||||||
|
$users = $this->getDatabase()->users();
|
||||||
|
$returnUsers = [];
|
||||||
|
|
||||||
|
foreach ($users as $user)
|
||||||
|
{
|
||||||
|
unset($user->password);
|
||||||
|
$user->display_name = GetUserDisplayName($user);
|
||||||
|
$returnUsers[] = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnUsers;
|
||||||
|
}
|
||||||
|
|
||||||
public function SetUserSetting($userId, $settingKey, $settingValue)
|
public function SetUserSetting($userId, $settingKey, $settingValue)
|
||||||
{
|
{
|
||||||
$settingRow = $this->getDatabase()->user_settings()->where('user_id = :1 AND key = :2', $userId, $settingKey)->fetch();
|
$settingRow = $this->getDatabase()->user_settings()->where('user_id = :1 AND key = :2', $userId, $settingKey)->fetch();
|
||||||
|
|
||||||
if ($settingRow !== null)
|
if ($settingRow !== null)
|
||||||
{
|
{
|
||||||
$settingRow->update(array(
|
$settingRow->update([
|
||||||
'value' => $settingValue,
|
'value' => $settingValue,
|
||||||
'row_updated_timestamp' => date('Y-m-d H:i:s')
|
'row_updated_timestamp' => date('Y-m-d H:i:s')
|
||||||
));
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$settingRow = $this->getDatabase()->user_settings()->createRow(array(
|
$settingRow = $this->getDatabase()->user_settings()->createRow([
|
||||||
'user_id' => $userId,
|
'user_id' => $userId,
|
||||||
'key' => $settingKey,
|
'key' => $settingKey,
|
||||||
'value' => $settingValue
|
'value' => $settingValue
|
||||||
));
|
]);
|
||||||
$settingRow->save();
|
$settingRow->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function UserExists($userId)
|
private function UserExists($userId)
|
||||||
@@ -114,4 +124,5 @@ class UsersService extends BaseService
|
|||||||
$userRow = $this->getDatabase()->users()->where('id = :1', $userId)->fetch();
|
$userRow = $this->getDatabase()->users()->where('id = :1', $userId)->fetch();
|
||||||
return $userRow !== null;
|
return $userRow !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user