From b4119142c7b262a16e8a30d730b60eb7bc5dabae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Sat, 20 Jan 2018 00:06:19 +0100 Subject: Generate form schema from sections/details MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- lib/Controller/APIController.php | 120 +++++++++++++++++++++++++++++++++++ lib/Detail.php | 11 +++- lib/DetailManager.php | 3 + lib/IDetail.php | 20 +++++- lib/ISection.php | 9 +++ lib/Service/ComponentService.php | 132 +++++++++++++++++++++++++++++++++++++++ lib/Settings/Admin.php | 88 +------------------------- 7 files changed, 294 insertions(+), 89 deletions(-) create mode 100644 lib/Controller/APIController.php create mode 100644 lib/Service/ComponentService.php (limited to 'lib') diff --git a/lib/Controller/APIController.php b/lib/Controller/APIController.php new file mode 100644 index 0000000..991e708 --- /dev/null +++ b/lib/Controller/APIController.php @@ -0,0 +1,120 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/** + * Created by PhpStorm. + * User: jus + * Date: 19.01.18 + * Time: 21:44 + */ + +namespace OCA\IssueTemplate\Controller; + + +use OCA\IssueTemplate\DetailManager; +use OCA\IssueTemplate\IDetail; +use OCA\IssueTemplate\ISection; +use OCA\IssueTemplate\Sections\ClientSection; +use OCA\IssueTemplate\Sections\LogSection; +use OCA\IssueTemplate\Sections\ServerSection; +use OCA\IssueTemplate\Service\ComponentService; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\QueryException; +use OCP\IRequest; +use Symfony\Component\EventDispatcher\EventDispatcher; +use Symfony\Component\EventDispatcher\GenericEvent; + +class APIController extends Controller { + + private $componentService; + private $detailManager; + private $eventDispatcher; + + public function __construct(string $appName, IRequest $request, ComponentService $componentService, DetailManager $detailManager, EventDispatcher $eventDispatcher) { + parent::__construct($appName, $request); + $this->componentService = $componentService; + $this->detailManager = $detailManager; + $this->eventDispatcher = $eventDispatcher; + + // Register core details that are used in every report + try { + $this->detailManager->addSection(\OC::$server->query(ServerSection::class)); + $this->detailManager->addSection(\OC::$server->query(ClientSection::class)); + $this->detailManager->addSection(\OC::$server->query(LogSection::class)); + } catch (QueryException $e) { + } + } + + public function components() { + return new JSONResponse($this->componentService->getComponents()); + } + + private function queryAppDetails($app) { + $event = new GenericEvent($this->detailManager, [$app]); + $this->eventDispatcher->dispatch('\OCA\IssueTemplate::requestInformation', $event); + } + + public function details($app) { + $this->queryAppDetails($app); + + $model = []; + $schema = []; + + $sections = $this->detailManager->getSections(); + /** @var ISection $section */ + foreach ($sections as $section) { + $model[$section->getIdentifier()] = []; + $group = [ + 'legend' => $section->getTitle(), + 'fields' => [] + ]; + /** @var IDetail $detail */ + foreach ($section->getDetails() as $detail) { + $model[$section->getIdentifier()][$detail->getIdentifier()] = $detail->getInformation(); + $group['fields'][] = [ + 'type' => $this->getTypeFieldSchema($detail->getType()), + 'label' => $detail->getTitle(), + 'model' => $section->getIdentifier() . '.' . $detail->getIdentifier() + ]; + } + $schema['groups'][] = $group; + } + return [ + 'model' => $model, + 'schema' => $schema + ]; + } + + private function getTypeFieldSchema($type) { + switch ($type) { + case IDetail::TYPE_SINGLE_LINE: + return 'input'; + break; + default: + return 'textArea'; + break; + } + } + +} \ No newline at end of file diff --git a/lib/Detail.php b/lib/Detail.php index 23b2555..0c30446 100644 --- a/lib/Detail.php +++ b/lib/Detail.php @@ -26,12 +26,17 @@ namespace OCA\IssueTemplate; class Detail implements IDetail { private $section; + private $identifier; private $title; private $information; private $type; - public function __construct($section, $title, $information, $type) { + public function __construct($section, $title, $information, $type, $identifier = '') { $this->section = $section; + $this->identifier = $identifier; + if ($identifier === '') { + $this->identifier = md5($title); + } $this->title = $title; $this->information = $information; $this->type = $type; @@ -52,4 +57,8 @@ class Detail implements IDetail { public function getSection() { return $this->section; } + + public function getIdentifier() { + return $this->identifier; + } } \ No newline at end of file diff --git a/lib/DetailManager.php b/lib/DetailManager.php index 874dad4..8bba6c5 100644 --- a/lib/DetailManager.php +++ b/lib/DetailManager.php @@ -55,6 +55,9 @@ class DetailManager { * @param int $type */ public function createDetail($sectionIdentifier, $title, $information, $type = IDetail::TYPE_MULTI_LINE_PREFORMAT) { + if (!is_string($information)) { + $information = print_r($information, true); + } $detail = new Detail($sectionIdentifier, $title, $information, $type); /** @var ISection $sectionObject */ $sectionObject = $this->sections[$sectionIdentifier]; diff --git a/lib/IDetail.php b/lib/IDetail.php index d250c33..f05c9fb 100644 --- a/lib/IDetail.php +++ b/lib/IDetail.php @@ -31,21 +31,37 @@ interface IDetail { const TYPE_COLLAPSIBLE_PREFORMAT = 4; /** + * Returns a unique identifier for the detail value + * * @return string */ - public function getTitle(); + public function getIdentifier(); + /** + * Returns the human readable title of the detail value + * * @return string */ + public function getTitle(); + + /** + * Returns the type of the detail field + * + * @return int + */ public function getType(); /** + * Returns the value that should be presented in the issue report + * * @return string */ public function getInformation(); /** - * @return int + * Return the parent section that the detail is linked to + * + * @return ISection */ public function getSection(); } \ No newline at end of file diff --git a/lib/ISection.php b/lib/ISection.php index 9c5a247..a2df8e9 100644 --- a/lib/ISection.php +++ b/lib/ISection.php @@ -31,22 +31,31 @@ namespace OCA\IssueTemplate; interface ISection { /** + * Returns a unique identifier for the section + * + * Predefined sections are server, client and log * @return string */ public function getIdentifier(); /** + * Returns a human readable title for the section + * * @return string */ public function getTitle(); /** + * Adds a detail entry to a section + * * @param IDetail $details * @return void */ public function addDetail(IDetail $details); /** + * Get all details contained in the section + * * @return IDetail[] */ public function getDetails(); diff --git a/lib/Service/ComponentService.php b/lib/Service/ComponentService.php new file mode 100644 index 0000000..8c07d9b --- /dev/null +++ b/lib/Service/ComponentService.php @@ -0,0 +1,132 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/** + * Created by PhpStorm. + * User: jus + * Date: 19.01.18 + * Time: 21:45 + */ + +namespace OCA\IssueTemplate\Service; + + +use OCP\App\IAppManager; +use OCP\IL10N; +use OCP\IURLGenerator; + +class ComponentService { + + /** @var IL10N */ + private $l10n; + /** @var IAppManager */ + private $appManager; + + public function __construct( + IL10N $l10n, + IAppManager $appManager, + IURLGenerator $urlGenerator + ) { + $this->l10n = $l10n; + $this->appManager = $appManager; + $this->urlGenerator = $urlGenerator; + } + + public function getComponents() { + $apps = \OC_App::getAllApps(); + $serverComponents = array( + $this->getComponent('server', $this->l10n->t('Nextcloud server'), 'https://github.com/nextcloud/server'), + $this->getComponent('client', $this->l10n->t('Nextcloud desktop client'), 'https://github.com/nextcloud/client'), + $this->getComponent('android', $this->l10n->t('Nextcloud Android app'), 'https://github.com/nextcloud/android'), + $this->getComponent('ios', $this->l10n->t('Nextcloud iOS app'), 'https://github.com/nextcloud/ios') + ); + $appComponents = []; + $externalComponents = [ + 'desktop' => [ + 'name' => $this->l10n->t('Nextcloud Android app repository'), + 'bugs' => 'https://github.com/nextcloud/android/issues' + ], + 'android' => [ + 'name' => $this->l10n->t('Nextcloud Android app repository'), + 'bugs' => 'https://github.com/nextcloud/android/issues' + ], + 'ios' => [ + 'name' => $this->l10n->t('Nextcloud iOS app repository'), + 'bugs' => 'https://github.com/nextcloud/ios/issues' + ] + ]; + foreach ($apps as $app) { + if ($this->appManager->isInstalled($app)) { + $appinfo = \OC_App::getAppInfo($app); + if (array_key_exists('name', $appinfo) + && array_key_exists('bugs', $appinfo) + && preg_match("/https:\/\/(www.)?github.com\/(.*)\/issues/i", $appinfo['bugs'])) { + $appId = $appinfo['id']; + if(is_array($appinfo['name'])) { + $appTitle = $appinfo['name'][0]; + } else { + $appTitle = $appinfo['name']; + } + $appComponents[$appId] = $appinfo; + $appComponents[$appId]['name'] = $appTitle; + try { + $icon = $this->urlGenerator->imagePath($appId, 'app.svg'); + } catch (\RuntimeException $ex) { + try { + $icon = $this->urlGenerator->imagePath($appId, $appId . '.svg'); + } catch (\RuntimeException $ex) { + $icon = $this->urlGenerator->imagePath('core', 'logo.svg'); + } + } + $appComponents[$appId]['icon'] = $icon; + } + + } + } + return [ + $this->getComponentSection('core', 'Nextcloud server', $serverComponents), + $this->getComponentSection('apps', 'Nextcloud apps', $appComponents), + + ]; + } + + public function getComponentSection($id, $title, $items) { + return [ + 'id' => $id, + 'title' => $title, + 'items' => $items + ]; + } + + public function getComponent($id, $title, $repo, $logo = '') { + if ($logo === '') { + $logo = \OC::$server->getURLGenerator()->imagePath('core','logo.svg'); + } + return [ + 'name' => $title, + 'bugs' => $repo, + 'icon' => $logo, + 'id' => $id + ]; + } +} \ No newline at end of file diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index 275695c..73122a6 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -42,73 +42,26 @@ class Admin implements ISettings { private $config; /** @var IL10N */ private $l10n; - /** @var IAppManager */ - private $appManager; - /** @var DetailManager */ - private $detailManager; - /** @var ServerSection */ - private $serverSection; - /** @var ClientSection */ - private $clientSection; - /** @var LogSection */ - private $logSection; - /** @var EventDispatcher */ - private $eventDispatcher; /** @var IRequest */ private $request; public function __construct( IConfig $config, IL10N $l10n, - IAppManager $appManager, - EventDispatcher $eventDispatcher, - DetailManager $detailManager, - ServerSection $serverSection, - ClientSection $clientSection, LogSection $logSection, IRequest $request ) { $this->config = $config; $this->l10n = $l10n; - $this->appManager = $appManager; - $this->detailManager = $detailManager; - $this->serverSection = $serverSection; - $this->clientSection = $clientSection; - $this->logSection = $logSection; - $this->eventDispatcher = $eventDispatcher; - $this->request = $request; - - // Register core details that are used in every report - $this->detailManager->addSection($this->serverSection); - $this->detailManager->addSection($this->clientSection); - $this->detailManager->addSection($this->logSection); - - } - public function queryAppDetails($app) { - $event = new GenericEvent($this->detailManager, [$app]); - $this->eventDispatcher->dispatch('\OCA\IssueTemplate::requestInformation', $event); + $this->request = $request; } public function getForm() { - - $app = $this->request->getParam('app'); - $this->queryAppDetails($app); - - $data = array( - 'details' => $this->detailManager->getRenderedDetails() - ); - - $issueTemplate = new TemplateResponse('issuetemplate', 'issuetemplate', $data, ''); - $parameters = [ - 'issueTemplate' => $issueTemplate->render(), - 'repos' => $this->getAppRepos(), - 'app' => $app - ]; \OC_Util::addScript('issuetemplate','build/build'); \OC_Util::addStyle('issuetemplate','style'); \OC_Util::addStyle('issuetemplate','style'); - return new TemplateResponse('issuetemplate', 'settings-admin', $parameters, ''); + return new TemplateResponse('issuetemplate', 'settings-admin', [], ''); } public function getSection() { @@ -119,41 +72,4 @@ class Admin implements ISettings { return 10; } - public function getAppRepos() { - $apps = \OC_App::getAllApps(); - $repos = array( - 'core' => [ - 'name' => $this->l10n->t('Nextcloud server repository'), - 'bugs' => 'https://github.com/nextcloud/server/issues' - ], - 'android' => [ - 'name' => $this->l10n->t('Nextcloud Android app repository'), - 'bugs' => 'https://github.com/nextcloud/android/issues' - ], - 'ios' => [ - 'name' => $this->l10n->t('Nextcloud iOS app repository'), - 'bugs' => 'https://github.com/nextcloud/ios/issues' - ] - ); - foreach ($apps as $app) { - if ($this->appManager->isInstalled($app)) { - $appinfo = \OC_App::getAppInfo($app); - if (array_key_exists('name', $appinfo) - && array_key_exists('bugs', $appinfo) - && preg_match("/https:\/\/(www.)?github.com\/(.*)\/issues/i", $appinfo['bugs'])) { - $appId = $appinfo['id']; - if(is_array($appinfo['name'])) { - $appTitle = $appinfo['name'][0]; - } else { - $appTitle = $appinfo['name']; - } - $repos[$appId] = $appinfo; - $repos[$appId]['name'] = $appTitle; - } - - } - } - return $repos; - } - } -- cgit v1.2.3