2016-07-22 20:00:27 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
use Vn\Lib;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a document to the Document Management System.
|
2016-12-20 09:32:17 +00:00
|
|
|
*/
|
2016-08-23 13:15:19 +00:00
|
|
|
class Add extends Vn\Web\JsonRequest
|
2016-07-22 20:00:27 +00:00
|
|
|
{
|
2016-09-23 22:47:34 +00:00
|
|
|
function run ($db)
|
2016-07-22 20:00:27 +00:00
|
|
|
{
|
|
|
|
// XXX: Uncomment only to test the script
|
|
|
|
//$_REQUEST['description'] = 'description';
|
|
|
|
|
|
|
|
$description = empty ($_REQUEST['description']) ?
|
|
|
|
NULL : $_REQUEST['description'];
|
|
|
|
|
|
|
|
$baseDir = _DATA_DIR .'/'. $this->app->getName ();
|
|
|
|
$docsDir = "$baseDir/dms";
|
|
|
|
$tempDir = "$baseDir/.dms";
|
|
|
|
|
|
|
|
$digXDir = 3;
|
|
|
|
$zerosDir = '';
|
|
|
|
|
|
|
|
for ($i = 0; $i < $digXDir; $i++)
|
|
|
|
$zerosDir .= '0';
|
|
|
|
|
|
|
|
// Checks document restrictions
|
|
|
|
|
|
|
|
if (empty ($_FILES['doc']['name']))
|
|
|
|
throw new Lib\UserException ('File not choosed');
|
|
|
|
|
|
|
|
$maxSize = $db->getValue ('SELECT max_size FROM dms_config');
|
|
|
|
|
|
|
|
if ($_FILES['doc']['size'] > $maxSize * 1048576)
|
|
|
|
throw new Lib\UserException (sprintf ('File size exceeds size: %d MB', $maxSize)));
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Registers the document in the database
|
|
|
|
|
|
|
|
$db->query ('START TRANSACTION');
|
|
|
|
|
|
|
|
$db->query ('INSERT INTO dms_document SET description = #', [$description]);
|
|
|
|
$docId = (string) $db->getValue ('SELECT LAST_INSERT_ID()');
|
|
|
|
|
|
|
|
$len = strlen ($docId);
|
|
|
|
$neededLevels = ceil ($len / $digXDir) - 1;
|
|
|
|
|
|
|
|
$dirLevels = $db->getValue (
|
|
|
|
'SELECT dir_levels FROM dms_config LOCK IN SHARE MODE');
|
|
|
|
|
|
|
|
if ($dirLevels > $neededLevels)
|
|
|
|
$neededLevels = $dirLevels;
|
|
|
|
|
|
|
|
// Reorganizes the file repository if necessary
|
|
|
|
|
|
|
|
if ($dirLevels < $neededLevels)
|
|
|
|
$dirLevels = $db->getValue (
|
|
|
|
'SELECT dir_levels FROM dms_config FOR UPDATE');
|
|
|
|
|
|
|
|
if ($dirLevels < $neededLevels)
|
|
|
|
{
|
|
|
|
if (is_dir ($docsDir))
|
|
|
|
{
|
|
|
|
$dif = ($neededLevels - $dirLevels) - 1;
|
|
|
|
$newDir = $docsDir;
|
|
|
|
|
|
|
|
for ($i = 0; $i < $dif; $i++)
|
|
|
|
$newDir .= "/$zerosDir";
|
|
|
|
|
|
|
|
$success = rename ($docsDir, $tempDir)
|
|
|
|
&& mkdir ($newDir, 0770, TRUE)
|
|
|
|
&& rename ($tempDir, "$newDir/$zerosDir");
|
|
|
|
|
|
|
|
if (!$success)
|
|
|
|
throw new Exception ('Error while reorganizing directory tree');
|
|
|
|
}
|
|
|
|
|
|
|
|
$curLevels = $db->query ('UPDATE dms_config SET dir_levels = #',
|
|
|
|
[$neededLevels]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Saves the document to the repository
|
|
|
|
|
|
|
|
$padLen = ($neededLevels + 1) * $digXDir;
|
|
|
|
$paddedId = str_pad ($docId, $padLen, '0', STR_PAD_LEFT);
|
|
|
|
|
|
|
|
$saveDir = $docsDir;
|
|
|
|
|
|
|
|
for ($i = 0; $i < $neededLevels; $i++)
|
|
|
|
$saveDir .= '/'. substr ($paddedId, $i * $digXDir, $digXDir);
|
|
|
|
|
|
|
|
if (!file_exists ($saveDir))
|
|
|
|
mkdir ($saveDir, 0770, TRUE);
|
|
|
|
|
|
|
|
$savePath = "$saveDir/". substr ($paddedId, -$digXDir);
|
|
|
|
|
|
|
|
move_uploaded_file ($_FILES['doc']['tmp_name'], $savePath);
|
|
|
|
|
|
|
|
$db->query ('COMMIT');
|
|
|
|
|
|
|
|
return $docId;
|
|
|
|
}
|
|
|
|
catch (Exception $e)
|
|
|
|
{
|
|
|
|
$db->query ('ROLLBACK');
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|