diff --git a/utils/Commands/AdddocumentCommand.php b/utils/Commands/AdddocumentCommand.php
new file mode 100644
index 000000000..b9a25c9f7
--- /dev/null
+++ b/utils/Commands/AdddocumentCommand.php
@@ -0,0 +1,280 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ $this->extmgr = $extmgr;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('dms:adddocument')
+ ->setDescription('Create a new document')
+ ->setHelp('Create a new document below the given parent folder')
+ ->addArgument('filename', InputArgument::REQUIRED, 'Name of file to be uploaded.')
+ ->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'Owner of new document.', '')
+ ->addOption('no-notifications', '', InputOption::VALUE_NONE, 'Do not send notifications.')
+ ->addOption('folder', 'F', InputOption::VALUE_REQUIRED, 'Parent folder.', null)
+ ->addOption('document', 'D', InputOption::VALUE_REQUIRED, 'Document to be updated.', null)
+ ->addOption('name', '', InputOption::VALUE_REQUIRED, 'Name of document.', null)
+ ->addOption('comment', 'c', InputOption::VALUE_REQUIRED, 'Comment of document.', '')
+ ->addOption('mimetype', 't', InputOption::VALUE_REQUIRED, 'Mime type of document.', '')
+ ->addOption('sequence', 's', InputOption::VALUE_REQUIRED, 'Sequence of document.', null)
+ ->addOption('keyword', 'k', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Keyword.', null)
+ ->addOption('category', 'K', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Category.', null)
+ ->addOption('attribute', 'a', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Document attribute.', null)
+ ->addOption('version_attribute', 'A', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Document version attribute.', null)
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.", OutputInterface::VERBOSITY_VERBOSE);
+
+ if (!is_writable($settings->_contentDir)) {
+ $output->writeln(sprintf("The content dir '%s' is not writable by the system user running this script.", $settings->_contentDir));
+ return Command::FAILURE;
+ }
+
+ $filename = $input->getArgument('filename');
+ $mymimetype = $input->getOption('mimetype');
+ /* Check if file is readable {{{ */
+ if (is_readable($filename)) {
+ if (filesize($filename)) {
+ $finfo = new finfo(FILEINFO_MIME_TYPE);
+ if (!$mymimetype) {
+ $mymimetype = $finfo->file($filename);
+ }
+ $filetype = "." . pathinfo($filename, PATHINFO_EXTENSION);
+ } else {
+ $output->writeln(sprintf("File '%s' has zero size", $filename));
+ return Command::FAILURE;
+ }
+ } else {
+ $output->writeln(sprintf("File '%s' is not readable", $filename));
+ return Command::FAILURE;
+ }
+ /* }}} */
+
+ $nonotifications = $input->getOption('no-notifications');
+
+ require_once('inc/inc.DBInit.php');
+ $username = $input->getOption('user');
+ if ($username) {
+ if (!($user = $dms->getUserByLogin($username))) {
+ $output->writeln(sprintf("No such user '%s'", $username));
+ return Command::FAILURE;
+ }
+ } else {
+ $user = $dms->getUser(1);
+ }
+ $dms->setUser($user);
+ $output->writeln("Running as user ".$user->getLogin().".", OutputInterface::VERBOSITY_VERBOSE);
+
+ $name = $input->getOption('name');
+ if (!$name) {
+ $output->writeln("You need to specify a document name.");
+ return Command::FAILURE;
+ }
+ $comment = $input->getOption('comment');
+
+ $folder = $document = null;
+ if ($folderid = $input->getOption('folder')) {
+ $folder = $dms->getFolder((int) $folderid);
+ if (!is_object($folder)) {
+ $output->writeln("Could not find specified parent folder.");
+ return Command::FAILURE;
+ }
+ if ($folder->getAccessMode($user) < M_READWRITE) {
+ $output->writeln("Not sufficient access rights.");
+ return Command::FAILURE;
+ }
+ } elseif ($documentid = $input->getOption('document')) {
+ $document = $dms->getDocument((int) $documentid);
+ if (!is_object($document)) {
+ $output->writeln("Could not find specified document.");
+ return Command::FAILURE;
+ }
+ if ($document->getAccessMode($user) < M_READWRITE) {
+ $output->writeln("Not sufficient access rights.");
+ return Command::FAILURE;
+ }
+ } else {
+ $output->writeln("You need to specify a parent folder or a document to be updated.");
+ return Command::FAILURE;
+ }
+
+ $sequence = $input->getOption('sequence');
+ if (!$sequence) {
+ $sequence = $this->settings->_defaultFolderPosition;
+ }
+ if (!is_numeric($sequence) && $sequence != 'start' && $sequence != 'end') {
+ $output->writeln("Sequence must be a numeric value, 'start', or 'end'");
+ return Command::FAILURE;
+ }
+ if ($folder) {
+ $minmax = $folder->getDocumentsMinMax();
+ if ($sequence == 'start') {
+ $seq = $minmax['min'] - 1;
+ } elseif ($sequence == 'end') {
+ $seq = $minmax['max'] + 1;
+ } else {
+ $seq = $sequence;
+ }
+ }
+
+ /* Parse categories {{{ */
+ $cats = $input->getOption('category');
+ if ($cats) {
+ foreach($cats as $categoryname) {
+ $cat = $dms->getDocumentCategoryByName($categoryname);
+ if ($cat) {
+ $categories[] = $cat;
+ } else {
+ $output->writeln(sprintf("Category '%s' not found.", $categoryname));
+ return Command::FAILURE;
+ }
+ }
+ } /* }}} */
+
+ /* Parse document attributes. {{{ */
+ $document_attributes = array();
+ $attributes = $input->getOption('attribute');
+ if ($attributes) {
+ foreach ($attributes as $thisAttribute) {
+ $attrKey = strstr($thisAttribute, '=', true);
+ $attrVal = substr(strstr($thisAttribute, '='), 1);
+ if (empty($attrKey) || empty($attrVal)) {
+ $output->writeln(sprintf("Document attribute %s not understood", $thisAttribute));
+ return Command::FAILURE;
+ }
+ $attrdef = $dms->getAttributeDefinitionByName($attrKey);
+ if (!$attrdef) {
+ $output->writeln(sprintf("Document attribute '%s' unknown", $attrKey));
+ return Command::FAILURE;
+ }
+ $document_attributes[$attrdef->getID()] = $attrVal;
+ }
+ } /* }}} */
+
+ /* Parse version attributes. {{{ */
+ $version_attributes = array();
+ $attributes = $input->getOption('version_attribute');
+ if ($attributes) {
+ foreach ($attributes as $thisAttribute) {
+ $attrKey = strstr($thisAttribute, '=', true);
+ $attrVal = substr(strstr($thisAttribute, '='), 1);
+ if (empty($attrKey) || empty($attrVal)) {
+ $output->writeln(sprintf("Document attribute %s not understood", $thisAttribute));
+ return Command::FAILURE;
+ }
+ $attrdef = $dms->getAttributeDefinitionByName($attrKey);
+ if (!$attrdef) {
+ $output->writeln(sprintf("Document attribute '%s' unknown", $attrKey));
+ return Command::FAILURE;
+ }
+ $version_attributes[$attrdef->getID()] = $attrVal;
+ }
+ } /* }}} */
+
+// return Command::FAILURE;
+ $keywords = implode(' ', $input->getOption('keyword'));
+ $expires = false;
+ $reviewers = array();
+ $approvers = array();
+ require_once("inc/inc.ClassController.php");
+ if ($folder) {
+ $controller = \Controller::factory('AddDocument', array('dms'=>$dms, 'user'=>$user, 'extmgr'=>$this->extmgr, 'settings'=>$this->settings));
+ $controller->setParam('documentsource', 'script');
+ $controller->setParam('folder', $folder);
+ $controller->setParam('fulltextservice', $fulltextservice);
+ $controller->setParam('name', $name);
+ $controller->setParam('comment', $comment);
+ $controller->setParam('expires', $expires);
+ $controller->setParam('keywords', $keywords);
+ $controller->setParam('categories', $categories);
+ $controller->setParam('owner', $user);
+ $controller->setParam('sequence', $seq);
+ $controller->setParam('userfiletmp', $filename);
+ $controller->setParam('userfilename', basename($filename));
+ $controller->setParam('filetype', $filetype);
+ $controller->setParam('userfiletype', $mymimetype);
+ $controller->setParam('reviewers', $reviewers);
+ $controller->setParam('approvers', $approvers);
+ $controller->setParam('attributes', array());
+ $controller->setParam('notificationgroups', array());
+ $controller->setParam('notificationusers', array());
+ if (!$document = $controller->run()) {
+ output->writeln("Could not create document");
+ return Command::FAILURE;
+ } else {
+ // Send notification to subscribers.
+ if ($notifier && !$nonotifications) {
+ $output->writeln(sprintf('Sending notifications ...'), OutputInterface::VERBOSITY_VERBOSE);
+ $notifier->sendNewDocumentMail($document, $user);
+ }
+ }
+ $output->writeln(sprintf('New document with id=%d created.', $document->getId()), OutputInterface::VERBOSITY_QUIET);
+ return Command::SUCCESS;
+ } elseif ($document) {
+ $controller = \Controller::factory('UpdateDocument', array('dms'=>$dms, 'user'=>$user));
+ $controller->setParam('folder', $document->getFolder());
+ $controller->setParam('document', $document);
+ $controller->setParam('fulltextservice', $fulltextservice);
+ $controller->setParam('comment', $comment);
+ $controller->setParam('userfiletmp', $filename);
+ $controller->setParam('userfilename', basename($filename));
+ $controller->setParam('filetype', $filetype);
+ $controller->setParam('userfiletype', $mymimetype);
+ $controller->setParam('reviewers', $reviewers);
+ $controller->setParam('approvers', $approvers);
+ $controller->setParam('attributes', $version_attributes);
+ $controller->setParam('workflow', null);
+
+ if (!$content = $controller->run()) {
+ output->writeln("Could not add version to document");
+ return Command::FAILURE;
+ } else {
+ // Send notification to subscribers.
+ if ($notifier && !$nonotifications) {
+ $output->writeln(sprintf('Sending notifications ...'));
+ $notifier->sendNewDocumentVersionMail($document, $user);
+ }
+ }
+ $output->writeln(sprintf('New document version %d of document with id=%d created.', $content->getVersion(), $document->getId()), OutputInterface::VERBOSITY_QUIET);
+ return Command::SUCCESS;
+ }
+ }
+}
+
+// vim: sw=4 ts=4 expandtab
diff --git a/utils/Commands/AddfolderCommand.php b/utils/Commands/AddfolderCommand.php
new file mode 100644
index 000000000..ec9f0bcac
--- /dev/null
+++ b/utils/Commands/AddfolderCommand.php
@@ -0,0 +1,155 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('dms:addfolder')
+ ->setDescription('Create a new folder')
+ ->setHelp('Create a new folder below the given parent folder')
+ ->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'Owner of new folder.', '')
+ ->addOption('parent', 'F', InputOption::VALUE_REQUIRED, 'Parent folder.', null)
+ ->addOption('name', '', InputOption::VALUE_REQUIRED, 'Name of folder.', null)
+ ->addOption('comment', 'c', InputOption::VALUE_REQUIRED, 'Comment of folder.', '')
+ ->addOption('sequence', 's', InputOption::VALUE_REQUIRED, 'Sequence of folder.', null);
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.", OutputInterface::VERBOSITY_VERBOSE);
+
+ if (!is_writable($settings->_contentDir)) {
+ $output->writeln(sprintf("The content dir '%s' is not writable by the system user running this script.", $settings->_contentDir));
+ return Command::FAILURE;
+ }
+
+ require_once('inc/inc.DBInit.php');
+ $username = $input->getOption('user');
+ if ($username) {
+ if (!($user = $dms->getUserByLogin($username))) {
+ $output->writeln(sprintf("No such user '%s'", $username));
+ return Command::FAILURE;
+ }
+ } else {
+ $user = $dms->getUser(1);
+ }
+ $dms->setUser($user);
+ $output->writeln("Running as user ".$user->getLogin().".", OutputInterface::VERBOSITY_VERBOSE);
+
+ $name = $input->getOption('name');
+ if(!$name) {
+ $output->writeln("You need to specify a folder name.");
+ return Command::FAILURE;
+ }
+ $comment = $input->getOption('comment');
+
+ if($folderid = $input->getOption('parent')) {
+ $folder = $dms->getFolder((int) $folderid);
+ if (!is_object($folder)) {
+ $output->writeln("Could not find specified parent folder.");
+ return Command::FAILURE;
+ }
+ } else {
+ $output->writeln("You need to specify a parent folder.");
+ return Command::FAILURE;
+ }
+
+ if ($folder->getAccessMode($user) < M_READWRITE) {
+ $output->writeln("Not sufficient access rights.");
+ return Command::FAILURE;
+ }
+
+ $sequence = $input->getOption('sequence');
+ if(!$sequence) {
+ $sequence = $this->settings->_defaultFolderPosition;
+ }
+ if (!is_numeric($sequence) && $sequence != 'start' && $sequence != 'end') {
+ $output->writeln("Sequence must be a numeric value, 'start', or 'end'");
+ return Command::FAILURE;
+ }
+ $minmax = $folder->getFoldersMinMax();
+ if($sequence == 'start') {
+ $seq = $minmax['min'] - 1;
+ } elseif ($sequence == 'end') {
+ $seq = $minmax['max'] + 1;
+ } else {
+ $seq = $sequence;
+ }
+
+ require_once('inc/inc.DBInit.php');
+ require_once('inc/inc.Extension.php');
+ require_once("inc/inc.ClassController.php");
+ $controller = \Controller::factory('AddSubFolder', array('dms'=>$dms, 'user'=>$user, 'extmgr'=>$extmgr, 'settings'=>$this->settings));
+ $controller->setParam('folder', $folder);
+ $controller->setParam('name', $name);
+ $controller->setParam('comment', $comment);
+ $controller->setParam('sequence', $seq);
+ $controller->setParam('attributes', array());
+ $controller->setParam('notificationgroups', array());
+ $controller->setParam('notificationusers', array());
+ if (!$subFolder = $controller->run()) {
+ output->writeln("Could not create folder");
+ return Command::FAILURE;
+ } else {
+ // Send notification to subscribers.
+ if ($notifier) {
+ $output->writeln(sprintf('Sending notifications ...'), OutputInterface::VERBOSITY_VERBOSE);
+ $fnl = $folder->getNotifyList();
+ $snl = $subFolder->getNotifyList();
+ $nl = array(
+ 'users'=>array_unique(array_merge($snl['users'], $fnl['users']), SORT_REGULAR),
+ 'groups'=>array_unique(array_merge($snl['groups'], $fnl['groups']), SORT_REGULAR)
+ );
+
+ $subject = "new_subfolder_email_subject";
+ $message = "new_subfolder_email_body";
+ $params = array();
+ $params['name'] = $subFolder->getName();
+ $params['folder_name'] = $folder->getName();
+ $params['folder_path'] = $folder->getFolderPathPlain();
+ $params['username'] = $user->getFullName();
+ $params['comment'] = $comment;
+ $params['url'] = $settings->getBaseUrlWithRoot()."out/out.ViewFolder.php?folderid=".$subFolder->getID();
+ $params['sitename'] = $settings->_siteName;
+ $params['http_root'] = $settings->_httpRoot;
+ $notifier->toList($user, $nl["users"], $subject, $message, $params);
+ foreach ($nl["groups"] as $grp) {
+ $notifier->toGroup($user, $grp, $subject, $message, $params);
+ }
+ }
+ }
+ $output->writeln(sprintf('New folder with id=%d created.', $subFolder->getId()), OutputInterface::VERBOSITY_QUIET);
+ return Command::SUCCESS;
+ }
+}
+
+// vim: sw=4 ts=4 expandtab
diff --git a/utils/Commands/ClearcacheCommand.php b/utils/Commands/ClearcacheCommand.php
new file mode 100644
index 000000000..0aae1c010
--- /dev/null
+++ b/utils/Commands/ClearcacheCommand.php
@@ -0,0 +1,68 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('cache:clear')
+ ->setDescription('Clears the cache')
+ ->setHelp('Clears all cache or those specified.')
+ ->addOption('cache', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Remove files from cache.', null)
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $app = $this->getApplication();
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.");
+ if (!is_writable($settings->_cacheDir)) {
+ $output->writeln(sprintf("The cache dir '%s' is not writable for the system user running this script.", $settings->_cacheDir));
+ return Command::FAILURE;
+ }
+
+ require_once('inc/inc.DBInit.php');
+
+ $post = array_flip($input->getOption('cache'));
+ array_walk($post, function (&$v, $k) {$v=1;});
+ $controller = Controller::factory('ClearCache', array('settings'=>$settings));
+ $controller->setParam('post', $post);
+ if(!$ret = $controller->run()) {
+ }
+
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/ConfigureextensionCommand.php b/utils/Commands/ConfigureextensionCommand.php
new file mode 100644
index 000000000..6358d1554
--- /dev/null
+++ b/utils/Commands/ConfigureextensionCommand.php
@@ -0,0 +1,93 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ $this->extmgr = $extmgr;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('ext:configure')
+ ->setDescription('Configure extension')
+ ->setHelp('Enables and disables an extensions.')
+ ->addOption('name', '', InputOption::VALUE_REQUIRED, 'Name of extension.', null)
+ ->addOption('enable', '', InputOption::VALUE_NONE, 'Enable extension.')
+ ->addOption('disable', '', InputOption::VALUE_NONE, 'Disable extension.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+ $extmgr = $this->extmgr;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.", OutputInterface::VERBOSITY_VERBOSE);
+
+ if (!is_writable($settings->_configFilePath)) {
+ $output->writeln(sprintf("The configuration file '%s' is not writable by the system user running this script.", $settings->_configFilePath));
+ return Command::FAILURE;
+ }
+ $extconf = $extmgr->getExtensionConfiguration();
+ $extname = $input->getOption('name');
+ if (!isset($extconf[$extname])) {
+ $output->writeln(sprintf("No such extension '%s'", $extname));
+ return Command::FAILURE;
+ }
+
+ if ($input->getOption('enable')) {
+ if ($settings->extensionIsDisabled($extname)) {
+ $settings->enableExtension($extname);
+ } else {
+ $output->writeln(sprintf("Extension already enabled."));
+ return Command::SUCCESS;
+ }
+ } elseif ($input->getOption('disable')) {
+ if (!$settings->extensionIsDisabled($extname)) {
+ $settings->disableExtension($extname);
+ } else {
+ $output->writeln(sprintf("Extension already disabled."));
+ return Command::SUCCESS;
+ }
+ } else {
+ $output->writeln(sprintf("Missing option --enable or --disable"));
+ return Command::FAILURE;
+ }
+
+ $settings->save();
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/DeleteCommand.php b/utils/Commands/DeleteCommand.php
new file mode 100644
index 000000000..f9de4368e
--- /dev/null
+++ b/utils/Commands/DeleteCommand.php
@@ -0,0 +1,128 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('dms:delete')
+ ->setDescription('Delete a folder or document')
+ ->setHelp('Folders can also be emptied.')
+ ->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'Run in behalf of this user.', '')
+ ->addOption('folder', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Delete this folder.', null)
+ ->addOption('document', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Delete this document.', null)
+ ->addOption('empty', '', InputOption::VALUE_REQUIRED, 'Do not delete but empty the given folder.', null);
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $app = $this->getApplication();
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.");
+ if (!is_writable($settings->_contentDir)) {
+ $output->writeln(sprintf("The content dir '%s' is not writable for the system user running this script.", $settings->_contentDir));
+ return Command::FAILURE;
+ }
+
+ require_once('inc/inc.DBInit.php');
+
+ $username = $input->getOption('user');
+ if ($username) {
+ if (!($user = $dms->getUserByLogin($username))) {
+ $output->writeln(sprintf("No such user '%s'", $username));
+ return Command::FAILURE;
+ }
+ } else {
+ $output->writeln("You must specify a user.");
+ return Command::FAILURE;
+ }
+ $dms->setUser($user);
+ $output->writeln("Running as user ".$user->getLogin().".");
+
+ $folderids = $input->getOption('folder');
+ $documentids = $input->getOption('document');
+ $empty = $input->getOption('empty');
+ if(!$documentids && !$folderids) {
+ $output->writeln("You need to specify a folder or document.");
+ return Command::FAILURE;
+ }
+
+ foreach($folderids as $folderid) {
+ $folder = $dms->getFolder((int) $folderid);
+ if (!is_object($folder)) {
+ $output->writeln("Could not find specified folder.");
+ return Command::FAILURE;
+ }
+ if ($folder->getAccessMode($user) < M_ALL) {
+ $output->writeln("Insufficient access rights to remove folder with id=".$folderid."");
+ return Command::FAILURE;
+ } else {
+ if($empty)
+ $controller = Controller::factory('EmptyFolder', array('dms'=>$dms, 'user'=>$user));
+ else
+ $controller = Controller::factory('RemoveFolder', array('dms'=>$dms, 'user'=>$user));
+ $controller->setParam('folder', $folder);
+ $controller->setParam('fulltextservice', $fulltextservice);
+ if(!$folder = $controller->run()) {
+ $output->writeln("Could not ".($empty ? 'empty' : 'remove')." folder with id=".$folderid."");
+ return Command::FAILURE;
+ } else {
+ $output->writeln("Folder with id=".$folderid." ".($empty ? 'emptied' : 'removed').".");
+ }
+ }
+ }
+
+ foreach($documentids as $documentid) {
+ $document = $dms->getDocument((int) $documentid);
+ if (!is_object($document)) {
+ $output->writeln("Could not find specified document.");
+ return Command::FAILURE;
+ }
+ if ($document->getAccessMode($user) < M_ALL) {
+ $output->writeln("Insufficient access rights to remove document with id=".$documentid."");
+ return Command::FAILURE;
+ } else {
+ $controller = Controller::factory('RemoveDocument', array('dms'=>$dms, 'user'=>$user));
+ $controller->setParam('document', $document);
+ $controller->setParam('fulltextservice', $fulltextservice);
+ if(!$document = $controller->run()) {
+ $output->writeln("Could not remove document with id=".$documentid."");
+ return Command::FAILURE;
+ } else {
+ $output->writeln("Document with id=".$documentid." removed.");
+ }
+ }
+ }
+
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/ListcacheCommand.php b/utils/Commands/ListcacheCommand.php
new file mode 100644
index 000000000..d42a6e649
--- /dev/null
+++ b/utils/Commands/ListcacheCommand.php
@@ -0,0 +1,101 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('cache:list')
+ ->setDescription('List caches')
+ ->setHelp('Lists all caches including size.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $app = $this->getApplication();
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+
+ $outformat = '%-20s %-40s %15s %7d';
+ require_once('inc/inc.DBInit.php');
+
+ $cachedir = $settings->_cacheDir;
+ $totalc = 0;
+ $totalspace = 0;
+ // Preview for png, pdf, and txt */
+ foreach(['png', 'pdf', 'txt'] as $t) {
+ $path = addDirSep($cachedir).$t;
+ if(file_exists($path)) {
+ $space = dskspace($path);
+ $fi = new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS);
+ $c = iterator_count($fi);
+ } else {
+ $space = $c = 0;
+ }
+ $totalc += $c;
+ $totalspace += $space;
+ $output->writeln(sprintf($outformat, 'preview'.$t, $translator->translate('preview_'.$t), SeedDMS_Core_File::format_filesize($space), $c));
+ }
+
+ /* Javascript */
+ $path = addDirSep($cachedir).'js';
+ if(file_exists($path)) {
+ $space = dskspace($path);
+ $fi = new FilesystemIterator($path, FilesystemIterator::SKIP_DOTS);
+ $c = iterator_count($fi);
+ } else {
+ $space = $c = 0;
+ }
+ $totalc += $c;
+ $totalspace += $space;
+ $output->writeln(sprintf($outformat, 'js', $translator->translate('temp_jscode'), SeedDMS_Core_File::format_filesize($space), $c));
+
+ $caches = [];
+ /* Create a dummy view for passing it to additionalCache() */
+ $view = new SeedDMS_View_Common(['settings'=>$settings]);
+ if (isset($GLOBALS['SEEDDMS_HOOKS']['view']['clearCache'])) {
+ foreach ($GLOBALS['SEEDDMS_HOOKS']['view']['clearCache'] as $hookObj) {
+ if (method_exists($hookObj, 'additionalCache')) {
+ $caches += $hookObj->additionalCache($view);
+ }
+ }
+ }
+ foreach($caches as $cache) {
+ $output->writeln(sprintf($outformat, $cache[0], $cache[1], SeedDMS_Core_File::format_filesize($cache[2]), $cache[3]));
+ }
+// print_r($caches);
+
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/ListextensionCommand.php b/utils/Commands/ListextensionCommand.php
new file mode 100644
index 000000000..6e9fc1bd2
--- /dev/null
+++ b/utils/Commands/ListextensionCommand.php
@@ -0,0 +1,92 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ $this->extmgr = $extmgr;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('ext:list')
+ ->setDescription('List extensions')
+ ->setHelp('Lists all enable and disable extensions.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+ $extmgr = $this->extmgr;
+
+ $outformat = '%s %-55s %-8s %-10s';
+ $descformat = '%-55s';
+ $extStyle = new OutputFormatterStyle('green', '', ['bold']);
+ $output->getFormatter()->setStyle('ext', $extStyle);
+ $descStyle = new OutputFormatterStyle('gray');
+ $output->getFormatter()->setStyle('desc', $descStyle);
+
+ $enabled = 0;
+ $disabled = 0;
+ $haserror = 0;
+ $extconf = $extmgr->getExtensionConfiguration();
+ foreach ($extconf as $extname=>$extconf) {
+ if (!$settings->extensionIsDisabled($extname)) {
+ $enabled++;
+ $output->writeln(sprintf(''.$outformat.'', '*', $extname, $extconf['version'], $extconf['releasedate']));
+ } else {
+ $disabled++;
+ $output->writeln(sprintf(''.$outformat.'', '-', $extname, $extconf['version'], $extconf['releasedate']));
+ }
+ $output->writeln(sprintf(' '.$descformat.'', $extconf['title']));
+ $lines = explode('|', wordwrap($extconf['description'], 55, '|'));
+ foreach($lines as $desc)
+ $output->writeln(sprintf(' '.$descformat.'', trim($desc)));
+ $output->writeln(sprintf(' '.$descformat.'', 'Author: '.$extconf['author']['name'].(!empty($extconf['author']['company']) ? ' ('.$extconf['author']['company'].')' : '')));
+ $check = $extmgr->checkExtensionByDir($extname);
+ $errmsgs = $extmgr->getErrorMsgs();
+ if($errmsgs) {
+ $haserror++;
+ foreach($errmsgs as $errmsg) {
+ $output->writeln(sprintf(' '.$descformat.'', trim($errmsg)));
+ }
+ }
+ }
+ $output->writeln('');
+ $output->writeln(sprintf('%d extensions, %d enabled, %d disabled, %d has errors', $enabled+$disabled, $enabled, $disabled, $haserror));
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/PackageextensionCommand.php b/utils/Commands/PackageextensionCommand.php
new file mode 100644
index 000000000..7a8fef84d
--- /dev/null
+++ b/utils/Commands/PackageextensionCommand.php
@@ -0,0 +1,79 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ $this->extmgr = $extmgr;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('ext:package')
+ ->setDescription('Package extension as a zip file. If --output-dir is given, the zip file will be placed into this directory otherwise it will be saved in the current directory. The name of the zip file will be -.zip. If such a file already exists, it will be deleted and recreated.')
+ ->setHelp('Creates a zip file of an extension, which can be uploaded into SeedDMS.')
+ ->addOption('name', '', InputOption::VALUE_REQUIRED, 'Name of extension.', null)
+ ->addOption('output-dir', '', InputOption::VALUE_REQUIRED, 'Name of directory where the zip file is saved.', null)
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+ $extmgr = $this->extmgr;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.", OutputInterface::VERBOSITY_VERBOSE);
+
+ $extconf = $extmgr->getExtensionConfiguration();
+ $extname = $input->getOption('name');
+ if (!isset($extconf[$extname])) {
+ $output->writeln(sprintf("No such extension '%s'", $extname));
+ return Command::FAILURE;
+ }
+
+ $outputdir = $input->getOption('output-dir');
+ if(!$outputdir)
+ $outputdir = '.';
+
+ /* If the $outputdir is not passed to createArchive(), the cache
+ * dir of SeedDMS will be used, which requires to run this script
+ * with sufficient access rights on that directory.
+ */
+ $filename = $extmgr->createArchive($extname, $extmgr->getExtensionConfiguration()[$extname]['version'], $outputdir);
+
+ $output->writeln(sprintf("Extension saved as '%s'", $filename));
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/ReloadextensionCommand.php b/utils/Commands/ReloadextensionCommand.php
new file mode 100644
index 000000000..5126737c0
--- /dev/null
+++ b/utils/Commands/ReloadextensionCommand.php
@@ -0,0 +1,68 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ $this->extmgr = $extmgr;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('ext:reload')
+ ->setDescription('Reload extensions')
+ ->setHelp('Recreates the cached extension list.')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+ $extmgr = $this->extmgr;
+
+ $output->writeln("Using configuration from '".$settings->_configFilePath."'.", OutputInterface::VERBOSITY_VERBOSE);
+
+ if (!is_writable($settings->_cacheDir)) {
+ $output->writeln(sprintf("The cache directory '%s' is not writable by the system user running this script.", $settings->_cacheDir));
+ return Command::FAILURE;
+ }
+ if($extmgr->createExtensionConf()) {
+ return Command::SUCCESS;
+ } else {
+ $output->writeln(sprintf("Failed to recreate the extension list.'"));
+ return Command::FAILURE;
+ }
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/Commands/StatsCommand.php b/utils/Commands/StatsCommand.php
new file mode 100644
index 000000000..e1df7257d
--- /dev/null
+++ b/utils/Commands/StatsCommand.php
@@ -0,0 +1,83 @@
+settings = $settings;
+ $this->logger = $logger;
+ $this->translator = $translator;
+ parent::__construct();
+ }
+
+ protected function configure()
+ {
+ $this->setName('dms:stats')
+ ->setDescription('Prints Statistics')
+ ->setHelp('Demonstration of custom commands created by Symfony Console component.')
+ ->addOption('json', '', InputOption::VALUE_NONE, 'Export data as json')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) : int
+ {
+ $app = $this->getApplication();
+ $settings = $this->settings;
+ $logger = $this->logger;
+ $translator = $this->translator;
+
+ require_once('inc/inc.DBInit.php');
+ foreach (array('docstotal'=>'documents', 'folderstotal'=>'folders', 'userstotal'=>'users', 'groupstotal'=>'groups', 'categoriestotal'=>'categories') as $type=>$name) {
+ $stats[$type] = $dms->getStatisticalData($type);
+ }
+ foreach (array('docsperuser'=>'documents', 'foldersperuser'=>'folders','sizeperuser'=>'size') as $type=>$name) {
+ $stats[$type] = $dms->getStatisticalData($type);
+ }
+
+ if ($input->getOption('json')) {
+ $output->writeln(json_encode($stats));
+ } else {
+ $outformat = '%-30s %-10d';
+ $output->writeln(sprintf($outformat, 'Documents', $stats['docstotal']));
+ $output->writeln(sprintf($outformat, 'Folders', $stats['folderstotal']));
+ $output->writeln(sprintf($outformat, 'Users', $stats['userstotal']));
+ $output->writeln(sprintf($outformat, 'Groups', $stats['groupstotal']));
+ $output->writeln(sprintf($outformat, 'Categories', $stats['categoriestotal']));
+ $output->writeln('');
+ $output->writeln('Documents per user:');
+ foreach($stats['docsperuser'] as $d) {
+ $output->writeln(sprintf($outformat, $d['key'], $d['total']));
+ }
+ $output->writeln('');
+ $output->writeln('Folders per user:');
+ foreach($stats['foldersperuser'] as $d) {
+ $output->writeln(sprintf($outformat, $d['key'], $d['total']));
+ }
+ $output->writeln('');
+ $output->writeln('Size per user:');
+ foreach($stats['sizeperuser'] as $d) {
+ $output->writeln(sprintf($outformat, $d['key'], $d['total']));
+ }
+ }
+ return Command::SUCCESS;
+ }
+}
+
+// vim: ts=4 sw=4 expandtab
diff --git a/utils/console b/utils/console
new file mode 100755
index 000000000..2cf31546b
--- /dev/null
+++ b/utils/console
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+init();
+$logger = getLogger($settings, 'console-');
+
+require_once('inc/inc.Extension.php');
+
+$application = new Application();
+$application->add(new StatsCommand($settings, $logger, $translator));
+$application->add(new AddfolderCommand($settings, $logger, $translator));
+$application->add(new AdddocumentCommand($settings, $logger, $translator, $extmgr));
+$application->add(new DeleteCommand($settings, $logger, $translator));
+$application->add(new ClearcacheCommand($settings, $logger, $translator));
+$application->add(new ListcacheCommand($settings, $logger, $translator));
+$application->add(new ListextensionCommand($settings, $logger, $translator, $extmgr));
+$application->add(new ConfigureextensionCommand($settings, $logger, $translator, $extmgr));
+$application->add(new PackageextensionCommand($settings, $logger, $translator, $extmgr));
+$application->add(new ReloadextensionCommand($settings, $logger, $translator, $extmgr));
+
+if(isset($GLOBALS['SEEDDMS_HOOKS']['console'])) {
+ foreach($GLOBALS['SEEDDMS_HOOKS']['console'] as $hookObj) {
+ if (method_exists($hookObj, 'addCommand')) {
+ $hookObj->addCommand($application, ['settings'=>$settings, 'logger'=>$logger, 'translator'=>$translator, 'extmgr'=>$extmgr]);
+ }
+ }
+}
+
+$application->run();