diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..61ead86
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/vendor
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 26ecca5..fe11f99 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -30,4 +30,8 @@
+
+ OCA\Printer\Settings\Admin\AllowedGroups
+ OCA\Printer\Settings\Admin\Section
+
diff --git a/css/admin.css b/css/admin.css
new file mode 100644
index 0000000..d77db4d
--- /dev/null
+++ b/css/admin.css
@@ -0,0 +1,3 @@
+#printer_admin input {
+ vertical-align: middle;
+}
diff --git a/img/app-dark.svg b/img/app-dark.svg
new file mode 100644
index 0000000..627af08
--- /dev/null
+++ b/img/app-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/js/admin.js b/js/admin.js
new file mode 100644
index 0000000..901d7de
--- /dev/null
+++ b/js/admin.js
@@ -0,0 +1,65 @@
+let elements = []
+
+const selector = '#printer-message';
+
+const appConfig = (name, value, callbacks) => {
+ OCP.AppConfig.setValue('printer', name, value, callbacks)
+}
+
+const saveSettings = (key) => {
+ const element = elements.get(key)
+ let value
+ let name
+
+ if (jQuery(element).is('[data-checkbox]')) {
+ name = jQuery(element).attr('data-name')
+ const inputs = jQuery('input[name="' + name + '[]"]:checked')
+ value = []
+
+ inputs.each((i, v) => {
+ value.push(v.value)
+ })
+
+ value = JSON.stringify(value)
+ } else {
+ name = jQuery(element).attr('name')
+ value = jQuery(element).val()
+ }
+
+ const size = elements.length
+
+ if (name === 'cache') {
+ ++value
+ }
+
+ const callbacks = {
+ success: () => {
+ OC.msg.finishedSuccess(
+ selector,
+ t('printer', (key + 1) + '/' + size)
+ )
+
+ if (key < size - 1) {
+ saveSettings(++key)
+ } else {
+ OC.msg.finishedSuccess(selector, t('printer', 'Saved'))
+ }
+ },
+ error: () => {
+ OC.msg.finishedError(selector, t('printer', 'Error while saving "' + element + '"'))
+ }
+ }
+
+ appConfig(name, value, callbacks)
+}
+
+jQuery(document).ready(() => {
+ elements = jQuery('.printer-setting')
+
+ jQuery('#printer-save').on('click', (event) => {
+ event.preventDefault()
+ OC.msg.startSaving(selector)
+
+ saveSettings(0)
+ });
+});
diff --git a/lib/Config.php b/lib/Config.php
new file mode 100644
index 0000000..08fc703
--- /dev/null
+++ b/lib/Config.php
@@ -0,0 +1,64 @@
+config = $config;
+ $this->groupManager = $groupManager;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getAllowedGroupIds(): array
+ {
+ $groups = $this->config->getAppValue('printer', 'allowed_groups', '[]');
+ $groups = json_decode($groups, true);
+
+ return \is_array($groups) ? $groups : [];
+ }
+
+ public function isDisabledForUser(IUser $user): bool
+ {
+ $allowedGroups = $this->getAllowedGroupIds();
+
+ if (empty($allowedGroups)) {
+ return false;
+ }
+
+ $userGroups = $this->groupManager->getUserGroupIds($user);
+
+ return empty(array_intersect($allowedGroups, $userGroups));
+ }
+}
diff --git a/lib/Controller/PrinterController.php b/lib/Controller/PrinterController.php
index e390408..8999a13 100644
--- a/lib/Controller/PrinterController.php
+++ b/lib/Controller/PrinterController.php
@@ -1,59 +1,79 @@
language = \OC::$server->getL10N('printer');
+ $this->printer = $printer;
+ $this->config = $config;
+ }
+
+ /**
+ * @NoAdminRequired
+ */
+ public function printfile(string $sourcefile, string $orientation): JSONResponse
+ {
+ $file = \OC\Files\Filesystem::getLocalFile($sourcefile);
+
+ $success = [
+ 'response' => 'success',
+ 'msg' => $this->language->t('Print succeeded!'),
+ ];
+
+ $error = [
+ 'response' => 'error',
+ 'msg' => $this->language->t('Print failed'),
+ ];
+
+ $notAllowed = [
+ 'response' => 'error',
+ 'msg' => $this->language->t('User not allowed'),
+ ];
+
+ $user = \OC::$server[IUserSession::class]->getUser();
+
+ if (!$user || $this->config->isDisabledForUser($user)) {
+ return new JSONResponse($notAllowed);
+ }
+
+ if (!$this->printer->isValidOrientation($orientation)) {
+ return new JSONResponse($error);
+ }
+ try {
+ $this->printer->print($file, $orientation);
-class PrinterController extends Controller {
-
- protected $language;
-
- public function __construct($appName, IRequest $request) {
-
- parent::__construct($appName, $request);
-
- // get i10n
- $this->language = \OC::$server->getL10N('printer');
-
- }
-
- /**
- * callback function to get md5 hash of a file
- * @NoAdminRequired
- * @param (string) $sourcefile - filename
- * @param (string) $orientation - Orientation of printed file
- */
- public function printfile($sourcefile, $orientation) {
- if($orientation === "landscape") {
- $filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile);
- exec('lpr "' . $filefullpath . '"');
- return new JSONResponse(
- array(
- 'response' => 'success',
- 'msg' => $this->language->t('Print succeeded!')
- )
- );
- }
-
- if($orientation === "portrait"){
- $filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile);
- exec('lpr -o orientation-requested=4 "' . $filefullpath . '"');
- return new JSONResponse(
- array(
- 'response' => 'success',
- 'msg' => $this->language->t('Print succeeded!')
- )
- );
- } else {
- return new JSONResponse(
- array(
- 'response' => 'error',
- 'msg' => $this->language->t('Print failed')
- )
- );
- };
- }
+ return new JSONResponse($success);
+ } catch (ProcessFailedException $exception) {
+ return new JSONResponse($error);
+ }
+ }
}
diff --git a/lib/Service/Printer.php b/lib/Service/Printer.php
new file mode 100644
index 0000000..6f20930
--- /dev/null
+++ b/lib/Service/Printer.php
@@ -0,0 +1,44 @@
+
+ */
+class Printer
+{
+ public function print(string $file, string $orientation)
+ {
+ $options = [
+ 'landscape' => [
+ 'lpr',
+ $file,
+ ],
+ 'portrait' => [
+ 'lpr',
+ '-o',
+ 'orientation-requested=4',
+ $file,
+ ],
+ ];
+
+ $process = new Process($options[$orientation]);
+ $process->mustRun();
+ }
+
+ /**
+ * Validates an orientation.
+ */
+ public function isValidOrientation(string $orientation): bool
+ {
+ return in_array($orientation, [
+ 'landscape',
+ 'portrait',
+ ]);
+ }
+}
diff --git a/lib/Settings/Admin/AllowedGroups.php b/lib/Settings/Admin/AllowedGroups.php
new file mode 100644
index 0000000..406f979
--- /dev/null
+++ b/lib/Settings/Admin/AllowedGroups.php
@@ -0,0 +1,63 @@
+config = $config;
+ $this->initialStateService = $initialStateService;
+ $this->groupManager = $groupManager;
+ }
+
+ public function getForm(): TemplateResponse
+ {
+ $this->initialStateService->provideInitialState(
+ 'printer',
+ 'allowed_groups',
+ $this->config->getAllowedGroupIds()
+ );
+
+ $groups = $this->groupManager->search('', 100);
+ $allowedGroups = $this->config->getAllowedGroupIds();
+
+ return new TemplateResponse('printer', 'settings/admin/allowed-groups', [
+ 'groups' => $groups,
+ 'allowedGroups' => $allowedGroups,
+ ], '');
+ }
+
+ public function getSection(): string
+ {
+ return 'printer';
+ }
+
+ public function getPriority(): int
+ {
+ return 10;
+ }
+}
diff --git a/lib/Settings/Admin/Section.php b/lib/Settings/Admin/Section.php
new file mode 100644
index 0000000..e9791b3
--- /dev/null
+++ b/lib/Settings/Admin/Section.php
@@ -0,0 +1,48 @@
+url = $url;
+ $this->l = $l;
+ }
+
+ public function getIcon(): string
+ {
+ return $this->url->imagePath('printer', 'app-dark.svg');
+ }
+
+ public function getID(): string
+ {
+ return 'printer';
+ }
+
+ public function getName(): string
+ {
+ return $this->l->t('Printer');
+ }
+
+ public function getPriority(): int
+ {
+ return 70;
+ }
+}
diff --git a/templates/settings/admin/allowed-groups.php b/templates/settings/admin/allowed-groups.php
new file mode 100644
index 0000000..2553000
--- /dev/null
+++ b/templates/settings/admin/allowed-groups.php
@@ -0,0 +1,38 @@
+
+
+
+
t('Limit to groups')) ?>
+
+ t('When at least one group is selected, only people of the listed groups can print.')); ?>
+
+
+
+
+
+
+
+
+