From 9c6114cf8643a84a9536074942d2e7f1a8451cd0 Mon Sep 17 00:00:00 2001 From: jdg Date: Mon, 21 Mar 2022 19:16:06 +0000 Subject: [PATCH] Service to manage wiki almost ready --- lib/Controller/WikiController.php | 2 +- lib/Helper/WikiHelper.php | 206 +++++++++++++++++--- lib/Service/WikiService.php | 49 +++-- tests/Integration/MyWikiIntegrationTest.php | 6 - vendor/composer/installed.php | 4 +- 5 files changed, 208 insertions(+), 59 deletions(-) diff --git a/lib/Controller/WikiController.php b/lib/Controller/WikiController.php index 79fb3be..8876936 100644 --- a/lib/Controller/WikiController.php +++ b/lib/Controller/WikiController.php @@ -24,7 +24,7 @@ * @NoAdminRequired */ public function test() { - $x = $this->service->test($this->userId); + $x = $this->service->test(); return new DataResponse(print_r($x,true)); } diff --git a/lib/Helper/WikiHelper.php b/lib/Helper/WikiHelper.php index 87d09b9..9097074 100644 --- a/lib/Helper/WikiHelper.php +++ b/lib/Helper/WikiHelper.php @@ -1,34 +1,194 @@ getById($folderId); - if ( count($nodes)>0 ) { - return $nodes[0]->getType() == \OCP\Files\Node::TYPE_FOLDER; - } - return false; + private const WIKI_FILE = 'wiki.json'; + private const WIKI_FILE_CONTENT = 'Readme.md'; + private Folder $userFolder; + private ?Folder $wikiFolder; + + private function getWikiFolder(Folder $folder, int $folderId): ?Folder { + $nodes = $folder->getById($folderId); + return count($nodes)>0?$nodes[0]:null; } - public static function isWiki(IRootFolder $storage, int $folderId) :string { - $nodes = $storage->getById($folderId); - if ( count($nodes)>0 ) { - $nodeStorage = $nodes[0]->getStorage(); - return $nodeStorage->file_get_contents('/wiki.yaml'); - // getPath() - // getStorage() - } - return false; + private function getFolderById(int $id): Folder { + return $this->wikiFolder->getById($id)[0]; } - public static function initWiki(int $folderId, string $title) :bool { - // ToDo - // create file ".wiki" - // title: $title - // pages: + private function getFileById(int $id): File { + return $this->wikiFolder->getById($id)[0]; + } + private function getFileByName(string $name): File { + return $this->wikiFolder->get($name); + } + private function sanitize_file_name(string $nameFile): string { + return preg_replace("([^\w\s\d\-_~,;\[\]\(\)])", "", $nameFile); + } + private function scanFolder(Folder $folder, WikiTree $wikiTree, int $parentId=0) { + $nodes = $folder->getDirectoryListing(); + foreach($nodes as $node) { + if ($node->getType() == \OCP\Files\Node::TYPE_FOLDER) { + $wikiPage = new WikiTreePage(); + $wikiPage->id = $node->getId(); + $wikiPage->pid = $parentId; + $wikiPage->title = $node->getName(); + $wikiTree->set($wikiPage); + $this->scanFolder($node, $wikiTree, $wikiPage->id); + } + } + } + private function rebuildWikiTree(): array { + $wikiTree = new WikiTree(null); + $this->scanFolder($this->userFolder, $wikiTree); + return $wikiTree->getWikiPages(); + } + + + public function __construct(Folder $folder) { + $this->userFolder = $folder; + $this->wikiFolder = null; + } + + public function setFolderId(int $folderId): WikiHelper { + $this->wikiFolder = $this->getWikiFolder($this->userFolder, $folderId); + return $this; + } + + private function isWiki() :bool { + return $this->wikiFolder && $this->wikiFolder->getType() == \OCP\Files\Node::TYPE_FOLDER; + } + + public function reloadWikiTree(): array { + $wiki = $this->getWikiData(); + $wiki['pages'] = $this->rebuildWikiTree(); + $this->setWikiData($wiki); + return $wiki; + } + + public function getWikiData(): ?array { + try { + $data = $this->getFileByName(self::WIKI_FILE)->getContent(); + } catch(\OCP\Files\NotFoundException $ex) { + return null; + } + return json_decode($data, true); + } + + public function setWikiData(array $wiki): bool { + try { + $data = json_encode($wiki); + $path = $this->wikiFolder->getInternalPath().'/'.self::WIKI_FILE; + if ( $this->wikiFolder->nodeExists($path) ) { + $this->getFileByName(self::WIKI_FILE)->putContent($data); + } else { + $this->wikiFolder + ->newFile(self::WIKI_FILE, $data); + } + } catch(\Exception $ex) { + return false; + } return true; } - public static function removePage(int $folderId, bool $includeSubfolders) { - // ToDo :: Remove this folder and all subfolders + + public function initWiki(string $title) :bool { + $wiki = [ + "title"=>$title, + "folderId"=>$this->wikiFolder->getId(), + "pages"=>$this->rebuildWikiTree() + ]; + if ( $this->getWikiData() === null ) { + return $this->setWikiData($wiki); + } + return true; } + + public function add(int $parentId, string $title) { +// $folder = ...newFolder($path) + +$wikiData = $this->getWikiData(); +if ($wikiData) { + $wikiTree = new WikiTree($wikiData['pages']); + $wikiPage = new WikiTreePage(); + $wikiPage->id = $id; + $wikiPage->pid = $parentId; + $wikiPage->title = $title; + $wikiTree->set($wikiPage); + $wikiData['pages'] = $wikiTree->getWikiPages(); + $this->setWikiData($wikiData); +} + + } + + public function update(int $id, string $content) { + try { + $path = $this->wikiFolder->getInternalPath().'/'.self::WIKI_FILE_CONTENT; + if ( $this->wikiFolder->nodeExists($path) ) { + $this->getFileByName(self::WIKI_FILE_CONTENT)->putContent($content); + } else { + $this->wikiFolder + ->newFile(self::WIKI_FILE_CONTENT, $content); + } + } catch(\Exception $ex) { + return false; + } + return true; + } + + public function rename(int $id, string $title) { + try { + $folder = $this->getFolderById($id); + $to = $folder->getParent()->getFullPath($this->sanitize_file_name($title)); + try { + if ( !$folder->move($to) ) return false; + + $wikiData = $this->getWikiData(); + if ($wikiData) { + $wikiTree = new WikiTree($wikiData['pages']); + $wikiPage = $wikiTree->get($id); + if ($wikiPage) { + $wikiPage->title = $title; + $wikiTree->set($wikiPage); + $wikiData['pages'] = $wikiTree->getWikiPages(); + $this->setWikiData($wikiData); + } + } + + } catch(\OCP\Lock\LockedException $ex) { + return false; + } + } catch(\Exception $ex) { + return false; + } + return true; + } + + public function delete(int $id=null) { + if ($id!==null) { + $folder = $this->getFolderById($id); + + $wikiData = $this->getWikiData(); + if ($wikiData) { + $wikiTree = new WikiTree($wikiData['pages']); + $wikiTree->del($id); + $wikiData['pages'] = $wikiTree->getWikiPages(); + $this->setWikiData($wikiData); + } + + } else { + $folder = $this->wikiFolder; + } + try { + $folder->delete(); + } catch(\Exception $ex) { + return false; + } + return true; + } + } \ No newline at end of file diff --git a/lib/Service/WikiService.php b/lib/Service/WikiService.php index 7a23b1b..887b4c5 100644 --- a/lib/Service/WikiService.php +++ b/lib/Service/WikiService.php @@ -5,33 +5,35 @@ use Exception; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; - +use OCP\Files\IRootFolder; use OCA\MyWiki\Db\Wiki; use OCA\MyWiki\Db\WikiMapper; use OCA\MyWiki\Helper\WikiHelper; -use \OCP\Files\Storage; -use \OCP\Files\IRootFolder; - -use \OCP\IUserSession; - class WikiService { private $mapper; - private $storage; - private $userSession; + private $userId; + private $wikiHelper; - public function __construct(WikiMapper $mapper, IRootFolder $storage) { - // , IUserSession $userSession ) { + public function __construct(WikiMapper $mapper, IRootFolder $storage, $UserId) { $this->mapper = $mapper; - // $this->userSession = $userSession; - $this->storage = $storage; - - // , IUserSession $userSession + $this->userId = $UserId; + + $userFolder = $storage->getUserFolder($this->userId); + $this->wikiHelper = new WikiHelper($userFolder); } - public function test(string $userId) { - return WikiHelper::isWiki($this->storage, 208); + public function test() { + $folderId = 381; + return $this->wikiHelper->setFolderId($folderId)->reloadWikiTree(); + return $this->wikiHelper->setFolderId($folderId)->rename(707, 'UnoMasUno'); + return $this->wikiHelper->setFolderId($folderId)->rename(647, 'RenameTest3'); + + return $this->wikiHelper->setFolderId(395)->delete(395) ? 'Yes' : 'No'; + $this->wikiHelper->setFolderId($folderId)->initWiki("First Wiki"); + return print_r($this->wikiHelper->setFolderId($folderId)->getWikiTree(), true); + return $this->wikiHelper->setFolderId($folderId)->isWiki() ? 'Yes' : 'No'; } public function findAll(string $userId) { @@ -50,22 +52,15 @@ class WikiService { public function find(int $id, string $userId) { try { return $this->mapper->find($id, $userId); - - // in order to be able to plug in different storage backends like files - // for instance it is a good idea to turn storage related exceptions - // into service related exceptions so controllers and service users - // have to deal with only one type of exception } catch(Exception $e) { $this->handleException($e); } } public function create(string $title, int $fileId, string $userId) { - if ( !WikiHelper::isFolder($fileId) ) { - throw new ReadOnlyException('The folder is not valid'); - } - if ( !WikiHelper::isWiki($fileId) ) { - if ( !WikiHelper::initWiki($fileId, $title) ) { + $this->wikiHelper->setFolderId($fileId); + if ( $this->wikiHelper->isWiki() ) { + if ( !$this->wikiHelper->initWiki($title) ) { throw new ReadOnlyException('Error creating wiki'); } } @@ -93,7 +88,7 @@ class WikiService { if ($removeFiles) { $fileId = $wiki->getFileId(); $this->mapper->usersCount($fileId); - WikiHelper::removePage($fileId, true); + $this->wikiHelper->setFolderId($fileId)->delete(); } $this->mapper->delete($wiki); return $wiki; diff --git a/tests/Integration/MyWikiIntegrationTest.php b/tests/Integration/MyWikiIntegrationTest.php index 45800e2..35b467d 100644 --- a/tests/Integration/MyWikiIntegrationTest.php +++ b/tests/Integration/MyWikiIntegrationTest.php @@ -37,12 +37,6 @@ class MyWikiIntegrationTest extends TestCase { public function e($x) { echo "\n>>>$x<<<"; } - public function testJDG() { - - $x = \OC\Files\Filesystem::getLocalFolder('\\'); - - $this->e(print_r($x,true)); - } /* public function testUpdate() { // create a new note that should be updated diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 1085eb6..59c6984 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -5,7 +5,7 @@ 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '1984e55837df92230d61b2bce1fcf2e08e2ec4a9', + 'reference' => 'a30a4f13ec699c6e80f32148dc3aa017511c5f5a', 'name' => 'jdg/mywiki', 'dev' => true, ), @@ -25,7 +25,7 @@ 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '1984e55837df92230d61b2bce1fcf2e08e2ec4a9', + 'reference' => 'a30a4f13ec699c6e80f32148dc3aa017511c5f5a', 'dev_requirement' => false, ), 'myclabs/deep-copy' => array(