elFinderSupportVer1.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /**
  2. * elFinder transport to support old protocol.
  3. *
  4. * @example
  5. * $('selector').elfinder({
  6. * ....
  7. * transport : new elFinderSupportVer1()
  8. * })
  9. *
  10. * @author Dmitry (dio) Levashov
  11. **/
  12. window.elFinderSupportVer1 = function(upload) {
  13. "use strict";
  14. var self = this,
  15. dateObj, today, yesterday,
  16. getDateString = function(date) {
  17. return date.replace('Today', today).replace('Yesterday', yesterday);
  18. };
  19. dateObj = new Date();
  20. today = dateObj.getFullYear() + '/' + (dateObj.getMonth() + 1) + '/' + dateObj.getDate();
  21. dateObj = new Date(Date.now() - 86400000);
  22. yesterday = dateObj.getFullYear() + '/' + (dateObj.getMonth() + 1) + '/' + dateObj.getDate();
  23. this.upload = upload || 'auto';
  24. this.init = function(fm) {
  25. this.fm = fm;
  26. this.fm.parseUploadData = function(text) {
  27. var data;
  28. if (!$.trim(text)) {
  29. return {error : ['errResponse', 'errDataEmpty']};
  30. }
  31. try {
  32. data = JSON.parse(text);
  33. } catch (e) {
  34. return {error : ['errResponse', 'errDataNotJSON']};
  35. }
  36. return self.normalize('upload', data);
  37. };
  38. };
  39. this.send = function(opts) {
  40. var self = this,
  41. fm = this.fm,
  42. dfrd = $.Deferred(),
  43. cmd = opts.data.cmd,
  44. args = [],
  45. _opts = {},
  46. data,
  47. xhr;
  48. dfrd.abort = function() {
  49. if (xhr.state() == 'pending') {
  50. xhr.quiet = true;
  51. xhr.abort();
  52. }
  53. };
  54. switch (cmd) {
  55. case 'open':
  56. opts.data.tree = 1;
  57. break;
  58. case 'parents':
  59. case 'tree':
  60. return dfrd.resolve({tree : []});
  61. case 'get':
  62. opts.data.cmd = 'read';
  63. opts.data.current = fm.file(opts.data.target).phash;
  64. break;
  65. case 'put':
  66. opts.data.cmd = 'edit';
  67. opts.data.current = fm.file(opts.data.target).phash;
  68. break;
  69. case 'archive':
  70. case 'rm':
  71. opts.data.current = fm.file(opts.data.targets[0]).phash;
  72. break;
  73. case 'extract':
  74. case 'rename':
  75. case 'resize':
  76. opts.data.current = fm.file(opts.data.target).phash;
  77. break;
  78. case 'duplicate':
  79. _opts = $.extend(true, {}, opts);
  80. $.each(opts.data.targets, function(i, hash) {
  81. $.ajax(Object.assign(_opts, {data : {cmd : 'duplicate', target : hash, current : fm.file(hash).phash}}))
  82. .fail(function(error) {
  83. fm.error(fm.res('error', 'connect'));
  84. })
  85. .done(function(data) {
  86. data = self.normalize('duplicate', data);
  87. if (data.error) {
  88. fm.error(data.error);
  89. } else if (data.added) {
  90. fm.trigger('add', {added : data.added});
  91. }
  92. });
  93. });
  94. return dfrd.resolve({});
  95. case 'mkdir':
  96. case 'mkfile':
  97. opts.data.current = opts.data.target;
  98. break;
  99. case 'paste':
  100. opts.data.current = opts.data.dst;
  101. if (! opts.data.tree) {
  102. $.each(opts.data.targets, function(i, h) {
  103. if (fm.file(h) && fm.file(h).mime === 'directory') {
  104. opts.data.tree = '1';
  105. return false;
  106. }
  107. });
  108. }
  109. break;
  110. case 'size':
  111. return dfrd.resolve({error : fm.res('error', 'cmdsupport')});
  112. case 'search':
  113. return dfrd.resolve({error : fm.res('error', 'cmdsupport')});
  114. case 'file':
  115. opts.data.cmd = 'open';
  116. opts.data.current = fm.file(opts.data.target).phash;
  117. break;
  118. }
  119. // cmd = opts.data.cmd
  120. xhr = $.ajax(opts)
  121. .fail(function(error) {
  122. dfrd.reject(error);
  123. })
  124. .done(function(raw) {
  125. data = self.normalize(cmd, raw);
  126. dfrd.resolve(data);
  127. });
  128. return dfrd;
  129. };
  130. // fix old connectors errors messages as possible
  131. // this.errors = {
  132. // 'Unknown command' : 'Unknown command.',
  133. // 'Invalid backend configuration' : 'Invalid backend configuration.',
  134. // 'Access denied' : 'Access denied.',
  135. // 'PHP JSON module not installed' : 'PHP JSON module not installed.',
  136. // 'File not found' : 'File not found.',
  137. // 'Invalid name' : 'Invalid file name.',
  138. // 'File or folder with the same name already exists' : 'File named "$1" already exists in this location.',
  139. // 'Not allowed file type' : 'Not allowed file type.',
  140. // 'File exceeds the maximum allowed filesize' : 'File exceeds maximum allowed size.',
  141. // 'Unable to copy into itself' : 'Unable to copy "$1" into itself.',
  142. // 'Unable to create archive' : 'Unable to create archive.',
  143. // 'Unable to extract files from archive' : 'Unable to extract files from "$1".'
  144. // }
  145. this.normalize = function(cmd, data) {
  146. var self = this,
  147. fm = this.fm,
  148. files = {},
  149. filter = function(file) { return file && file.hash && file.name && file.mime ? file : null; },
  150. getDirs = function(items) {
  151. return $.grep(items, function(i) {
  152. return i && i.mime && i.mime === 'directory'? true : false;
  153. });
  154. },
  155. getTreeDiff = function(files) {
  156. var dirs = getDirs(files);
  157. treeDiff = fm.diff(dirs, null, ['date', 'ts']);
  158. if (treeDiff.added.length) {
  159. treeDiff.added = getDirs(treeDiff.added);
  160. }
  161. if (treeDiff.changed.length) {
  162. treeDiff.changed = getDirs(treeDiff.changed);
  163. }
  164. if (treeDiff.removed.length) {
  165. var removed = [];
  166. $.each(treeDiff.removed, function(i, h) {
  167. var item;
  168. if ((item = fm.file(h)) && item.mime === 'directory') {
  169. removed.push(h);
  170. }
  171. });
  172. treeDiff.removed = removed;
  173. }
  174. return treeDiff;
  175. },
  176. phash, diff, isCwd, treeDiff;
  177. if ((cmd == 'tmb' || cmd == 'get')) {
  178. return data;
  179. }
  180. // if (data.error) {
  181. // $.each(data.error, function(i, msg) {
  182. // if (self.errors[msg]) {
  183. // data.error[i] = self.errors[msg];
  184. // }
  185. // });
  186. // }
  187. if (cmd == 'upload' && data.error && data.cwd) {
  188. data.warning = Object.assign({}, data.error);
  189. data.error = false;
  190. }
  191. if (data.error) {
  192. return data;
  193. }
  194. if (cmd == 'put') {
  195. phash = fm.file(data.target.hash).phash;
  196. return {changed : [this.normalizeFile(data.target, phash)]};
  197. }
  198. phash = data.cwd.hash;
  199. isCwd = (phash == fm.cwd().hash);
  200. if (data.tree) {
  201. $.each(this.normalizeTree(data.tree), function(i, file) {
  202. files[file.hash] = file;
  203. });
  204. }
  205. $.each(data.cdc||[], function(i, file) {
  206. var hash = file.hash,
  207. mcts;
  208. if (files[hash]) {
  209. if (file.date) {
  210. mcts = Date.parse(getDateString(file.date));
  211. if (mcts && !isNaN(mcts)) {
  212. files[hash].ts = Math.floor(mcts / 1000);
  213. } else {
  214. files[hash].date = file.date || fm.formatDate(file);
  215. }
  216. }
  217. files[hash].locked = file.hash == phash ? true : file.rm === void(0) ? false : !file.rm;
  218. } else {
  219. files[hash] = self.normalizeFile(file, phash, data.tmb);
  220. }
  221. });
  222. if (!data.tree) {
  223. $.each(fm.files(), function(hash, file) {
  224. if (!files[hash] && file.phash != phash && file.mime == 'directory') {
  225. files[hash] = file;
  226. }
  227. });
  228. }
  229. if (cmd == 'open') {
  230. return {
  231. cwd : files[phash] || this.normalizeFile(data.cwd),
  232. files : $.map(files, function(f) { return f; }),
  233. options : self.normalizeOptions(data),
  234. init : !!data.params,
  235. debug : data.debug
  236. };
  237. }
  238. if (isCwd) {
  239. diff = fm.diff($.map(files, filter));
  240. } else {
  241. if (data.tree && cmd !== 'paste') {
  242. diff = getTreeDiff(files);
  243. } else {
  244. diff = {
  245. added : [],
  246. removed : [],
  247. changed : []
  248. };
  249. if (cmd === 'paste') {
  250. diff.sync = true;
  251. }
  252. }
  253. }
  254. return Object.assign({
  255. current : data.cwd.hash,
  256. error : data.error,
  257. warning : data.warning,
  258. options : {tmb : !!data.tmb}
  259. }, diff);
  260. };
  261. /**
  262. * Convert old api tree into plain array of dirs
  263. *
  264. * @param Object root dir
  265. * @return Array
  266. */
  267. this.normalizeTree = function(root) {
  268. var self = this,
  269. result = [],
  270. traverse = function(dirs, phash) {
  271. var i, dir;
  272. for (i = 0; i < dirs.length; i++) {
  273. dir = dirs[i];
  274. result.push(self.normalizeFile(dir, phash));
  275. dir.dirs.length && traverse(dir.dirs, dir.hash);
  276. }
  277. };
  278. traverse([root]);
  279. return result;
  280. };
  281. /**
  282. * Convert file info from old api format into new one
  283. *
  284. * @param Object file
  285. * @param String parent dir hash
  286. * @return Object
  287. */
  288. this.normalizeFile = function(file, phash, tmb) {
  289. var mime = file.mime || 'directory',
  290. size = mime == 'directory' && !file.linkTo ? 0 : file.size,
  291. mcts = file.date? Date.parse(getDateString(file.date)) : void 0,
  292. info = {
  293. url : file.url,
  294. hash : file.hash,
  295. phash : phash,
  296. name : file.name,
  297. mime : mime,
  298. ts : file.ts,
  299. size : size,
  300. read : file.read,
  301. write : file.write,
  302. locked : !phash ? true : file.rm === void(0) ? false : !file.rm
  303. };
  304. if (! info.ts) {
  305. if (mcts && !isNaN(mcts)) {
  306. info.ts = Math.floor(mcts / 1000);
  307. } else {
  308. info.date = file.date || this.fm.formatDate(file);
  309. }
  310. }
  311. if (file.mime == 'application/x-empty' || file.mime == 'inode/x-empty') {
  312. info.mime = 'text/plain';
  313. }
  314. if (file.linkTo) {
  315. info.alias = file.linkTo;
  316. }
  317. if (file.linkTo) {
  318. info.linkTo = file.linkTo;
  319. }
  320. if (file.tmb) {
  321. info.tmb = file.tmb;
  322. } else if (info.mime.indexOf('image/') === 0 && tmb) {
  323. info.tmb = 1;
  324. }
  325. if (file.dirs && file.dirs.length) {
  326. info.dirs = true;
  327. }
  328. if (file.dim) {
  329. info.dim = file.dim;
  330. }
  331. if (file.resize) {
  332. info.resize = file.resize;
  333. }
  334. return info;
  335. };
  336. this.normalizeOptions = function(data) {
  337. var opts = {
  338. path : data.cwd.rel,
  339. disabled : $.merge((data.disabled || []), [ 'search', 'netmount', 'zipdl' ]),
  340. tmb : !!data.tmb,
  341. copyOverwrite : true
  342. };
  343. if (data.params) {
  344. opts.api = 1;
  345. opts.url = data.params.url;
  346. opts.archivers = {
  347. create : data.params.archives || [],
  348. extract : data.params.extract || []
  349. };
  350. }
  351. if (opts.path.indexOf('/') !== -1) {
  352. opts.separator = '/';
  353. } else if (opts.path.indexOf('\\') !== -1) {
  354. opts.separator = '\\';
  355. }
  356. return opts;
  357. };
  358. };