login (); $db = $this->getSysConn (); $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; } } } ?>