paperless/class.paperless.php

1761 lines
66 KiB
PHP
Raw Normal View History

2022-12-10 10:25:22 +00:00
<?php
/**
* Paperless extension
*
2023-03-30 05:13:29 +00:00
* @author Uwe Steinmann <uwe@steinmann.cx>
* @package SeedDMS
* @subpackage paperless
* @license GPL3
* @copyright Copyright (C) 2023 Uwe Steinmann
2022-12-10 10:25:22 +00:00
*/
class SeedDMS_ExtPaperless extends SeedDMS_ExtBase { /* {{{ */
/**
* Initialization
*
* Use this method to do some initialization like setting up the hooks
* You have access to the following global variables:
* $GLOBALS['settings'] : current global configuration
* $GLOBALS['settings']->_extensions['example'] : configuration of this extension
* $GLOBALS['LANG'] : the language array with translations for all languages
* $GLOBALS['SEEDDMS_HOOKS'] : all hooks added so far
*/
function init() { /* {{{ */
$GLOBALS['SEEDDMS_HOOKS']['initRestAPI'][] = new SeedDMS_ExtPaperless_RestAPI;
$GLOBALS['SEEDDMS_HOOKS']['view']['settings'][] = new SeedDMS_ExtPaperless_Settings;
2022-12-10 10:25:22 +00:00
} /* }}} */
function main() { /* {{{ */
} /* }}} */
} /* }}} */
/**
* Class containing method for checking the configuration
*
* @author Uwe Steinmann <uwe@steinmann.cx>
* @package SeedDMS
* @subpackage paperless
*/
class SeedDMS_ExtPaperless_Settings { /* {{{ */
/**
* Hook for checking the configuration
*
* This hook is not called if the extension isn't enabled
*/
function checkConfig($view, $extname, $conf) {
$settings = $view->getParam('settings');
if($extname != 'paperless')
return;
2024-07-16 06:41:57 +00:00
if(empty($settings->_extensions['paperless']['jwtsecret']) || empty($settings->_enableFullSearch)) {
echo $view->contentSubHeading(getMLText($extname));
2024-07-16 06:41:57 +00:00
if(empty($settings->_extensions['paperless']['jwtsecret']))
echo $view->warningMsg(getMLText('paperless_jwtsecret_not_set'));
if(empty($settings->_enableXsendfile))
echo $view->warningMsg(getMLText('paperless_needs_fulltextsearch'));
}
}
} /* }}} */
2022-12-10 10:25:22 +00:00
use Psr\Container\ContainerInterface;
class SeedDMS_ExtPaperless_Process_Folder { /* {{{ */
protected $list;
public function __construct() {
$this->list = [];
}
public function process($folder, $depth=0) { /* {{{ */
// FIXME: hasDocuments() contains also documents not in status=2
$this->list[$folder->getId()] = [$folder->getFolderPathPlain(true, '/'), $folder->hasDocuments()];
} /* }}} */
public function getList() { /* {{{ */
return $this->list;
} /* }}} */
} /* }}} */
2022-12-10 10:25:22 +00:00
class SeedDMS_ExtPaperless_RestAPI_Controller { /* {{{ */
protected $container;
2023-03-15 13:23:03 +00:00
static public function mb_word_count($string, $mode = MB_CASE_TITLE, $characters = null) { /* {{{ */
$string = mb_convert_case($string, $mode, "UTF-8");
$addChars = $characters ? preg_quote($characters, '~') : "";
// $regEx = "~[^\p{L}".$addChars."]+~u";
$regEx = "~[^\p{L}".$addChars."]+~u";
return array_count_values(preg_split($regEx,$string, -1, PREG_SPLIT_NO_EMPTY));
} /* }}} */
protected function __getDocumentData($document, $truncate_content=false) { /* {{{ */
2022-12-10 10:25:22 +00:00
$fulltextservice = $this->container->fulltextservice;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$lc = $document->getLatestContent();
$dms = $document->getDMS();
2022-12-10 10:25:22 +00:00
$content = '';
/* The plain text can either be created by the text previewer
* or taken from the fulltext index. The text from the fulltext index
* does not have stop words anymore if a stop words file was
* configured during indexing.
*/
if(1) {
$txtpreviewer = new SeedDMS_Preview_TxtPreviewer($settings->_cacheDir, $settings->_cmdTimeout, $settings->_enableXsendfile);
$txtpreviewer->setConversionMgr($conversionmgr);
if(!$txtpreviewer->hasPreview($lc))
$txtpreviewer->createPreview($lc);
$file = $txtpreviewer->getFileName($lc).".txt";
if(file_exists($file))
$content = file_get_contents($file);
} else {
2024-07-16 06:41:57 +00:00
if($fulltextservice && $index = $fulltextservice->Indexer()) {
$lucenesearch = $fulltextservice->Search();
if($searchhit = $lucenesearch->getDocument($document->getID())) {
$idoc = $searchhit->getDocument();
try {
if($truncate_content)
$content = htmlspecialchars(mb_strimwidth($idoc->getFieldValue('content'), 0, 500, '...'));
else
$content = htmlspecialchars($idoc->getFieldValue('content'));
} catch (Exception $e) {
}
2022-12-10 10:25:22 +00:00
}
}
}
$cats = $document->getCategories();
$tags = array();
foreach($cats as $cat)
$tags[] = (int) $cat->getId();
$correspondent = null;
if(!empty($settings->_extensions['paperless']['correspondentsattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['correspondentsattr'])) {
if($attr = $document->getAttribute($attrdef)) {
$valueset = $attrdef->getValueSetAsArray();
$i = array_search($attr->getValue(), $valueset);
if($i !== false)
$correspondent = $i+1;
}
}
$documenttype = null;
if(!empty($settings->_extensions['paperless']['documenttypesattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['documenttypesattr'])) {
if($attr = $document->getAttribute($attrdef)) {
$valueset = $attrdef->getValueSetAsArray();
$i = array_search($attr->getValue(), $valueset);
if($i !== false)
$documenttype = $i+1;
}
}
2022-12-10 10:25:22 +00:00
$data = array(
'id'=>(int)$document->getId(),
'correspondent'=>$correspondent,
'document_type'=>$documenttype,
2022-12-10 10:25:22 +00:00
'storage_path'=>null,
'title'=>$document->getName(),
'content'=>$content,
'tags'=>$tags,
'checksum'=>$lc->getChecksum(),
'created'=>date('Y-m-d\TH:i:s+02:00', $document->getDate()),
'created_date'=>date('Y-m-d', $document->getDate()),
'modified'=>date('Y-m-d\TH:i:s+02:00', $lc->getDate()),
2022-12-10 10:25:22 +00:00
'added'=>date('Y-m-d\TH:i:s+02:00', $document->getDate()),
2023-02-18 08:33:55 +00:00
'archive_serial_number'=> (int) $document->getId(), // was null
2022-12-10 10:25:22 +00:00
'original_file_name'=>$lc->getOriginalFileName(),
'archived_file_name'=>$lc->getOriginalFileName()
);
return $data;
} /* }}} */
2023-09-30 10:51:58 +00:00
public function getContrastColor($hexcolor) { /* {{{ */
2022-12-10 10:25:22 +00:00
$r = hexdec(substr($hexcolor, 1, 2));
$g = hexdec(substr($hexcolor, 3, 2));
$b = hexdec(substr($hexcolor, 5, 2));
$yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
2022-12-12 18:00:52 +00:00
return ($yiq >= 148) ? '000000' : 'ffffff';
2023-09-30 10:51:58 +00:00
} /* }}} */
2022-12-10 10:25:22 +00:00
2022-12-12 18:00:52 +00:00
protected function __getCategoryData($category, $inboxtags) { /* {{{ */
2022-12-10 10:25:22 +00:00
$color = substr(md5($category->getName()), 0, 6);
$data = [
'id'=>(int)$category->getId(),
'slug'=>strtolower($category->getName()),
'name'=>$category->getName(),
'color'=>'#'.$color, //'#50b02c',
2022-12-10 10:25:22 +00:00
'text_color'=>'#'.$this->getContrastColor($color),
'match'=>'',
'matching_algorithm'=>6,
'is_insensitive'=>true,
2022-12-12 18:00:52 +00:00
'is_inbox_tag'=>in_array($category->getId(), $inboxtags),
2022-12-10 10:25:22 +00:00
'document_count'=>0
];
return $data;
} /* }}} */
// constructor receives container instance
public function __construct(ContainerInterface $container) { /* {{{ */
$this->container = $container;
} /* }}} */
function api($request, $response) { /* {{{ */
$data = array(
'correspondents'=>$request->getUri().'correspondents/',
'document_types'=>$request->getUri().'document_types/',
'documents'=>$request->getUri().'documents/',
'logs'=>$request->getUri().'logs/',
'tags'=>$request->getUri().'tags/',
'saved_views'=>$request->getUri().'saved_views/',
'storage_paths'=>$request->getUri().'storage_paths/',
'tasks'=>$request->getUri().'tasks/',
'mail_accounts'=>$request->getUri().'mail_accounts/',
'mail_rule'=>$request->getUri().'mail_rule/',
2022-12-10 10:25:22 +00:00
);
return $response->withJson($data, 200);
} /* }}} */
function token($request, $response) { /* {{{ */
$settings = $this->container->config;
$authenticator = $this->container->authenticator;
$logger = $this->container->logger;
$data = $request->getParsedBody();
if(empty($data['username'])) {
$body = $request->getBody();
$data = json_decode($body, true);
}
if($data) {
$userobj = $authenticator->authenticate($data['username'], $data['password']);
if(!$userobj)
return $response->withJson(array('non_field_errors'=>['Unable to log in with provided credentials.']), 403);
2022-12-10 10:25:22 +00:00
else {
if(!empty($settings->_extensions['paperless']['jwtsecret'])) {
$token = new SeedDMS_JwtToken($settings->_extensions['paperless']['jwtsecret']);
2022-12-12 18:01:31 +00:00
if(!empty($settings->_extensions['paperless']['tokenlivetime']))
$days = (int) $settings->_extensions['paperless']['tokenlivetime'];
else
2023-02-08 19:46:01 +00:00
$days = 365;
2022-12-12 18:01:31 +00:00
if(!$tokenstr = $token->jwtEncode($userobj->getId().':'.(time()+$days*84600))) {
2022-12-10 10:25:22 +00:00
return $response->withStatus(403);
}
return $response->withJson(array('token'=>$tokenstr), 200);
} else {
return $response->withJson(array('token'=>$settings->_apiKey), 200);
}
}
}
return $response->withStatus(403);
} /* }}} */
function tags($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$fulltextservice = $this->container->fulltextservice;
$logger = $this->container->logger;
if(false === ($categories = $dms->getDocumentCategories())) {
return $response->withJson(array('results'=>null), 500);
}
if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
2022-12-12 18:03:25 +00:00
if(!($startfolder = $dms->getFolder((int) $userobj->getHomeFolder())))
2022-12-10 10:25:22 +00:00
$startfolder = $dms->getFolder($settings->_rootFolderID);
} elseif(!isset($settings->_extensions['paperless']['rootfolder']) || !($startfolder = $dms->getFolder($settings->_extensions['paperless']['rootfolder'])))
$startfolder = $dms->getFolder($settings->_rootFolderID);
2024-07-16 06:41:57 +00:00
if($fulltextservice && $index = $fulltextservice->Indexer()) {
2022-12-10 10:25:22 +00:00
$lucenesearch = $fulltextservice->Search();
2023-03-09 16:19:36 +00:00
$searchresult = $lucenesearch->search('', array('record_type'=>['document'], 'status'=>[2], 'user'=>[$userobj->getLogin()], 'startFolder'=>$startfolder, 'rootFolder'=>$startfolder), array('limit'=>20), array());
2022-12-10 10:25:22 +00:00
if($searchresult === false) {
return $response->withStatus(500);
} else {
$recs = array();
$facets = $searchresult['facets'];
}
}
$data = [];
$inboxtags = [];
if(!empty($settings->_extensions['paperless']['inboxtags']))
$inboxtags = explode(',', $settings->_extensions['paperless']['inboxtags']);
2022-12-10 10:25:22 +00:00
foreach($categories as $category) {
$tmp = $this->__getCategoryData($category, $inboxtags);
2022-12-10 10:25:22 +00:00
if(isset($facets['category'][$category->getName()]))
$tmp['document_count'] = (int) $facets['category'][$category->getName()];
$data[] = $tmp;
}
return $response->withJson(array('count'=>count($data), 'next'=>null, 'previous'=>null, 'results'=>$data), 200);
} /* }}} */
function post_tag($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
$fulltextservice = $this->container->fulltextservice;
$notifier = $this->container->notifier;
if(!$userobj->isAdmin())
return $response->withStatus(404);
$data = $request->getParsedBody();
$oldcat = $dms->getDocumentCategoryByName($data['name']);
if (is_object($oldcat)) {
return $response->withJson(getMLText('paperless_tag_already_exists'), 400);
}
$newCategory = $dms->addDocumentCategory($data['name']);
if (!$newCategory)
return $response->withJson(getMLText('paperless_could_not_create_tag'), 400);
return $response->withJson($this->__getCategoryData($newCategory, []), 201);
} /* }}} */
function delete_tag($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
$notifier = $this->container->notifier;
$fulltextservice = $this->container->fulltextservice;
if(!$userobj->isAdmin())
return $response->withStatus(404);
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
$cat = $dms->getDocumentCategory($args['id']);
if($cat) {
$documents = $cat->getDocumentsByCategory(10);
if($documents) {
2022-12-14 17:09:16 +00:00
$logger->log('Will not remove because cat has documents', PEAR_LOG_WARNING);
return $response->withStatus(400);
} else {
$logger->log('remove categorie', PEAR_LOG_INFO);
$cat->remove();
}
}
return $response->withStatus(204);
} /* }}} */
2023-03-09 16:19:36 +00:00
/* FIXME: This method does not take the document status into account
* It might be better to create a facet from the correspondant field
* instead of calling getStatistics()
*/
2022-12-10 10:25:22 +00:00
function correspondents($request, $response) { /* {{{ */
2023-02-08 19:47:58 +00:00
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
2022-12-10 10:25:22 +00:00
//file_put_contents("php://stdout", var_dump($request, true));
2023-02-08 19:47:58 +00:00
$correspondents = array();
if(!empty($settings->_extensions['paperless']['correspondentsattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['correspondentsattr'])) {
$res = $attrdef->getStatistics(30);
// print_r($res['frequencies']);
2023-02-08 19:47:58 +00:00
$valueset = $attrdef->getValueSetAsArray();
foreach($valueset as $id=>$val) {
$c = isset($res['frequencies']['document'][md5($val)]) ? $res['frequencies']['document'][md5($val)]['c'] : 0;
2023-02-08 19:47:58 +00:00
$correspondents[] = array(
'id'=>$id+1,
'slug'=>strtolower($val),
'name'=>$val,
'match'=>'',
'matching_algorithm'=>1,
'is_insensitive'=>true,
'document_count'=>$c,
2023-02-08 19:47:58 +00:00
'last_correspondence'=>null
);
}
}
2022-12-10 10:25:22 +00:00
return $response->withJson(array('count'=>count($correspondents), 'next'=>null, 'previous'=>null, 'results'=>$correspondents), 200);
} /* }}} */
function document_types($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
2022-12-10 10:25:22 +00:00
$types = array();
2023-02-21 12:08:09 +00:00
if(!empty($settings->_extensions['paperless']['documenttypesattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['documenttypesattr'])) {
$res = $attrdef->getStatistics(30);
$valueset = $attrdef->getValueSetAsArray();
foreach($valueset as $id=>$val) {
2023-02-21 12:08:09 +00:00
$c = isset($res['frequencies']['document'][md5($val)]) ? $res['frequencies']['document'][md5($val)]['c'] : 0;
$types[] = array(
'id'=>$id+1,
'slug'=>strtolower($val),
'name'=>$val,
'match'=>'',
'matching_algorithm'=>1,
'is_insensitive'=>true,
2023-02-21 12:08:09 +00:00
'document_count'=>$c
);
}
}
2022-12-10 10:25:22 +00:00
return $response->withJson(array('count'=>count($types), 'next'=>null, 'previous'=>null, 'results'=>$types), 200);
} /* }}} */
function saved_views($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
2022-12-10 10:25:22 +00:00
require_once('class.PaperlessView.php');
$views = SeedDMS_PaperlessView::getAllInstances($userobj, $dms);
$data = [];
foreach($views as $view) {
$tmp = $view->getView();
$data[] = $tmp;
}
return $response->withJson(array('count'=>count($data), 'next'=>null, 'previous'=>null, 'results'=>$data), 200);
} /* }}} */
function post_saved_views($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
$fulltextservice = $this->container->fulltextservice;
$notifier = $this->container->notifier;
require_once('class.PaperlessView.php');
$data = $request->getParsedBody();
2022-12-14 17:09:16 +00:00
$logger->log(var_export($data, true), PEAR_LOG_DEBUG);
$view = new SeedDMS_PaperlessView($data['id'], $userobj, $data);
$view->setDMS($dms);
if($newview = $view->save()) {
2022-12-14 17:09:16 +00:00
// $logger->log(var_export($newview, true), PEAR_LOG_DEBUG);
return $response->withJson($newview->getView(), 201);
} else {
return $response->withJson('', 501);
}
} /* }}} */
function delete_saved_views($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
$notifier = $this->container->notifier;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
require_once('class.PaperlessView.php');
$view = SeedDMS_PaperlessView::getInstance($args['id'], $dms);
if($view) {
$logger->log("remove saved view '".$view->getView()['name']."'", PEAR_LOG_INFO);
$view->remove();
}
return $response->withStatus(204);
2022-12-10 10:25:22 +00:00
} /* }}} */
function patch_saved_views($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
$notifier = $this->container->notifier;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
require_once('class.PaperlessView.php');
$data = $request->getParsedBody();
$logger->log(var_export($data, true), PEAR_LOG_DEBUG);
$view = SeedDMS_PaperlessView::getInstance($args['id'], $dms);
if($view) {
$logger->log('patch saved view', PEAR_LOG_INFO);
$view->setView($data);
$view->save();
}
return $response->withJson($view->getView(), 200);
} /* }}} */
2022-12-10 10:25:22 +00:00
function storage_paths($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
2022-12-10 10:25:22 +00:00
if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
if(!($rootfolder = $dms->getFolder((int) $userobj->getHomeFolder())))
$rootfolder = $dms->getFolder($settings->_rootFolderID);
} elseif(!isset($settings->_extensions['paperless']['rootfolder']) || !($rootfolder = $dms->getFolder($settings->_extensions['paperless']['rootfolder'])))
$rootfolder = $dms->getFolder($settings->_rootFolderID);
$folderprocess = new SeedDMS_ExtPaperless_Process_Folder();
// call_user_func(array($folderprocess, 'process'), $folder, -1);
$tree = new SeedDMS_FolderTree($rootfolder, array($folderprocess, 'process'));
$list = $folderprocess->getList();
$paths = array();
foreach($list as $fid=>$path) {
if($path[1] > 0)
$paths[] = array('id'=>(int)$fid, 'name'=>$path[0], 'slug'=>$path[0], 'path'=>$path[0], 'match'=>'', 'matching_algorithm'=>6, 'is_insensitive'=>true, 'document_count'=>$path[1]);
}
2022-12-10 10:25:22 +00:00
return $response->withJson(array('count'=>count($paths), 'next'=>null, 'previous'=>null, 'results'=>$paths), 200);
} /* }}} */
function documents($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$fulltextservice = $this->container->fulltextservice;
$logger = $this->container->logger;
$params = $request->getQueryParams();
2022-12-14 17:09:16 +00:00
$logger->log(var_export($params, true), PEAR_LOG_DEBUG);
2022-12-10 10:25:22 +00:00
if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
if(!($rootfolder = $dms->getFolder((int) $userobj->getHomeFolder())))
$rootfolder = $dms->getFolder($settings->_rootFolderID);
} elseif(!isset($settings->_extensions['paperless']['rootfolder']) || !($rootfolder = $dms->getFolder($settings->_extensions['paperless']['rootfolder'])))
$rootfolder = $dms->getFolder($settings->_rootFolderID);
$startfolder = $rootfolder;
2022-12-10 10:25:22 +00:00
$logger->log('Searching for documents in folder '.$rootfolder->getId(), PEAR_LOG_DEBUG);
2022-12-10 10:25:22 +00:00
$fullsearch = true;
2022-12-18 12:41:06 +00:00
$query = '';
2023-05-11 07:29:40 +00:00
$astart = $mstart = 0;
$aend = $mend = 0;
2022-12-10 10:25:22 +00:00
if($fullsearch) {
if (isset($params["query"]) && is_string($params["query"])) {
$queryparts = explode(',', $params["query"]);
foreach($queryparts as $querypart) {
2023-05-11 07:29:40 +00:00
/* 'added' is time when a document was added. This is 'created'
* in the fulltext index.
*/
if(substr($querypart, 0, 7) == 'added:[') {
$q = substr($querypart, 7, -1);
if($t = explode(' to ', $q, 2)) {
$astart = strtotime($t[0]);
$aend = strtotime($t[1])+86400;
// echo "astart: ".date('Y-m-d', $astart)."\n";
// echo "aend: ".date('Y-m-d', $aend);
}
2023-05-11 07:29:40 +00:00
}
/* 'created' is the time when a document was actually created.
* There is no equivalent in the fulltext index.
* Currently is identical to 'added'.
*/
elseif(substr($querypart, 0, 9) == 'created:[') {
$q = substr($querypart, 9, -1);
if($t = explode(' to ', $q, 2)) {
$astart = strtotime($t[0]);
$aend = strtotime($t[1])+86400;
// echo "astart: ".date('Y-m-d', $astart)."\n";
// echo "aend: ".date('Y-m-d', $aend);
}
2023-09-30 10:51:58 +00:00
}
2023-05-11 07:29:40 +00:00
/* 'modified' is the time when a document was last modified.
* This is 'modified' in the fulltext index.
*/
elseif(substr($querypart, 0, 10) == 'modified:[') {
$q = substr($querypart, 10, -1);
if($t = explode(' to ', $q, 2)) {
$mstart = strtotime($t[0]);
$mend = strtotime($t[1])+86400;
// echo "mstart: ".date('Y-m-d', $mstart)."\n";
// echo "mend: ".date('Y-m-d', $mend);
}
2023-09-30 10:51:58 +00:00
} else {
$query = $querypart;
2023-05-11 07:29:40 +00:00
}
}
} elseif (isset($params["title_content"]) && is_string($params["title_content"])) {
$query = $params['title_content'];
} elseif (isset($params["title__icontains"]) && is_string($params["title__icontains"])) {
$query = $params['title__icontains'];
2022-12-10 10:25:22 +00:00
}
2023-02-18 08:42:59 +00:00
$limit = isset($params['page_size']) ? (int) $params['page_size'] : 25;
$page = (isset($params['page']) && $params['page'] > 0) ? (int) $params['page'] : 1;
2023-03-15 13:23:03 +00:00
$offset = ($page-1)*$limit;
/* Truncate content if requested
* See https://github.com/paperless-ngx/paperless-ngx/blob/main/src/documents/serialisers.py
*/
$truncate_content = isset($params['truncate_content']) && ($params['truncate_content'] == 'true');
2023-02-18 08:42:59 +00:00
2022-12-10 10:25:22 +00:00
$order = [];
if (isset($params["ordering"]) && is_string($params["ordering"])) {
if($params["ordering"][0] == '-') {
$order['dir'] = 'desc';
2022-12-10 10:25:22 +00:00
$orderfield = substr($params["ordering"], 1);
} else {
$order['dir'] = 'asc';
2022-12-10 10:25:22 +00:00
$orderfield = $params["ordering"];
}
2023-05-02 09:43:44 +00:00
if(in_array($orderfield, ['modified', 'created', 'title']))
2022-12-10 10:25:22 +00:00
$order['by'] = $orderfield;
elseif($orderfield == 'added')
$order['by'] = 'created';
2023-02-18 08:42:59 +00:00
elseif($orderfield == 'archive_serial_number')
$order['by'] = 'id';
2023-05-02 08:13:43 +00:00
elseif($orderfield == 'correspondent__name') {
if(!empty($settings->_extensions['paperless']['correspondentsattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['correspondentsattr'])) {
$order['by'] = 'attr_'.$attrdef->getId();
}
}
2022-12-10 10:25:22 +00:00
}
2023-10-10 10:28:57 +00:00
/* Searching for tags (category) {{{ */
2022-12-10 10:25:22 +00:00
$categories = array();
$categorynames = array();
if(isset($params['tags__id'])) {
$catid = (int) $params['tags__id'];
if($catid) {
if($cat = $dms->getDocumentCategory($catid)) {
$categories[] = $cat;
$categorynames[] = $cat->getName();
}
}
}
/* tags__id__in is used when searching for documents by id */
if(isset($params['tags__id__all'])) {
$catids = explode(',', $params['tags__id__all']);
foreach($catids as $catid)
if($catid) {
if($cat = $dms->getDocumentCategory($catid)) {
$categories[] = $cat;
$categorynames[] = $cat->getName();
}
}
}
/* tags__id__in is used when getting the documents of the inbox */
if(isset($params['tags__id__in'])) {
$catids = explode(',', $params['tags__id__in']);
if($catids) {
foreach($catids as $catid)
if($cat = $dms->getDocumentCategory($catid)) {
$categories[] = $cat;
$categorynames[] = $cat->getName();
}
2022-12-10 10:25:22 +00:00
}
} elseif(isset($params['is_tagged']) && $params['is_tagged'] == '1') {
$categorynames[] = '*';
2022-12-10 10:25:22 +00:00
}
2023-10-10 10:28:57 +00:00
/* }}} */
2022-12-10 10:25:22 +00:00
2023-05-02 06:23:59 +00:00
/* more_like_id is set to find similar documents {{{ */
if(isset($params['more_like_id'])) {
2023-03-15 13:23:03 +00:00
if($fulltextservice && $index = $fulltextservice->Indexer()) {
$lucenesearch = $fulltextservice->Search();
2024-07-16 06:41:57 +00:00
if($searchhit = $lucenesearch->getDocument((int) $params['more_like_id'])) {
$idoc = $searchhit->getDocument();
if($idoc) {
try {
$fullcontent = $idoc->getFieldValue('content');
} catch (Exception $e) {
$fullcontent = '';
}
$wcl = 2000;
$shortcontent = mb_strimwidth($fullcontent, 0, $wcl);
/* Create a list of words and its occurences to be passed
* to the classification.
* The '.' is added as valid character in a word, because solr's
* standard tokenizer treats it as a valid char as well.
* But sqlitefts treats '.' as a separator
*/
$wordcount = self::mb_word_count($shortcontent, MB_CASE_LOWER, '');
arsort($wordcount);
$newquery = [];
foreach($wordcount as $word=>$n) {
if(mb_strlen($word) > 4 && ($n > 2 || count($newquery) < 5))
$newquery[] = $word;
}
// echo implode(' ', $newquery);
$logger->log("Query for '".implode(' ', $newquery)."'", PEAR_LOG_DEBUG);
/* $newquery is empty if the document doesn't have a fulltext.
* In that case it makes no sense to search for similar documents
* Otherwise search for documents with newquery, but if doesn't yield
* a result, short the newquery by the last term and try again until
* newquery is void
*/
while($newquery) {
$searchresult = $lucenesearch->search(implode(' ', $newquery), array('record_type'=>['document'], 'status'=>[2], 'user'=>[$userobj->getLogin()], 'startFolder'=>$startfolder, 'rootFolder'=>$rootfolder), array('limit'=>$limit, 'offset'=>$offset), $order);
if($searchresult) {
$recs = array();
if($searchresult['hits']) {
$allids = '';
foreach($searchresult['hits'] as $hit) {
if(($hit['document_id'][0] == 'D') && ($hit['document_id'] != 'D'.((int)$params['more_like_id']))) {
if($tmp = $dms->getDocument((int) substr($hit['document_id'], 1))) {
$allids .= $hit['document_id'].' ';
$recs[] = $this->__getDocumentData($tmp, $truncate_content);
}
} else {
$searchresult['count']--;
}
2023-03-15 13:23:03 +00:00
}
2024-07-16 06:41:57 +00:00
$logger->log('Result is '.$allids, PEAR_LOG_DEBUG);
if($recs)
return $response->withJson(array('count'=>$searchresult['count'], 'next'=>null, 'previous'=>null, 'offset'=>$offset, 'limit'=>$limit, 'results'=>$recs), 200);
else {
/* Still nothing found, so try a shorter query */
array_pop($newquery);
}
} else {
/* Still nothing found, so try a shorter query */
array_pop($newquery);
}
} else {
2024-07-16 06:41:57 +00:00
/* Quit the while loop right away, if the search failed */
$newquery = false;
2023-03-15 13:23:03 +00:00
}
}
}
}
}
return $response->withJson(array('count'=>0, 'next'=>null, 'previous'=>null, 'offset'=>0, 'limit'=>$limit, 'results'=>[]), 200);
2023-03-15 13:23:03 +00:00
/* Get all documents in the same folder and subfolders
$likeid = (int) $params['more_like_id'];
if($likeid && $likedoc = $dms->getDocument($likeid)) {
$startfolder = $likedoc->getFolder();
}
2023-03-15 13:23:03 +00:00
*/
2023-05-02 06:23:59 +00:00
} /* }}} */
2023-10-10 10:28:57 +00:00
/* Search for correspondent {{{ */
$cattrs = [];
$correspondent = null;
if(!empty($settings->_extensions['paperless']['correspondentsattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['correspondentsattr'])) {
if(isset($params['correspondent__id']) && $params['correspondent__id']>0) {
$valueset = $attrdef->getValueSetAsArray();
if(isset($valueset[$params['correspondent__id']-1])) {
$correspondent = $valueset[$params['correspondent__id']-1];
$cattrs['attr_'.$attrdef->getId()] = $correspondent;
}
}
/* Search for any correspondent (correspondent__isnull = 0) */
if(isset($params['correspondent__isnull']) && $params['correspondent__isnull'] == '0') {
$cattrs['attr_'.$attrdef->getId()] = '__any__';
}
/* Search for no correspondent (correspondent__isnull = 1) */
if(isset($params['correspondent__isnull']) && $params['correspondent__isnull'] == '1') {
$cattrs['attr_'.$attrdef->getId()] = '__notset__';
}
}
2023-10-10 10:28:57 +00:00
/* }}} */
2023-10-10 10:28:57 +00:00
/* Search form document type {{{ */
$documenttype = null;
if(isset($params['document_type__id']) && $params['document_type__id']>0) {
if(!empty($settings->_extensions['paperless']['documenttypesattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['documenttypesattr'])) {
$valueset = $attrdef->getValueSetAsArray();
if(isset($valueset[$params['document_type__id']-1])) {
$documenttype = $valueset[$params['document_type__id']-1];
$cattrs['attr_'.$attrdef->getId()] = $documenttype;
}
}
}
2023-10-10 10:28:57 +00:00
/* Search for any document_type (document_type__isnull = 0) */
/* Search for no document_type (document_type__isnull = 1) */
/* }}} */
if(isset($params['storage_path__id']) && $params['storage_path__id']>0) {
if($f = $dms->getFolder((int) $params['storage_path__id']))
$startfolder = $f;
}
2022-12-11 14:01:09 +00:00
/* The start and end date for e.g. 2012-12-10 is
* 2022-12-09 and 2022-12-11
* Because makeTsFromDate() returns the start of the day
* one day has to be added.
*/
2022-12-10 10:25:22 +00:00
if(isset($params['added__date__gt'])) {
2022-12-11 14:01:09 +00:00
$astart = (int) makeTsFromDate($params['added__date__gt'])+86400;
2022-12-10 10:25:22 +00:00
}
if(isset($params['added__date__lt'])) {
$aend = (int) makeTsFromDate($params['added__date__lt']);
}
2023-01-10 19:40:19 +00:00
if(isset($params['created__date__gt'])) {
$astart = (int) makeTsFromDate($params['created__date__gt'])+86400;
}
if(isset($params['created__date__lt'])) {
$aend = (int) makeTsFromDate($params['created__date__lt']);
}
if($fulltextservice && $index = $fulltextservice->Indexer()) {
$lucenesearch = $fulltextservice->Search();
2023-01-10 19:40:19 +00:00
$logger->log('Query is '.$query, PEAR_LOG_DEBUG);
/*
$logger->log('User is '.$userobj->getLogin(), PEAR_LOG_DEBUG);
$logger->log('created_start is '.$astart, PEAR_LOG_DEBUG);
$logger->log('created_end is '.$aend, PEAR_LOG_DEBUG);
$logger->log('modified_start is '.$mstart, PEAR_LOG_DEBUG);
$logger->log('modified_end is '.$mend, PEAR_LOG_DEBUG);
$logger->log('startfolder is '.$startfolder->getId(), PEAR_LOG_DEBUG);
$logger->log('rootfolder is '.$rootfolder->getId(), PEAR_LOG_DEBUG);
$logger->log('limit is '.$limit, PEAR_LOG_DEBUG);
$logger->log('offset is '.$offset, PEAR_LOG_DEBUG);
*/
$searchresult = $lucenesearch->search($query, array('record_type'=>['document'], 'status'=>[2], 'user'=>[$userobj->getLogin()], 'category'=>$categorynames, 'created_start'=>$astart, 'created_end'=>$aend, 'modified_start'=>$mstart, 'modified_end'=>$mend, 'startFolder'=>$startfolder, 'rootFolder'=>$rootfolder, 'attributes'=>$cattrs), array('limit'=>$limit, 'offset'=>$offset), $order, array('no_facets'=>true));
2022-12-13 10:59:05 +00:00
if($searchresult) {
2022-12-10 10:25:22 +00:00
$recs = array();
$facets = $searchresult['facets'];
$dcount = 0;
$fcount = 0;
if($searchresult['hits']) {
$allids = '';
2022-12-10 10:25:22 +00:00
foreach($searchresult['hits'] as $hit) {
if($hit['document_id'][0] == 'D') {
if($tmp = $dms->getDocument((int) substr($hit['document_id'], 1))) {
$allids .= $hit['document_id'].' ';
2022-12-10 10:25:22 +00:00
// if($tmp->getAccessMode($user) >= M_READ) {
// $tmp->verifyLastestContentExpriry();
$recs[] = $this->__getDocumentData($tmp, $truncate_content);
2022-12-10 10:25:22 +00:00
// }
}
}
}
$logger->log('Result is '.$allids, PEAR_LOG_DEBUG);
2022-12-10 10:25:22 +00:00
}
2022-12-13 10:59:05 +00:00
if($offset + $limit < $searchresult['count']) {
$params['page'] = $page+1;
2022-12-13 10:59:05 +00:00
$next = $request->getUri()->getBasePath().'/api/documents?'.http_build_query($params);
} else
$next = null;
if($offset > 0) {
$params['page'] = $page-1;
2022-12-13 10:59:05 +00:00
$prev = $request->getUri()->getBasePath().'/api/documents?'.http_build_query($params);
} else
$prev = null;
return $response->withJson(array('count'=>$searchresult['count'], 'next'=>$next, 'previous'=>$prev, 'offset'=>$offset, 'limit'=>$limit, 'results'=>$recs), 200);
2022-12-10 10:25:22 +00:00
}
}
}
2022-12-13 10:59:05 +00:00
return $response->withJson('Error', 500);
2022-12-10 10:25:22 +00:00
} /* }}} */
2023-11-03 15:42:28 +00:00
function document($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$fulltextservice = $this->container->fulltextservice;
$logger = $this->container->logger;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
$document = $dms->getDocument($args['id']);
if($document) {
if($document->getAccessMode($userobj) >= M_READ) {
$rec = $this->__getDocumentData($document, true);
return $response->withJson($rec, 200);
} else {
return $response->withStatus(404);
}
}
return $response->withJson('Error', 500);
} /* }}} */
/**
* autocompletion is done on the last term of a list of comma separated
* terms. The returned value is then a list of the first n-1 terms
* concatenated with the completed terms, e.g.
* 'term1 ter' will be auto completed to 'term1 term2', 'term1 term3',
* etc.
*/
2022-12-10 10:25:22 +00:00
function autocomplete($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$fulltextservice = $this->container->fulltextservice;
$logger = $this->container->logger;
2023-01-16 15:03:10 +00:00
if(!empty($settings->_extensions['paperless']['autocompletefield']))
$field = $settings->_extensions['paperless']['autocompletefield'];
else
$field = 'title';
2022-12-10 10:25:22 +00:00
$params = $request->getQueryParams();
$allterms = explode(' ', $params['term']);
$query = trim(array_pop($allterms));
2022-12-14 17:09:16 +00:00
$logger->log(var_export($params, true), PEAR_LOG_DEBUG);
2022-12-10 10:25:22 +00:00
$list = [];
2024-07-16 06:41:57 +00:00
if($fulltextservice && ($index = $fulltextservice->Indexer())) {
2023-01-16 15:03:10 +00:00
if($terms = $index->terms($query, $field)) {
2022-12-10 10:25:22 +00:00
foreach($terms as $term)
$list[] = implode(' ', $allterms).' '.$term->text;
2022-12-10 10:25:22 +00:00
}
}
return $response->withJson($list, 200);
} /* }}} */
function ui_settings($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
$data = array(
'user_id'=>$userobj->getId(),
'username'=>$userobj->getLogin(),
'display_name'=>$userobj->getFullName(),
'settings'=>array(
'update_checking'=>array(
'enabled'=>false,
'backend_setting'=>'default'
),
'bulk_edit'=>array(
'apply_on_close'=>false,
'confirmation_dialogs'=>true
),
'documentListSize'=>50,
'slim_sidebar'=>false,
'dark_mode'=>array(
'use_system'=>true,
'enabled'=>false, // paperless-ngx 1.13.0 returns a string
'thumb_inverted'=>true, // paperless-ngx 1.13.0 returns a string
),
'theme'=>array(
'color'=>'',
),
'document_details'=>array(
'native_pdf_viewer'=>false,
),
'date_display'=>array(
'date_local'=>'',
'date_format'=>'mediumDate',
),
'notifications'=>array(
'consumer_new_documents'=>true,
'consumer_success'=>true,
'consumer_failed'=>true,
'consumer_suppress_on_dashboard'=>true,
),
'comments_enabled'=>true,
'language'=>'en-gb',
),
);
/*
$data = array(
'user'=>[
'id'=>$userobj->getId(),
'username'=>$userobj->getLogin(),
'is_superuser'=>$userobj->isAdmin(),
'groups'=>[]
],
2022-12-10 10:25:22 +00:00
'settings'=>array('update_checking'=>array('backend_setting'=>'default')),
);
*/
2022-12-10 10:25:22 +00:00
return $response->withJson($data, 200);
} /* }}} */
2022-12-12 18:02:22 +00:00
function statstotal($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$fulltextservice = $this->container->fulltextservice;
$logger = $this->container->logger;
if(false === ($categories = $dms->getDocumentCategories())) {
return $response->withJson(array('results'=>null), 500);
}
if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
if(!($startfolder = $dms->getFolder((int) $userobj->getHomeFolder())))
$startfolder = $dms->getFolder($settings->_rootFolderID);
} elseif(!isset($settings->_extensions['paperless']['rootfolder']) || !($startfolder = $dms->getFolder($settings->_extensions['paperless']['rootfolder'])))
$startfolder = $dms->getFolder($settings->_rootFolderID);
$data = array(
'documents_total'=>0,
'documents_inbox'=>0,
);
if($fulltextservice && ($index = $fulltextservice->Indexer())) {
$lucenesearch = $fulltextservice->Search();
$searchresult = $lucenesearch->search('', array('record_type'=>['document'], 'status'=>[2], 'user'=>[$userobj->getLogin()], 'startFolder'=>$startfolder, 'rootFolder'=>$startfolder), array('limit'=>1), array(), array('no_facets'=>true));
2022-12-12 18:02:22 +00:00
if($searchresult === false) {
return $response->withStatus(500);
} else {
$recs = array();
$facets = $searchresult['facets'];
// $logger->log(var_export($facets, true), PEAR_LOG_DEBUG);
2022-12-12 18:02:22 +00:00
}
2023-10-11 14:36:06 +00:00
$data['documents_total'] = $searchresult['count'];
$inboxtags = [];
if(!empty($settings->_extensions['paperless']['inboxtags']) && $inboxtags = explode(',', $settings->_extensions['paperless']['inboxtags'])) {
foreach($inboxtags as $inboxtagid) {
$cats = [];
if($inboxtag = $dms->getDocumentCategory((int) $inboxtagid)) {
$cats[] = $inboxtag->getName();
}
if($cats) {
$searchresult = $lucenesearch->search('', array('record_type'=>['document'], 'status'=>[2], 'user'=>[$userobj->getLogin()], 'category'=>$cats, 'startFolder'=>$startfolder, 'rootFolder'=>$startfolder), array('limit'=>1), array(), array('no_facets'=>true));
if($searchresult === false) {
return $response->withStatus(500);
}
$data['documents_inbox'] = $searchresult['count'];
}
}
}
2022-12-12 18:02:22 +00:00
}
return $response->withJson($data, 200);
} /* }}} */
2022-12-10 10:25:22 +00:00
function fetch_thumb($request, $response, $args) { /* {{{ */
return $response->withRedirect($request->getUri()->getBasePath().'/api/documents/'.$args['id'].'/thumb/', 302);
} /* }}} */
function documents_thumb($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
2023-10-11 14:37:56 +00:00
2022-12-10 10:25:22 +00:00
$document = $dms->getDocument($args['id']);
if($document) {
if($document->getAccessMode($userobj) >= M_READ) {
$object = $document->getLatestContent();
$width = 400;
$previewer = new SeedDMS_Preview_Previewer($settings->_cacheDir, $width);
if($conversionmgr)
$previewer->setConversionMgr($conversionmgr);
else
$previewer->setConverters($settings->_converters['preview']);
if(!$previewer->hasPreview($object))
$previewer->createPreview($object);
$file = $previewer->getFileName($object, $width).".png";
if(!($fh = @fopen($file, 'rb'))) {
return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500);
}
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
return $response->withHeader('Content-Type', 'image/png')
->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Content-Disposition', 'attachment; filename="preview-' . $document->getID() . "-" . $object->getVersion() . "-" . $width . ".png" . '"')
->withHeader('Content-Length', $previewer->getFilesize($object))
->withBody($stream);
}
}
return $response->withStatus(403);
} /* }}} */
function fetch_doc($request, $response, $args) { /* {{{ */
$logger = $this->container->logger;
$logger->log('Fetch doc '.$args['id'], PEAR_LOG_INFO);
return $response->withRedirect($request->getUri()->getBasePath().'/api/documents/'.$args['id'].'/download/', 302);
} /* }}} */
/**
* documents_preview works like documents_download but converts
* documents which are not pdf already into pdf
*/
function documents_preview($request, $response, $args) { /* {{{ */
2022-12-10 10:25:22 +00:00
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
2023-10-11 14:37:56 +00:00
2022-12-14 17:09:16 +00:00
$logger->log('Get preview of doc '.$args['id'], PEAR_LOG_INFO);
2022-12-10 10:25:22 +00:00
$document = $dms->getDocument($args['id']);
if($document) {
if($document->getAccessMode($userobj) >= M_READ) {
$lc = $document->getLatestContent();
if($lc) {
if($lc->getMimeType() == 'application/pdf') {
if (pathinfo($document->getName(), PATHINFO_EXTENSION) == $lc->getFileType())
$filename = $document->getName();
else
$filename = $document->getName().$lc->getFileType();
$file = $dms->contentDir . $lc->getPath();
if(!($fh = @fopen($file, 'rb'))) {
return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500);
}
$filesize = filesize($dms->contentDir . $lc->getPath());
} else {
$previewer = new SeedDMS_Preview_PdfPreviewer($settings->_cacheDir);
if($conversionmgr)
$previewer->setConversionMgr($conversionmgr);
else
$previewer->setConverters(isset($settings->_converters['pdf']) ? $settings->_converters['pdf'] : array());
if(!$previewer->hasPreview($lc))
$previewer->createPreview($lc);
if(!$previewer->hasPreview($lc)) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500);
} else {
$filename = $document->getName().".pdf";
$file = $previewer->getFileName($lc).".pdf";
$filesize = filesize($file);
if(!($fh = @fopen($file, 'rb'))) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500);
}
}
2022-12-10 10:25:22 +00:00
}
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
return $response->withHeader('Content-Type', $lc->getMimeType())
->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
->withHeader('Content-Length', $filesize)
2022-12-10 10:25:22 +00:00
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->withHeader('Pragma', 'no-cache')
->withBody($stream);
} else {
return $response->withStatus(403);
}
} else
return $response->withStatus(404);
} else {
return $response->withStatus(500);
}
} /* }}} */
function documents_download($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
$params = $request->getQueryParams();
$logger->log(var_export($params, true), PEAR_LOG_DEBUG);
$logger->log('Download doc '.$args['id'], PEAR_LOG_INFO);
$document = $dms->getDocument($args['id']);
if($document) {
if($document->getAccessMode($userobj) >= M_READ) {
$lc = $document->getLatestContent();
if($lc) {
/* Used to check if empty($settings->_extensions['paperless']['converttopdf'])
* but that makes no sense any more, because paperless mobile sets
* the parameter 'original=true' if the original document shall be
* downloaded.
*/
if((isset($params['original']) && $params['original'] == 'true') || $lc->getMimeType() == 'application/pdf') {
if (pathinfo($document->getName(), PATHINFO_EXTENSION) == $lc->getFileType())
$filename = $document->getName();
else
$filename = $document->getName().$lc->getFileType();
$file = $dms->contentDir . $lc->getPath();
if(!($fh = @fopen($file, 'rb'))) {
return $response->withJson(array('success'=>false, 'message'=>'', 'data'=>''), 500);
}
$filesize = filesize($dms->contentDir . $lc->getPath());
} else {
$previewer = new SeedDMS_Preview_PdfPreviewer($settings->_cacheDir);
if($conversionmgr)
$previewer->setConversionMgr($conversionmgr);
else
$previewer->setConverters(isset($settings->_converters['pdf']) ? $settings->_converters['pdf'] : array());
if(!$previewer->hasPreview($lc))
$previewer->createPreview($lc);
if(!$previewer->hasPreview($lc)) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500);
} else {
$filename = $document->getName().".pdf";
$file = $previewer->getFileName($lc).".pdf";
$filesize = filesize($file);
if(!($fh = @fopen($file, 'rb'))) {
$logger->log('Creating pdf preview failed', PEAR_LOG_ERR);
return $response->withJson('', 500);
}
}
}
$stream = new \Slim\Http\Stream($fh); // create a stream instance for the response body
return $response->withHeader('Content-Type', $lc->getMimeType())
->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Transfer-Encoding', 'binary')
->withHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
->withHeader('Content-Length', $filesize)
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->withHeader('Pragma', 'no-cache')
->withBody($stream);
} else {
return $response->withStatus(403);
}
} else
return $response->withStatus(404);
} else {
return $response->withStatus(500);
}
} /* }}} */
2022-12-10 10:25:22 +00:00
function documents_metadata($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
2023-10-11 14:37:56 +00:00
2022-12-10 10:25:22 +00:00
$document = $dms->getDocument($args['id']);
if($document) {
if($document->getAccessMode($userobj) >= M_READ) {
$lc = $document->getLatestContent();
if($lc) {
return $response->withJson(array(
'original_checksum'=>$lc->getChecksum(),
2022-12-11 14:01:31 +00:00
'original_size'=>(int) $lc->getFilesize(),
'original_mime_type'=>$lc->getMimeType(),
'media_filename'=>$lc->getOriginalFileName(),
'has_archive_version'=>false,
'original_metadata'=>[],
'archive_checksum'=>$lc->getChecksum(),
'archive_media_filename'=>$lc->getOriginalFileName(),
'original_filename'=>$lc->getOriginalFileName(),
2023-11-03 15:42:28 +00:00
'lang'=>'en',
2022-12-11 14:01:31 +00:00
'archive_size'=>(int) $lc->getFilesize(),
'archive_metadata'=>[],
2022-12-10 10:25:22 +00:00
), 200);
} else {
return $response->withStatus(403);
}
} else
return $response->withStatus(404);
} else {
return $response->withStatus(500);
}
} /* }}} */
function post_document($request, $response) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$logger = $this->container->logger;
$fulltextservice = $this->container->fulltextservice;
$notifier = $this->container->notifier;
2023-01-09 09:05:22 +00:00
if(isset($settings->_extensions['paperless']['uploadfolder']))
$mfolder = $dms->getFolder($settings->_extensions['paperless']['uploadfolder']);
if(!$mfolder) {
if(!empty($settings->_extensions['paperless']['usehomefolder'])) {
if(!($mfolder = $dms->getFolder((int) $userobj->getHomeFolder())))
$mfolder = $dms->getFolder($settings->_rootFolderID);
} elseif(!isset($settings->_extensions['paperless']['rootfolder']) || !($mfolder = $dms->getFolder($settings->_extensions['paperless']['rootfolder'])))
2022-12-10 10:25:22 +00:00
$mfolder = $dms->getFolder($settings->_rootFolderID);
2023-01-09 09:05:22 +00:00
}
2022-12-10 10:25:22 +00:00
if($mfolder) {
$logger->log("Uploading into folder '".$mfolder->getName()."' (".$mfolder->getId().")", PEAR_LOG_DEBUG);
if($mfolder->getAccessMode($userobj) < M_READWRITE) {
$logger->log('No write access on folder '.$mfolder->getId(), PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withStatus(403);
}
2022-12-10 10:25:22 +00:00
$data = $request->getParsedBody();
2022-12-14 17:09:16 +00:00
// $logger->log(var_export($data, true), PEAR_LOG_DEBUG);
2022-12-10 10:25:22 +00:00
$uploadedFiles = $request->getUploadedFiles();
if (count($uploadedFiles) == 0) {
2022-12-11 14:02:07 +00:00
$logger->log('No files uploaded', PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withJson(getMLText("paperless_no_files_uploaded"), 400);
}
2022-12-11 14:02:07 +00:00
2022-12-10 10:25:22 +00:00
$file_info = array_pop($uploadedFiles);
2022-12-11 14:02:07 +00:00
$maxuploadsize = SeedDMS_Core_File::parse_filesize($settings->_maxUploadSize);
if ($maxuploadsize && $file_info->getSize() > $maxuploadsize) {
$logger->log('File too large ('.$file_info->getSize().' > '.$maxuploadsize.')', PEAR_LOG_ERR);
return $response->withJson(getMLText("paperless_upload_maxsize"), 400);
}
$origfilename = null;
2022-12-10 10:25:22 +00:00
if ($origfilename == null)
$origfilename = $file_info->getClientFilename();
if(!empty($data['title']))
$docname = $data['title'];
else
$docname = $origfilename;
/* Check if name already exists in the folder */
if(!$settings->_enableDuplicateDocNames) {
if($mfolder->hasDocumentByName($docname)) {
2022-12-11 14:20:45 +00:00
$logger->log('Duplicate document name '.$docname, PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withJson(getMLText("document_duplicate_name"), 409);
}
}
/* If several tags are set, they will all be saved individually in
* a parameter named 'tags'. This cannot be handled by php. It would
* require to use 'tags[]'. Hence, only the last tag will be taken into
* account.
*/
$cats = [];
if(!empty($data['tags'])) {
if($cat = $dms->getDocumentCategory((int) $data['tags']))
$cats[] = $cat;
}
2022-12-10 10:25:22 +00:00
$userfiletmp = $file_info->file;
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$userfiletype = finfo_file($finfo, $userfiletmp);
$fileType = ".".pathinfo($origfilename, PATHINFO_EXTENSION);
finfo_close($finfo);
$reviewers = array();
$approvers = array();
$reviewers["i"] = array();
$reviewers["g"] = array();
$approvers["i"] = array();
$approvers["g"] = array();
$workflow = null;
if($settings->_workflowMode == 'traditional' || $settings->_workflowMode == 'traditional_only_approval') {
// add mandatory reviewers/approvers
if($settings->_workflowMode == 'traditional') {
2024-03-15 09:45:19 +00:00
$mreviewers = getMandatoryReviewers($mfolder, null, $userobj);
if($mreviewers['i'])
$reviewers['i'] = array_merge($reviewers['i'], $mreviewers['i']);
if($mreviewers['g'])
$reviewers['g'] = array_merge($reviewers['g'], $mreviewers['g']);
}
2024-03-15 09:45:19 +00:00
$mapprovers = getMandatoryApprovers($mfolder, null, $userobj);
if($mapprovers['i'])
$approvers['i'] = array_merge($approvers['i'], $mapprovers['i']);
if($mapprovers['g'])
$approvers['g'] = array_merge($approvers['g'], $mapprovers['g']);
} elseif($settings->_workflowMode == 'advanced') {
if($workflows = $userobj->getMandatoryWorkflows()) {
$workflow = array_shift($workflows);
}
}
2022-12-10 10:25:22 +00:00
$comment = '';
$expires = null;
$owner = null;
$keywords = '';
$sequence = 1;
$reqversion = null;
$version_comment = '';
$attributes = array();
$attributes_version = array();
$notusers = array();
$notgroups = array();
$controller = Controller::factory('AddDocument', array('dms'=>$dms, 'user'=>$userobj));
$controller->setParam('documentsource', 'paperless');
$controller->setParam('folder', $mfolder);
$controller->setParam('fulltextservice', $fulltextservice);
$controller->setParam('name', $docname);
$controller->setParam('comment', $comment);
$controller->setParam('expires', $expires);
$controller->setParam('keywords', $keywords);
$controller->setParam('categories', $cats);
$controller->setParam('owner', $userobj);
$controller->setParam('userfiletmp', $userfiletmp);
$controller->setParam('userfilename', $origfilename ? $origfilename : basename($userfiletmp));
$controller->setParam('filetype', $fileType);
$controller->setParam('userfiletype', $userfiletype);
$controller->setParam('sequence', $sequence);
$controller->setParam('reviewers', $reviewers);
$controller->setParam('approvers', $approvers);
$controller->setParam('reqversion', $reqversion);
$controller->setParam('versioncomment', $version_comment);
$controller->setParam('attributes', $attributes);
$controller->setParam('attributesversion', $attributes_version);
$controller->setParam('workflow', $workflow);
$controller->setParam('notificationgroups', $notgroups);
$controller->setParam('notificationusers', $notusers);
$controller->setParam('maxsizeforfulltext', $settings->_maxSizeForFullText);
$controller->setParam('defaultaccessdocs', $settings->_defaultAccessDocs);
if(!$document = $controller()) {
$err = $controller->getErrorMsg();
if(is_string($err))
$errmsg = getMLText($err);
elseif(is_array($err)) {
$errmsg = getMLText($err[0], $err[1]);
} else {
$errmsg = $err;
}
2022-12-14 17:09:16 +00:00
$logger->log('Upload failed: '.$errmsg, PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withJson(getMLText('paperless_upload_failed'), 500);
} else {
2022-12-14 17:09:16 +00:00
$logger->log('Upload succeeded', PEAR_LOG_INFO);
2022-12-10 10:25:22 +00:00
/* Turn off for now, because file_info is not an array
if($controller->hasHook('cleanUpDocument')) {
$controller->callHook('cleanUpDocument', $document, $file_info);
}
*/
// Send notification to subscribers of folder.
if($notifier) {
$notifier->sendNewDocumentMail($document, $userobj);
}
if($settings->_removeFromDropFolder) {
if(file_exists($userfiletmp)) {
unlink($userfiletmp);
}
}
return $response->withJson('OK', 200);
}
}
return $response->withJson(getMLText('paperless_missing_target_folder'), 400);
} /* }}} */
function patch_documents($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
$fulltextservice = $this->container->fulltextservice;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
$document = $dms->getDocument($args['id']);
if($document) {
$body = $request->getBody();
if($data = json_decode($body, true)) {
if(isset($data['tags'])) {
$cats = [];
foreach($data['tags'] as $tagid) {
if($cat = $dms->getDocumentCategory($tagid)) {
$cats[] = $cat;
}
}
if(!$document->setCategories($cats))
return $response->withStatus(500);
if($fulltextservice && ($index = $fulltextservice->Indexer())) {
$idoc = $fulltextservice->IndexedDocument($document);
// if(false !== $this->callHook('preIndexDocument', $document, $idoc)) {
$lucenesearch = $fulltextservice->Search();
if($hit = $lucenesearch->getDocument((int) $document->getId())) {
$index->delete($hit->id);
}
$index->addDocument($idoc);
$index->commit();
// }
}
}
2023-10-11 14:37:56 +00:00
}
2022-12-10 10:25:22 +00:00
}
return $response->withStatus(204);
2022-12-10 10:25:22 +00:00
} /* }}} */
2023-01-17 15:31:59 +00:00
/**
* Currently just sets tags but receives all kind of data, which
* is still disregarded.
*/
2022-12-10 10:25:22 +00:00
function put_documents($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
$fulltextservice = $this->container->fulltextservice;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
$document = $dms->getDocument($args['id']);
if($document) {
$body = $request->getBody();
if($data = json_decode($body, true)) {
2023-10-11 14:38:32 +00:00
$updatefulltext = false;
2023-01-17 15:31:59 +00:00
$logger->log(var_export($data, true), PEAR_LOG_DEBUG);
2022-12-10 10:25:22 +00:00
if(isset($data['tags'])) {
$cats = [];
foreach($data['tags'] as $tagid) {
if($cat = $dms->getDocumentCategory($tagid)) {
$cats[] = $cat;
}
}
if(!$document->setCategories($cats))
return $response->withStatus(500);
2023-10-11 14:38:32 +00:00
$updatefulltext = true;
}
if(isset($data['correspondent'])) {
if(!empty($settings->_extensions['paperless']['correspondentsattr']) && $attrdef = $dms->getAttributeDefinition($settings->_extensions['paperless']['correspondentsattr'])) {
$valueset = $attrdef->getValueSetAsArray();
if(isset($valueset[$data['correspondent']-1])) {
$attrvalue = $valueset[$data['correspondent']-1];
$logger->log('set attribute '.$attrdef->getName().' to '.$attrvalue, PEAR_LOG_DEBUG);
if(!$document->setAttributeValue($attrdef, $attrvalue)) {
}
$updatefulltext = true;
}
}
}
if($updatefulltext) {
2022-12-10 10:25:22 +00:00
if($fulltextservice && ($index = $fulltextservice->Indexer())) {
$idoc = $fulltextservice->IndexedDocument($document);
// if(false !== $this->callHook('preIndexDocument', $document, $idoc)) {
$lucenesearch = $fulltextservice->Search();
if($hit = $lucenesearch->getDocument((int) $document->getId())) {
$index->delete($hit->id);
}
$index->addDocument($idoc);
$index->commit();
// }
}
}
2023-10-11 14:37:56 +00:00
}
2022-12-10 10:25:22 +00:00
}
return $response->withJson($this->__getDocumentData($document), 200);
} /* }}} */
function delete_documents($request, $response, $args) { /* {{{ */
$dms = $this->container->dms;
$userobj = $this->container->userobj;
$settings = $this->container->config;
$conversionmgr = $this->container->conversionmgr;
$logger = $this->container->logger;
$notifier = $this->container->notifier;
2022-12-10 10:25:22 +00:00
$fulltextservice = $this->container->fulltextservice;
if (!isset($args['id']) || !$args['id'])
return $response->withStatus(404);
$document = $dms->getDocument($args['id']);
if($document) {
$folder = $document->getFolder();
/* Remove all preview images. */
$previewer = new SeedDMS_Preview_Previewer($settings->_cacheDir);
$previewer->deleteDocumentPreviews($document);
/* Get the notify list before removing the document
* Also inform the users/groups of the parent folder
* Getting the list now will keep them in the document object
* even after the document has been deleted.
*/
$dnl = $document->getNotifyList();
$fnl = $folder->getNotifyList();
$docname = $document->getName();
2022-12-10 10:25:22 +00:00
$controller = Controller::factory('RemoveDocument', array('dms'=>$dms, 'user'=>$userobj));
$controller->setParam('document', $document);
$controller->setParam('fulltextservice', $fulltextservice);
if(!$controller()) {
$logger->log($controller->getErrorMsg(), PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withStatus(500);
}
$logger->log('Document deleted', PEAR_LOG_INFO);
if ($notifier){
/* $document still has the data from the just deleted document,
* which is just enough to send the email.
*/
$notifier->sendDeleteDocumentMail($document, $userobj);
}
2022-12-10 10:25:22 +00:00
}
return $response->withStatus(204);
2022-12-10 10:25:22 +00:00
} /* }}} */
2022-12-10 10:25:22 +00:00
} /* }}} */
class SeedDMS_ExtPaperless_RestAPI_Auth { /* {{{ */
private $container;
public function __construct($container) {
$this->container = $container;
}
/**
* Example middleware invokable class
*
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
* @param callable $next Next middleware
*
* @return \Psr\Http\Message\ResponseInterface
*/
public function __invoke($request, $response, $next) { /* {{{ */
// $this->container has the DI
$dms = $this->container->dms;
$settings = $this->container->config;
$logger = $this->container->logger;
/* Skip this middleware if the authentication was already successful */
$userobj = null;
if($this->container->has('userobj'))
$userobj = $this->container->userobj;
if($userobj) {
$response = $next($request, $response);
return $response;
}
/* Pretent to be paperless ngx 1.10.0 with api version 2 */
2023-10-10 10:30:54 +00:00
$response = $response->withHeader('x-api-version', '2')->withHeader('x-version', '1.13.0');
2022-12-10 10:25:22 +00:00
$logger->log("Invoke paperless middleware for method ".$request->getMethod()." on '".$request->getUri()->getPath()."'", PEAR_LOG_INFO);
if(!in_array($request->getUri()->getPath(), array('api/token/', 'api/'))) {
$userobj = null;
if(!empty($this->container->environment['HTTP_AUTHORIZATION'])) {
$tmp = explode(' ', $this->container->environment['HTTP_AUTHORIZATION'], 2);
switch($tmp[0]) {
case 'Token':
/* if jwtsecret is set, the token is expected to be a jwt */
if(!empty($settings->_extensions['paperless']['jwtsecret'])) {
$token = new SeedDMS_JwtToken($settings->_extensions['paperless']['jwtsecret']);
if(!$tokenstr = $token->jwtDecode($tmp[1])) {
$logger->log("Could not decode jwt", PEAR_LOG_ERR);
return $response->withJson("Invalid token", 403);
}
$tmp = explode(':', json_decode($tokenstr, true));
if($tmp[1] < time()) {
$logger->log("Jwt has expired at ".date('Y-m-d H:i:s', $tmp[1]), PEAR_LOG_ERR);
return $response->withJson(getMLText('paperless_token_has_expired'), 403);
2022-12-10 10:25:22 +00:00
} else {
$logger->log("Token is valid till ".date('Y-m-d H:i:s', $tmp[1]), PEAR_LOG_DEBUG);
}
if(!($userobj = $dms->getUser((int) $tmp[0]))) {
$logger->log("No such user ".$tmp[0], PEAR_LOG_ERR);
return $response->withJson("No such user", 403);
}
$dms->setUser($userobj);
$this->container['userobj'] = $userobj;
$logger->log("Login with jwt as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO);
} else {
if(!empty($settings->_apiKey) && !empty($settings->_apiUserId)) {
if($settings->_apiKey == $tmp[1]) {
if(!($userobj = $dms->getUser($settings->_apiUserId))) {
return $response->withStatus(403);
}
} else {
2022-12-14 17:09:16 +00:00
$logger->log("Login with apikey '".$tmp[1]."' failed", PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withStatus(403);
}
$dms->setUser($userobj);
$this->container['userobj'] = $userobj;
$logger->log("Login with apikey as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO);
}
}
break;
case 'Basic':
$authenticator = $this->container->authenticator;
$kk = explode(':', base64_decode($tmp[1]));
$userobj = $authenticator->authenticate($kk[0], $kk[1]);
if(!$userobj) {
2022-12-14 17:09:16 +00:00
$logger->log("Login with basic authentication for '".$kk[0]."' failed", PEAR_LOG_ERR);
2022-12-10 10:25:22 +00:00
return $response->withStatus(403);
}
$dms->setUser($userobj);
$this->container['userobj'] = $userobj;
$logger->log("Login with basic authentication as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO);
break;
}
}
} else {
/* Set userobj to keep other middlewares for authentication from running */
$this->container['userobj'] = true;
}
2023-10-10 10:31:18 +00:00
$logger->log("End of paperless middleware for method ".$request->getMethod()." on '".$request->getUri()->getPath()."'", PEAR_LOG_INFO);
2022-12-10 10:25:22 +00:00
$response = $next($request, $response);
return $response;
} /* }}} */
} /* }}} */
/**
* Class containing methods which adds additional routes to the RestAPI
*
* @author Uwe Steinmann <uwe@steinmann.cx>
* @package SeedDMS
* @subpackage paperless
*/
class SeedDMS_ExtPaperless_RestAPI { /* {{{ */
/**
* Hook for adding additional routes to the RestAPI
*
* @param object $app instance of \Slim\App
* @return void
*/
public function addMiddleware($app) { /* {{{ */
$container = $app->getContainer();
$app->add(new SeedDMS_ExtPaperless_RestAPI_Auth($container));
} /* }}} */
/**
* Hook for adding additional routes to the RestAPI
*
* @param object $app instance of \Slim\App
* @return void
*/
public function addRoute($app) { /* {{{ */
$app->get('/api/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':api');
/* /api/token/ is actually a get, but paperless_app calls it to check for ngx */
$app->post('/api/token/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':token');
$app->get('/api/token/', function($request, $response) use ($app) {
return $response->withStatus(405);
});
$app->get('/api/tags/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':tags');
$app->post('/api/tags/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':post_tag');
$app->delete('/api/tags/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':delete_tag');
2022-12-10 10:25:22 +00:00
$app->get('/api/documents/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':documents');
$app->get('/api/correspondents/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':correspondents');
$app->get('/api/document_types/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':document_types');
$app->get('/api/saved_views/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':saved_views');
$app->post('/api/saved_views/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':post_saved_views');
$app->delete('/api/saved_views/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':delete_saved_views');
$app->patch('/api/saved_views/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':patch_saved_views');
2022-12-10 10:25:22 +00:00
$app->get('/api/storage_paths/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':storage_paths');
$app->post('/api/documents/post_document/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':post_document');
$app->get('/api/documents/{id}/preview/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':documents_preview');
2022-12-10 10:25:22 +00:00
$app->get('/api/documents/{id}/thumb/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':documents_thumb');
$app->get('/fetch/thumb/{id}', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':fetch_thumb');
2023-11-03 15:42:28 +00:00
$app->get('/api/documents/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':document');
2022-12-10 10:25:22 +00:00
$app->get('/api/documents/{id}/download/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':documents_download');
$app->get('/api/documents/{id}/metadata/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':documents_metadata');
$app->get('/fetch/doc/{id}', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':fetch_doc');
$app->patch('/api/documents/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':patch_documents');
$app->put('/api/documents/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':put_documents');
$app->delete('/api/documents/{id}/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':delete_documents');
$app->get('/api/search/autocomplete/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':autocomplete');
$app->get('/api/ui_settings/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':ui_settings');
2022-12-12 18:02:22 +00:00
$app->get('/api/statstotal/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':statstotal');
2023-02-18 08:43:25 +00:00
$app->get('/api/statistics/', \SeedDMS_ExtPaperless_RestAPI_Controller::class.':statstotal');
2022-12-10 10:25:22 +00:00
return null;
} /* }}} */
} /* }}} */