Skip to content

Add a helper class to manage the user folders #1007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 19, 2022
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@
".github/actions/run-tests/volumes/nextcloud/3rdparty/**",
".github/actions/run-tests/volumes/**",
".github/actions/run-tests/volumes"
],
"intelephense.references.exclude": [
"**/vendor/**",
".github/actions/run-tests/volumes/**"
]
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
### Added
- Create service class for downloading and extracting JSON
[#553](https://github.com./nextcloud/cookbook/pull/553) @christianlupus

### Changed
- Extracted user folder handling into its own helper class
[#1007](https://github.com./nextcloud/cookbook/pull/1007) @christianlupus

### Fixed
- Fix visual regression in edit mode to prevent overflow of breadcrumbs
Expand Down
20 changes: 17 additions & 3 deletions lib/Controller/ConfigController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use OCA\Cookbook\Service\RecipeService;
use OCA\Cookbook\Service\DbCacheService;
use OCA\Cookbook\Helper\RestParameterParser;
use OCA\Cookbook\Helper\UserFolderHelper;

class ConfigController extends Controller {
/**
Expand All @@ -27,12 +28,25 @@ class ConfigController extends Controller {
*/
private $restParser;

public function __construct($AppName, IRequest $request, RecipeService $recipeService, DbCacheService $dbCacheService, RestParameterParser $restParser) {
/**
* @var UserFolderHelper
*/
private $userFolder;

public function __construct(
$AppName,
IRequest $request,
RecipeService $recipeService,
DbCacheService $dbCacheService,
RestParameterParser $restParser,
UserFolderHelper $userFolder
) {
parent::__construct($AppName, $request);

$this->service = $recipeService;
$this->dbCacheService = $dbCacheService;
$this->restParser = $restParser;
$this->userFolder = $userFolder;
}

/**
Expand All @@ -43,7 +57,7 @@ public function list() {
$this->dbCacheService->triggerCheck();

return new DataResponse([
'folder' => $this->service->getUserFolderPath(),
'folder' => $this->userFolder->getPath(),
'update_interval' => $this->dbCacheService->getSearchIndexUpdateInterval(),
'print_image' => $this->service->getPrintImage(),
], Http::STATUS_OK);
Expand All @@ -57,7 +71,7 @@ public function config() {
$data = $this->restParser->getParameters();

if (isset($data['folder'])) {
$this->service->setUserFolderPath($data['folder']);
$this->userFolder->setPath($data['folder']);
$this->dbCacheService->updateCache();
}

Expand Down
19 changes: 17 additions & 2 deletions lib/Controller/MainController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use OCA\Cookbook\Exception\UserFolderNotWritableException;
use OCA\Cookbook\Exception\RecipeExistsException;
use OCA\Cookbook\Exception\UserNotLoggedInException;
use OCA\Cookbook\Helper\UserFolderHelper;
use OCP\AppFramework\Http\JSONResponse;

class MainController extends Controller {
Expand All @@ -38,14 +39,28 @@ class MainController extends Controller {
*/
private $restParser;

public function __construct(string $AppName, IRequest $request, RecipeService $recipeService, DbCacheService $dbCacheService, IURLGenerator $urlGenerator, RestParameterParser $restParser) {
/**
* @var UserFolderHelper
*/
private $userFolder;

public function __construct(
string $AppName,
IRequest $request,
RecipeService $recipeService,
DbCacheService $dbCacheService,
IURLGenerator $urlGenerator,
RestParameterParser $restParser,
UserFolderHelper $userFolder
) {
parent::__construct($AppName, $request);

$this->service = $recipeService;
$this->urlGenerator = $urlGenerator;
$this->appName = $AppName;
$this->dbCacheService = $dbCacheService;
$this->restParser = $restParser;
$this->userFolder = $userFolder;
}

/**
Expand All @@ -58,7 +73,7 @@ public function __construct(string $AppName, IRequest $request, RecipeService $r
public function index(): TemplateResponse {
try {
// Check if the user folder can be accessed
$this->service->getFolderForUser();
$this->userFolder->getFolder();
} catch (UserFolderNotWritableException $ex) {
Util::addScript('cookbook', 'nextcloud-cookbook-guest');
return new TemplateResponse($this->appName, 'invalid_guest');
Expand Down
9 changes: 9 additions & 0 deletions lib/Exception/UserFolderNotValidException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace OCA\Cookbook\Exception;

class UserFolderNotValidException extends \Exception {
public function __construct($message = null, $code = null, $previous = null) {
parent::__construct($message, $code, $previous);
}
}
10 changes: 9 additions & 1 deletion lib/Helper/UserConfigHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserConfigHelper {
* @var IConfig
*/
private $config;

/**
* @var IL10N
*/
Expand Down Expand Up @@ -164,6 +164,10 @@ public function setPrintImage(bool $value): void {
*
* If no folder is stored in the config yet, a default setting will be generated and saved.
*
* **Note:**
* Do not use this method directly.
* Instead use the methods of the UserFolderHelper class
*
* @return string The name of the folder within the users files
* @throws UserNotLoggedInException if no user is logged in
*/
Expand All @@ -182,6 +186,10 @@ public function getFolderName(): string {
/**
* Set the folder for the user's cookbook.
*
* **Note:**
* Do not use this method directly.
* Instead use the methods of the UserFolderHelper class
*
* @param string $value The name of the folder within the user's files
* @return void
* @throws UserNotLoggedInException if no user is logged in
Expand Down
142 changes: 142 additions & 0 deletions lib/Helper/UserFolderHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

namespace OCA\Cookbook\Helper;

use OCP\IL10N;
use OCP\Files\Node;
use OCP\Files\Folder;
use OCP\Files\NotPermittedException;
use OCA\Cookbook\Exception\UserFolderNotValidException;
use OCA\Cookbook\Exception\UserFolderNotWritableException;
use OCA\Cookbook\Exception\UserNotLoggedInException;
use OCP\Files\FileInfo;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;

/**
* This class caches the access to the user folder throughout the app.
*
* The user folder is the path, were all recipes are stored.
*/
class UserFolderHelper {

/**
* @var UserConfigHelper
*/
private $config;

/**
* @var IL10N
*/
private $l;

/**
* @var ?string
*/
private $userId;

/**
* @var IRootFolder
*/
private $root;

/**
* The folder with all recipes or null if this is not yet cached
*
* @var ?Node
*/
private $cache;

public function __construct(
?string $UserId,
IRootFolder $root,
IL10N $l,
UserConfigHelper $configHelper
) {
$this->userId = $UserId;
$this->root = $root;
$this->l = $l;
$this->config = $configHelper;

$this->cache = null;
}

/**
* Set the current path in the settings relative to the user's root folder
*
* @param string $path The name of the path to be used for the recipes
* @return void
*/
public function setPath(string $path) {
$this->config->setFolderName($path);
$this->cache = null;
}

/**
* Get the path of the recipes relative to the user's root folder
*
* @return string The relative path name
* @throws UserNotLoggedInException If there is currently no logged in user
*/
public function getPath(): string {
$path = $this->config->getFolderName();

// TODO This was in the original code. Is it still needed?
// $path = str_replace('//', '/', $path);

return $path;
}

/**
* Get the current folder where all recipes are stored of the user
*
* @return Folder The folder containing all recipes
* @throws UserFolderNotValidException If the saved user folder is a file or could not be generated
* @throws UserNotLoggedInException If there is no logged-in user at that time
*/
public function getFolder(): Folder {
// Ensure the cache is built.
if (is_null($this->cache)) {
$path = $this->getPath();

// Correct path to be relative to nc root
$path = '/' . $this->userId . '/files/' . $path;
$path = str_replace('//', '/', $path);


$this->cache = $this->getOrCreateFolder($path);
}

return $this->cache;
}

private function getOrCreateFolder($path): Folder {
try {
$node = $this->root->get($path);
} catch (NotFoundException $ex) {
try {
$node = $this->root->newFolder($path);
} catch (NotPermittedException $ex1) {
throw new UserFolderNotValidException(
$this->l->t('The user folder cannot be created due to missing permissions.'),
null,
$ex1
);
}
}

if ($node->getType() !== FileInfo::TYPE_FOLDER) {
throw new UserFolderNotValidException(
$this->l->t('The configured user folder is a file.')
);
}

if (! $node->isCreatable()) {
throw new UserFolderNotWritableException(
$this->l->t('User cannot create recipe folder')
);
}

return $node;
}
}
Loading