WebdavHelper.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. <?php
  2. if (!function_exists('myLog')) {
  3. /**
  4. * myLog(__CLASS__, __FUNCTION__, __LINE__, "");
  5. */
  6. function myLog($cls, $fun, $line, $msg = '') {
  7. trigger_error(":U({$_SERVER['PHP_AUTH_USER']}): {$cls}::{$fun}():{$line}: {$msg}", E_USER_NOTICE);
  8. }
  9. }
  10. Lib::loadClass('FoldersConfig');
  11. /**
  12. * Webdav Helper class.
  13. *
  14. * Directory structure (samba - filesystem root path):
  15. *
  16. * samba/DRUKI/
  17. *
  18. * samba/DRUKI/1..../* pliki fizycznie w katalogu
  19. * samba/DRUKI/1..../PROJEKT.2/ -> to samo co w samba/PROJEKTY/2..../
  20. * samba/DRUKI/1..../PROJEKT.3/ -> to samo co w samba/PROJEKTY/3..../
  21. *
  22. * samba/PROJEKTY/
  23. *
  24. * samba/PROJEKTY/2..../ * pliki fizycznie w katalogu
  25. * samba/PROJEKTY/2..../DRUK.1/ -> to samo co w samba/DRUKI/1..../
  26. * RM: samba/PROJEKTY/2..../PISMO.10/ * plik skan/pdf - pismo
  27. * RM: samba/PROJEKTY/2..../PISMO.11/ * plik skan/pdf - pismo
  28. * samba/PROJEKTY/2..../PISMA/{ID}.*.* * plik skan/pdf - pismo
  29. *
  30. * samba/PROJEKTY/3..../ * pliki fizycznie w katalogu
  31. *
  32. * Database folder ID names:
  33. * PROJEKTY - IN7_MK_BAZA_DYSTRYBUCJI
  34. * DRUKI - CRM_LISTA_ZASOBOW
  35. * PISMA - IN7_DZIENNIK_KORESP
  36. *
  37. * PROJEKTY <--> DRUKI : IN7_MK_BAZA_DYSTRYBUCJI.ID_ZASOB_REVITALIZE <--> CRM_LISTA_ZASOBOW.ID
  38. * PROJEKTY <--> PISMA : IN7_DZIENNIK_KORESP.ID_PROJECT <--> IN7_MK_BAZA_DYSTRYBUCJI.ID
  39. *
  40. */
  41. class WebdavHelper {
  42. function getRootDir() {
  43. return FoldersConfig::getRootPoint('mount_point');
  44. }
  45. function getTrashDir() {
  46. return FoldersConfig::getRootPoint('mount_point') . '/Trash';
  47. }
  48. function getBaseDir($col_name) {
  49. return FoldersConfig::get($col_name, 'mount_point');
  50. }
  51. /**
  52. * @param string $davpath eg.: SE/DRUKI/1379.UMOWA.2011-06-03.umowa_abonencka.2011-06-03
  53. *
  54. * @returns array $list [realname => type(dir,file,virtualdir?)]
  55. */
  56. function getChildren($davpath = '', $user = null) {
  57. $list = array();
  58. $file = self::getRealFile($davpath, $user);
  59. if ($file) {
  60. if ($file->is_dir === true) {
  61. if ($davpath == 'SE') {
  62. $list['PROJEKTY'] = 'dir';
  63. $list['DRUKI'] = 'dir';
  64. return $list;
  65. }
  66. if (!empty($file->virtual_dirs)) {
  67. foreach ($file->virtual_dirs as $name) {
  68. $list[$name] = 'dir';
  69. }
  70. }
  71. if (!empty($file->virtual_files)) {
  72. foreach ($file->virtual_files as $name) {
  73. $list[$name] = 'file';
  74. }
  75. }
  76. if (empty($file->prevent_scandir)) {
  77. foreach (scandir($file->realpath) as $name) {
  78. if (substr($name, 0, 1) == '.') continue;
  79. //$id = reset(explode('.', $name));
  80. //if (is_numeric($id)) {// TODO: check name format
  81. if (is_dir($file->realpath . '/' . $name)) {
  82. $list[$name] = 'dir';
  83. } else {
  84. $list[$name] = 'file';
  85. }
  86. //}
  87. }
  88. }
  89. }
  90. }
  91. return $list;
  92. }
  93. /**
  94. *
  95. * @returns string $type ('dir', 'file', '' - not exists)
  96. *
  97. * webdav> ls -> TODO: getItem(SE)
  98. * webdav> ls DRUKI -> TODO: getItem(SE/DRUKI)
  99. */
  100. function getChildType($davpath = '', $user = null) {
  101. $file = self::getRealFile($davpath, $user);
  102. //myLog(__CLASS__, __FUNCTION__, __LINE__, "TODO: ({$davpath}) file: " . json_encode($file));
  103. if ($file) {
  104. if ($file->is_dir === true) {
  105. return 'dir';
  106. } else if ($file->is_dir === false) {
  107. return 'file';
  108. }
  109. }
  110. return '';
  111. }
  112. /**
  113. * Convert WebDAV path to real path, and add additional info.
  114. *
  115. */
  116. function getRealFile($davpath, $user = null) {
  117. $file = new stdClass();
  118. $file->realpath = WebdavHelper::getRootDir();
  119. $file->is_dir = null;
  120. $file->virtual_dirs = null;
  121. $file->virtual_files = null;
  122. $file->perms = 'R';
  123. $pathObj = new stdClass();
  124. $pathObj->_main_dir = null;
  125. $pathObj->_projekt_id = null;
  126. $pathObj->_druk_id = null;
  127. $pathObj->_pismo_id = null;
  128. $pathObj->_proj_pisma = false;
  129. $dav_parts = explode('/', $davpath);
  130. {// 1st part: SE
  131. $part = array_shift($dav_parts);
  132. if ($part == 'SE') {
  133. if (empty($dav_parts)) {
  134. $file->is_dir = true;
  135. return $file;
  136. }
  137. } else {
  138. return null;
  139. }
  140. }
  141. {// 2nd part: SE/ PROJEKTY, DRUKI
  142. $part = array_shift($dav_parts);
  143. if (in_array($part, array('PROJEKTY', 'DRUKI'))) {
  144. $file->realpath .= '/' . $part;
  145. if (empty($dav_parts)) {
  146. $file->is_dir = true;
  147. if ($part == 'PROJEKTY') {
  148. Lib::loadClass('User');
  149. $user_name = User::getName();
  150. $projekty_ids = self::getProjektyIds($user_name);
  151. $file->prevent_scandir = true;
  152. foreach (scandir($file->realpath) as $name) {
  153. if (substr($name, 0, 1) == '.') continue;
  154. $id = reset(explode('.', $name));
  155. if (!is_numeric($id)) continue;
  156. if (!in_array($id, $projekty_ids)) {
  157. continue;
  158. }
  159. if (is_dir($file->realpath . '/' . $name)) {
  160. $file->virtual_dirs[] = $name;
  161. } else {
  162. $file->virtual_files[] = $name;
  163. }
  164. }
  165. }
  166. else if ($part == 'DRUKI') {
  167. // TODO: only druki with access by procesy
  168. }
  169. return $file;
  170. }
  171. }
  172. else {
  173. return null;
  174. }
  175. }
  176. {// 3rd part: SE/[PROJEKTY,DRUKI]/ files, directories
  177. $pathObj->_main_dir = $part;
  178. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) 3rd part: {$pathObj->_main_dir}/...");
  179. $part = array_shift($dav_parts);
  180. if ($pathObj->_main_dir == 'DRUKI') {
  181. $druk_id = (int)reset(explode('.', $part));
  182. if ($druk_id > 0) {
  183. $pathObj->_druk_id = $druk_id;
  184. } else {
  185. // TODO: error wrong file name?
  186. }
  187. // TODO: change realpath if PROJEKT.{$ID}/
  188. $file->realpath .= '/' . $part;
  189. if (empty($dav_parts)) {
  190. $file->is_dir = is_dir($file->realpath);
  191. if ($druk_id > 0) {
  192. // TODO: add $file->virtual_dirs - PROJEKT.{$ID}/ <-- get creator projekt ID from DB
  193. $projektyIds = WebdavHelper::getProjektyIdsByDruk($druk_id, $user);
  194. foreach ($projektyIds as $projektID) {
  195. $file->virtual_dirs[] = "PROJEKT.{$projektID}";
  196. }
  197. }
  198. return $file;
  199. }
  200. }
  201. else if ($pathObj->_main_dir == 'PROJEKTY') {
  202. $projekt_id = (int)reset(explode('.', $part));
  203. if ($projekt_id > 0) {
  204. $pathObj->_projekt_id = $projekt_id;
  205. } else {
  206. // TODO: error wrong file name?
  207. }
  208. $file->realpath .= '/' . $part;
  209. if (!file_exists($file->realpath)) {
  210. return null;
  211. }
  212. if (empty($dav_parts)) {
  213. $file->is_dir = is_dir($file->realpath);
  214. if ($projekt_id > 0) {
  215. $file->perms = 'RWXC';
  216. $file->virtual_dirs[] = "PISMA";
  217. $druki = self::getDrukiIdsByProjekt($pathObj->_projekt_id);
  218. foreach ($druki as $druk_id) {
  219. $file->virtual_dirs[] = "DRUK.{$druk_id}";
  220. }
  221. }
  222. return $file;
  223. }
  224. }
  225. else {
  226. return null;
  227. }
  228. }
  229. {// 4rd part: SE/[PROJEKTY,DRUKI]/{item_folder:$ID.*}/ files, directories, virtual
  230. $item_folder = $part;
  231. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) 4rd part: {$pathObj->_main_dir}/{$item_folder}/...");
  232. $part = array_shift($dav_parts);
  233. if ($pathObj->_main_dir == 'DRUKI') {
  234. $file->realpath .= '/' . $part;
  235. // $pathObj->_druk_id
  236. $cur_parts = explode('.', $part);
  237. if (count($cur_parts) == 2) {
  238. if ($cur_parts[0] == 'PROJEKT') {
  239. $id = (int)$cur_parts[1];
  240. if ($id > 0) {
  241. // TODO: find realpath for PROJEKT
  242. $file->realpath = self::findRealPath('PROJEKT', $id);
  243. if (empty($dav_parts)) {
  244. $file->is_dir = true;//is_dir($file->realpath);
  245. return $file;
  246. }
  247. }
  248. }
  249. }
  250. if (empty($dav_parts)) {
  251. $file->is_dir = is_dir($file->realpath);
  252. return $file;
  253. }
  254. }
  255. else if ($pathObj->_main_dir == 'PROJEKTY') {
  256. // $pathObj->_projekt_id
  257. $virtual_type = null;
  258. $virtual_id = null;
  259. $cur_parts = explode('.', $part);
  260. if ($part == 'PISMA') {
  261. $virtual_type = 'PISMA';
  262. }
  263. else if (count($cur_parts) == 2) {
  264. if ($cur_parts[0] == 'PROJEKT') {// alias do innego projektu?
  265. $virtual_id = (int)$cur_parts[1];
  266. $virtual_type = 'PROJEKT';
  267. } else if ($cur_parts[0] == 'DRUK') {
  268. $virtual_id = (int)$cur_parts[1];
  269. $virtual_type = 'DRUK';
  270. } else if ($cur_parts[0] == 'PISMO') {
  271. $virtual_id = (int)$cur_parts[1];
  272. $virtual_type = 'PISMO';
  273. }
  274. }
  275. if ($virtual_type) {
  276. if ($virtual_type == 'PISMA') {
  277. $pathObj->_proj_pisma = true;
  278. $pismaIds = self::getPismaIdsByProjekt($pathObj->_projekt_id);
  279. if (!empty($pismaIds)) {
  280. $pismaFiles = self::findRealPaths('PISMA', $pismaIds);
  281. foreach ($pismaFiles as $pismoFile) {
  282. $file->virtual_files[] = end(explode('/', $pismoFile));
  283. }
  284. $file->is_dir = true;
  285. $file->prevent_scandir = true;
  286. }
  287. }
  288. else if ($virtual_type == 'PISMO') {
  289. $pathObj->_pismo_id = $virtual_id;
  290. if (empty($dav_parts)) {
  291. $pismo_file = self::findRealPath('PISMO', $pathObj->_pismo_id);
  292. //myLog(__CLASS__, __FUNCTION__, __LINE__, "PISMO {$pismo_file}...");
  293. //$file->realpath = $pismo_file;
  294. $file->virtual_files[] = end(explode('/', $pismo_file));
  295. $file->prevent_scandir = true;
  296. }
  297. }
  298. else if ($virtual_type == 'DRUK') {
  299. $pathObj->_druk_id = $virtual_id;
  300. $druk_dir = self::findRealPath('DRUK', $pathObj->_druk_id);
  301. $file->realpath = $druk_dir;
  302. $file->is_dir = is_dir($file->realpath);
  303. $file->prevent_scandir = false;
  304. //myLog(__CLASS__, __FUNCTION__, __LINE__, "DRUK dir({$file->is_dir}) {$druk_dir}...");
  305. }
  306. }
  307. else {
  308. $file->perms = 'RWXC';
  309. $file->realpath .= '/' . $part;
  310. }
  311. }
  312. if (empty($dav_parts)) {
  313. if (!file_exists($file->realpath)) {
  314. return null;
  315. }
  316. $file->is_dir = is_dir($file->realpath);
  317. return $file;
  318. }
  319. }
  320. {// 5rd part: SE/[PROJEKTY,DRUKI]/{item_folder[:$ID.*]}/[files,directories,virtual]/ files, directories, virtual
  321. $part = array_shift($dav_parts);
  322. if ($pathObj->_main_dir == 'DRUKI') {
  323. myLog(__CLASS__, __FUNCTION__, __LINE__, "TODO: ({$davpath}) 5rd part: main({$pathObj->_main_dir}) ...");
  324. }
  325. else if ($pathObj->_main_dir == 'PROJEKTY') {
  326. if ($pathObj->_proj_pisma) {// virtual PISMA/{pismo_file}
  327. $pismo_id = intval(reset(explode('.', $part)));
  328. if ($pismo_id <= 0) {
  329. return null;
  330. }
  331. $file->realpath = self::findRealPath('PISMO', $pismo_id);
  332. if (!$file->realpath) {
  333. myLog(__CLASS__, __FUNCTION__, __LINE__, "TODO: ({$davpath}) 5rd part: 404 ".json_encode($file));
  334. return null;
  335. }
  336. $file->is_dir = false;
  337. return $file;
  338. }
  339. else if ($pathObj->_pismo_id > 0) {// virtual PISMO.{$pathObj->_pismo_id}
  340. $file->realpath = self::findRealPath('PISMO', $pathObj->_pismo_id);
  341. if (!$file->realpath) {
  342. myLog(__CLASS__, __FUNCTION__, __LINE__, "TODO: ({$davpath}) 5rd part: 404 ".json_encode($file));
  343. return null;
  344. }
  345. $file->is_dir = false;
  346. return $file;
  347. }
  348. else if ($pathObj->_druk_id > 0) {// virtual DRUK.{$pathObj->_druk_id}
  349. $file->realpath .= '/' . $part;
  350. }
  351. else {
  352. $file->realpath .= '/' . $part;
  353. myLog(__CLASS__, __FUNCTION__, __LINE__, "TODO: ({$davpath}) 5rd part: main({$pathObj->_main_dir}) ...");
  354. }
  355. }
  356. }
  357. while (!empty($dav_parts)) {
  358. $part = array_shift($dav_parts);
  359. $file->realpath .= '/' . $part;
  360. }
  361. if (!file_exists($file->realpath)) {
  362. return null;
  363. }
  364. $file->is_dir = is_dir($file->realpath);
  365. return $file;
  366. }
  367. function findRealPath($type, $id) {
  368. $file = null;
  369. if ($type == 'PROJEKT') {
  370. $basePath = WebdavHelper::getBaseDir('IN7_MK_BAZA_DYSTRYBUCJI_COLUMN');
  371. $files = glob("{$basePath}/{$id}.*", GLOB_NOSORT);
  372. if (empty($files)) {
  373. return false;
  374. }
  375. $file = reset($files);
  376. return $file;
  377. }
  378. else if ($type == 'DRUK') {
  379. $basePath = WebdavHelper::getBaseDir('CRM_LISTA_ZASOBOW_COLUMN');
  380. $files = glob("{$basePath}/{$id}.*", GLOB_NOSORT);
  381. if (empty($files)) {
  382. return false;
  383. }
  384. $file = reset($files);
  385. return $file;
  386. }
  387. else if ($type == 'PISMO') {
  388. $basePath = WebdavHelper::getBaseDir('IN7_DZIENNIK_KORESP_COLUMN');
  389. $pismoType = WebdavHelper::getPismoType($id);
  390. if ($pismoType) {
  391. $files = glob("{$basePath}/{$pismoType}/{$id}.*", GLOB_NOSORT);
  392. if (empty($files)) {
  393. return false;
  394. }
  395. $file = reset($files);
  396. }
  397. return $file;
  398. }
  399. }
  400. function findRealPaths($type, $ids) {
  401. $foundFiles = null;
  402. if ($type == 'PISMA') {
  403. $basePath = WebdavHelper::getBaseDir('IN7_DZIENNIK_KORESP_COLUMN');
  404. foreach ($ids as $id) {
  405. $files = glob("{$basePath}/*/{$id}.*", GLOB_NOSORT);
  406. if (empty($files)) {
  407. continue;
  408. }
  409. $file = reset($files);
  410. $foundFiles[] = $file;
  411. }
  412. }
  413. return $foundFiles;
  414. }
  415. function getFileSize($davpath, $user = null) {
  416. $file = self::getRealFile($davpath, $user);
  417. if ($file) {
  418. if ($file->is_dir === false) {
  419. if ($file->realpath && file_exists($file->realpath)) {
  420. return filesize($file->realpath);
  421. }
  422. }
  423. }
  424. return 0;
  425. }
  426. function getFileETag($davpath, $user = null) {
  427. $file = self::getRealFile($davpath, $user);
  428. if ($file) {
  429. if ($file->is_dir === false) {
  430. return '"' . md5_file($file->realpath) . '"';
  431. }
  432. }
  433. return '"0"';
  434. }
  435. function getFileContent($davpath, $user = null) {
  436. $file = self::getRealFile($davpath, $user);
  437. if ($file) {
  438. if ($file->is_dir === false) {
  439. return fopen($file->realpath, 'r');
  440. }
  441. }
  442. return null;
  443. }
  444. function file_exists($davpath) {
  445. $file = self::getRealFile($davpath);
  446. if (!$file) {
  447. return false;
  448. }
  449. return file_exists($file->realpath);
  450. }
  451. function setName($davpath, $newName) {
  452. $parts = explode('/', $davpath);
  453. $oldName = array_pop($parts);
  454. $davpath = implode('/', $parts);
  455. $file = self::getRealFile($davpath);
  456. if (!$file) {
  457. return 403;
  458. }
  459. if (false === strpos($file->perms, 'C')) {
  460. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$newName}) oldName({$oldName}) file not renamed - 403");
  461. return 403;
  462. }
  463. @rename($file->realpath . '/' . $oldName, $file->realpath . '/' . $newName);
  464. if (!file_exists($file->realpath . '/' . $newName)) {
  465. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$newName}) file not renamed - return 403");
  466. return 403;
  467. }
  468. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$newName}) file renamed - return 0");
  469. return 0;
  470. }
  471. function getMimeType($davpath, $user = null) {
  472. $file = self::getRealFile($davpath, $user);
  473. if ($file->is_dir) {
  474. return 'httpd/unix-directory';
  475. }
  476. $mimeType = self::getMimeTypeByExt($file->realpath);
  477. if ($mimeType == 'application/octet-stream') {
  478. // PHP >= 5.3.0, PECL fileinfo >= 0.1.0
  479. if (function_exists('finfo_open')) {
  480. if ($finfo = finfo_open(FILEINFO_MIME)) {
  481. $info = @strtolower(finfo_file($finfo, $file->realpath));
  482. if ($info) {
  483. $mimeType = substr($info, 0, strpos($info, ';'));
  484. }
  485. finfo_close($finfo);
  486. }
  487. } else if (function_exists('mime_content_type')) {
  488. $mimeType = mime_content_type($file->realpath);
  489. }
  490. }
  491. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) mimeType({$mimeType})");
  492. return $mimeType;
  493. }
  494. function getMimeTypeByExt($realPath) {
  495. $mimeTypesByExt = array(
  496. 'css'=>'text/css',
  497. 'flac'=>'audio/flac',
  498. 'gif'=>'image/gif',
  499. 'gzip'=>'application/x-gzip',
  500. 'gz'=>'application/x-gzip',
  501. 'html'=>'text/html',
  502. 'htm'=>'text/html',
  503. 'ics'=>'text/calendar',
  504. 'ical'=>'text/calendar',
  505. 'jpeg'=>'image/jpeg',
  506. 'jpg'=>'image/jpeg',
  507. 'js'=>'application/javascript',
  508. 'oga'=>'audio/ogg',
  509. 'ogg'=>'audio/ogg',
  510. 'ogv'=>'video/ogg',
  511. 'pdf'=>'application/pdf',
  512. 'png'=>'image/png',
  513. 'svg'=>'image/svg+xml',
  514. 'tar'=>'application/x-tar',
  515. 'tgz'=>'application/x-compressed',
  516. 'tar.gz'=>'application/x-compressed',
  517. 'tif'=>'image/tiff',
  518. 'tiff'=>'image/tiff',
  519. 'txt'=>'text/plain',
  520. 'zip'=>'application/zip',
  521. 'wav'=>'audio/wav',
  522. 'odt'=>'application/vnd.oasis.opendocument.text',
  523. 'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
  524. 'odg'=>'application/vnd.oasis.opendocument.graphics',
  525. 'odp'=>'application/vnd.oasis.opendocument.presentation',
  526. 'pages'=>'application/x-iwork-pages-sffpages',
  527. 'numbers'=>'application/x-iwork-numbers-sffnumbers',
  528. 'keynote'=>'application/x-iwork-keynote-sffkey',
  529. 'kra'=>'application/x-krita',
  530. 'mp3'=>'audio/mpeg',
  531. 'doc'=>'application/msword',
  532. 'docx'=>'application/msword',
  533. 'xls'=>'application/msexcel',
  534. 'xlsx'=>'application/msexcel',
  535. 'php'=>'application/x-php',
  536. 'exe'=>'application/x-ms-dos-executable',
  537. 'pl'=>'application/x-pearl',
  538. 'py'=>'application/x-python',
  539. 'blend'=>'application/x-blender',
  540. 'xcf'=>'application/x-gimp',
  541. 'psd'=>'application/x-photoshop',
  542. 'xml'=>'application/xml',
  543. 'avi'=>'video/x-msvideo',
  544. 'dv'=>'video/dv',
  545. 'm2t'=>'video/mp2t',
  546. 'mp4'=>'video/mp4',
  547. 'm4v'=>'video/mp4',
  548. 'mpg'=>'video/mpeg',
  549. 'mpeg'=>'video/mpeg',
  550. 'mov'=>'video/quicktime',
  551. 'webm'=>'video/webm',
  552. 'wmv'=>'video/x-ms-asf',
  553. 'py'=>'text/x-script.phyton',
  554. 'vcf' => 'text/vcard',
  555. 'vcard' => 'text/vcard',
  556. 'doc'=>'application/msword',
  557. 'docx'=>'application/msword',
  558. 'xls'=>'application/msexcel',
  559. 'xlsx'=>'application/msexcel',
  560. 'ppt'=>'application/mspowerpoint',
  561. 'pptx'=>'application/mspowerpoint',
  562. 'sgf' => 'application/sgf',
  563. 'cdr' => 'application/coreldraw',
  564. 'impress' => 'text/impress',
  565. 'ai' => 'application/illustrator',
  566. 'epub' => 'application/epub+zip',
  567. 'mobi' => 'application/x-mobipocket-ebook',
  568. 'exe' => 'application',
  569. 'msi' => 'application'
  570. );
  571. if (strpos($realPath, '.')) {
  572. $extension = substr(strtolower(strrchr(basename($realPath), ".")), 1);
  573. $mimeType = (isset($mimeTypesByExt[$extension]))? $mimeTypesByExt[$extension] : 'application/octet-stream';
  574. } else {
  575. $mimeType = 'application/octet-stream';
  576. }
  577. return $mimeType;
  578. }
  579. function createDirectory($davpath, $name, $user = null) {
  580. $file = self::getRealFile($davpath);
  581. if (!$file) {
  582. return 403;
  583. }
  584. // TODO: check perms RWXC by user
  585. if (false === strpos($file->perms, 'C')) {
  586. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$name}) file not created - 403");
  587. return 403;
  588. }
  589. // TODO: check $name - remove special chars
  590. //$name = 'TODO-newdir';
  591. //myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$name}) FILE:" . json_encode($file));
  592. @mkdir($file->realpath . '/' . $name, 0777);
  593. if (!file_exists($file->realpath . '/' . $name)) {
  594. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$name}) file not created - return 403");
  595. return 403;
  596. }
  597. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$name}) file created - return 0");
  598. return 0;
  599. }
  600. function createFile($davpath, $name, $data = null) {
  601. /*
  602. Creates a new file in the directory
  603. Data will either be supplied as a stream resource, or in certain cases as a string. Keep in mind that you may have to support either.
  604. After successful creation of the file, you may choose to return the ETag of the new file here.
  605. The returned ETag must be surrounded by double-quotes (The quotes should be part of the actual string).
  606. If you cannot accurately determine the ETag, you should not return it. If you don't store the file exactly as-is (you're transforming it somehow) you should also not return an ETag.
  607. This means that if a subsequent GET to this new file does not exactly return the same contents of what was submitted here, you are strongly recommended to omit the ETag.
  608. */
  609. $file = self::getRealFile($davpath);
  610. if (!$file) {
  611. return 403;
  612. }
  613. if (false === strpos($file->perms, 'C')) {
  614. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$name}) file not created - 403");
  615. return 403;
  616. }
  617. if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
  618. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) name({$name}) HTTP_OC_CHUNKED(".isset($_SERVER['HTTP_OC_CHUNKED']).")");
  619. return 501;
  620. /*
  621. $info = OC_FileChunking::decodeName($name);
  622. if (empty($info)) {
  623. throw new Sabre_DAV_Exception_NotImplemented();
  624. }
  625. $chunk_handler = new OC_FileChunking($info);
  626. $chunk_handler->store($info['index'], $data);
  627. if ($chunk_handler->isComplete()) {
  628. $newPath = $this->path . '/' . $info['name'];
  629. $chunk_handler->file_assemble($newPath);
  630. return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
  631. }
  632. */
  633. }
  634. else {
  635. // TODO: $name - remove special chars
  636. $newPath = $file->realpath . '/' . $name;
  637. // mark file as partial while uploading
  638. $partPath = $newPath . '.part';
  639. file_put_contents($partPath, $data);
  640. if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) {
  641. if (isset($_SERVER['CONTENT_LENGTH'])) {
  642. $expected = $_SERVER['CONTENT_LENGTH'];
  643. $actual = filesize($partPath);
  644. if ($actual != $expected) {
  645. unlink($partPath);
  646. return 400;
  647. }
  648. }
  649. }
  650. rename($partPath, $newPath);
  651. return '"' . md5_file($newPath) . '"';
  652. }
  653. return null;
  654. }
  655. function delete($davpath, $user = null) {
  656. $file = self::getRealFile($davpath);
  657. if (!$file) {
  658. return 403;
  659. }
  660. // if (false === strpos($file->perms, 'X')) {
  661. // myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) file not deleted - 403");
  662. // return 403;
  663. // }
  664. $rootDir = self::getRootDir();
  665. $trashDir = self::getTrashDir();
  666. $trashPath = str_replace($rootDir, $trashDir, $file->realpath);
  667. $trashPath = explode('/', $trashPath);
  668. $oldName = array_pop($trashPath);
  669. $oldName .= '.' . time();
  670. $trashPath = implode('/', $trashPath);
  671. myLog(__CLASS__, __FUNCTION__, __LINE__, "({$davpath}) trashPath({$trashPath}/{$oldName})");
  672. @mkdir($trashPath, 0777, true);
  673. @rename($file->realpath, $trashPath . '/' . $oldName);
  674. return 0;
  675. }
  676. function getPismoType($id) {
  677. $db = DB::getDB();
  678. $sql = "select kor.`K_TYP_KORESP` from `IN7_DZIENNIK_KORESP` as kor where kor.`ID`='{$id}' ";
  679. $res = $db->query($sql);
  680. if ($r = $db->fetch($res)) {
  681. return $r->K_TYP_KORESP;
  682. }
  683. return null;
  684. }
  685. function getProjektyIds($user_name = null) {
  686. $projektyIds = array();
  687. $db = DB::getDB();
  688. $sql = "select proj.`ID` from `IN7_MK_BAZA_DYSTRYBUCJI` as proj where proj.`L_APPOITMENT_USER`='{$user_name}' ";
  689. $res = $db->query($sql);
  690. while ($r = $db->fetch($res)) {
  691. $projektyIds[] = $r->ID;
  692. }
  693. return $projektyIds;
  694. }
  695. /*
  696. * PROJEKTY <--> DRUKI : IN7_MK_BAZA_DYSTRYBUCJI.ID_ZASOB_REVITALIZE <--> CRM_LISTA_ZASOBOW.ID
  697. */
  698. function getProjektyIdsByDruk($druk_id, $user = null) {
  699. $projektyIds = array();
  700. //$projektyIds[] = 1756;// TODO: test - read from DB by PROJEKTY <--> DRUKI : IN7_MK_BAZA_DYSTRYBUCJI.ID_ZASOB_REVITALIZE <--> CRM_LISTA_ZASOBOW.ID
  701. return $projektyIds;
  702. }
  703. /*
  704. * PROJEKTY <--> DRUKI : IN7_MK_BAZA_DYSTRYBUCJI.ID_ZASOB_REVITALIZE <--> CRM_LISTA_ZASOBOW.ID
  705. */
  706. function getDrukiIdsByProjekt($projekt_id, $user = null) {
  707. $drukiIds = array();
  708. $db = DB::getDB();
  709. $sql = "select proj.`ID_ZASOB_REVITALIZE`
  710. from `IN7_MK_BAZA_DYSTRYBUCJI` as proj
  711. where proj.`ID`='{$projekt_id}' and proj.`ID_ZASOB_REVITALIZE`>0
  712. ";
  713. $res = $db->query($sql);
  714. while ($r = $db->fetch($res)) {
  715. $drukiIds[] = $r->ID_ZASOB_REVITALIZE;
  716. }
  717. return $drukiIds;
  718. }
  719. /*
  720. * PROJEKTY <--> PISMA : IN7_DZIENNIK_KORESP.ID_PROJECT <--> IN7_MK_BAZA_DYSTRYBUCJI.ID
  721. */
  722. function getPismaIdsByProjekt($projekt_id, $user = null) {
  723. $pismaIds = array();
  724. $db = DB::getDB();
  725. $sql = "select kor.`ID` from `IN7_DZIENNIK_KORESP` as kor where kor.`ID_PROJECT`='{$projekt_id}' ";
  726. $res = $db->query($sql);
  727. while ($r = $db->fetch($res)) {
  728. $pismaIds[] = $r->ID;
  729. }
  730. return $pismaIds;
  731. }
  732. function auth() {
  733. Lib::loadClass('User');
  734. if ( ! User::logged() ) {
  735. //myLog(__CLASS__, __FUNCTION__, __LINE__, "not logged in...");
  736. if (!isset($_SERVER['PHP_AUTH_USER'])) {
  737. header('WWW-Authenticate: Basic realm="SE"');
  738. header('HTTP/1.0 401 Unauthorized');
  739. die('Access denied');
  740. } else {
  741. $ADM_ACCOUNT = V::get('PHP_AUTH_USER', '', $_SERVER);
  742. $ADM_PASSWD = V::get('PHP_AUTH_PW', '', $_SERVER);
  743. $errors = array();
  744. User::login($ADM_ACCOUNT, $ADM_PASSWD, $errors);
  745. if ( ! User::logged() ) {
  746. header('WWW-Authenticate: Basic realm="SE"');
  747. header('HTTP/1.0 401 Unauthorized');
  748. die('Access denied');
  749. }
  750. }
  751. } else {
  752. //myLog(__CLASS__, __FUNCTION__, __LINE__, "logged in...");
  753. }
  754. }
  755. /**
  756. * BUG: nie zadziała, bo wymaga albo hasła jawnym tekstem, albo dodatkowej kolumny z hashem do autoryzacji Digest
  757. */
  758. function auth_TODO_DIGEST() {
  759. $realm = 'Restricted area';
  760. if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
  761. header('HTTP/1.1 401 Unauthorized');
  762. header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
  763. die('Access denied');
  764. }
  765. // analyze the PHP_AUTH_DIGEST variable
  766. $data = self::http_digest_parse($_SERVER['PHP_AUTH_DIGEST']);
  767. myLog(__CLASS__, __FUNCTION__, __LINE__, " data: ".json_encode($data));
  768. if (!$data) {// || !isset($users[$data['username']])
  769. die('Wrong Credentials!');
  770. } else {
  771. //user => password
  772. $users = array('admin' => 'mypass', 'pl' => 'pl');
  773. // TODO: fetch $data['username'] password from DB
  774. // TODO: if user not exists die('User not exists!');
  775. Lib::loadClass('User');
  776. if ( ! User::logged() ) {
  777. $ADM_ACCOUNT = V::get('ADM_ACCOUNT', '', $_REQUEST);
  778. $ADM_PASSWD = V::get('ADM_PASSWD', '', $_REQUEST);
  779. $errors = array();
  780. User::login($ADM_ACCOUNT, $ADM_PASSWD, $errors);
  781. }
  782. }
  783. // generate the valid response
  784. $A1 = $data['username'] . ':' . $realm . ':' . $users[$data['username']];
  785. $A2 = $_SERVER['REQUEST_METHOD'].':'.$data['uri'];
  786. $valid_response = md5(implode(':', array(md5($A1), $data['nonce'], $data['nc'], $data['cnonce'], $data['qop'], md5($A2))));
  787. if ($data['response'] != $valid_response) {
  788. die('Wrong Credentials!');
  789. }
  790. // ok, valid username & password
  791. //echo 'You are logged in as: ' . $data['username'];
  792. }
  793. /**
  794. * Function to parse the http auth header
  795. */
  796. function http_digest_parse($txt) {
  797. // protect against missing data
  798. $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
  799. $data = array();
  800. $keys = implode('|', array_keys($needed_parts));
  801. preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
  802. foreach ($matches as $m) {
  803. $data[$m[1]] = $m[3] ? $m[3] : $m[4];
  804. unset($needed_parts[$m[1]]);
  805. }
  806. return $needed_parts ? false : $data;
  807. }
  808. }