| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- <?php
- // @requires $_SERVER['SERVER_NAME']
- Lib::loadClass('RouteBase');
- Lib::loadClass('Schema_TableFactory');
- Lib::loadClass('Response');
- Lib::loadClass('UI');
- Lib::loadClass('OBJ');
- /*
- # FileStorage:
- - [x] create CRM_FILES - sql at the end of file
- - [x] only meta fields, perms? - no perms in relation based on record which is connected
- - [x] add file to storage - API POST/PUT action
- - [ ] base storage folder - from config - default /Library/Server/Web/Data/p5-pliki, chmod - add to instalator, upgrade
- - [x] subfolders like postfix, but [0-9],[A-Z] - substr(strrev(base_convert($id, 10, 10 + 26)), 0, 1) - 36 folderów
- - [x] file connected to user - A_RECORD_CREATE_AUTHOR
- - [ ] connect file to record - {tbl_name}__REF__FILES
- # upload API: `index.php?_route=FileStorage&_task=upload&name={file_name}`
- */
- class Route_FileStorage extends RouteBase {
- public function handleAuth() {
- if (!User::logged()) {
- User::authByRequest();
- }
- }
- public function defaultAction() {
- UI::gora();
- UI::menu();
- try {
- echo '...';
- } catch (Exception $e) {
- UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
- }
- UI::dol();
- }
- public function isProduction() {// TODO: mv to Config
- // return V::get('P5_ENV', '/Library/Server/Web/Data/p5-file-storage', $_SERVER);
- // $env = getenv('P5_ENV');
- // if (empty($env)) $env = 'production';
- return ('production' == V::get('P5_ENV', 'production', $_SERVER));
- }
- public function getRootStoragePath() {
- return ($this->isProduction()) ? '/Library/Server/Web/Data/p5-file-storage' : '/tmp/test-upload-file-storage';
- }
- public function getTableName() {
- return ($this->isProduction()) ? 'CRM_FILES' : 'CRM_FILES__#DEV';
- }
- public function addFile($content, $name = '') {
- $rootFileStoragePath = $this->getRootStoragePath();
- $sqlLogin = User::getLogin();
- $sqlLabel = DB::getPDO()->quote($sqlLabel, PDO::PARAM_STR);
- $sqlTblName = $this->getTableName();
- $sql = "
- insert into {$sqlTblName} (`A_RECORD_CREATE_AUTHOR`,`A_RECORD_CREATE_DATE`,`FILE_LABEL`)
- values ('{$sqlLogin}', NOW(), {$sqlLabel})
- ";
- DBG::_('DBG', '>2', "sql", $sql, __CLASS__, __FUNCTION__, __LINE__);
- DB::getPDO()->exec($sql);
- $dbLastId = DB::getPDO()->lastInsertId();
- DBG::_('DBG', '>1', "dbLastId", $dbLastId, __CLASS__, __FUNCTION__, __LINE__);
- $filePath = $this->generateFilePathHashFromID($dbLastId);
- DBG::_('DBG', '>1', "filePath", $filePath, __CLASS__, __FUNCTION__, __LINE__);
- $absFilePath = "{$rootFileStoragePath}/{$filePath}";
- $dirPath = dirname($absFilePath);
- @mkdir($dirPath, $mode = 0777, $recursive = true);
- if (!file_exists($dirPath)) throw new Exception("Cannot create path");
- @chmod($dirPath, $mode = 0777);
- $fp = fopen($absFilePath, 'w');
- fwrite($fp, $fileContent);
- fclose($fp);
- if (!file_exists($dirPath)) throw new Exception("Cannot save file");
- }
- public function uploadAction() {
- try {
- $fileContent = Request::getRequestBody();
- $sqlLabel = V::get('name', '', $_REQUEST);
- $this->addFile($fileContent, $sqlLabel);
- echo 'file uploaded';
- } catch (Exception $e) {
- echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
- }
- }
- public function uploadFromBinaryTestAction() {
- try {
- $fileContent = Request::getRequestBody();
- $filePath = $this->getRootStoragePath() . '/test-upload-data.txt';
- $fp = fopen($filePath, 'w');
- fwrite($fp, $fileContent);
- fclose($fp);
- echo 'file uploaded?';
- } catch (Exception $e) {
- echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
- }
- }
- public function downloadTestAction() {
- try {
- $filePath = $this->getRootStoragePath() . '/test-upload-data.txt';
- if (!file_exists($filePath)) throw new Exception("file not exists!");
- header('Content-Description: File Transfer');
- header('Content-Type: application/octet-stream');
- header('Content-Disposition: attachment; filename="'.basename($filePath).'"');
- header('Expires: 0');
- header('Cache-Control: must-revalidate');
- header('Pragma: public');
- header('Content-Length: ' . filesize($filePath));
- readfile($filePath);
- exit;
- } catch (Exception $e) {
- echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
- }
- }
- public function uploadFromFormTestAction() {
- try {
- // $fileContent = Request::getRequestBody();
- DBG::_(true, true, '_POST', $_POST, __CLASS__, __FUNCTION__, __LINE__);
- // $filePath = $this->getRootStoragePath() . '/test-upload-data.txt';
- // $fp = fopen($filePath, 'w');
- // fwrite($fp, $fileContent);
- // fclose($fp);
- // echo 'file uploaded?';
- } catch (Exception $e) {
- echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
- }
- }
- public function uploadFormTestAction() {
- UI::gora();
- UI::menu();
- try {
- // multiple: <input type="file" id="file_input" multiple="multiple" />
- // only images: <input type="file" id="file_input" multiple="multiple" accept="image/*" />
- ?>
- <div class="container">
- <form>
- <input type="file" id="file_input" style="display:block; width:100%; height:200px; background-color:silver; text-align:center">
- </form>
- <button class="btn btn-primary" id="upload_file_as_binary_btn">upload as binary</button>
- <button class="btn btn-default" id="upload_file_as_form_btn">upload as form</button>
- <a class="btn btn-default" href="index.php?_route=FileStorage&_task=downloadTest" target="_blank">download</a>
- <blockquote>
- <p>root storage path: <code><?php echo $this->getRootStoragePath(); ?></code></p>
- <p>table name: <code><?php echo $this->getTableName(); ?></code></p>
- </blockquote>
- </div>
- <script>
- document.getElementById('file_input').addEventListener('change', function() {
- for (var i = 0; i < this.files.length; i++){
- var file = this.files[i];
- // This code is only for demo ...
- console.group("File "+i);
- console.log("name : " + file.name);
- console.log("size : " + file.size);
- console.log("type : " + file.type);
- console.log("date : " + file.lastModified);
- console.groupEnd();
- }
- }, false);
- function uploadFileAsForm(file) {
- var serverUrl = '<?php echo Request::getPathUri() . "index.php?_route=FileStorage&_task=uploadFromFormTest"; ?>';
- var xhr = new XMLHttpRequest();
- var fd = new FormData();
- xhr.open("POST", serverUrl, true);
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4 && xhr.status == 200) {
- // Every thing ok, file uploaded
- console.log(xhr.responseText); // handle response.
- }
- };
- fd.append("upload_file", file);
- xhr.send(fd);
- }
- function uploadFileAsBinary(file) {
- var serverUrl = '<?php echo Request::getPathUri() . "index.php?_route=FileStorage&_task=uploadFromBinaryTest"; ?>';
- var serverUrl = '<?php echo Request::getPathUri() . "index.php?_route=FileStorage&_task=upload"; ?>';
- var _dbg = true;
- // .set('Accept', 'application/json')
- superagent.post(serverUrl + '&name=' + file.name)
- .set('Content-Type', file.type)
- .send(file)
- .end(function(err, res) {
- if(_dbg)console.log('DBG: res:', res, 'res.body:', res.body);
- })
- return
- jQuery.ajax({
- type: "POST",
- beforeSend: function (request) {
- request.setRequestHeader("Content-Type", file.type);
- },
- url: serverUrl,
- data: file,
- processData: false,
- contentType: false,
- success: function (data) {
- console.log("File available at: ", data);
- },
- error: function (data) {
- var obj = jQuery.parseJSON(data);
- alert(obj.error);
- }
- })
- }
- jQuery('#upload_file_as_binary_btn').on('click', function() {
- var fileInput = document.getElementById('file_input')
- if (!fileInput) return false;// TODO: error msg
- if (!fileInput.files) return false;// TODO: error msg
- if (!fileInput.files.length) return false;// TODO: error msg
- var fileInfo = fileInput.files[0];
- console.log('fileInfo', fileInfo);
- uploadFileAsBinary(fileInfo);
- });
- jQuery('#upload_file_as_form_btn').on('click', function() {
- var fileInput = document.getElementById('file_input')
- if (!fileInput) return false;// TODO: error msg
- if (!fileInput.files) return false;// TODO: error msg
- if (!fileInput.files.length) return false;// TODO: error msg
- var fileInfo = fileInput.files[0];
- console.log('fileInfo', fileInfo);
- uploadFileAsForm(fileInfo);
- });
- </script>
- <?php
- } catch (Exception $e) {
- UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
- }
- UI::dol();
- }
- public function generateFilePathHashFromID($intId) {
- // $base36Id = base_convert($intId, 10, 10 + 26);// 0-9 + A-Z
- $base36Id = base_convert($intId, 10, 10 + 6);// 0-9 + A-F
- $base36Str = str_pad($base36Id, 10, "0", STR_PAD_LEFT);
- $base36Str = strrev($base36Str);
- $pathParts = array();
- $pathParts[] = substr($base36Str, 0, 2);
- $pathParts[] = substr($base36Str, 2, 2);
- $pathParts[] = substr($base36Str, 4);
- $hashPath = implode("/", $pathParts);
- echo "ID($intId) converted to ({$base36Id})\t to ({$base36Str})\t to path ({$hashPath})\n";
- return $hashPath;
- }
- public function generatePathTestAction() {
- try {
- $start = 0;
- $start = 446071;
- $limit = $start + 100;
- echo '<pre>';
- for ($i = $start; $i < $limit; $i++) {
- $this->generateFilePathHashFromID($i);
- }
- echo '</pre>';
- } catch (Exception $e) {
- echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
- }
- }
- public function reinstallAction() {
- UI::gora();
- UI::menu();
- $this->reinstall();
- UI::dol();
- }
- public function reinstall() {
- try {
- DB::getPDO()->exec("
- CREATE TABLE IF NOT EXISTS `CRM_FILES` (
- `ID` int(11) NOT NULL AUTO_INCREMENT,
- `FILE_HASH` varchar(255) NOT NULL, -- generated from ID by hash function - only for cache
- `FILE_LABEL` varchar(255) NOT NULL, -- original file name or system name
- `FILE_TYPE` varchar(32) NOT NULL DEFAULT '', -- $TRG_FILE -> config/.cnf--folders...
- `FILE_MTIME` datetime NOT NULL,
- `FILE_VERSION` int(11) NOT NULL DEFAULT 0, -- used for update
- `A_STATUS` enum('WAITING','NORMAL','MONITOR','OFF_HARD','OFF_SOFT','DELETED') NOT NULL DEFAULT 'WAITING',
- `A_RECORD_CREATE_DATE` datetime DEFAULT NULL,
- `A_RECORD_CREATE_AUTHOR` varchar(40) NOT NULL DEFAULT '',
- `A_RECORD_UPDATE_DATE` datetime DEFAULT NULL,
- `A_RECORD_UPDATE_AUTHOR` varchar(40) NOT NULL DEFAULT '',
- `A_ADM_COMPANY` varchar(100) NOT NULL DEFAULT '',
- `A_CLASSIFIED` varchar(100) NOT NULL DEFAULT '',
- PRIMARY KEY (`ID`),
- KEY `FILE_TYPE` (`FILE_TYPE`)
- ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
- ");
- DB::getPDO()->exec("
- CREATE TABLE IF NOT EXISTS `CRM_FILES__#DEV` (
- `ID` int(11) NOT NULL AUTO_INCREMENT,
- `FILE_HASH` varchar(255) NOT NULL, -- generated from ID by hash function - only for cache
- `FILE_LABEL` varchar(255) NOT NULL, -- original file name or system name
- `FILE_TYPE` varchar(32) NOT NULL DEFAULT '', -- $TRG_FILE -> config/.cnf--folders...
- `FILE_MTIME` datetime NOT NULL,
- `FILE_VERSION` int(11) NOT NULL DEFAULT 0, -- used for update
- `A_STATUS` enum('WAITING','NORMAL','MONITOR','OFF_HARD','OFF_SOFT','DELETED') NOT NULL DEFAULT 'WAITING',
- `A_RECORD_CREATE_DATE` datetime DEFAULT NULL,
- `A_RECORD_CREATE_AUTHOR` varchar(40) NOT NULL DEFAULT '',
- `A_RECORD_UPDATE_DATE` datetime DEFAULT NULL,
- `A_RECORD_UPDATE_AUTHOR` varchar(40) NOT NULL DEFAULT '',
- `A_ADM_COMPANY` varchar(100) NOT NULL DEFAULT '',
- `A_CLASSIFIED` varchar(100) NOT NULL DEFAULT '',
- PRIMARY KEY (`ID`),
- KEY `FILE_TYPE` (`FILE_TYPE`)
- ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
- ");
- {// TODO: only in cli mode - require root perms
- $devRootPath = '/tmp/test-upload-file-storage';
- if (!file_exists($devRootPath)) {
- @mkdir($devRootPath, $mode = 0777, $recursive = true);
- if (!file_exists($devRootPath)) throw new Exception("Cannot create FileStorage root path for dev");
- @chmod($devRootPath, $mode = 0777);
- @chown($devRootPath, $user = '_www');
- }
- $productionRootPath = '/Library/Server/Web/Data/p5-file-storage';
- if (!file_exists($productionRootPath)) {
- @mkdir($productionRootPath, $mode = 0775, $recursive = true);
- if (!file_exists($productionRootPath)) throw new Exception("Cannot create FileStorage root path");
- @chmod($productionRootPath, $mode = 0775);
- @chown($productionRootPath, $user = '_www');
- }
- }
- } catch (Exception $e) {
- UI::alert('danger', $e->getMessage());
- }
- }
- }
|