my_admin 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (822) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +4 -0
  3. data/Gemfile +12 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +407 -0
  6. data/Rakefile +35 -0
  7. data/app/assets/fonts/my_admin/FontAwesome.otf +0 -0
  8. data/app/assets/fonts/my_admin/fontawesome-webfont.eot +0 -0
  9. data/app/assets/fonts/my_admin/fontawesome-webfont.svg +284 -0
  10. data/app/assets/fonts/my_admin/fontawesome-webfont.ttf +0 -0
  11. data/app/assets/fonts/my_admin/fontawesome-webfont.woff +0 -0
  12. data/app/assets/fonts/my_admin/glyphicons-regular.eot +0 -0
  13. data/app/assets/fonts/my_admin/glyphicons-regular.otf +0 -0
  14. data/app/assets/fonts/my_admin/glyphicons-regular.svg +435 -0
  15. data/app/assets/fonts/my_admin/glyphicons-regular.ttf +0 -0
  16. data/app/assets/fonts/my_admin/glyphicons-regular.woff +0 -0
  17. data/app/assets/images/my_admin/apple-touch-icon-precomposed.png +0 -0
  18. data/app/assets/images/my_admin/email-login.jpg +0 -0
  19. data/app/assets/images/my_admin/email-logo.jpg +0 -0
  20. data/app/assets/images/my_admin/favicon.ico +0 -0
  21. data/app/assets/images/my_admin/glyphicons-halflings-white.png +0 -0
  22. data/app/assets/images/my_admin/glyphicons-halflings.png +0 -0
  23. data/app/assets/images/my_admin/loading.gif +0 -0
  24. data/app/assets/images/my_admin/logo-big.png +0 -0
  25. data/app/assets/images/my_admin/logo-big@2x.png +0 -0
  26. data/app/assets/images/my_admin/logo.png +0 -0
  27. data/app/assets/images/my_admin/logo@2x.png +0 -0
  28. data/app/assets/images/my_admin/navigation-bg-small.png +0 -0
  29. data/app/assets/images/my_admin/navigation-bg.png +0 -0
  30. data/app/assets/images/my_admin/no_image.gif +0 -0
  31. data/app/assets/images/my_admin/plugins/chosen/chosen-sprite.png +0 -0
  32. data/app/assets/images/my_admin/plugins/colorbox/controls.png +0 -0
  33. data/app/assets/images/my_admin/plugins/colorbox/loading.gif +0 -0
  34. data/app/assets/images/my_admin/plugins/colorpicker/alpha.png +0 -0
  35. data/app/assets/images/my_admin/plugins/colorpicker/hue.png +0 -0
  36. data/app/assets/images/my_admin/plugins/colorpicker/saturation.png +0 -0
  37. data/app/assets/images/my_admin/plugins/elfinder/arrows-active.png +0 -0
  38. data/app/assets/images/my_admin/plugins/elfinder/arrows-normal.png +0 -0
  39. data/app/assets/images/my_admin/plugins/elfinder/crop.gif +0 -0
  40. data/app/assets/images/my_admin/plugins/elfinder/dialogs.png +0 -0
  41. data/app/assets/images/my_admin/plugins/elfinder/icons-big.png +0 -0
  42. data/app/assets/images/my_admin/plugins/elfinder/icons-small.png +0 -0
  43. data/app/assets/images/my_admin/plugins/elfinder/logo.png +0 -0
  44. data/app/assets/images/my_admin/plugins/elfinder/progress.gif +0 -0
  45. data/app/assets/images/my_admin/plugins/elfinder/quicklook-bg.png +0 -0
  46. data/app/assets/images/my_admin/plugins/elfinder/quicklook-icons.png +0 -0
  47. data/app/assets/images/my_admin/plugins/elfinder/resize.png +0 -0
  48. data/app/assets/images/my_admin/plugins/elfinder/spinner-mini.gif +0 -0
  49. data/app/assets/images/my_admin/plugins/elfinder/toolbar.png +0 -0
  50. data/app/assets/images/my_admin/plugins/gmap/here.png +0 -0
  51. data/app/assets/images/my_admin/plugins/gmap/icon_greenA.png +0 -0
  52. data/app/assets/images/my_admin/plugins/gmap/icon_greenB.png +0 -0
  53. data/app/assets/images/my_admin/plugins/gmap/zoomin.png +0 -0
  54. data/app/assets/images/my_admin/plugins/gmap/zoomout.png +0 -0
  55. data/app/assets/images/my_admin/plugins/gritter/gritter-light.png +0 -0
  56. data/app/assets/images/my_admin/plugins/gritter/gritter-long.png +0 -0
  57. data/app/assets/images/my_admin/plugins/gritter/gritter.png +0 -0
  58. data/app/assets/images/my_admin/plugins/gritter/ie-spacer.gif +0 -0
  59. data/app/assets/images/my_admin/plugins/icheck/flat/aero.png +0 -0
  60. data/app/assets/images/my_admin/plugins/icheck/flat/aero@2x.png +0 -0
  61. data/app/assets/images/my_admin/plugins/icheck/flat/blue.png +0 -0
  62. data/app/assets/images/my_admin/plugins/icheck/flat/blue@2x.png +0 -0
  63. data/app/assets/images/my_admin/plugins/icheck/flat/flat.png +0 -0
  64. data/app/assets/images/my_admin/plugins/icheck/flat/flat@2x.png +0 -0
  65. data/app/assets/images/my_admin/plugins/icheck/flat/green.png +0 -0
  66. data/app/assets/images/my_admin/plugins/icheck/flat/green@2x.png +0 -0
  67. data/app/assets/images/my_admin/plugins/icheck/flat/grey.png +0 -0
  68. data/app/assets/images/my_admin/plugins/icheck/flat/grey@2x.png +0 -0
  69. data/app/assets/images/my_admin/plugins/icheck/flat/orange.png +0 -0
  70. data/app/assets/images/my_admin/plugins/icheck/flat/orange@2x.png +0 -0
  71. data/app/assets/images/my_admin/plugins/icheck/flat/pink.png +0 -0
  72. data/app/assets/images/my_admin/plugins/icheck/flat/pink@2x.png +0 -0
  73. data/app/assets/images/my_admin/plugins/icheck/flat/purple.png +0 -0
  74. data/app/assets/images/my_admin/plugins/icheck/flat/purple@2x.png +0 -0
  75. data/app/assets/images/my_admin/plugins/icheck/flat/red.png +0 -0
  76. data/app/assets/images/my_admin/plugins/icheck/flat/red@2x.png +0 -0
  77. data/app/assets/images/my_admin/plugins/icheck/flat/yellow.png +0 -0
  78. data/app/assets/images/my_admin/plugins/icheck/flat/yellow@2x.png +0 -0
  79. data/app/assets/images/my_admin/plugins/icheck/futurico/futurico.png +0 -0
  80. data/app/assets/images/my_admin/plugins/icheck/futurico/futurico@2x.png +0 -0
  81. data/app/assets/images/my_admin/plugins/icheck/line/line.png +0 -0
  82. data/app/assets/images/my_admin/plugins/icheck/line/line@2x.png +0 -0
  83. data/app/assets/images/my_admin/plugins/icheck/minimal/aero.png +0 -0
  84. data/app/assets/images/my_admin/plugins/icheck/minimal/aero@2x.png +0 -0
  85. data/app/assets/images/my_admin/plugins/icheck/minimal/blue.png +0 -0
  86. data/app/assets/images/my_admin/plugins/icheck/minimal/blue@2x.png +0 -0
  87. data/app/assets/images/my_admin/plugins/icheck/minimal/green.png +0 -0
  88. data/app/assets/images/my_admin/plugins/icheck/minimal/green@2x.png +0 -0
  89. data/app/assets/images/my_admin/plugins/icheck/minimal/grey.png +0 -0
  90. data/app/assets/images/my_admin/plugins/icheck/minimal/grey@2x.png +0 -0
  91. data/app/assets/images/my_admin/plugins/icheck/minimal/minimal.png +0 -0
  92. data/app/assets/images/my_admin/plugins/icheck/minimal/minimal@2x.png +0 -0
  93. data/app/assets/images/my_admin/plugins/icheck/minimal/orange.png +0 -0
  94. data/app/assets/images/my_admin/plugins/icheck/minimal/orange@2x.png +0 -0
  95. data/app/assets/images/my_admin/plugins/icheck/minimal/pink.png +0 -0
  96. data/app/assets/images/my_admin/plugins/icheck/minimal/pink@2x.png +0 -0
  97. data/app/assets/images/my_admin/plugins/icheck/minimal/purple.png +0 -0
  98. data/app/assets/images/my_admin/plugins/icheck/minimal/purple@2x.png +0 -0
  99. data/app/assets/images/my_admin/plugins/icheck/minimal/red.png +0 -0
  100. data/app/assets/images/my_admin/plugins/icheck/minimal/red@2x.png +0 -0
  101. data/app/assets/images/my_admin/plugins/icheck/minimal/yellow.png +0 -0
  102. data/app/assets/images/my_admin/plugins/icheck/minimal/yellow@2x.png +0 -0
  103. data/app/assets/images/my_admin/plugins/icheck/polaris/polaris.png +0 -0
  104. data/app/assets/images/my_admin/plugins/icheck/polaris/polaris@2x.png +0 -0
  105. data/app/assets/images/my_admin/plugins/icheck/square/aero.png +0 -0
  106. data/app/assets/images/my_admin/plugins/icheck/square/aero@2x.png +0 -0
  107. data/app/assets/images/my_admin/plugins/icheck/square/blue.png +0 -0
  108. data/app/assets/images/my_admin/plugins/icheck/square/blue@2x.png +0 -0
  109. data/app/assets/images/my_admin/plugins/icheck/square/green.png +0 -0
  110. data/app/assets/images/my_admin/plugins/icheck/square/green@2x.png +0 -0
  111. data/app/assets/images/my_admin/plugins/icheck/square/grey.png +0 -0
  112. data/app/assets/images/my_admin/plugins/icheck/square/grey@2x.png +0 -0
  113. data/app/assets/images/my_admin/plugins/icheck/square/orange.png +0 -0
  114. data/app/assets/images/my_admin/plugins/icheck/square/orange@2x.png +0 -0
  115. data/app/assets/images/my_admin/plugins/icheck/square/pink.png +0 -0
  116. data/app/assets/images/my_admin/plugins/icheck/square/pink@2x.png +0 -0
  117. data/app/assets/images/my_admin/plugins/icheck/square/purple.png +0 -0
  118. data/app/assets/images/my_admin/plugins/icheck/square/purple@2x.png +0 -0
  119. data/app/assets/images/my_admin/plugins/icheck/square/red.png +0 -0
  120. data/app/assets/images/my_admin/plugins/icheck/square/red@2x.png +0 -0
  121. data/app/assets/images/my_admin/plugins/icheck/square/square.png +0 -0
  122. data/app/assets/images/my_admin/plugins/icheck/square/square@2x.png +0 -0
  123. data/app/assets/images/my_admin/plugins/icheck/square/yellow.png +0 -0
  124. data/app/assets/images/my_admin/plugins/icheck/square/yellow@2x.png +0 -0
  125. data/app/assets/images/my_admin/plugins/multiselect/switch.png +0 -0
  126. data/app/assets/images/my_admin/plugins/pageguide/pageguide_arrow.png +0 -0
  127. data/app/assets/images/my_admin/plugins/plupload/backgrounds.gif +0 -0
  128. data/app/assets/images/my_admin/plugins/plupload/buttons-disabled.png +0 -0
  129. data/app/assets/images/my_admin/plugins/plupload/buttons.png +0 -0
  130. data/app/assets/images/my_admin/plugins/plupload/delete.gif +0 -0
  131. data/app/assets/images/my_admin/plugins/plupload/done.gif +0 -0
  132. data/app/assets/images/my_admin/plugins/plupload/error.gif +0 -0
  133. data/app/assets/images/my_admin/plugins/plupload/throbber.gif +0 -0
  134. data/app/assets/images/my_admin/plugins/plupload/transp50.png +0 -0
  135. data/app/assets/images/my_admin/plugins/select2/select2-spinner.gif +0 -0
  136. data/app/assets/images/my_admin/plugins/select2/select2.png +0 -0
  137. data/app/assets/images/my_admin/plugins/select2/select2x2.png +0 -0
  138. data/app/assets/images/my_admin/plugins/xeditable/clear.png +0 -0
  139. data/app/assets/images/my_admin/plugins/xeditable/loading.gif +0 -0
  140. data/app/assets/images/my_admin/sorting-asc.png +0 -0
  141. data/app/assets/images/my_admin/sorting-desc.png +0 -0
  142. data/app/assets/images/my_admin/sorting.png +0 -0
  143. data/app/assets/images/my_admin/users/missing_mini.png +0 -0
  144. data/app/assets/images/my_admin/users/missing_my_admin.png +0 -0
  145. data/app/assets/javascripts/my_admin/application.js +62 -0
  146. data/app/assets/javascripts/my_admin/application_locked.js +20 -0
  147. data/app/assets/javascripts/my_admin/application_off.js +22 -0
  148. data/app/assets/javascripts/my_admin/bootstrap.js +2268 -0
  149. data/app/assets/javascripts/my_admin/demonstration.js +1101 -0
  150. data/app/assets/javascripts/my_admin/eakroko.js +538 -0
  151. data/app/assets/javascripts/my_admin/extensions.js +20 -0
  152. data/app/assets/javascripts/my_admin/jquery.dateFormat.js +355 -0
  153. data/app/assets/javascripts/my_admin/jquery.maskMoney.js +355 -0
  154. data/app/assets/javascripts/my_admin/locale/pt-br/validate.js +24 -0
  155. data/app/assets/javascripts/my_admin/main.js +891 -0
  156. data/app/assets/javascripts/my_admin/my_admin.js +186 -0
  157. data/app/assets/javascripts/my_admin/plugins/bootbox/jquery.bootbox.js +17 -0
  158. data/app/assets/javascripts/my_admin/plugins/chosen/chosen.jquery.min.js +10 -0
  159. data/app/assets/javascripts/my_admin/plugins/chosen/chosen.jquery.min.min.js +9 -0
  160. data/app/assets/javascripts/my_admin/plugins/ckeditor/CHANGES.md +60 -0
  161. data/app/assets/javascripts/my_admin/plugins/ckeditor/LICENSE.md +1264 -0
  162. data/app/assets/javascripts/my_admin/plugins/ckeditor/README.md +39 -0
  163. data/app/assets/javascripts/my_admin/plugins/ckeditor/build-config.js +161 -0
  164. data/app/assets/javascripts/my_admin/plugins/ckeditor/ckeditor.js +874 -0
  165. data/app/assets/javascripts/my_admin/plugins/ckeditor/config.js +11 -0
  166. data/app/assets/javascripts/my_admin/plugins/ckeditor/contents.css +99 -0
  167. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/af.js +5 -0
  168. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ar.js +5 -0
  169. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/bg.js +5 -0
  170. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/bn.js +5 -0
  171. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/bs.js +5 -0
  172. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ca.js +5 -0
  173. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/cs.js +5 -0
  174. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/cy.js +5 -0
  175. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/da.js +5 -0
  176. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/de.js +5 -0
  177. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/el.js +5 -0
  178. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/en-au.js +5 -0
  179. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/en-ca.js +5 -0
  180. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/en-gb.js +5 -0
  181. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/en.js +5 -0
  182. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/eo.js +5 -0
  183. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/es.js +5 -0
  184. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/et.js +5 -0
  185. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/eu.js +5 -0
  186. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/fa.js +5 -0
  187. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/fi.js +5 -0
  188. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/fo.js +5 -0
  189. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/fr-ca.js +5 -0
  190. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/fr.js +5 -0
  191. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/gl.js +5 -0
  192. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/gu.js +5 -0
  193. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/he.js +5 -0
  194. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/hi.js +5 -0
  195. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/hr.js +5 -0
  196. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/hu.js +5 -0
  197. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/is.js +5 -0
  198. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/it.js +5 -0
  199. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ja.js +5 -0
  200. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ka.js +5 -0
  201. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/km.js +5 -0
  202. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ko.js +5 -0
  203. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ku.js +5 -0
  204. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/lt.js +5 -0
  205. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/lv.js +5 -0
  206. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/mk.js +5 -0
  207. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/mn.js +5 -0
  208. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ms.js +5 -0
  209. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/nb.js +5 -0
  210. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/nl.js +5 -0
  211. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/no.js +5 -0
  212. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/pl.js +5 -0
  213. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/pt-br.js +5 -0
  214. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/pt.js +5 -0
  215. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ro.js +5 -0
  216. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ru.js +5 -0
  217. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/sk.js +5 -0
  218. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/sl.js +5 -0
  219. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/sr-latn.js +5 -0
  220. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/sr.js +5 -0
  221. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/sv.js +5 -0
  222. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/th.js +5 -0
  223. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/tr.js +5 -0
  224. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/ug.js +5 -0
  225. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/uk.js +5 -0
  226. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/vi.js +5 -0
  227. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/zh-cn.js +5 -0
  228. data/app/assets/javascripts/my_admin/plugins/ckeditor/lang/zh.js +5 -0
  229. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js +10 -0
  230. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/_translationstatus.txt +25 -0
  231. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ar.js +9 -0
  232. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/bg.js +9 -0
  233. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ca.js +9 -0
  234. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/cs.js +10 -0
  235. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/cy.js +9 -0
  236. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/da.js +9 -0
  237. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/de.js +10 -0
  238. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/el.js +10 -0
  239. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/en.js +9 -0
  240. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/eo.js +10 -0
  241. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/es.js +10 -0
  242. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/et.js +9 -0
  243. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fa.js +9 -0
  244. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fi.js +10 -0
  245. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fr.js +10 -0
  246. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/gu.js +9 -0
  247. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/he.js +9 -0
  248. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/hi.js +9 -0
  249. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/hr.js +9 -0
  250. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/hu.js +9 -0
  251. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/it.js +10 -0
  252. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ja.js +9 -0
  253. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ku.js +10 -0
  254. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/lt.js +9 -0
  255. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/lv.js +10 -0
  256. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/mk.js +9 -0
  257. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/mn.js +9 -0
  258. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/nb.js +9 -0
  259. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/nl.js +10 -0
  260. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/no.js +9 -0
  261. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/pl.js +9 -0
  262. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/pt-br.js +9 -0
  263. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/pt.js +9 -0
  264. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ro.js +9 -0
  265. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ru.js +9 -0
  266. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sk.js +10 -0
  267. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sl.js +9 -0
  268. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sv.js +10 -0
  269. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/tr.js +10 -0
  270. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ug.js +9 -0
  271. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/uk.js +9 -0
  272. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/vi.js +9 -0
  273. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/zh-cn.js +7 -0
  274. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/about/dialogs/about.js +6 -0
  275. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/about/dialogs/logo_ckeditor.png +0 -0
  276. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/clipboard/dialogs/paste.js +11 -0
  277. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/colordialog/dialogs/colordialog.js +13 -0
  278. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/dialog/dialogDefinition.js +4 -0
  279. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/div/dialogs/div.js +9 -0
  280. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/fakeobjects/images/spacer.gif +0 -0
  281. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/find/dialogs/find.js +24 -0
  282. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/flash/dialogs/flash.js +23 -0
  283. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/flash/images/placeholder.png +0 -0
  284. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/button.js +8 -0
  285. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/checkbox.js +8 -0
  286. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/form.js +8 -0
  287. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/hiddenfield.js +8 -0
  288. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/radio.js +8 -0
  289. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/select.js +20 -0
  290. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/textarea.js +8 -0
  291. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/dialogs/textfield.js +10 -0
  292. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/forms/images/hiddenfield.gif +0 -0
  293. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/icons.png +0 -0
  294. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/iframe/dialogs/iframe.js +10 -0
  295. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/iframe/images/placeholder.png +0 -0
  296. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/image/dialogs/image.js +41 -0
  297. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/image/images/noimage.png +0 -0
  298. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/link/dialogs/anchor.js +8 -0
  299. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/link/dialogs/link.js +36 -0
  300. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/link/images/anchor.png +0 -0
  301. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/liststyle/dialogs/liststyle.js +10 -0
  302. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/magicline/images/icon.png +0 -0
  303. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/pagebreak/images/pagebreak.gif +0 -0
  304. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/pastefromword/filter/default.js +31 -0
  305. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/preview/preview.html +10 -0
  306. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/scayt/LICENSE.md +28 -0
  307. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/scayt/README.md +25 -0
  308. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/scayt/dialogs/options.js +19 -0
  309. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/scayt/dialogs/toolbar.css +71 -0
  310. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_address.png +0 -0
  311. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_blockquote.png +0 -0
  312. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_div.png +0 -0
  313. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_h1.png +0 -0
  314. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_h2.png +0 -0
  315. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_h3.png +0 -0
  316. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_h4.png +0 -0
  317. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_h5.png +0 -0
  318. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_h6.png +0 -0
  319. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_p.png +0 -0
  320. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/showblocks/images/block_pre.png +0 -0
  321. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/dialogs/smiley.js +10 -0
  322. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/angel_smile.gif +0 -0
  323. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/angry_smile.gif +0 -0
  324. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/broken_heart.gif +0 -0
  325. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/confused_smile.gif +0 -0
  326. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/cry_smile.gif +0 -0
  327. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/devil_smile.gif +0 -0
  328. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/embaressed_smile.gif +0 -0
  329. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/embarrassed_smile.gif +0 -0
  330. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/envelope.gif +0 -0
  331. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/heart.gif +0 -0
  332. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/kiss.gif +0 -0
  333. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/lightbulb.gif +0 -0
  334. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/omg_smile.gif +0 -0
  335. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/regular_smile.gif +0 -0
  336. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/sad_smile.gif +0 -0
  337. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/shades_smile.gif +0 -0
  338. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/teeth_smile.gif +0 -0
  339. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/thumbs_down.gif +0 -0
  340. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/thumbs_up.gif +0 -0
  341. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/tongue_smile.gif +0 -0
  342. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/tounge_smile.gif +0 -0
  343. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/whatchutalkingabout_smile.gif +0 -0
  344. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/smiley/images/wink_smile.gif +0 -0
  345. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/_translationstatus.txt +20 -0
  346. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/ca.js +13 -0
  347. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/cs.js +13 -0
  348. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/cy.js +14 -0
  349. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/de.js +13 -0
  350. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/el.js +13 -0
  351. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/en.js +13 -0
  352. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/eo.js +12 -0
  353. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/et.js +13 -0
  354. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/fa.js +13 -0
  355. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/fi.js +13 -0
  356. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/fr.js +11 -0
  357. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/he.js +13 -0
  358. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/hr.js +13 -0
  359. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/it.js +14 -0
  360. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/ku.js +14 -0
  361. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/lv.js +13 -0
  362. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/nb.js +11 -0
  363. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/nl.js +13 -0
  364. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/no.js +11 -0
  365. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/pt-br.js +11 -0
  366. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/sk.js +13 -0
  367. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/sv.js +11 -0
  368. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/tr.js +12 -0
  369. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/ug.js +13 -0
  370. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/lang/zh-cn.js +9 -0
  371. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/specialchar/dialogs/specialchar.js +14 -0
  372. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/table/dialogs/table.js +20 -0
  373. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/tabletools/dialogs/tableCell.js +16 -0
  374. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/templates/dialogs/templates.css +84 -0
  375. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/templates/dialogs/templates.js +10 -0
  376. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/templates/templates/default.js +6 -0
  377. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/templates/templates/images/template1.gif +0 -0
  378. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/templates/templates/images/template2.gif +0 -0
  379. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/templates/templates/images/template3.gif +0 -0
  380. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/wsc/LICENSE.md +28 -0
  381. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/wsc/README.md +25 -0
  382. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/wsc/dialogs/ciframe.html +49 -0
  383. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/wsc/dialogs/tmpFrameset.html +52 -0
  384. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/wsc/dialogs/wsc.css +82 -0
  385. data/app/assets/javascripts/my_admin/plugins/ckeditor/plugins/wsc/dialogs/wsc.js +11 -0
  386. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/dialog.css +5 -0
  387. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/dialog_ie.css +5 -0
  388. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/dialog_ie7.css +5 -0
  389. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/dialog_ie8.css +5 -0
  390. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/dialog_iequirks.css +5 -0
  391. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/dialog_opera.css +5 -0
  392. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/editor.css +5 -0
  393. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/editor_gecko.css +5 -0
  394. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/editor_ie.css +5 -0
  395. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/editor_ie7.css +5 -0
  396. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/editor_ie8.css +5 -0
  397. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/editor_iequirks.css +5 -0
  398. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/icons.png +0 -0
  399. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/images/arrow.png +0 -0
  400. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/images/close.png +0 -0
  401. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/images/mini.png +0 -0
  402. data/app/assets/javascripts/my_admin/plugins/ckeditor/skins/moono/readme.md +51 -0
  403. data/app/assets/javascripts/my_admin/plugins/ckeditor/styles.js +112 -0
  404. data/app/assets/javascripts/my_admin/plugins/colorbox/jquery.colorbox-min.js +6 -0
  405. data/app/assets/javascripts/my_admin/plugins/colorpicker/bootstrap-colorpicker.js +540 -0
  406. data/app/assets/javascripts/my_admin/plugins/complexify/jquery.complexify-banlist.js +3 -0
  407. data/app/assets/javascripts/my_admin/plugins/complexify/jquery.complexify-banlist.min.js +3 -0
  408. data/app/assets/javascripts/my_admin/plugins/complexify/jquery.complexify.js +185 -0
  409. data/app/assets/javascripts/my_admin/plugins/complexify/jquery.complexify.min.js +5 -0
  410. data/app/assets/javascripts/my_admin/plugins/datatable/ColReorder.min.js +33 -0
  411. data/app/assets/javascripts/my_admin/plugins/datatable/ColVis.js +1133 -0
  412. data/app/assets/javascripts/my_admin/plugins/datatable/ColVis.min.js +20 -0
  413. data/app/assets/javascripts/my_admin/plugins/datatable/FixedColumns.min.js +18 -0
  414. data/app/assets/javascripts/my_admin/plugins/datatable/FixedColumns.min.min.js +18 -0
  415. data/app/assets/javascripts/my_admin/plugins/datatable/TableTools.min.js +76 -0
  416. data/app/assets/javascripts/my_admin/plugins/datatable/as3/ZeroClipboard.as +221 -0
  417. data/app/assets/javascripts/my_admin/plugins/datatable/as3/ZeroClipboardPdf.as +310 -0
  418. data/app/assets/javascripts/my_admin/plugins/datatable/as3/lib/AlivePDF.swc +0 -0
  419. data/app/assets/javascripts/my_admin/plugins/datatable/dataTables.scroller.min.js +40 -0
  420. data/app/assets/javascripts/my_admin/plugins/datatable/demo.txt +2503 -0
  421. data/app/assets/javascripts/my_admin/plugins/datatable/jquery.dataTables.columnFilter.js +764 -0
  422. data/app/assets/javascripts/my_admin/plugins/datatable/jquery.dataTables.columnFilter.min.js +22 -0
  423. data/app/assets/javascripts/my_admin/plugins/datatable/jquery.dataTables.min.js +155 -0
  424. data/app/assets/javascripts/my_admin/plugins/datatable/swf/copy_csv_xls.swf +0 -0
  425. data/app/assets/javascripts/my_admin/plugins/datatable/swf/copy_csv_xls_pdf.swf +0 -0
  426. data/app/assets/javascripts/my_admin/plugins/datepicker/bootstrap-datepicker.js +988 -0
  427. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.bg.js +14 -0
  428. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.ca.js +14 -0
  429. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.cs.js +15 -0
  430. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.da.js +14 -0
  431. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.de.js +16 -0
  432. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.el.js +13 -0
  433. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.es.js +14 -0
  434. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.fi.js +14 -0
  435. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.fr.js +16 -0
  436. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.he.js +15 -0
  437. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.hr.js +13 -0
  438. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.id.js +13 -0
  439. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.is.js +14 -0
  440. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.it.js +16 -0
  441. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.ja.js +13 -0
  442. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.kr.js +13 -0
  443. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.lt.js +16 -0
  444. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.lv.js +16 -0
  445. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.ms.js +14 -0
  446. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.nb.js +14 -0
  447. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.nl.js +14 -0
  448. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.pl.js +15 -0
  449. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.pt-BR.js +15 -0
  450. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.pt.js +14 -0
  451. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.ro.js +15 -0
  452. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.rs-latin.js +14 -0
  453. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.rs.js +14 -0
  454. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.ru.js +14 -0
  455. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.sk.js +15 -0
  456. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.sl.js +14 -0
  457. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.sv.js +14 -0
  458. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.sw.js +15 -0
  459. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.th.js +14 -0
  460. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.tr.js +15 -0
  461. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.uk.js +14 -0
  462. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js +14 -0
  463. data/app/assets/javascripts/my_admin/plugins/datepicker/locales/bootstrap-datepicker.zh-TW.js +13 -0
  464. data/app/assets/javascripts/my_admin/plugins/dynatree/jquery.dynatree.js +3432 -0
  465. data/app/assets/javascripts/my_admin/plugins/easy-pie-chart/jquery.easy-pie-chart.min.js +16 -0
  466. data/app/assets/javascripts/my_admin/plugins/elfinder/elfinder.min.js +26 -0
  467. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_Rm9sZGVyICMxL3Njb3R0d2lsbHNfdW5kZXJ3YXRlcjIuanBn1221239104.png +0 -0
  468. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_Rm9sZGVyICMxL3Njb3R0d2lsbHNfdW5kZXJ3YXRlcjUuanBn1221239108.png +0 -0
  469. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_Rm9sZGVyICMyL3Njb3R0d2lsbHNfY2F0LmpwZw1221239094.png +0 -0
  470. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_Rm9sZGVyICMyL3Njb3R0d2lsbHNfZ2FyZGVucy5qcGc1221239206.png +0 -0
  471. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_Rm9sZGVyICMyL3Njb3R0d2lsbHNfZmlzaC5qcGc1221239096.png +0 -0
  472. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_Rm9sZGVyICMyL3Njb3R0d2lsbHNfaG9yc2UuanBn1221239096.png +0 -0
  473. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_bWFkbmVzc19iZWFjaC5qcGc1208954324.png +0 -0
  474. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_bWFkbmVzc19ib2F0LmpwZw1208954324.png +0 -0
  475. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_c2NvdHR3aWxsc19hdXR1bW4zLmpwZw1221239274.png +0 -0
  476. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_c2NvdHR3aWxsc19idWZmYWxvLmpwZw1221239094.png +0 -0
  477. data/app/assets/javascripts/my_admin/plugins/elfinder/files/.tmb/l1_c2NvdHR3aWxsc19idXR0ZXJmbHkuanBn1221239286.png +0 -0
  478. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #1/Another_file.txt +0 -0
  479. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #1/file.txt +0 -0
  480. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #1/scottwills_underwater2.jpg +0 -0
  481. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #1/scottwills_underwater5.jpg +0 -0
  482. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #2/scottwills_cat.jpg +0 -0
  483. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #2/scottwills_fish.jpg +0 -0
  484. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #2/scottwills_gardens.jpg +0 -0
  485. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Folder #2/scottwills_horse.jpg +0 -0
  486. data/app/assets/javascripts/my_admin/plugins/elfinder/files/Main-file.txt +1 -0
  487. data/app/assets/javascripts/my_admin/plugins/elfinder/files/madness_beach.jpg +0 -0
  488. data/app/assets/javascripts/my_admin/plugins/elfinder/files/madness_boat.jpg +0 -0
  489. data/app/assets/javascripts/my_admin/plugins/elfinder/files/scottwills_autumn3.jpg +0 -0
  490. data/app/assets/javascripts/my_admin/plugins/elfinder/files/scottwills_buffalo.jpg +0 -0
  491. data/app/assets/javascripts/my_admin/plugins/elfinder/files/scottwills_butterfly.jpg +0 -0
  492. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.LANG.js +355 -0
  493. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.ar.js +290 -0
  494. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.bg.js +310 -0
  495. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.ca.js +310 -0
  496. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.cs.js +340 -0
  497. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.de.js +287 -0
  498. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.el.js +355 -0
  499. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.es.js +291 -0
  500. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.fa.js +339 -0
  501. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.fr.js +325 -0
  502. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.hu.js +280 -0
  503. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.it.js +340 -0
  504. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.jp.js +335 -0
  505. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.ko.js +340 -0
  506. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.nl.js +352 -0
  507. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.no.js +280 -0
  508. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.pl.js +309 -0
  509. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.pt_BR.js +320 -0
  510. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.ru.js +355 -0
  511. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.tr.js +340 -0
  512. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.vi.js +340 -0
  513. data/app/assets/javascripts/my_admin/plugins/elfinder/i18n/elfinder.zh_CN.js +354 -0
  514. data/app/assets/javascripts/my_admin/plugins/elfinder/php/MySQLStorage.sql +23 -0
  515. data/app/assets/javascripts/my_admin/plugins/elfinder/php/connector.minimal.php +57 -0
  516. data/app/assets/javascripts/my_admin/plugins/elfinder/php/connector.php +65 -0
  517. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinder.class.php +1500 -0
  518. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinderConnector.class.php +133 -0
  519. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinderVolumeDriver.class.php +3520 -0
  520. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinderVolumeDropbox.class.php +1450 -0
  521. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinderVolumeFTP.class.php +994 -0
  522. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinderVolumeLocalFileSystem.class.php +837 -0
  523. data/app/assets/javascripts/my_admin/plugins/elfinder/php/elFinderVolumeMySQL.class.php +960 -0
  524. data/app/assets/javascripts/my_admin/plugins/elfinder/php/mime.types +512 -0
  525. data/app/assets/javascripts/my_admin/plugins/elfinder/proxy/elFinderSupportVer1.js +338 -0
  526. data/app/assets/javascripts/my_admin/plugins/fileupload/bootstrap-fileupload.min.js +18 -0
  527. data/app/assets/javascripts/my_admin/plugins/flot/jquery.flot.bar.order.min.js +21 -0
  528. data/app/assets/javascripts/my_admin/plugins/flot/jquery.flot.min.js +28 -0
  529. data/app/assets/javascripts/my_admin/plugins/flot/jquery.flot.pie.js +812 -0
  530. data/app/assets/javascripts/my_admin/plugins/flot/jquery.flot.pie.min.js +56 -0
  531. data/app/assets/javascripts/my_admin/plugins/flot/jquery.flot.resize.min.js +18 -0
  532. data/app/assets/javascripts/my_admin/plugins/flot/jquery.flot.stack.js +184 -0
  533. data/app/assets/javascripts/my_admin/plugins/form/jquery.form.min.js +11 -0
  534. data/app/assets/javascripts/my_admin/plugins/fullcalendar/fullcalendar.min.js +17 -0
  535. data/app/assets/javascripts/my_admin/plugins/gmap/gmap3-menu.js +99 -0
  536. data/app/assets/javascripts/my_admin/plugins/gmap/gmap3.min.js +10 -0
  537. data/app/assets/javascripts/my_admin/plugins/gritter/jquery.gritter.min.js +1 -0
  538. data/app/assets/javascripts/my_admin/plugins/icheck/jquery.icheck.min.js +9 -0
  539. data/app/assets/javascripts/my_admin/plugins/imagesLoaded/jquery.imagesloaded.min.js +3 -0
  540. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.core.min.js +5 -0
  541. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.datepicker.min.js +5 -0
  542. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.draggable.min.js +15 -0
  543. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.droppable.min.js +16 -0
  544. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.mouse.min.js +13 -0
  545. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.position.js +497 -0
  546. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.resizable.min.js +5 -0
  547. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.selectable.min.js +15 -0
  548. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.slider.js +649 -0
  549. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.sortable.min.js +5 -0
  550. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.spinner.js +492 -0
  551. data/app/assets/javascripts/my_admin/plugins/jquery-ui/jquery.ui.widget.min.js +5 -0
  552. data/app/assets/javascripts/my_admin/plugins/maskedinput/jquery.maskedinput.min.js +7 -0
  553. data/app/assets/javascripts/my_admin/plugins/masonry/jquery.masonry.min.js +10 -0
  554. data/app/assets/javascripts/my_admin/plugins/mockjax/jquery.mockjax.js +25 -0
  555. data/app/assets/javascripts/my_admin/plugins/momentjs/jquery.moment.js +6 -0
  556. data/app/assets/javascripts/my_admin/plugins/multiselect/jquery.multi-select.js +464 -0
  557. data/app/assets/javascripts/my_admin/plugins/nicescroll/jquery.nicescroll.min.js +101 -0
  558. data/app/assets/javascripts/my_admin/plugins/pageguide/jquery.pageguide.js +980 -0
  559. data/app/assets/javascripts/my_admin/plugins/placeholder/jquery.placeholder.min.js +2 -0
  560. data/app/assets/javascripts/my_admin/plugins/plupload/jquery.plupload.queue.js +1 -0
  561. data/app/assets/javascripts/my_admin/plugins/plupload/plupload.flash.swf +0 -0
  562. data/app/assets/javascripts/my_admin/plugins/plupload/plupload.full.js +2 -0
  563. data/app/assets/javascripts/my_admin/plugins/plupload/plupload.silverlight.xap +0 -0
  564. data/app/assets/javascripts/my_admin/plugins/select2/select2.min.js +22 -0
  565. data/app/assets/javascripts/my_admin/plugins/slimscroll/jquery.slimscroll.js +440 -0
  566. data/app/assets/javascripts/my_admin/plugins/slimscroll/jquery.slimscroll.min.js +7 -0
  567. data/app/assets/javascripts/my_admin/plugins/sparklines/jquery.sparklines.min.js +5 -0
  568. data/app/assets/javascripts/my_admin/plugins/tagsinput/jquery.tagsinput.min.js +1 -0
  569. data/app/assets/javascripts/my_admin/plugins/timepicker/bootstrap-timepicker.min.js +6 -0
  570. data/app/assets/javascripts/my_admin/plugins/touch-punch/jquery.touch-punch.min.js +11 -0
  571. data/app/assets/javascripts/my_admin/plugins/touchwipe/touchwipe.js +82 -0
  572. data/app/assets/javascripts/my_admin/plugins/touchwipe/touchwipe.min.js +9 -0
  573. data/app/assets/javascripts/my_admin/plugins/validation/additional-methods.min.js +4 -0
  574. data/app/assets/javascripts/my_admin/plugins/validation/jquery.validate.min.js +4 -0
  575. data/app/assets/javascripts/my_admin/plugins/vmap/jquery.vmap.min.js +12 -0
  576. data/app/assets/javascripts/my_admin/plugins/vmap/jquery.vmap.sampledata.js +1 -0
  577. data/app/assets/javascripts/my_admin/plugins/vmap/jquery.vmap.world.js +2 -0
  578. data/app/assets/javascripts/my_admin/plugins/wizard/jquery.form.wizard.min.js +12 -0
  579. data/app/assets/javascripts/my_admin/plugins/xeditable/address.js +168 -0
  580. data/app/assets/javascripts/my_admin/plugins/xeditable/bootstrap-editable.min.js +5 -0
  581. data/app/assets/javascripts/my_admin/plugins/xeditable/demo.js +139 -0
  582. data/app/assets/javascripts/my_admin/plugins/xeditable/demo.min.js +1 -0
  583. data/app/assets/javascripts/my_admin/rails.js +352 -0
  584. data/app/assets/javascripts/my_admin.js +0 -0
  585. data/app/assets/stylesheets/my_admin/application.css +30 -0
  586. data/app/assets/stylesheets/my_admin/application_locked.css +17 -0
  587. data/app/assets/stylesheets/my_admin/application_off.css +18 -0
  588. data/app/assets/stylesheets/my_admin/bootstrap-responsive.css +1109 -0
  589. data/app/assets/stylesheets/my_admin/bootstrap.css.erb +6159 -0
  590. data/app/assets/stylesheets/my_admin/my_admin.css +11 -0
  591. data/app/assets/stylesheets/my_admin/plugins/chosen/chosen.css.erb +397 -0
  592. data/app/assets/stylesheets/my_admin/plugins/colorbox/colorbox.css.erb +49 -0
  593. data/app/assets/stylesheets/my_admin/plugins/colorpicker/colorpicker.css.erb +7 -0
  594. data/app/assets/stylesheets/my_admin/plugins/datatable/TableTools.css +321 -0
  595. data/app/assets/stylesheets/my_admin/plugins/datatable/jquery.dataTables.css +221 -0
  596. data/app/assets/stylesheets/my_admin/plugins/datepicker/datepicker.css +301 -0
  597. data/app/assets/stylesheets/my_admin/plugins/dynatree/icons.gif +0 -0
  598. data/app/assets/stylesheets/my_admin/plugins/dynatree/loading.gif +0 -0
  599. data/app/assets/stylesheets/my_admin/plugins/dynatree/ui.dynatree.css +452 -0
  600. data/app/assets/stylesheets/my_admin/plugins/easy-pie-chart/jquery.easy-pie-chart.css +1 -0
  601. data/app/assets/stylesheets/my_admin/plugins/elfinder/elfinder.min.css +9 -0
  602. data/app/assets/stylesheets/my_admin/plugins/elfinder/theme.css.erb +50 -0
  603. data/app/assets/stylesheets/my_admin/plugins/fullcalendar/fullcalendar.css +1 -0
  604. data/app/assets/stylesheets/my_admin/plugins/fullcalendar/fullcalendar.print.css +1 -0
  605. data/app/assets/stylesheets/my_admin/plugins/gmap/gmap3-menu.css.erb +44 -0
  606. data/app/assets/stylesheets/my_admin/plugins/gritter/jquery.gritter.css +1 -0
  607. data/app/assets/stylesheets/my_admin/plugins/icheck/all.css +61 -0
  608. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/_all.css +540 -0
  609. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/aero.css +54 -0
  610. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/blue.css +54 -0
  611. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/flat.css +54 -0
  612. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/green.css +54 -0
  613. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/grey.css +54 -0
  614. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/orange.css +54 -0
  615. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/pink.css +54 -0
  616. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/purple.css +54 -0
  617. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/red.css +54 -0
  618. data/app/assets/stylesheets/my_admin/plugins/icheck/flat/yellow.css +54 -0
  619. data/app/assets/stylesheets/my_admin/plugins/icheck/futurico/futurico.css +54 -0
  620. data/app/assets/stylesheets/my_admin/plugins/icheck/line/_all.css +650 -0
  621. data/app/assets/stylesheets/my_admin/plugins/icheck/line/aero.css +65 -0
  622. data/app/assets/stylesheets/my_admin/plugins/icheck/line/blue.css +65 -0
  623. data/app/assets/stylesheets/my_admin/plugins/icheck/line/green.css +65 -0
  624. data/app/assets/stylesheets/my_admin/plugins/icheck/line/grey.css +65 -0
  625. data/app/assets/stylesheets/my_admin/plugins/icheck/line/line.css +65 -0
  626. data/app/assets/stylesheets/my_admin/plugins/icheck/line/orange.css +65 -0
  627. data/app/assets/stylesheets/my_admin/plugins/icheck/line/pink.css +65 -0
  628. data/app/assets/stylesheets/my_admin/plugins/icheck/line/purple.css +65 -0
  629. data/app/assets/stylesheets/my_admin/plugins/icheck/line/red.css +65 -0
  630. data/app/assets/stylesheets/my_admin/plugins/icheck/line/yellow.css +65 -0
  631. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/_all.css +640 -0
  632. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/aero.css +64 -0
  633. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/blue.css +64 -0
  634. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/green.css +64 -0
  635. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/grey.css +64 -0
  636. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/minimal.css +64 -0
  637. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/orange.css +64 -0
  638. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/pink.css +64 -0
  639. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/purple.css +64 -0
  640. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/red.css +64 -0
  641. data/app/assets/stylesheets/my_admin/plugins/icheck/minimal/yellow.css +64 -0
  642. data/app/assets/stylesheets/my_admin/plugins/icheck/polaris/polaris.css +64 -0
  643. data/app/assets/stylesheets/my_admin/plugins/icheck/square/_all.css +640 -0
  644. data/app/assets/stylesheets/my_admin/plugins/icheck/square/aero.css +64 -0
  645. data/app/assets/stylesheets/my_admin/plugins/icheck/square/blue.css +64 -0
  646. data/app/assets/stylesheets/my_admin/plugins/icheck/square/green.css +64 -0
  647. data/app/assets/stylesheets/my_admin/plugins/icheck/square/grey.css +64 -0
  648. data/app/assets/stylesheets/my_admin/plugins/icheck/square/orange.css +64 -0
  649. data/app/assets/stylesheets/my_admin/plugins/icheck/square/pink.css +64 -0
  650. data/app/assets/stylesheets/my_admin/plugins/icheck/square/purple.css +64 -0
  651. data/app/assets/stylesheets/my_admin/plugins/icheck/square/red.css +64 -0
  652. data/app/assets/stylesheets/my_admin/plugins/icheck/square/square.css +64 -0
  653. data/app/assets/stylesheets/my_admin/plugins/icheck/square/yellow.css +64 -0
  654. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/animated-overlay.gif +0 -0
  655. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  656. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  657. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  658. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  659. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  660. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  661. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  662. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  663. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-icons_222222_256x240.png +0 -0
  664. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  665. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-icons_454545_256x240.png +0 -0
  666. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-icons_888888_256x240.png +0 -0
  667. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  668. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/jquery-ui.css +1087 -0
  669. data/app/assets/stylesheets/my_admin/plugins/jquery-ui/smoothness/jquery.ui.theme.css +406 -0
  670. data/app/assets/stylesheets/my_admin/plugins/multiselect/multi-select.css.erb +93 -0
  671. data/app/assets/stylesheets/my_admin/plugins/pageguide/pageguide.css +647 -0
  672. data/app/assets/stylesheets/my_admin/plugins/plupload/jquery.plupload.queue.css.erb +176 -0
  673. data/app/assets/stylesheets/my_admin/plugins/select2/select2.css.erb +615 -0
  674. data/app/assets/stylesheets/my_admin/plugins/tagsinput/jquery.tagsinput.css +7 -0
  675. data/app/assets/stylesheets/my_admin/plugins/timepicker/bootstrap-timepicker.min.css +10 -0
  676. data/app/assets/stylesheets/my_admin/plugins/xeditable/bootstrap-editable.css +480 -0
  677. data/app/assets/stylesheets/my_admin/style.css.erb +7827 -0
  678. data/app/assets/stylesheets/my_admin/themes.css +3821 -0
  679. data/app/assets/stylesheets/my_admin.css +0 -0
  680. data/app/controllers/my_admin/configurations_controller.rb +22 -0
  681. data/app/controllers/my_admin/dashboards_controller.rb +15 -0
  682. data/app/controllers/my_admin/first_users_controller.rb +42 -0
  683. data/app/controllers/my_admin/models_controller.rb +205 -0
  684. data/app/controllers/my_admin/my_admin_controller.rb +53 -0
  685. data/app/controllers/my_admin/my_admin_groups_controller.rb +5 -0
  686. data/app/controllers/my_admin/my_admin_logs_controller.rb +3 -0
  687. data/app/controllers/my_admin/my_admin_users_controller.rb +3 -0
  688. data/app/controllers/my_admin/password_controller.rb +29 -0
  689. data/app/controllers/my_admin/recovers_controller.rb +61 -0
  690. data/app/controllers/my_admin/sessions_controller.rb +62 -0
  691. data/app/helpers/asset_package_helper.rb +37 -0
  692. data/app/helpers/my_admin_application_helper.rb +7 -0
  693. data/app/helpers/my_admin_field_helper.rb +179 -0
  694. data/app/helpers/my_admin_helper.rb +35 -0
  695. data/app/helpers/my_admin_log_helper.rb +7 -0
  696. data/app/helpers/my_admin_model_helper.rb +34 -0
  697. data/app/helpers/my_admin_session_helper.rb +50 -0
  698. data/app/mailers/my_admin/recover_mailer.rb +13 -0
  699. data/app/model/ckeditor/asset.rb +4 -0
  700. data/app/model/ckeditor/attachment_file.rb +13 -0
  701. data/app/model/ckeditor/picture.rb +14 -0
  702. data/app/model/my_admin/configuration.rb +10 -0
  703. data/app/model/my_admin/group.rb +26 -0
  704. data/app/model/my_admin/group_permission.rb +7 -0
  705. data/app/model/my_admin/locale.rb +8 -0
  706. data/app/model/my_admin/log.rb +33 -0
  707. data/app/model/my_admin/permission.rb +19 -0
  708. data/app/model/my_admin/user.rb +153 -0
  709. data/app/model/my_admin/user_group.rb +7 -0
  710. data/app/views/layouts/my_admin.html.erb +81 -0
  711. data/app/views/layouts/my_admin_locked.html.erb +44 -0
  712. data/app/views/layouts/my_admin_off.html.erb +72 -0
  713. data/app/views/my_admin/_dashboard.html.erb +0 -0
  714. data/app/views/my_admin/_header.html.erb +101 -0
  715. data/app/views/my_admin/_header.html.erb.old +42 -0
  716. data/app/views/my_admin/_left.html.erb +23 -0
  717. data/app/views/my_admin/configurations/_form.html.erb +31 -0
  718. data/app/views/my_admin/configurations/show.html.erb +17 -0
  719. data/app/views/my_admin/dashboards/index.html.erb +1 -0
  720. data/app/views/my_admin/fields/config/type/default.html.erb +18 -0
  721. data/app/views/my_admin/fields/config/type/text.html.erb +18 -0
  722. data/app/views/my_admin/fields/edit/type/belongs_to.html.erb +28 -0
  723. data/app/views/my_admin/fields/edit/type/boolean.html.erb +5 -0
  724. data/app/views/my_admin/fields/edit/type/clear_text.html.erb +8 -0
  725. data/app/views/my_admin/fields/edit/type/color.html.erb +1 -0
  726. data/app/views/my_admin/fields/edit/type/date.html.erb +3 -0
  727. data/app/views/my_admin/fields/edit/type/datetime.html.erb +11 -0
  728. data/app/views/my_admin/fields/edit/type/decimal.html.erb +3 -0
  729. data/app/views/my_admin/fields/edit/type/default.html.erb +4 -0
  730. data/app/views/my_admin/fields/edit/type/default_struct.html.erb +9 -0
  731. data/app/views/my_admin/fields/edit/type/email.html.erb +4 -0
  732. data/app/views/my_admin/fields/edit/type/file.html.erb +9 -0
  733. data/app/views/my_admin/fields/edit/type/float.html.erb +1 -0
  734. data/app/views/my_admin/fields/edit/type/has_and_belongs_to_many.html.erb +34 -0
  735. data/app/views/my_admin/fields/edit/type/has_many.html.erb +12 -0
  736. data/app/views/my_admin/fields/edit/type/has_many_edit.html.erb +79 -0
  737. data/app/views/my_admin/fields/edit/type/has_many_locale.html.erb +40 -0
  738. data/app/views/my_admin/fields/edit/type/has_many_locale_struct.html.erb +1 -0
  739. data/app/views/my_admin/fields/edit/type/integer.html.erb +3 -0
  740. data/app/views/my_admin/fields/edit/type/list.html.erb +23 -0
  741. data/app/views/my_admin/fields/edit/type/list_string.html.erb +19 -0
  742. data/app/views/my_admin/fields/edit/type/money.html.erb +7 -0
  743. data/app/views/my_admin/fields/edit/type/paperclip/attachment.html.erb +28 -0
  744. data/app/views/my_admin/fields/edit/type/password.html.erb +4 -0
  745. data/app/views/my_admin/fields/edit/type/read_only.html.erb +10 -0
  746. data/app/views/my_admin/fields/edit/type/text.html.erb +3 -0
  747. data/app/views/my_admin/fields/edit/type/time.html.erb +6 -0
  748. data/app/views/my_admin/fields/filter/type/belongs_to.html.erb +11 -0
  749. data/app/views/my_admin/fields/filter/type/boolean.html.erb +5 -0
  750. data/app/views/my_admin/fields/filter/type/date.html.erb +3 -0
  751. data/app/views/my_admin/fields/filter/type/datetime.html.erb +13 -0
  752. data/app/views/my_admin/fields/filter/type/default.html.erb +2 -0
  753. data/app/views/my_admin/fields/filter/type/default_struct.html.erb +7 -0
  754. data/app/views/my_admin/fields/filter/type/email.html.erb +5 -0
  755. data/app/views/my_admin/fields/filter/type/list.html.erb +11 -0
  756. data/app/views/my_admin/fields/filter/type/list_string.html.erb +11 -0
  757. data/app/views/my_admin/fields/type/big_decimal.html.erb +1 -0
  758. data/app/views/my_admin/fields/type/boolean.html.erb +5 -0
  759. data/app/views/my_admin/fields/type/color.html.erb +2 -0
  760. data/app/views/my_admin/fields/type/datetime.html.erb +1 -0
  761. data/app/views/my_admin/fields/type/decimal.html.erb +1 -0
  762. data/app/views/my_admin/fields/type/default.html.erb +1 -0
  763. data/app/views/my_admin/fields/type/file.html.erb +1 -0
  764. data/app/views/my_admin/fields/type/float.html.erb +1 -0
  765. data/app/views/my_admin/fields/type/has_many.html.erb +1 -0
  766. data/app/views/my_admin/fields/type/has_many_edit.html.erb +1 -0
  767. data/app/views/my_admin/fields/type/paperclip/attachment.html.erb +5 -0
  768. data/app/views/my_admin/first_users/new.html.erb +51 -0
  769. data/app/views/my_admin/models/_field.html.erb +9 -0
  770. data/app/views/my_admin/models/_filters.html.erb +43 -0
  771. data/app/views/my_admin/models/_form.html.erb +43 -0
  772. data/app/views/my_admin/models/_paginate.html.erb +9 -0
  773. data/app/views/my_admin/models/_popup_hint.html.erb +8 -0
  774. data/app/views/my_admin/models/edit.html.erb +9 -0
  775. data/app/views/my_admin/models/index.html.erb +116 -0
  776. data/app/views/my_admin/models/new.html.erb +9 -0
  777. data/app/views/my_admin/models/remote.js.erb +13 -0
  778. data/app/views/my_admin/password/edit.html.erb +58 -0
  779. data/app/views/my_admin/recover_mailer/send_recover_mail.html.erb +25 -0
  780. data/app/views/my_admin/recovers/new.html.erb +20 -0
  781. data/app/views/my_admin/recovers/show.html.erb +27 -0
  782. data/app/views/my_admin/sessions/new.html.erb +30 -0
  783. data/app/views/my_admin/sessions/unlock.html.erb +34 -0
  784. data/config/locales/en.yml +35 -0
  785. data/config/locales/es.yml +22 -0
  786. data/config/locales/pt.yml +210 -0
  787. data/config/routes.rb +52 -0
  788. data/lib/generators/my_admin/install/USAGE +8 -0
  789. data/lib/generators/my_admin/install/install_generator.rb +68 -0
  790. data/lib/generators/my_admin/install/templates/config/initializers/my_admin.rb +8 -0
  791. data/lib/generators/my_admin/install/templates/migrations/ckeditor_assets.rb +26 -0
  792. data/lib/generators/my_admin/install/templates/migrations/configurations.rb +22 -0
  793. data/lib/generators/my_admin/install/templates/migrations/group_permissions.rb +16 -0
  794. data/lib/generators/my_admin/install/templates/migrations/groups.rb +16 -0
  795. data/lib/generators/my_admin/install/templates/migrations/locales.rb +15 -0
  796. data/lib/generators/my_admin/install/templates/migrations/logs.rb +19 -0
  797. data/lib/generators/my_admin/install/templates/migrations/permissions.rb +15 -0
  798. data/lib/generators/my_admin/install/templates/migrations/user_groups.rb +16 -0
  799. data/lib/generators/my_admin/install/templates/migrations/users.rb +28 -0
  800. data/lib/generators/my_admin/install/templates/public/plugins/ckeditor/ckupload.php +35 -0
  801. data/lib/generators/my_admin/model/model_generator.rb +26 -0
  802. data/lib/generators/my_admin/model/templates/controllers/controller.rb +3 -0
  803. data/lib/generators/my_admin/permissions/permissions_generator.rb +26 -0
  804. data/lib/my_admin/active_record.rb +118 -0
  805. data/lib/my_admin/application.rb +62 -0
  806. data/lib/my_admin/breadcrumbs/my_admin.rb +44 -0
  807. data/lib/my_admin/ckeditor.rb +39 -0
  808. data/lib/my_admin/engine.rb +23 -0
  809. data/lib/my_admin/jsmin.rb +205 -0
  810. data/lib/my_admin/locales.rb +29 -0
  811. data/lib/my_admin/model_configuration.rb +53 -0
  812. data/lib/my_admin/paperclip.rb +4 -0
  813. data/lib/my_admin/paperclip_processors/cropper.rb +20 -0
  814. data/lib/my_admin/paperclip_processors/rotator.rb +25 -0
  815. data/lib/my_admin/string.rb +5 -0
  816. data/lib/my_admin/to_xls.rb +53 -0
  817. data/lib/my_admin/version.rb +3 -0
  818. data/lib/my_admin/will_paginate/bootstrap_link_renderer.rb +20 -0
  819. data/lib/my_admin/yml_manage.rb +41 -0
  820. data/lib/my_admin.rb +31 -0
  821. data/my_admin.gemspec +30 -0
  822. metadata +975 -0
@@ -0,0 +1,3520 @@
1
+ <?php
2
+ /**
3
+ * Base class for elFinder volume.
4
+ * Provide 2 layers:
5
+ * 1. Public API (commands)
6
+ * 2. abstract fs API
7
+ *
8
+ * All abstract methods begin with "_"
9
+ *
10
+ * @author Dmitry (dio) Levashov
11
+ * @author Troex Nevelin
12
+ * @author Alexey Sukhotin
13
+ **/
14
+ abstract class elFinderVolumeDriver {
15
+
16
+ /**
17
+ * Driver id
18
+ * Must be started from letter and contains [a-z0-9]
19
+ * Used as part of volume id
20
+ *
21
+ * @var string
22
+ **/
23
+ protected $driverId = 'a';
24
+
25
+ /**
26
+ * Volume id - used as prefix for files hashes
27
+ *
28
+ * @var string
29
+ **/
30
+ protected $id = '';
31
+
32
+ /**
33
+ * Flag - volume "mounted" and available
34
+ *
35
+ * @var bool
36
+ **/
37
+ protected $mounted = false;
38
+
39
+ /**
40
+ * Root directory path
41
+ *
42
+ * @var string
43
+ **/
44
+ protected $root = '';
45
+
46
+ /**
47
+ * Root basename | alias
48
+ *
49
+ * @var string
50
+ **/
51
+ protected $rootName = '';
52
+
53
+ /**
54
+ * Default directory to open
55
+ *
56
+ * @var string
57
+ **/
58
+ protected $startPath = '';
59
+
60
+ /**
61
+ * Base URL
62
+ *
63
+ * @var string
64
+ **/
65
+ protected $URL = '';
66
+
67
+ /**
68
+ * Thumbnails dir path
69
+ *
70
+ * @var string
71
+ **/
72
+ protected $tmbPath = '';
73
+
74
+ /**
75
+ * Is thumbnails dir writable
76
+ *
77
+ * @var bool
78
+ **/
79
+ protected $tmbPathWritable = false;
80
+
81
+ /**
82
+ * Thumbnails base URL
83
+ *
84
+ * @var string
85
+ **/
86
+ protected $tmbURL = '';
87
+
88
+ /**
89
+ * Thumbnails size in px
90
+ *
91
+ * @var int
92
+ **/
93
+ protected $tmbSize = 48;
94
+
95
+ /**
96
+ * Image manipulation lib name
97
+ * auto|imagick|mogtify|gd
98
+ *
99
+ * @var string
100
+ **/
101
+ protected $imgLib = 'auto';
102
+
103
+ /**
104
+ * Library to crypt files name
105
+ *
106
+ * @var string
107
+ **/
108
+ protected $cryptLib = '';
109
+
110
+ /**
111
+ * Archivers config
112
+ *
113
+ * @var array
114
+ **/
115
+ protected $archivers = array(
116
+ 'create' => array(),
117
+ 'extract' => array()
118
+ );
119
+
120
+ /**
121
+ * How many subdirs levels return for tree
122
+ *
123
+ * @var int
124
+ **/
125
+ protected $treeDeep = 1;
126
+
127
+ /**
128
+ * Errors from last failed action
129
+ *
130
+ * @var array
131
+ **/
132
+ protected $error = array();
133
+
134
+ /**
135
+ * Today 24:00 timestamp
136
+ *
137
+ * @var int
138
+ **/
139
+ protected $today = 0;
140
+
141
+ /**
142
+ * Yesterday 24:00 timestamp
143
+ *
144
+ * @var int
145
+ **/
146
+ protected $yesterday = 0;
147
+
148
+ /**
149
+ * Object configuration
150
+ *
151
+ * @var array
152
+ **/
153
+ protected $options = array(
154
+ 'id' => '',
155
+ // root directory path
156
+ 'path' => '',
157
+ // open this path on initial request instead of root path
158
+ 'startPath' => '',
159
+ // how many subdirs levels return per request
160
+ 'treeDeep' => 1,
161
+ // root url, not set to disable sending URL to client (replacement for old "fileURL" option)
162
+ 'URL' => '',
163
+ // directory separator. required by client to show paths correctly
164
+ 'separator' => DIRECTORY_SEPARATOR,
165
+ // library to crypt/uncrypt files names (not implemented)
166
+ 'cryptLib' => '',
167
+ // how to detect files mimetypes. (auto/internal/finfo/mime_content_type)
168
+ 'mimeDetect' => 'auto',
169
+ // mime.types file path (for mimeDetect==internal)
170
+ 'mimefile' => '',
171
+ // directory for thumbnails
172
+ 'tmbPath' => '.tmb',
173
+ // mode to create thumbnails dir
174
+ 'tmbPathMode' => 0777,
175
+ // thumbnails dir URL. Set it if store thumbnails outside root directory
176
+ 'tmbURL' => '',
177
+ // thumbnails size (px)
178
+ 'tmbSize' => 48,
179
+ // thumbnails crop (true - crop, false - scale image to fit thumbnail size)
180
+ 'tmbCrop' => true,
181
+ // thumbnails background color (hex #rrggbb or 'transparent')
182
+ 'tmbBgColor' => '#ffffff',
183
+ // image manipulations library
184
+ 'imgLib' => 'auto',
185
+ // on paste file - if true - old file will be replaced with new one, if false new file get name - original_name-number.ext
186
+ 'copyOverwrite' => true,
187
+ // if true - join new and old directories content on paste
188
+ 'copyJoin' => true,
189
+ // on upload - if true - old file will be replaced with new one, if false new file get name - original_name-number.ext
190
+ 'uploadOverwrite' => true,
191
+ // mimetypes allowed to upload
192
+ 'uploadAllow' => array(),
193
+ // mimetypes not allowed to upload
194
+ 'uploadDeny' => array(),
195
+ // order to proccess uploadAllow and uploadDeny options
196
+ 'uploadOrder' => array('deny', 'allow'),
197
+ // maximum upload file size. NOTE - this is size for every uploaded files
198
+ 'uploadMaxSize' => 0,
199
+ // files dates format
200
+ 'dateFormat' => 'j M Y H:i',
201
+ // files time format
202
+ 'timeFormat' => 'H:i',
203
+ // if true - every folder will be check for children folders, otherwise all folders will be marked as having subfolders
204
+ 'checkSubfolders' => true,
205
+ // allow to copy from this volume to other ones?
206
+ 'copyFrom' => true,
207
+ // allow to copy from other volumes to this one?
208
+ 'copyTo' => true,
209
+ // list of commands disabled on this root
210
+ 'disabled' => array(),
211
+ // regexp or function name to validate new file name
212
+ 'acceptedName' => '/^[^\.].*/', //<-- DONT touch this! Use constructor options to overwrite it!
213
+ // function/class method to control files permissions
214
+ 'accessControl' => null,
215
+ // some data required by access control
216
+ 'accessControlData' => null,
217
+ // default permissions. not set hidden/locked here - take no effect
218
+ 'defaults' => array(
219
+ 'read' => true,
220
+ 'write' => true
221
+ ),
222
+ // files attributes
223
+ 'attributes' => array(),
224
+ // Allowed archive's mimetypes to create. Leave empty for all available types.
225
+ 'archiveMimes' => array(),
226
+ // Manual config for archivers. See example below. Leave empty for auto detect
227
+ 'archivers' => array(),
228
+ // required to fix bug on macos
229
+ 'utf8fix' => false,
230
+ // й ё Й Ё Ø Å
231
+ 'utf8patterns' => array("\u0438\u0306", "\u0435\u0308", "\u0418\u0306", "\u0415\u0308", "\u00d8A", "\u030a"),
232
+ 'utf8replace' => array("\u0439", "\u0451", "\u0419", "\u0401", "\u00d8", "\u00c5")
233
+ );
234
+
235
+ /**
236
+ * Defaults permissions
237
+ *
238
+ * @var array
239
+ **/
240
+ protected $defaults = array(
241
+ 'read' => true,
242
+ 'write' => true,
243
+ 'locked' => false,
244
+ 'hidden' => false
245
+ );
246
+
247
+ /**
248
+ * Access control function/class
249
+ *
250
+ * @var mixed
251
+ **/
252
+ protected $attributes = array();
253
+
254
+ /**
255
+ * Access control function/class
256
+ *
257
+ * @var mixed
258
+ **/
259
+ protected $access = null;
260
+
261
+ /**
262
+ * Mime types allowed to upload
263
+ *
264
+ * @var array
265
+ **/
266
+ protected $uploadAllow = array();
267
+
268
+ /**
269
+ * Mime types denied to upload
270
+ *
271
+ * @var array
272
+ **/
273
+ protected $uploadDeny = array();
274
+
275
+ /**
276
+ * Order to validate uploadAllow and uploadDeny
277
+ *
278
+ * @var array
279
+ **/
280
+ protected $uploadOrder = array();
281
+
282
+ /**
283
+ * Maximum allowed upload file size.
284
+ * Set as number or string with unit - "10M", "500K", "1G"
285
+ *
286
+ * @var int|string
287
+ **/
288
+ protected $uploadMaxSize = 0;
289
+
290
+ /**
291
+ * Mimetype detect method
292
+ *
293
+ * @var string
294
+ **/
295
+ protected $mimeDetect = 'auto';
296
+
297
+ /**
298
+ * Flag - mimetypes from externail file was loaded
299
+ *
300
+ * @var bool
301
+ **/
302
+ private static $mimetypesLoaded = false;
303
+
304
+ /**
305
+ * Finfo object for mimeDetect == 'finfo'
306
+ *
307
+ * @var object
308
+ **/
309
+ protected $finfo = null;
310
+
311
+ /**
312
+ * List of disabled client's commands
313
+ *
314
+ * @var array
315
+ **/
316
+ protected $diabled = array();
317
+
318
+ /**
319
+ * default extensions/mimetypes for mimeDetect == 'internal'
320
+ *
321
+ * @var array
322
+ **/
323
+ protected static $mimetypes = array(
324
+ // applications
325
+ 'ai' => 'application/postscript',
326
+ 'eps' => 'application/postscript',
327
+ 'exe' => 'application/x-executable',
328
+ 'doc' => 'application/vnd.ms-word',
329
+ 'xls' => 'application/vnd.ms-excel',
330
+ 'ppt' => 'application/vnd.ms-powerpoint',
331
+ 'pps' => 'application/vnd.ms-powerpoint',
332
+ 'pdf' => 'application/pdf',
333
+ 'xml' => 'application/xml',
334
+ 'swf' => 'application/x-shockwave-flash',
335
+ 'torrent' => 'application/x-bittorrent',
336
+ 'jar' => 'application/x-jar',
337
+ // open office (finfo detect as application/zip)
338
+ 'odt' => 'application/vnd.oasis.opendocument.text',
339
+ 'ott' => 'application/vnd.oasis.opendocument.text-template',
340
+ 'oth' => 'application/vnd.oasis.opendocument.text-web',
341
+ 'odm' => 'application/vnd.oasis.opendocument.text-master',
342
+ 'odg' => 'application/vnd.oasis.opendocument.graphics',
343
+ 'otg' => 'application/vnd.oasis.opendocument.graphics-template',
344
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
345
+ 'otp' => 'application/vnd.oasis.opendocument.presentation-template',
346
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
347
+ 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
348
+ 'odc' => 'application/vnd.oasis.opendocument.chart',
349
+ 'odf' => 'application/vnd.oasis.opendocument.formula',
350
+ 'odb' => 'application/vnd.oasis.opendocument.database',
351
+ 'odi' => 'application/vnd.oasis.opendocument.image',
352
+ 'oxt' => 'application/vnd.openofficeorg.extension',
353
+ // MS office 2007 (finfo detect as application/zip)
354
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
355
+ 'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
356
+ 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
357
+ 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
358
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
359
+ 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
360
+ 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
361
+ 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
362
+ 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
363
+ 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
364
+ 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
365
+ 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
366
+ 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
367
+ 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
368
+ 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
369
+ 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
370
+ 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
371
+ 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
372
+ 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
373
+ // archives
374
+ 'gz' => 'application/x-gzip',
375
+ 'tgz' => 'application/x-gzip',
376
+ 'bz' => 'application/x-bzip2',
377
+ 'bz2' => 'application/x-bzip2',
378
+ 'tbz' => 'application/x-bzip2',
379
+ 'zip' => 'application/zip',
380
+ 'rar' => 'application/x-rar',
381
+ 'tar' => 'application/x-tar',
382
+ '7z' => 'application/x-7z-compressed',
383
+ // texts
384
+ 'txt' => 'text/plain',
385
+ 'php' => 'text/x-php',
386
+ 'html' => 'text/html',
387
+ 'htm' => 'text/html',
388
+ 'js' => 'text/javascript',
389
+ 'css' => 'text/css',
390
+ 'rtf' => 'text/rtf',
391
+ 'rtfd' => 'text/rtfd',
392
+ 'py' => 'text/x-python',
393
+ 'java' => 'text/x-java-source',
394
+ 'rb' => 'text/x-ruby',
395
+ 'sh' => 'text/x-shellscript',
396
+ 'pl' => 'text/x-perl',
397
+ 'xml' => 'text/xml',
398
+ 'sql' => 'text/x-sql',
399
+ 'c' => 'text/x-csrc',
400
+ 'h' => 'text/x-chdr',
401
+ 'cpp' => 'text/x-c++src',
402
+ 'hh' => 'text/x-c++hdr',
403
+ 'log' => 'text/plain',
404
+ 'csv' => 'text/x-comma-separated-values',
405
+ // images
406
+ 'bmp' => 'image/x-ms-bmp',
407
+ 'jpg' => 'image/jpeg',
408
+ 'jpeg' => 'image/jpeg',
409
+ 'gif' => 'image/gif',
410
+ 'png' => 'image/png',
411
+ 'tif' => 'image/tiff',
412
+ 'tiff' => 'image/tiff',
413
+ 'tga' => 'image/x-targa',
414
+ 'psd' => 'image/vnd.adobe.photoshop',
415
+ 'ai' => 'image/vnd.adobe.photoshop',
416
+ 'xbm' => 'image/xbm',
417
+ 'pxm' => 'image/pxm',
418
+ //audio
419
+ 'mp3' => 'audio/mpeg',
420
+ 'mid' => 'audio/midi',
421
+ 'ogg' => 'audio/ogg',
422
+ 'oga' => 'audio/ogg',
423
+ 'm4a' => 'audio/x-m4a',
424
+ 'wav' => 'audio/wav',
425
+ 'wma' => 'audio/x-ms-wma',
426
+ // video
427
+ 'avi' => 'video/x-msvideo',
428
+ 'dv' => 'video/x-dv',
429
+ 'mp4' => 'video/mp4',
430
+ 'mpeg' => 'video/mpeg',
431
+ 'mpg' => 'video/mpeg',
432
+ 'mov' => 'video/quicktime',
433
+ 'wm' => 'video/x-ms-wmv',
434
+ 'flv' => 'video/x-flv',
435
+ 'mkv' => 'video/x-matroska',
436
+ 'webm' => 'video/webm',
437
+ 'ogv' => 'video/ogg',
438
+ 'ogm' => 'video/ogg'
439
+ );
440
+
441
+ /**
442
+ * Directory separator - required by client
443
+ *
444
+ * @var string
445
+ **/
446
+ protected $separator = DIRECTORY_SEPARATOR;
447
+
448
+ /**
449
+ * Mimetypes allowed to display
450
+ *
451
+ * @var array
452
+ **/
453
+ protected $onlyMimes = array();
454
+
455
+ /**
456
+ * Store files moved or overwrited files info
457
+ *
458
+ * @var array
459
+ **/
460
+ protected $removed = array();
461
+
462
+ /**
463
+ * Cache storage
464
+ *
465
+ * @var array
466
+ **/
467
+ protected $cache = array();
468
+
469
+ /**
470
+ * Cache by folders
471
+ *
472
+ * @var array
473
+ **/
474
+ protected $dirsCache = array();
475
+
476
+ /*********************************************************************/
477
+ /* INITIALIZATION */
478
+ /*********************************************************************/
479
+
480
+ /**
481
+ * Prepare driver before mount volume.
482
+ * Return true if volume is ready.
483
+ *
484
+ * @return bool
485
+ * @author Dmitry (dio) Levashov
486
+ **/
487
+ protected function init() {
488
+ return true;
489
+ }
490
+
491
+ /**
492
+ * Configure after successfull mount.
493
+ * By default set thumbnails path and image manipulation library.
494
+ *
495
+ * @return void
496
+ * @author Dmitry (dio) Levashov
497
+ **/
498
+ protected function configure() {
499
+ // set thumbnails path
500
+ $path = $this->options['tmbPath'];
501
+ if ($path) {
502
+ if (!file_exists($path)) {
503
+ if (@mkdir($path)) {
504
+ chmod($path, $this->options['tmbPathMode']);
505
+ } else {
506
+ $path = '';
507
+ }
508
+ }
509
+
510
+ if (is_dir($path) && is_readable($path)) {
511
+ $this->tmbPath = $path;
512
+ $this->tmbPathWritable = is_writable($path);
513
+ }
514
+ }
515
+
516
+ // set image manipulation library
517
+ $type = preg_match('/^(imagick|gd|auto)$/i', $this->options['imgLib'])
518
+ ? strtolower($this->options['imgLib'])
519
+ : 'auto';
520
+
521
+ if (($type == 'imagick' || $type == 'auto') && extension_loaded('imagick')) {
522
+ $this->imgLib = 'imagick';
523
+ } else {
524
+ $this->imgLib = function_exists('gd_info') ? 'gd' : '';
525
+ }
526
+
527
+ }
528
+
529
+
530
+ /*********************************************************************/
531
+ /* PUBLIC API */
532
+ /*********************************************************************/
533
+
534
+ /**
535
+ * Return driver id. Used as a part of volume id.
536
+ *
537
+ * @return string
538
+ * @author Dmitry (dio) Levashov
539
+ **/
540
+ public function driverId() {
541
+ return $this->driverId;
542
+ }
543
+
544
+ /**
545
+ * Return volume id
546
+ *
547
+ * @return string
548
+ * @author Dmitry (dio) Levashov
549
+ **/
550
+ public function id() {
551
+ return $this->id;
552
+ }
553
+
554
+ /**
555
+ * Return debug info for client
556
+ *
557
+ * @return array
558
+ * @author Dmitry (dio) Levashov
559
+ **/
560
+ public function debug() {
561
+ return array(
562
+ 'id' => $this->id(),
563
+ 'name' => strtolower(substr(get_class($this), strlen('elfinderdriver'))),
564
+ 'mimeDetect' => $this->mimeDetect,
565
+ 'imgLib' => $this->imgLib
566
+ );
567
+ }
568
+
569
+ /**
570
+ * "Mount" volume.
571
+ * Return true if volume available for read or write,
572
+ * false - otherwise
573
+ *
574
+ * @return bool
575
+ * @author Dmitry (dio) Levashov
576
+ * @author Alexey Sukhotin
577
+ **/
578
+ public function mount(array $opts) {
579
+ if (!isset($opts['path']) || $opts['path'] === '') {
580
+ return $this->setError('Path undefined.');;
581
+ }
582
+
583
+ $this->options = array_merge($this->options, $opts);
584
+ $this->id = $this->driverId.(!empty($this->options['id']) ? $this->options['id'] : elFinder::$volumesCnt++).'_';
585
+ $this->root = $this->_normpath($this->options['path']);
586
+ $this->separator = isset($this->options['separator']) ? $this->options['separator'] : DIRECTORY_SEPARATOR;
587
+
588
+ // default file attribute
589
+ $this->defaults = array(
590
+ 'read' => isset($this->options['defaults']['read']) ? !!$this->options['defaults']['read'] : true,
591
+ 'write' => isset($this->options['defaults']['write']) ? !!$this->options['defaults']['write'] : true,
592
+ 'locked' => false,
593
+ 'hidden' => false
594
+ );
595
+
596
+ // root attributes
597
+ $this->attributes[] = array(
598
+ 'pattern' => '~^'.preg_quote(DIRECTORY_SEPARATOR).'$~',
599
+ 'locked' => true,
600
+ 'hidden' => false
601
+ );
602
+ // set files attributes
603
+ if (!empty($this->options['attributes']) && is_array($this->options['attributes'])) {
604
+
605
+ foreach ($this->options['attributes'] as $a) {
606
+ // attributes must contain pattern and at least one rule
607
+ if (!empty($a['pattern']) || count($a) > 1) {
608
+ $this->attributes[] = $a;
609
+ }
610
+ }
611
+ }
612
+
613
+ if (!empty($this->options['accessControl']) && is_callable($this->options['accessControl'])) {
614
+ $this->access = $this->options['accessControl'];
615
+ }
616
+
617
+ $this->today = mktime(0,0,0, date('m'), date('d'), date('Y'));
618
+ $this->yesterday = $this->today-86400;
619
+
620
+ // debug($this->attributes);
621
+ if (!$this->init()) {
622
+ return false;
623
+ }
624
+
625
+ // check some options is arrays
626
+ $this->uploadAllow = isset($this->options['uploadAllow']) && is_array($this->options['uploadAllow'])
627
+ ? $this->options['uploadAllow']
628
+ : array();
629
+
630
+ $this->uploadDeny = isset($this->options['uploadDeny']) && is_array($this->options['uploadDeny'])
631
+ ? $this->options['uploadDeny']
632
+ : array();
633
+
634
+ if (is_string($this->options['uploadOrder'])) { // telephat_mode on, compatibility with 1.x
635
+ $parts = explode(',', isset($this->options['uploadOrder']) ? $this->options['uploadOrder'] : 'deny,allow');
636
+ $this->uploadOrder = array(trim($parts[0]), trim($parts[1]));
637
+ } else { // telephat_mode off
638
+ $this->uploadOrder = $this->options['uploadOrder'];
639
+ }
640
+
641
+ if (!empty($this->options['uploadMaxSize'])) {
642
+ $size = ''.$this->options['uploadMaxSize'];
643
+ $unit = strtolower(substr($size, strlen($size) - 1));
644
+ $n = 1;
645
+ switch ($unit) {
646
+ case 'k':
647
+ $n = 1024;
648
+ break;
649
+ case 'm':
650
+ $n = 1048576;
651
+ break;
652
+ case 'g':
653
+ $n = 1073741824;
654
+ }
655
+ $this->uploadMaxSize = intval($size)*$n;
656
+ }
657
+
658
+ $this->disabled = isset($this->options['disabled']) && is_array($this->options['disabled'])
659
+ ? $this->options['disabled']
660
+ : array();
661
+
662
+ $this->cryptLib = $this->options['cryptLib'];
663
+ $this->mimeDetect = $this->options['mimeDetect'];
664
+
665
+ // find available mimetype detect method
666
+ $type = strtolower($this->options['mimeDetect']);
667
+ $type = preg_match('/^(finfo|mime_content_type|internal|auto)$/i', $type) ? $type : 'auto';
668
+ $regexp = '/text\/x\-(php|c\+\+)/';
669
+
670
+ if (($type == 'finfo' || $type == 'auto')
671
+ && class_exists('finfo')) {
672
+ $tmpFileInfo = @explode(';', @finfo_file(finfo_open(FILEINFO_MIME), __FILE__));
673
+ } else {
674
+ $tmpFileInfo = false;
675
+ }
676
+
677
+ if ($tmpFileInfo && preg_match($regexp, array_shift($tmpFileInfo))) {
678
+ $type = 'finfo';
679
+ $this->finfo = finfo_open(FILEINFO_MIME);
680
+ } elseif (($type == 'mime_content_type' || $type == 'auto')
681
+ && function_exists('mime_content_type')
682
+ && preg_match($regexp, array_shift(explode(';', mime_content_type(__FILE__))))) {
683
+ $type = 'mime_content_type';
684
+ } else {
685
+ $type = 'internal';
686
+ }
687
+ $this->mimeDetect = $type;
688
+
689
+ // load mimes from external file for mimeDetect == 'internal'
690
+ // based on Alexey Sukhotin idea and patch: http://elrte.org/redmine/issues/163
691
+ // file must be in file directory or in parent one
692
+ if ($this->mimeDetect == 'internal' && !self::$mimetypesLoaded) {
693
+ self::$mimetypesLoaded = true;
694
+ $this->mimeDetect = 'internal';
695
+ $file = false;
696
+ if (!empty($this->options['mimefile']) && file_exists($this->options['mimefile'])) {
697
+ $file = $this->options['mimefile'];
698
+ } elseif (file_exists(dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types')) {
699
+ $file = dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types';
700
+ } elseif (file_exists(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'mime.types')) {
701
+ $file = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'mime.types';
702
+ }
703
+
704
+ if ($file && file_exists($file)) {
705
+ $mimecf = file($file);
706
+
707
+ foreach ($mimecf as $line_num => $line) {
708
+ if (!preg_match('/^\s*#/', $line)) {
709
+ $mime = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY);
710
+ for ($i = 1, $size = count($mime); $i < $size ; $i++) {
711
+ if (!isset(self::$mimetypes[$mime[$i]])) {
712
+ self::$mimetypes[$mime[$i]] = $mime[0];
713
+ }
714
+ }
715
+ }
716
+ }
717
+ }
718
+ }
719
+
720
+ $this->rootName = empty($this->options['alias']) ? $this->_basename($this->root) : $this->options['alias'];
721
+ $root = $this->stat($this->root);
722
+
723
+ if (!$root) {
724
+ return $this->setError('Root folder does not exists.');
725
+ }
726
+ if (!$root['read'] && !$root['write']) {
727
+ return $this->setError('Root folder has not read and write permissions.');
728
+ }
729
+
730
+ // debug($root);
731
+
732
+ if ($root['read']) {
733
+ // check startPath - path to open by default instead of root
734
+ if ($this->options['startPath']) {
735
+ $start = $this->stat($this->options['startPath']);
736
+ if (!empty($start)
737
+ && $start['mime'] == 'directory'
738
+ && $start['read']
739
+ && empty($start['hidden'])
740
+ && $this->_inpath($this->options['startPath'], $this->root)) {
741
+ $this->startPath = $this->options['startPath'];
742
+ if (substr($this->startPath, -1, 1) == $this->options['separator']) {
743
+ $this->startPath = substr($this->startPath, 0, -1);
744
+ }
745
+ }
746
+ }
747
+ } else {
748
+ $this->options['URL'] = '';
749
+ $this->options['tmbURL'] = '';
750
+ $this->options['tmbPath'] = '';
751
+ // read only volume
752
+ array_unshift($this->attributes, array(
753
+ 'pattern' => '/.*/',
754
+ 'read' => false
755
+ ));
756
+ }
757
+ $this->treeDeep = $this->options['treeDeep'] > 0 ? (int)$this->options['treeDeep'] : 1;
758
+ $this->tmbSize = $this->options['tmbSize'] > 0 ? (int)$this->options['tmbSize'] : 48;
759
+ $this->URL = $this->options['URL'];
760
+ if ($this->URL && preg_match("|[^/?&=]$|", $this->URL)) {
761
+ $this->URL .= '/';
762
+ }
763
+
764
+ $this->tmbURL = !empty($this->options['tmbURL']) ? $this->options['tmbURL'] : '';
765
+ if ($this->tmbURL && preg_match("|[^/?&=]$|", $this->tmbURL)) {
766
+ $this->tmbURL .= '/';
767
+ }
768
+
769
+ $this->nameValidator = is_string($this->options['acceptedName']) && !empty($this->options['acceptedName'])
770
+ ? $this->options['acceptedName']
771
+ : '';
772
+
773
+ $this->_checkArchivers();
774
+ // manual control archive types to create
775
+ if (!empty($this->options['archiveMimes']) && is_array($this->options['archiveMimes'])) {
776
+ foreach ($this->archivers['create'] as $mime => $v) {
777
+ if (!in_array($mime, $this->options['archiveMimes'])) {
778
+ unset($this->archivers['create'][$mime]);
779
+ }
780
+ }
781
+ }
782
+
783
+ // manualy add archivers
784
+ if (!empty($this->options['archivers']['create']) && is_array($this->options['archivers']['create'])) {
785
+ foreach ($this->options['archivers']['create'] as $mime => $conf) {
786
+ if (strpos($mime, 'application/') === 0
787
+ && !empty($conf['cmd'])
788
+ && isset($conf['argc'])
789
+ && !empty($conf['ext'])
790
+ && !isset($this->archivers['create'][$mime])) {
791
+ $this->archivers['create'][$mime] = $conf;
792
+ }
793
+ }
794
+ }
795
+
796
+ if (!empty($this->options['archivers']['extract']) && is_array($this->options['archivers']['extract'])) {
797
+ foreach ($this->options['archivers']['extract'] as $mime => $conf) {
798
+ if (substr($mime, 'application/') === 0
799
+ && !empty($cons['cmd'])
800
+ && isset($conf['argc'])
801
+ && !empty($conf['ext'])
802
+ && !isset($this->archivers['extract'][$mime])) {
803
+ $this->archivers['extract'][$mime] = $conf;
804
+ }
805
+ }
806
+ }
807
+
808
+ $this->configure();
809
+ // echo $this->uploadMaxSize;
810
+ // echo $this->options['uploadMaxSize'];
811
+ return $this->mounted = true;
812
+ }
813
+
814
+ /**
815
+ * Some "unmount" stuffs - may be required by virtual fs
816
+ *
817
+ * @return void
818
+ * @author Dmitry (dio) Levashov
819
+ **/
820
+ public function umount() {
821
+ }
822
+
823
+ /**
824
+ * Return error message from last failed action
825
+ *
826
+ * @return array
827
+ * @author Dmitry (dio) Levashov
828
+ **/
829
+ public function error() {
830
+ return $this->error;
831
+ }
832
+
833
+ /**
834
+ * Set mimetypes allowed to display to client
835
+ *
836
+ * @param array $mimes
837
+ * @return void
838
+ * @author Dmitry (dio) Levashov
839
+ **/
840
+ public function setMimesFilter($mimes) {
841
+ if (is_array($mimes)) {
842
+ $this->onlyMimes = $mimes;
843
+ }
844
+ }
845
+
846
+ /**
847
+ * Return root folder hash
848
+ *
849
+ * @return string
850
+ * @author Dmitry (dio) Levashov
851
+ **/
852
+ public function root() {
853
+ return $this->encode($this->root);
854
+ }
855
+
856
+ /**
857
+ * Return root or startPath hash
858
+ *
859
+ * @return string
860
+ * @author Dmitry (dio) Levashov
861
+ **/
862
+ public function defaultPath() {
863
+ return $this->encode($this->startPath ? $this->startPath : $this->root);
864
+ }
865
+
866
+ /**
867
+ * Return volume options required by client:
868
+ *
869
+ * @return array
870
+ * @author Dmitry (dio) Levashov
871
+ **/
872
+ public function options($hash) {
873
+ return array(
874
+ 'path' => $this->_path($this->decode($hash)),
875
+ 'url' => $this->URL,
876
+ 'tmbUrl' => $this->tmbURL,
877
+ 'disabled' => $this->disabled,
878
+ 'separator' => $this->separator,
879
+ 'copyOverwrite' => intval($this->options['copyOverwrite']),
880
+ 'archivers' => array(
881
+ // 'create' => array_keys($this->archivers['create']),
882
+ // 'extract' => array_keys($this->archivers['extract']),
883
+ 'create' => is_array($this->archivers['create']) ? array_keys($this->archivers['create']) : array(),
884
+ 'extract' => is_array($this->archivers['extract']) ? array_keys($this->archivers['extract']) : array()
885
+ )
886
+ );
887
+ }
888
+
889
+ /**
890
+ * Return true if command disabled in options
891
+ *
892
+ * @param string $cmd command name
893
+ * @return bool
894
+ * @author Dmitry (dio) Levashov
895
+ **/
896
+ public function commandDisabled($cmd) {
897
+ return in_array($cmd, $this->disabled);
898
+ }
899
+
900
+ /**
901
+ * Return true if mime is required mimes list
902
+ *
903
+ * @param string $mime mime type to check
904
+ * @param array $mimes allowed mime types list or not set to use client mimes list
905
+ * @param bool|null $empty what to return on empty list
906
+ * @return bool|null
907
+ * @author Dmitry (dio) Levashov
908
+ * @author Troex Nevelin
909
+ **/
910
+ public function mimeAccepted($mime, $mimes = array(), $empty = true) {
911
+ $mimes = !empty($mimes) ? $mimes : $this->onlyMimes;
912
+ if (empty($mimes)) {
913
+ return $empty;
914
+ }
915
+ return $mime == 'directory'
916
+ || in_array('all', $mimes)
917
+ || in_array('All', $mimes)
918
+ || in_array($mime, $mimes)
919
+ || in_array(substr($mime, 0, strpos($mime, '/')), $mimes);
920
+ }
921
+
922
+ /**
923
+ * Return true if voume is readable.
924
+ *
925
+ * @return bool
926
+ * @author Dmitry (dio) Levashov
927
+ **/
928
+ public function isReadable() {
929
+ $stat = $this->stat($this->root);
930
+ return $stat['read'];
931
+ }
932
+
933
+ /**
934
+ * Return true if copy from this volume allowed
935
+ *
936
+ * @return bool
937
+ * @author Dmitry (dio) Levashov
938
+ **/
939
+ public function copyFromAllowed() {
940
+ return !!$this->options['copyFrom'];
941
+ }
942
+
943
+ /**
944
+ * Return file path related to root
945
+ *
946
+ * @param string $hash file hash
947
+ * @return string
948
+ * @author Dmitry (dio) Levashov
949
+ **/
950
+ public function path($hash) {
951
+ return $this->_path($this->decode($hash));
952
+ }
953
+
954
+ /**
955
+ * Return file real path if file exists
956
+ *
957
+ * @param string $hash file hash
958
+ * @return string
959
+ * @author Dmitry (dio) Levashov
960
+ **/
961
+ public function realpath($hash) {
962
+ $path = $this->decode($hash);
963
+ return $this->stat($path) ? $path : false;
964
+ }
965
+
966
+ /**
967
+ * Return list of moved/overwrited files
968
+ *
969
+ * @return array
970
+ * @author Dmitry (dio) Levashov
971
+ **/
972
+ public function removed() {
973
+ return $this->removed;
974
+ }
975
+
976
+ /**
977
+ * Clean removed files list
978
+ *
979
+ * @return void
980
+ * @author Dmitry (dio) Levashov
981
+ **/
982
+ public function resetRemoved() {
983
+ $this->removed = array();
984
+ }
985
+
986
+ /**
987
+ * Return file/dir hash or first founded child hash with required attr == $val
988
+ *
989
+ * @param string $hash file hash
990
+ * @param string $attr attribute name
991
+ * @param bool $val attribute value
992
+ * @return string|false
993
+ * @author Dmitry (dio) Levashov
994
+ **/
995
+ public function closest($hash, $attr, $val) {
996
+ return ($path = $this->closestByAttr($this->decode($hash), $attr, $val)) ? $this->encode($path) : false;
997
+ }
998
+
999
+ /**
1000
+ * Return file info or false on error
1001
+ *
1002
+ * @param string $hash file hash
1003
+ * @param bool $realpath add realpath field to file info
1004
+ * @return array|false
1005
+ * @author Dmitry (dio) Levashov
1006
+ **/
1007
+ public function file($hash) {
1008
+ $path = $this->decode($hash);
1009
+
1010
+ return ($file = $this->stat($path)) ? $file : $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1011
+
1012
+ if (($file = $this->stat($path)) != false) {
1013
+ if ($realpath) {
1014
+ $file['realpath'] = $path;
1015
+ }
1016
+ return $file;
1017
+ }
1018
+ return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1019
+ }
1020
+
1021
+ /**
1022
+ * Return folder info
1023
+ *
1024
+ * @param string $hash folder hash
1025
+ * @param bool $hidden return hidden file info
1026
+ * @return array|false
1027
+ * @author Dmitry (dio) Levashov
1028
+ **/
1029
+ public function dir($hash, $resolveLink=false) {
1030
+ if (($dir = $this->file($hash)) == false) {
1031
+ return $this->setError(elFinder::ERROR_DIR_NOT_FOUND);
1032
+ }
1033
+
1034
+ if ($resolveLink && !empty($dir['thash'])) {
1035
+ $dir = $this->file($dir['thash']);
1036
+ }
1037
+
1038
+ return $dir && $dir['mime'] == 'directory' && empty($dir['hidden'])
1039
+ ? $dir
1040
+ : $this->setError(elFinder::ERROR_NOT_DIR);
1041
+ }
1042
+
1043
+ /**
1044
+ * Return directory content or false on error
1045
+ *
1046
+ * @param string $hash file hash
1047
+ * @return array|false
1048
+ * @author Dmitry (dio) Levashov
1049
+ **/
1050
+ public function scandir($hash) {
1051
+ if (($dir = $this->dir($hash)) == false) {
1052
+ return false;
1053
+ }
1054
+
1055
+ return $dir['read']
1056
+ ? $this->getScandir($this->decode($hash))
1057
+ : $this->setError(elFinder::ERROR_PERM_DENIED);
1058
+ }
1059
+
1060
+ /**
1061
+ * Return dir files names list
1062
+ *
1063
+ * @param string $hash file hash
1064
+ * @return array
1065
+ * @author Dmitry (dio) Levashov
1066
+ **/
1067
+ public function ls($hash) {
1068
+ if (($dir = $this->dir($hash)) == false || !$dir['read']) {
1069
+ return false;
1070
+ }
1071
+
1072
+ $list = array();
1073
+ $path = $this->decode($hash);
1074
+
1075
+ foreach ($this->getScandir($path) as $stat) {
1076
+ if (empty($stat['hidden']) && $this->mimeAccepted($stat['mime'])) {
1077
+ $list[] = $stat['name'];
1078
+ }
1079
+ }
1080
+
1081
+ return $list;
1082
+ }
1083
+
1084
+ /**
1085
+ * Return subfolders for required folder or false on error
1086
+ *
1087
+ * @param string $hash folder hash or empty string to get tree from root folder
1088
+ * @param int $deep subdir deep
1089
+ * @param string $exclude dir hash which subfolders must be exluded from result, required to not get stat twice on cwd subfolders
1090
+ * @return array|false
1091
+ * @author Dmitry (dio) Levashov
1092
+ **/
1093
+ public function tree($hash='', $deep=0, $exclude='') {
1094
+ $path = $hash ? $this->decode($hash) : $this->root;
1095
+
1096
+ if (($dir = $this->stat($path)) == false || $dir['mime'] != 'directory') {
1097
+ return false;
1098
+ }
1099
+
1100
+ $dirs = $this->gettree($path, $deep > 0 ? $deep -1 : $this->treeDeep-1, $exclude ? $this->decode($exclude) : null);
1101
+ array_unshift($dirs, $dir);
1102
+ return $dirs;
1103
+ }
1104
+
1105
+ /**
1106
+ * Return part of dirs tree from required dir up to root dir
1107
+ *
1108
+ * @param string $hash directory hash
1109
+ * @return array
1110
+ * @author Dmitry (dio) Levashov
1111
+ **/
1112
+ public function parents($hash) {
1113
+ if (($current = $this->dir($hash)) == false) {
1114
+ return false;
1115
+ }
1116
+
1117
+ $path = $this->decode($hash);
1118
+ $tree = array();
1119
+
1120
+ while ($path && $path != $this->root) {
1121
+ $path = $this->_dirname($path);
1122
+ $stat = $this->stat($path);
1123
+ if (!empty($stat['hidden']) || !$stat['read']) {
1124
+ return false;
1125
+ }
1126
+
1127
+ array_unshift($tree, $stat);
1128
+ if ($path != $this->root) {
1129
+ foreach ($this->gettree($path, 0) as $dir) {
1130
+ if (!in_array($dir, $tree)) {
1131
+ $tree[] = $dir;
1132
+ }
1133
+ }
1134
+ }
1135
+ }
1136
+
1137
+ return $tree ? $tree : array($current);
1138
+ }
1139
+
1140
+ /**
1141
+ * Create thumbnail for required file and return its name of false on failed
1142
+ *
1143
+ * @return string|false
1144
+ * @author Dmitry (dio) Levashov
1145
+ **/
1146
+ public function tmb($hash) {
1147
+ $path = $this->decode($hash);
1148
+ $stat = $this->stat($path);
1149
+
1150
+ if (isset($stat['tmb'])) {
1151
+ return $stat['tmb'] == "1" ? $this->createTmb($path, $stat) : $stat['tmb'];
1152
+ }
1153
+ return false;
1154
+ }
1155
+
1156
+ /**
1157
+ * Return file size / total directory size
1158
+ *
1159
+ * @param string file hash
1160
+ * @return int
1161
+ * @author Dmitry (dio) Levashov
1162
+ **/
1163
+ public function size($hash) {
1164
+ return $this->countSize($this->decode($hash));
1165
+ }
1166
+
1167
+ /**
1168
+ * Open file for reading and return file pointer
1169
+ *
1170
+ * @param string file hash
1171
+ * @return Resource
1172
+ * @author Dmitry (dio) Levashov
1173
+ **/
1174
+ public function open($hash) {
1175
+ if (($file = $this->file($hash)) == false
1176
+ || $file['mime'] == 'directory') {
1177
+ return false;
1178
+ }
1179
+
1180
+ return $this->_fopen($this->decode($hash), 'rb');
1181
+ }
1182
+
1183
+ /**
1184
+ * Close file pointer
1185
+ *
1186
+ * @param Resource $fp file pointer
1187
+ * @param string $hash file hash
1188
+ * @return void
1189
+ * @author Dmitry (dio) Levashov
1190
+ **/
1191
+ public function close($fp, $hash) {
1192
+ $this->_fclose($fp, $this->decode($hash));
1193
+ }
1194
+
1195
+ /**
1196
+ * Create directory and return dir info
1197
+ *
1198
+ * @param string $dst destination directory
1199
+ * @param string $name directory name
1200
+ * @return array|false
1201
+ * @author Dmitry (dio) Levashov
1202
+ **/
1203
+ public function mkdir($dst, $name) {
1204
+ if ($this->commandDisabled('mkdir')) {
1205
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1206
+ }
1207
+
1208
+ if (!$this->nameAccepted($name)) {
1209
+ return $this->setError(elFinder::ERROR_INVALID_NAME);
1210
+ }
1211
+
1212
+ if (($dir = $this->dir($dst)) == false) {
1213
+ return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst);
1214
+ }
1215
+
1216
+ if (!$dir['write']) {
1217
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1218
+ }
1219
+
1220
+ $path = $this->decode($dst);
1221
+ $dst = $this->_joinPath($path, $name);
1222
+ $stat = $this->stat($dst);
1223
+ if (!empty($stat)) {
1224
+ return $this->setError(elFinder::ERROR_EXISTS, $name);
1225
+ }
1226
+ $this->clearcache();
1227
+ return ($path = $this->_mkdir($path, $name)) ? $this->stat($path) : false;
1228
+ }
1229
+
1230
+ /**
1231
+ * Create empty file and return its info
1232
+ *
1233
+ * @param string $dst destination directory
1234
+ * @param string $name file name
1235
+ * @return array|false
1236
+ * @author Dmitry (dio) Levashov
1237
+ **/
1238
+ public function mkfile($dst, $name) {
1239
+ if ($this->commandDisabled('mkfile')) {
1240
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1241
+ }
1242
+
1243
+ if (!$this->nameAccepted($name)) {
1244
+ return $this->setError(elFinder::ERROR_INVALID_NAME);
1245
+ }
1246
+
1247
+ if (($dir = $this->dir($dst)) == false) {
1248
+ return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst);
1249
+ }
1250
+
1251
+ $path = $this->decode($dst);
1252
+
1253
+ if (!$dir['write'] || !$this->allowCreate($path, $name)) {
1254
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1255
+ }
1256
+
1257
+ if ($this->stat($this->_joinPath($path, $name))) {
1258
+ return $this->setError(elFinder::ERROR_EXISTS, $name);
1259
+ }
1260
+
1261
+ $this->clearcache();
1262
+ return ($path = $this->_mkfile($path, $name)) ? $this->stat($path) : false;
1263
+ }
1264
+
1265
+ /**
1266
+ * Rename file and return file info
1267
+ *
1268
+ * @param string $hash file hash
1269
+ * @param string $name new file name
1270
+ * @return array|false
1271
+ * @author Dmitry (dio) Levashov
1272
+ **/
1273
+ public function rename($hash, $name) {
1274
+ if ($this->commandDisabled('rename')) {
1275
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1276
+ }
1277
+
1278
+ if (!$this->nameAccepted($name)) {
1279
+ return $this->setError(elFinder::ERROR_INVALID_NAME, $name);
1280
+ }
1281
+
1282
+ if (!($file = $this->file($hash))) {
1283
+ return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1284
+ }
1285
+
1286
+ if ($name == $file['name']) {
1287
+ return $file;
1288
+ }
1289
+
1290
+ if (!empty($file['locked'])) {
1291
+ return $this->setError(elFinder::ERROR_LOCKED, $file['name']);
1292
+ }
1293
+
1294
+ $path = $this->decode($hash);
1295
+ $dir = $this->_dirname($path);
1296
+ $stat = $this->stat($this->_joinPath($dir, $name));
1297
+ if ($stat) {
1298
+ return $this->setError(elFinder::ERROR_EXISTS, $name);
1299
+ }
1300
+
1301
+ if (!$this->allowCreate($dir, $name)) {
1302
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1303
+ }
1304
+
1305
+ $this->rmTmb($file); // remove old name tmbs, we cannot do this after dir move
1306
+
1307
+
1308
+ if (($path = $this->_move($path, $dir, $name))) {
1309
+ $this->clearcache();
1310
+ return $this->stat($path);
1311
+ }
1312
+ return false;
1313
+ }
1314
+
1315
+ /**
1316
+ * Create file copy with suffix "copy number" and return its info
1317
+ *
1318
+ * @param string $hash file hash
1319
+ * @param string $suffix suffix to add to file name
1320
+ * @return array|false
1321
+ * @author Dmitry (dio) Levashov
1322
+ **/
1323
+ public function duplicate($hash, $suffix='copy') {
1324
+ if ($this->commandDisabled('duplicate')) {
1325
+ return $this->setError(elFinder::ERROR_COPY, '#'.$hash, elFinder::ERROR_PERM_DENIED);
1326
+ }
1327
+
1328
+ if (($file = $this->file($hash)) == false) {
1329
+ return $this->setError(elFinder::ERROR_COPY, elFinder::ERROR_FILE_NOT_FOUND);
1330
+ }
1331
+
1332
+ $path = $this->decode($hash);
1333
+ $dir = $this->_dirname($path);
1334
+ $name = $this->uniqueName($dir, $this->_basename($path), ' '.$suffix.' ');
1335
+
1336
+ if (!$this->allowCreate($dir, $name)) {
1337
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1338
+ }
1339
+
1340
+ return ($path = $this->copy($path, $dir, $name)) == false
1341
+ ? false
1342
+ : $this->stat($path);
1343
+ }
1344
+
1345
+ /**
1346
+ * Save uploaded file.
1347
+ * On success return array with new file stat and with removed file hash (if existed file was replaced)
1348
+ *
1349
+ * @param Resource $fp file pointer
1350
+ * @param string $dst destination folder hash
1351
+ * @param string $src file name
1352
+ * @param string $tmpname file tmp name - required to detect mime type
1353
+ * @return array|false
1354
+ * @author Dmitry (dio) Levashov
1355
+ **/
1356
+ public function upload($fp, $dst, $name, $tmpname) {
1357
+ if ($this->commandDisabled('upload')) {
1358
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1359
+ }
1360
+
1361
+ if (($dir = $this->dir($dst)) == false) {
1362
+ return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst);
1363
+ }
1364
+
1365
+ if (!$dir['write']) {
1366
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1367
+ }
1368
+
1369
+ if (!$this->nameAccepted($name)) {
1370
+ return $this->setError(elFinder::ERROR_INVALID_NAME);
1371
+ }
1372
+
1373
+ $mime = $this->mimetype($this->mimeDetect == 'internal' ? $name : $tmpname, $name);
1374
+ if ($mime == 'unknown' && $this->mimeDetect == 'internal') {
1375
+ $mime = elFinderVolumeDriver::mimetypeInternalDetect($name);
1376
+ }
1377
+
1378
+ // logic based on http://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#order
1379
+ $allow = $this->mimeAccepted($mime, $this->uploadAllow, null);
1380
+ $deny = $this->mimeAccepted($mime, $this->uploadDeny, null);
1381
+ $upload = true; // default to allow
1382
+ if (strtolower($this->uploadOrder[0]) == 'allow') { // array('allow', 'deny'), default is to 'deny'
1383
+ $upload = false; // default is deny
1384
+ if (!$deny && ($allow === true)) { // match only allow
1385
+ $upload = true;
1386
+ }// else (both match | no match | match only deny) { deny }
1387
+ } else { // array('deny', 'allow'), default is to 'allow' - this is the default rule
1388
+ $upload = true; // default is allow
1389
+ if (($deny === true) && !$allow) { // match only deny
1390
+ $upload = false;
1391
+ } // else (both match | no match | match only allow) { allow }
1392
+ }
1393
+ if (!$upload) {
1394
+ return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME);
1395
+ }
1396
+
1397
+ if ($this->uploadMaxSize > 0 && filesize($tmpname) > $this->uploadMaxSize) {
1398
+ return $this->setError(elFinder::ERROR_UPLOAD_FILE_SIZE);
1399
+ }
1400
+
1401
+ $dstpath = $this->decode($dst);
1402
+ $test = $this->_joinPath($dstpath, $name);
1403
+
1404
+ $file = $this->stat($test);
1405
+ $this->clearcache();
1406
+
1407
+ if ($file) { // file exists
1408
+ if ($this->options['uploadOverwrite']) {
1409
+ if (!$file['write']) {
1410
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1411
+ } elseif ($file['mime'] == 'directory') {
1412
+ return $this->setError(elFinder::ERROR_NOT_REPLACE, $name);
1413
+ }
1414
+ $this->remove($test);
1415
+ } else {
1416
+ $name = $this->uniqueName($dstpath, $name, '-', false);
1417
+ }
1418
+ }
1419
+
1420
+ $stat = array(
1421
+ 'mime' => $mime,
1422
+ 'width' => 0,
1423
+ 'height' => 0,
1424
+ 'size' => filesize($tmpname));
1425
+
1426
+ // $w = $h = 0;
1427
+ if (strpos($mime, 'image') === 0 && ($s = getimagesize($tmpname))) {
1428
+ $stat['width'] = $s[0];
1429
+ $stat['height'] = $s[1];
1430
+ }
1431
+ // $this->clearcache();
1432
+ if (($path = $this->_save($fp, $dstpath, $name, $stat)) == false) {
1433
+ return false;
1434
+ }
1435
+
1436
+
1437
+
1438
+ return $this->stat($path);
1439
+ }
1440
+
1441
+ /**
1442
+ * Paste files
1443
+ *
1444
+ * @param Object $volume source volume
1445
+ * @param string $source file hash
1446
+ * @param string $dst destination dir hash
1447
+ * @param bool $rmSrc remove source after copy?
1448
+ * @return array|false
1449
+ * @author Dmitry (dio) Levashov
1450
+ **/
1451
+ public function paste($volume, $src, $dst, $rmSrc = false) {
1452
+ $err = $rmSrc ? elFinder::ERROR_MOVE : elFinder::ERROR_COPY;
1453
+
1454
+ if ($this->commandDisabled('paste')) {
1455
+ return $this->setError($err, '#'.$src, elFinder::ERROR_PERM_DENIED);
1456
+ }
1457
+
1458
+ if (($file = $volume->file($src, $rmSrc)) == false) {
1459
+ return $this->setError($err, '#'.$src, elFinder::ERROR_FILE_NOT_FOUND);
1460
+ }
1461
+
1462
+ $name = $file['name'];
1463
+ $errpath = $volume->path($src);
1464
+
1465
+ if (($dir = $this->dir($dst)) == false) {
1466
+ return $this->setError($err, $errpath, elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst);
1467
+ }
1468
+
1469
+ if (!$dir['write'] || !$file['read']) {
1470
+ return $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED);
1471
+ }
1472
+
1473
+ $destination = $this->decode($dst);
1474
+
1475
+ if (($test = $volume->closest($src, $rmSrc ? 'locked' : 'read', $rmSrc))) {
1476
+ return $rmSrc
1477
+ ? $this->setError($err, $errpath, elFinder::ERROR_LOCKED, $volume->path($test))
1478
+ : $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED);
1479
+ }
1480
+
1481
+ $test = $this->_joinPath($destination, $name);
1482
+ $stat = $this->stat($test);
1483
+ $this->clearcache();
1484
+ if ($stat) {
1485
+ if ($this->options['copyOverwrite']) {
1486
+ // do not replace file with dir or dir with file
1487
+ if (!$this->isSameType($file['mime'], $stat['mime'])) {
1488
+ return $this->setError(elFinder::ERROR_NOT_REPLACE, $this->_path($test));
1489
+ }
1490
+ // existed file is not writable
1491
+ if (!$stat['write']) {
1492
+ return $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED);
1493
+ }
1494
+ // existed file locked or has locked child
1495
+ if (($locked = $this->closestByAttr($test, 'locked', true))) {
1496
+ return $this->setError(elFinder::ERROR_LOCKED, $this->_path($locked));
1497
+ }
1498
+ // target is entity file of alias
1499
+ if ($volume == $this && ($test == @$file['target'] || $test == $this->decode($src))) {
1500
+ return $this->setError(elFinder::ERROR_REPLACE, $errpath);
1501
+ }
1502
+ // remove existed file
1503
+ if (!$this->remove($test)) {
1504
+ return $this->setError(elFinder::ERROR_REPLACE, $this->_path($test));
1505
+ }
1506
+ } else {
1507
+ $name = $this->uniqueName($destination, $name, ' ', false);
1508
+ }
1509
+ }
1510
+
1511
+ // copy/move inside current volume
1512
+ if ($volume == $this) {
1513
+ $source = $this->decode($src);
1514
+ // do not copy into itself
1515
+ if ($this->_inpath($destination, $source)) {
1516
+ return $this->setError(elFinder::ERROR_COPY_INTO_ITSELF, $errpath);
1517
+ }
1518
+ $method = $rmSrc ? 'move' : 'copy';
1519
+ return ($path = $this->$method($source, $destination, $name)) ? $this->stat($path) : false;
1520
+ }
1521
+
1522
+ // copy/move from another volume
1523
+ if (!$this->options['copyTo'] || !$volume->copyFromAllowed()) {
1524
+ return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_PERM_DENIED);
1525
+ }
1526
+
1527
+ if (($path = $this->copyFrom($volume, $src, $destination, $name)) == false) {
1528
+ return false;
1529
+ }
1530
+
1531
+ if ($rmSrc) {
1532
+ if ($volume->rm($src)) {
1533
+ $this->removed[] = $file;
1534
+ } else {
1535
+ return $this->setError(elFinder::ERROR_MOVE, $errpath, elFinder::ERROR_RM_SRC);
1536
+ }
1537
+ }
1538
+ return $this->stat($path);
1539
+ }
1540
+
1541
+ /**
1542
+ * Return file contents
1543
+ *
1544
+ * @param string $hash file hash
1545
+ * @return string|false
1546
+ * @author Dmitry (dio) Levashov
1547
+ **/
1548
+ public function getContents($hash) {
1549
+ $file = $this->file($hash);
1550
+
1551
+ if (!$file) {
1552
+ return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1553
+ }
1554
+
1555
+ if ($file['mime'] == 'directory') {
1556
+ return $this->setError(elFinder::ERROR_NOT_FILE);
1557
+ }
1558
+
1559
+ if (!$file['read']) {
1560
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1561
+ }
1562
+
1563
+ return $this->_getContents($this->decode($hash));
1564
+ }
1565
+
1566
+ /**
1567
+ * Put content in text file and return file info.
1568
+ *
1569
+ * @param string $hash file hash
1570
+ * @param string $content new file content
1571
+ * @return array
1572
+ * @author Dmitry (dio) Levashov
1573
+ **/
1574
+ public function putContents($hash, $content) {
1575
+ if ($this->commandDisabled('edit')) {
1576
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1577
+ }
1578
+
1579
+ $path = $this->decode($hash);
1580
+
1581
+ if (!($file = $this->file($hash))) {
1582
+ return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1583
+ }
1584
+
1585
+ if (!$file['write']) {
1586
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1587
+ }
1588
+ $this->clearcache();
1589
+ return $this->_filePutContents($path, $content) ? $this->stat($path) : false;
1590
+ }
1591
+
1592
+ /**
1593
+ * Extract files from archive
1594
+ *
1595
+ * @param string $hash archive hash
1596
+ * @return array|bool
1597
+ * @author Dmitry (dio) Levashov,
1598
+ * @author Alexey Sukhotin
1599
+ **/
1600
+ public function extract($hash) {
1601
+ if ($this->commandDisabled('extract')) {
1602
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1603
+ }
1604
+
1605
+ if (($file = $this->file($hash)) == false) {
1606
+ return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1607
+ }
1608
+
1609
+ $archiver = isset($this->archivers['extract'][$file['mime']])
1610
+ ? $this->archivers['extract'][$file['mime']]
1611
+ : false;
1612
+
1613
+ if (!$archiver) {
1614
+ return $this->setError(elFinder::ERROR_NOT_ARCHIVE);
1615
+ }
1616
+
1617
+ $path = $this->decode($hash);
1618
+ $parent = $this->stat($this->_dirname($path));
1619
+
1620
+ if (!$file['read'] || !$parent['write']) {
1621
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1622
+ }
1623
+ $this->clearcache();
1624
+ return ($path = $this->_extract($path, $archiver)) ? $this->stat($path) : false;
1625
+ }
1626
+
1627
+ /**
1628
+ * Add files to archive
1629
+ *
1630
+ * @return void
1631
+ **/
1632
+ public function archive($hashes, $mime) {
1633
+ if ($this->commandDisabled('archive')) {
1634
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1635
+ }
1636
+
1637
+ $archiver = isset($this->archivers['create'][$mime])
1638
+ ? $this->archivers['create'][$mime]
1639
+ : false;
1640
+
1641
+ if (!$archiver) {
1642
+ return $this->setError(elFinder::ERROR_ARCHIVE_TYPE);
1643
+ }
1644
+
1645
+ $files = array();
1646
+
1647
+ foreach ($hashes as $hash) {
1648
+ if (($file = $this->file($hash)) == false) {
1649
+ return $this->error(elFinder::ERROR_FILE_NOT_FOUND, '#'+$hash);
1650
+ }
1651
+ if (!$file['read']) {
1652
+ return $this->error(elFinder::ERROR_PERM_DENIED);
1653
+ }
1654
+ $path = $this->decode($hash);
1655
+ if (!isset($dir)) {
1656
+ $dir = $this->_dirname($path);
1657
+ $stat = $this->stat($dir);
1658
+ if (!$stat['write']) {
1659
+ return $this->error(elFinder::ERROR_PERM_DENIED);
1660
+ }
1661
+ }
1662
+
1663
+ $files[] = $this->_basename($path);
1664
+ }
1665
+
1666
+ $name = (count($files) == 1 ? $files[0] : 'Archive').'.'.$archiver['ext'];
1667
+ $name = $this->uniqueName($dir, $name, '');
1668
+ $this->clearcache();
1669
+ return ($path = $this->_archive($dir, $files, $name, $archiver)) ? $this->stat($path) : false;
1670
+ }
1671
+
1672
+ /**
1673
+ * Resize image
1674
+ *
1675
+ * @param string $hash image file
1676
+ * @param int $width new width
1677
+ * @param int $height new height
1678
+ * @param int $x X start poistion for crop
1679
+ * @param int $y Y start poistion for crop
1680
+ * @param string $mode action how to mainpulate image
1681
+ * @return array|false
1682
+ * @author Dmitry (dio) Levashov
1683
+ * @author Alexey Sukhotin
1684
+ * @author nao-pon
1685
+ * @author Troex Nevelin
1686
+ **/
1687
+ public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg = '', $degree = 0) {
1688
+ if ($this->commandDisabled('resize')) {
1689
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1690
+ }
1691
+
1692
+ if (($file = $this->file($hash)) == false) {
1693
+ return $this->setError(elFinder::ERROR_FILE_NOT_FOUND);
1694
+ }
1695
+
1696
+ if (!$file['write'] || !$file['read']) {
1697
+ return $this->setError(elFinder::ERROR_PERM_DENIED);
1698
+ }
1699
+
1700
+ $path = $this->decode($hash);
1701
+
1702
+ if (!$this->canResize($path, $file)) {
1703
+ return $this->setError(elFinder::ERROR_UNSUPPORT_TYPE);
1704
+ }
1705
+
1706
+ switch($mode) {
1707
+
1708
+ case 'propresize':
1709
+ $result = $this->imgResize($path, $width, $height, true, true);
1710
+ break;
1711
+
1712
+ case 'crop':
1713
+ $result = $this->imgCrop($path, $width, $height, $x, $y);
1714
+ break;
1715
+
1716
+ case 'fitsquare':
1717
+ $result = $this->imgSquareFit($path, $width, $height, 'center', 'middle', ($bg ? $bg : $this->options['tmbBgColor']));
1718
+ break;
1719
+
1720
+ case 'rotate':
1721
+ $result = $this->imgRotate($path, $degree, ($bg ? $bg : $this->options['tmbBgColor']));
1722
+ break;
1723
+
1724
+ default:
1725
+ $result = $this->imgResize($path, $width, $height, false, true);
1726
+ break;
1727
+ }
1728
+
1729
+ if ($result) {
1730
+ $this->rmTmb($file);
1731
+ $this->clearcache();
1732
+ return $this->stat($path);
1733
+ }
1734
+
1735
+ return false;
1736
+ }
1737
+
1738
+ /**
1739
+ * Remove file/dir
1740
+ *
1741
+ * @param string $hash file hash
1742
+ * @return bool
1743
+ * @author Dmitry (dio) Levashov
1744
+ **/
1745
+ public function rm($hash) {
1746
+ return $this->commandDisabled('rm')
1747
+ ? array(elFinder::ERROR_ACCESS_DENIED)
1748
+ : $this->remove($this->decode($hash));
1749
+ }
1750
+
1751
+ /**
1752
+ * Search files
1753
+ *
1754
+ * @param string $q search string
1755
+ * @param array $mimes
1756
+ * @return array
1757
+ * @author Dmitry (dio) Levashov
1758
+ **/
1759
+ public function search($q, $mimes) {
1760
+ return $this->doSearch($this->root, $q, $mimes);
1761
+ }
1762
+
1763
+ /**
1764
+ * Return image dimensions
1765
+ *
1766
+ * @param string $hash file hash
1767
+ * @return array
1768
+ * @author Dmitry (dio) Levashov
1769
+ **/
1770
+ public function dimensions($hash) {
1771
+ if (($file = $this->file($hash)) == false) {
1772
+ return false;
1773
+ }
1774
+
1775
+ return $this->_dimensions($this->decode($hash), $file['mime']);
1776
+ }
1777
+
1778
+ /**
1779
+ * Return content URL (for netmout volume driver)
1780
+ * If file.url == 1 requests from JavaScript client with XHR
1781
+ *
1782
+ * @param string $hash file hash
1783
+ * @param array $options options array
1784
+ * @return boolean|string
1785
+ * @author Naoki Sawada
1786
+ */
1787
+ public function getContentUrl($hash, $options = array()) {
1788
+ if (($file = $this->file($hash)) == false || !$file['url'] || $file['url'] == 1) {
1789
+ return false;
1790
+ }
1791
+ return $file['url'];
1792
+ }
1793
+
1794
+ /**
1795
+ * Return temp path
1796
+ *
1797
+ * @return string
1798
+ * @author Naoki Sawada
1799
+ */
1800
+ public function getTempPath() {
1801
+ if (@ $this->tmpPath) {
1802
+ return $this->tmpPath;
1803
+ } else if (@ $this->tmp) {
1804
+ return $this->tmp;
1805
+ } else if (@ $this->tmbPath) {
1806
+ return $this->tmbPath;
1807
+ } else {
1808
+ return null;
1809
+ }
1810
+ }
1811
+
1812
+ /**
1813
+ * Save error message
1814
+ *
1815
+ * @param array error
1816
+ * @return false
1817
+ * @author Dmitry(dio) Levashov
1818
+ **/
1819
+ protected function setError($error) {
1820
+
1821
+ $this->error = array();
1822
+
1823
+ foreach (func_get_args() as $err) {
1824
+ if (is_array($err)) {
1825
+ $this->error = array_merge($this->error, $err);
1826
+ } else {
1827
+ $this->error[] = $err;
1828
+ }
1829
+ }
1830
+
1831
+ // $this->error = is_array($error) ? $error : func_get_args();
1832
+ return false;
1833
+ }
1834
+
1835
+ /*********************************************************************/
1836
+ /* FS API */
1837
+ /*********************************************************************/
1838
+
1839
+ /***************** paths *******************/
1840
+
1841
+ /**
1842
+ * Encode path into hash
1843
+ *
1844
+ * @param string file path
1845
+ * @return string
1846
+ * @author Dmitry (dio) Levashov
1847
+ * @author Troex Nevelin
1848
+ **/
1849
+ protected function encode($path) {
1850
+ if ($path !== '') {
1851
+
1852
+ // cut ROOT from $path for security reason, even if hacker decodes the path he will not know the root
1853
+ $p = $this->_relpath($path);
1854
+ // if reqesting root dir $path will be empty, then assign '/' as we cannot leave it blank for crypt
1855
+ if ($p === '') {
1856
+ $p = DIRECTORY_SEPARATOR;
1857
+ }
1858
+
1859
+ // TODO crypt path and return hash
1860
+ $hash = $this->crypt($p);
1861
+ // hash is used as id in HTML that means it must contain vaild chars
1862
+ // make base64 html safe and append prefix in begining
1863
+ $hash = strtr(base64_encode($hash), '+/=', '-_.');
1864
+ // remove dots '.' at the end, before it was '=' in base64
1865
+ $hash = rtrim($hash, '.');
1866
+ // append volume id to make hash unique
1867
+ return $this->id.$hash;
1868
+ }
1869
+ }
1870
+
1871
+ /**
1872
+ * Decode path from hash
1873
+ *
1874
+ * @param string file hash
1875
+ * @return string
1876
+ * @author Dmitry (dio) Levashov
1877
+ * @author Troex Nevelin
1878
+ **/
1879
+ protected function decode($hash) {
1880
+ if (strpos($hash, $this->id) === 0) {
1881
+ // cut volume id after it was prepended in encode
1882
+ $h = substr($hash, strlen($this->id));
1883
+ // replace HTML safe base64 to normal
1884
+ $h = base64_decode(strtr($h, '-_.', '+/='));
1885
+ // TODO uncrypt hash and return path
1886
+ $path = $this->uncrypt($h);
1887
+ // append ROOT to path after it was cut in encode
1888
+ return $this->_abspath($path);//$this->root.($path == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR.$path);
1889
+ }
1890
+ }
1891
+
1892
+ /**
1893
+ * Return crypted path
1894
+ * Not implemented
1895
+ *
1896
+ * @param string path
1897
+ * @return mixed
1898
+ * @author Dmitry (dio) Levashov
1899
+ **/
1900
+ protected function crypt($path) {
1901
+ return $path;
1902
+ }
1903
+
1904
+ /**
1905
+ * Return uncrypted path
1906
+ * Not implemented
1907
+ *
1908
+ * @param mixed hash
1909
+ * @return mixed
1910
+ * @author Dmitry (dio) Levashov
1911
+ **/
1912
+ protected function uncrypt($hash) {
1913
+ return $hash;
1914
+ }
1915
+
1916
+ /**
1917
+ * Validate file name based on $this->options['acceptedName'] regexp
1918
+ *
1919
+ * @param string $name file name
1920
+ * @return bool
1921
+ * @author Dmitry (dio) Levashov
1922
+ **/
1923
+ protected function nameAccepted($name) {
1924
+ if ($this->nameValidator) {
1925
+ if (function_exists($this->nameValidator)) {
1926
+ $f = $this->nameValidator;
1927
+ return $f($name);
1928
+ }
1929
+
1930
+ return preg_match($this->nameValidator, $name);
1931
+ }
1932
+ return true;
1933
+ }
1934
+
1935
+ /**
1936
+ * Return new unique name based on file name and suffix
1937
+ *
1938
+ * @param string $path file path
1939
+ * @param string $suffix suffix append to name
1940
+ * @return string
1941
+ * @author Dmitry (dio) Levashov
1942
+ **/
1943
+ public function uniqueName($dir, $name, $suffix = ' copy', $checkNum=true) {
1944
+ $ext = '';
1945
+
1946
+ if (preg_match('/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/i', $name, $m)) {
1947
+ $ext = '.'.$m[1];
1948
+ $name = substr($name, 0, strlen($name)-strlen($m[0]));
1949
+ }
1950
+
1951
+ if ($checkNum && preg_match('/('.$suffix.')(\d*)$/i', $name, $m)) {
1952
+ $i = (int)$m[2];
1953
+ $name = substr($name, 0, strlen($name)-strlen($m[2]));
1954
+ } else {
1955
+ $i = 1;
1956
+ $name .= $suffix;
1957
+ }
1958
+ $max = $i+100000;
1959
+
1960
+ while ($i <= $max) {
1961
+ $n = $name.($i > 0 ? $i : '').$ext;
1962
+
1963
+ if (!$this->stat($this->_joinPath($dir, $n))) {
1964
+ $this->clearcache();
1965
+ return $n;
1966
+ }
1967
+ $i++;
1968
+ }
1969
+ return $name.md5($dir).$ext;
1970
+ }
1971
+
1972
+ /*********************** file stat *********************/
1973
+
1974
+ /**
1975
+ * Check file attribute
1976
+ *
1977
+ * @param string $path file path
1978
+ * @param string $name attribute name (read|write|locked|hidden)
1979
+ * @param bool $val attribute value returned by file system
1980
+ * @return bool
1981
+ * @author Dmitry (dio) Levashov
1982
+ **/
1983
+ protected function attr($path, $name, $val=null) {
1984
+ if (!isset($this->defaults[$name])) {
1985
+ return false;
1986
+ }
1987
+
1988
+
1989
+ $perm = null;
1990
+
1991
+ if ($this->access) {
1992
+ $perm = call_user_func($this->access, $name, $path, $this->options['accessControlData'], $this);
1993
+
1994
+ if ($perm !== null) {
1995
+ return !!$perm;
1996
+ }
1997
+ }
1998
+
1999
+ if ($this->separator != '/') {
2000
+ $path = str_replace($this->separator, '/', $this->_relpath($path));
2001
+ } else {
2002
+ $path = $this->_relpath($path);
2003
+ }
2004
+
2005
+ $path = '/'.$path;
2006
+
2007
+ for ($i = 0, $c = count($this->attributes); $i < $c; $i++) {
2008
+ $attrs = $this->attributes[$i];
2009
+
2010
+ if (isset($attrs[$name]) && isset($attrs['pattern']) && preg_match($attrs['pattern'], $path)) {
2011
+ $perm = $attrs[$name];
2012
+ }
2013
+ }
2014
+
2015
+ return $perm === null ? (is_null($val)? $this->defaults[$name] : $val) : !!$perm;
2016
+ }
2017
+
2018
+ /**
2019
+ * Return true if file with given name can be created in given folder.
2020
+ *
2021
+ * @param string $dir parent dir path
2022
+ * @param string $name new file name
2023
+ * @return bool
2024
+ * @author Dmitry (dio) Levashov
2025
+ **/
2026
+ protected function allowCreate($dir, $name) {
2027
+ $path = $this->_joinPath($dir, $name);
2028
+ $perm = null;
2029
+
2030
+ if ($this->access) {
2031
+ $perm = call_user_func($this->access, 'write', $path, $this->options['accessControlData'], $this);
2032
+ if ($perm !== null) {
2033
+ return !!$perm;
2034
+ }
2035
+ }
2036
+
2037
+ $testPath = $this->separator.$this->_relpath($path);
2038
+
2039
+ for ($i = 0, $c = count($this->attributes); $i < $c; $i++) {
2040
+ $attrs = $this->attributes[$i];
2041
+
2042
+ if (isset($attrs['write']) && isset($attrs['pattern']) && preg_match($attrs['pattern'], $testPath)) {
2043
+ $perm = $attrs['write'];
2044
+ }
2045
+ }
2046
+
2047
+ return $perm === null ? true : $perm;
2048
+ }
2049
+
2050
+ /**
2051
+ * Return fileinfo
2052
+ *
2053
+ * @param string $path file cache
2054
+ * @return array
2055
+ * @author Dmitry (dio) Levashov
2056
+ **/
2057
+ protected function stat($path) {
2058
+ if ($path === false) {
2059
+ return false;
2060
+ }
2061
+ return isset($this->cache[$path])
2062
+ ? $this->cache[$path]
2063
+ : $this->updateCache($path, $this->_stat($path));
2064
+ }
2065
+
2066
+ /**
2067
+ * Put file stat in cache and return it
2068
+ *
2069
+ * @param string $path file path
2070
+ * @param array $stat file stat
2071
+ * @return array
2072
+ * @author Dmitry (dio) Levashov
2073
+ **/
2074
+ protected function updateCache($path, $stat) {
2075
+ if (empty($stat) || !is_array($stat)) {
2076
+ return $this->cache[$path] = array();
2077
+ }
2078
+
2079
+ $stat['hash'] = $this->encode($path);
2080
+
2081
+ $root = $path == $this->root;
2082
+
2083
+ if ($root) {
2084
+ $stat['volumeid'] = $this->id;
2085
+ if ($this->rootName) {
2086
+ $stat['name'] = $this->rootName;
2087
+ }
2088
+ } else {
2089
+ if (!isset($stat['name']) || !strlen($stat['name'])) {
2090
+ $stat['name'] = $this->_basename($path);
2091
+ }
2092
+ if (empty($stat['phash'])) {
2093
+ $stat['phash'] = $this->encode($this->_dirname($path));
2094
+ }
2095
+ }
2096
+
2097
+ // fix name if required
2098
+ if ($this->options['utf8fix'] && $this->options['utf8patterns'] && $this->options['utf8replace']) {
2099
+ $stat['name'] = json_decode(str_replace($this->options['utf8patterns'], $this->options['utf8replace'], json_encode($stat['name'])));
2100
+ }
2101
+
2102
+
2103
+ if (empty($stat['mime'])) {
2104
+ $stat['mime'] = $this->mimetype($stat['name']);
2105
+ }
2106
+
2107
+ // @todo move dateformat to client
2108
+ // $stat['date'] = isset($stat['ts'])
2109
+ // ? $this->formatDate($stat['ts'])
2110
+ // : 'unknown';
2111
+
2112
+ if (!isset($stat['size'])) {
2113
+ $stat['size'] = 'unknown';
2114
+ }
2115
+
2116
+ $stat['read'] = intval($this->attr($path, 'read', isset($stat['read']) ? !!$stat['read'] : null));
2117
+ $stat['write'] = intval($this->attr($path, 'write', isset($stat['write']) ? !!$stat['write'] : null));
2118
+ if ($root) {
2119
+ $stat['locked'] = 1;
2120
+ } elseif ($this->attr($path, 'locked', !empty($stat['locked']))) {
2121
+ $stat['locked'] = 1;
2122
+ } else {
2123
+ unset($stat['locked']);
2124
+ }
2125
+
2126
+ if ($root) {
2127
+ unset($stat['hidden']);
2128
+ } elseif ($this->attr($path, 'hidden', !empty($stat['hidden']))
2129
+ || !$this->mimeAccepted($stat['mime'])) {
2130
+ $stat['hidden'] = $root ? 0 : 1;
2131
+ } else {
2132
+ unset($stat['hidden']);
2133
+ }
2134
+
2135
+ if ($stat['read'] && empty($stat['hidden'])) {
2136
+
2137
+ if ($stat['mime'] == 'directory') {
2138
+ // for dir - check for subdirs
2139
+
2140
+ if ($this->options['checkSubfolders']) {
2141
+ if (isset($stat['dirs'])) {
2142
+ if ($stat['dirs']) {
2143
+ $stat['dirs'] = 1;
2144
+ } else {
2145
+ unset($stat['dirs']);
2146
+ }
2147
+ } elseif (!empty($stat['alias']) && !empty($stat['target'])) {
2148
+ $stat['dirs'] = isset($this->cache[$stat['target']])
2149
+ ? intval(isset($this->cache[$stat['target']]['dirs']))
2150
+ : $this->_subdirs($stat['target']);
2151
+
2152
+ } elseif ($this->_subdirs($path)) {
2153
+ $stat['dirs'] = 1;
2154
+ }
2155
+ } else {
2156
+ $stat['dirs'] = 1;
2157
+ }
2158
+ } else {
2159
+ // for files - check for thumbnails
2160
+ $p = isset($stat['target']) ? $stat['target'] : $path;
2161
+ if ($this->tmbURL && !isset($stat['tmb']) && $this->canCreateTmb($p, $stat)) {
2162
+ $tmb = $this->gettmb($p, $stat);
2163
+ $stat['tmb'] = $tmb ? $tmb : 1;
2164
+ }
2165
+
2166
+ }
2167
+ }
2168
+
2169
+ if (!empty($stat['alias']) && !empty($stat['target'])) {
2170
+ $stat['thash'] = $this->encode($stat['target']);
2171
+ unset($stat['target']);
2172
+ }
2173
+
2174
+ if (isset($this->options['netkey']) && $path === $this->root) {
2175
+ $stat['netkey'] = $this->options['netkey'];
2176
+ }
2177
+
2178
+ return $this->cache[$path] = $stat;
2179
+ }
2180
+
2181
+ /**
2182
+ * Get stat for folder content and put in cache
2183
+ *
2184
+ * @param string $path
2185
+ * @return void
2186
+ * @author Dmitry (dio) Levashov
2187
+ **/
2188
+ protected function cacheDir($path) {
2189
+ $this->dirsCache[$path] = array();
2190
+
2191
+ foreach ($this->_scandir($path) as $p) {
2192
+ if (($stat = $this->stat($p)) && empty($stat['hidden'])) {
2193
+ $this->dirsCache[$path][] = $p;
2194
+ }
2195
+ }
2196
+ }
2197
+
2198
+ /**
2199
+ * Clean cache
2200
+ *
2201
+ * @return void
2202
+ * @author Dmitry (dio) Levashov
2203
+ **/
2204
+ protected function clearcache() {
2205
+ $this->cache = $this->dirsCache = array();
2206
+ }
2207
+
2208
+ /**
2209
+ * Return file mimetype
2210
+ *
2211
+ * @param string $path file path
2212
+ * @return string
2213
+ * @author Dmitry (dio) Levashov
2214
+ **/
2215
+ protected function mimetype($path, $name = '') {
2216
+ $type = '';
2217
+
2218
+ if ($this->mimeDetect == 'finfo') {
2219
+ if ($type = @finfo_file($this->finfo, $path)) {
2220
+ if ($name === '') {
2221
+ $name = $path;
2222
+ }
2223
+ $ext = (false === $pos = strrpos($name, '.')) ? '' : substr($name, $pos + 1);
2224
+ if ($ext && preg_match('~^application/(?:octet-stream|(?:x-)?zip)~', $type)) {
2225
+ if (isset(elFinderVolumeDriver::$mimetypes[$ext])) $type = elFinderVolumeDriver::$mimetypes[$ext];
2226
+ }
2227
+ }
2228
+ } elseif ($type == 'mime_content_type') {
2229
+ $type = mime_content_type($path);
2230
+ } else {
2231
+ $type = elFinderVolumeDriver::mimetypeInternalDetect($path);
2232
+ }
2233
+
2234
+ $type = explode(';', $type);
2235
+ $type = trim($type[0]);
2236
+
2237
+ if (in_array($type, array('application/x-empty', 'inode/x-empty'))) {
2238
+ // finfo return this mime for empty files
2239
+ $type = 'text/plain';
2240
+ } elseif ($type == 'application/x-zip') {
2241
+ // http://elrte.org/redmine/issues/163
2242
+ $type = 'application/zip';
2243
+ }
2244
+
2245
+ return $type == 'unknown' && $this->mimeDetect != 'internal'
2246
+ ? elFinderVolumeDriver::mimetypeInternalDetect($path)
2247
+ : $type;
2248
+
2249
+ }
2250
+
2251
+ /**
2252
+ * Detect file mimetype using "internal" method
2253
+ *
2254
+ * @param string $path file path
2255
+ * @return string
2256
+ * @author Dmitry (dio) Levashov
2257
+ **/
2258
+ static protected function mimetypeInternalDetect($path) {
2259
+ $pinfo = pathinfo($path);
2260
+ $ext = isset($pinfo['extension']) ? strtolower($pinfo['extension']) : '';
2261
+ return isset(elFinderVolumeDriver::$mimetypes[$ext]) ? elFinderVolumeDriver::$mimetypes[$ext] : 'unknown';
2262
+
2263
+ }
2264
+
2265
+ /**
2266
+ * Return file/total directory size
2267
+ *
2268
+ * @param string $path file path
2269
+ * @return int
2270
+ * @author Dmitry (dio) Levashov
2271
+ **/
2272
+ protected function countSize($path) {
2273
+ $stat = $this->stat($path);
2274
+
2275
+ if (empty($stat) || !$stat['read'] || !empty($stat['hidden'])) {
2276
+ return 'unknown';
2277
+ }
2278
+
2279
+ if ($stat['mime'] != 'directory') {
2280
+ return $stat['size'];
2281
+ }
2282
+
2283
+ $subdirs = $this->options['checkSubfolders'];
2284
+ $this->options['checkSubfolders'] = true;
2285
+ $result = 0;
2286
+ foreach ($this->getScandir($path) as $stat) {
2287
+ $size = $stat['mime'] == 'directory' && $stat['read']
2288
+ ? $this->countSize($this->_joinPath($path, $stat['name']))
2289
+ : (isset($stat['size']) ? intval($stat['size']) : 0);
2290
+ if ($size > 0) {
2291
+ $result += $size;
2292
+ }
2293
+ }
2294
+ $this->options['checkSubfolders'] = $subdirs;
2295
+ return $result;
2296
+ }
2297
+
2298
+ /**
2299
+ * Return true if all mimes is directory or files
2300
+ *
2301
+ * @param string $mime1 mimetype
2302
+ * @param string $mime2 mimetype
2303
+ * @return bool
2304
+ * @author Dmitry (dio) Levashov
2305
+ **/
2306
+ protected function isSameType($mime1, $mime2) {
2307
+ return ($mime1 == 'directory' && $mime1 == $mime2) || ($mime1 != 'directory' && $mime2 != 'directory');
2308
+ }
2309
+
2310
+ /**
2311
+ * If file has required attr == $val - return file path,
2312
+ * If dir has child with has required attr == $val - return child path
2313
+ *
2314
+ * @param string $path file path
2315
+ * @param string $attr attribute name
2316
+ * @param bool $val attribute value
2317
+ * @return string|false
2318
+ * @author Dmitry (dio) Levashov
2319
+ **/
2320
+ protected function closestByAttr($path, $attr, $val) {
2321
+ $stat = $this->stat($path);
2322
+
2323
+ if (empty($stat)) {
2324
+ return false;
2325
+ }
2326
+
2327
+ $v = isset($stat[$attr]) ? $stat[$attr] : false;
2328
+
2329
+ if ($v == $val) {
2330
+ return $path;
2331
+ }
2332
+
2333
+ return $stat['mime'] == 'directory'
2334
+ ? $this->childsByAttr($path, $attr, $val)
2335
+ : false;
2336
+ }
2337
+
2338
+ /**
2339
+ * Return first found children with required attr == $val
2340
+ *
2341
+ * @param string $path file path
2342
+ * @param string $attr attribute name
2343
+ * @param bool $val attribute value
2344
+ * @return string|false
2345
+ * @author Dmitry (dio) Levashov
2346
+ **/
2347
+ protected function childsByAttr($path, $attr, $val) {
2348
+ foreach ($this->_scandir($path) as $p) {
2349
+ if (($_p = $this->closestByAttr($p, $attr, $val)) != false) {
2350
+ return $_p;
2351
+ }
2352
+ }
2353
+ return false;
2354
+ }
2355
+
2356
+ /***************** get content *******************/
2357
+
2358
+ /**
2359
+ * Return required dir's files info.
2360
+ * If onlyMimes is set - return only dirs and files of required mimes
2361
+ *
2362
+ * @param string $path dir path
2363
+ * @return array
2364
+ * @author Dmitry (dio) Levashov
2365
+ **/
2366
+ protected function getScandir($path) {
2367
+ $files = array();
2368
+
2369
+ !isset($this->dirsCache[$path]) && $this->cacheDir($path);
2370
+
2371
+ foreach ($this->dirsCache[$path] as $p) {
2372
+ if (($stat = $this->stat($p)) && empty($stat['hidden'])) {
2373
+ $files[] = $stat;
2374
+ }
2375
+ }
2376
+
2377
+ return $files;
2378
+ }
2379
+
2380
+
2381
+ /**
2382
+ * Return subdirs tree
2383
+ *
2384
+ * @param string $path parent dir path
2385
+ * @param int $deep tree deep
2386
+ * @return array
2387
+ * @author Dmitry (dio) Levashov
2388
+ **/
2389
+ protected function gettree($path, $deep, $exclude='') {
2390
+ $dirs = array();
2391
+
2392
+ !isset($this->dirsCache[$path]) && $this->cacheDir($path);
2393
+
2394
+ foreach ($this->dirsCache[$path] as $p) {
2395
+ $stat = $this->stat($p);
2396
+
2397
+ if ($stat && empty($stat['hidden']) && $p != $exclude && $stat['mime'] == 'directory') {
2398
+ $dirs[] = $stat;
2399
+ if ($deep > 0 && !empty($stat['dirs'])) {
2400
+ $dirs = array_merge($dirs, $this->gettree($p, $deep-1));
2401
+ }
2402
+ }
2403
+ }
2404
+
2405
+ return $dirs;
2406
+ }
2407
+
2408
+ /**
2409
+ * Recursive files search
2410
+ *
2411
+ * @param string $path dir path
2412
+ * @param string $q search string
2413
+ * @param array $mimes
2414
+ * @return array
2415
+ * @author Dmitry (dio) Levashov
2416
+ **/
2417
+ protected function doSearch($path, $q, $mimes) {
2418
+ $result = array();
2419
+
2420
+ foreach($this->_scandir($path) as $p) {
2421
+ $stat = $this->stat($p);
2422
+
2423
+ if (!$stat) { // invalid links
2424
+ continue;
2425
+ }
2426
+
2427
+ if (!empty($stat['hidden']) || !$this->mimeAccepted($stat['mime'])) {
2428
+ continue;
2429
+ }
2430
+
2431
+ $name = $stat['name'];
2432
+
2433
+ if ($this->stripos($name, $q) !== false) {
2434
+ $stat['path'] = $this->_path($p);
2435
+ if ($this->URL && !isset($stat['url'])) {
2436
+ $stat['url'] = $this->URL . str_replace($this->separator, '/', substr($p, strlen($this->root) + 1));
2437
+ }
2438
+
2439
+ $result[] = $stat;
2440
+ }
2441
+ if ($stat['mime'] == 'directory' && $stat['read'] && !isset($stat['alias'])) {
2442
+ $result = array_merge($result, $this->doSearch($p, $q, $mimes));
2443
+ }
2444
+ }
2445
+
2446
+ return $result;
2447
+ }
2448
+
2449
+ /********************** manuipulations ******************/
2450
+
2451
+ /**
2452
+ * Copy file/recursive copy dir only in current volume.
2453
+ * Return new file path or false.
2454
+ *
2455
+ * @param string $src source path
2456
+ * @param string $dst destination dir path
2457
+ * @param string $name new file name (optionaly)
2458
+ * @return string|false
2459
+ * @author Dmitry (dio) Levashov
2460
+ **/
2461
+ protected function copy($src, $dst, $name) {
2462
+ $srcStat = $this->stat($src);
2463
+ $this->clearcache();
2464
+
2465
+ if (!empty($srcStat['thash'])) {
2466
+ $target = $this->decode($srcStat['thash']);
2467
+ $stat = $this->stat($target);
2468
+ $this->clearcache();
2469
+ return $stat && $this->_symlink($target, $dst, $name)
2470
+ ? $this->_joinPath($dst, $name)
2471
+ : $this->setError(elFinder::ERROR_COPY, $this->_path($src));
2472
+ }
2473
+
2474
+ if ($srcStat['mime'] == 'directory') {
2475
+ $test = $this->stat($this->_joinPath($dst, $name));
2476
+
2477
+ if (($test && $test['mime'] != 'directory') || !$this->_mkdir($dst, $name)) {
2478
+ return $this->setError(elFinder::ERROR_COPY, $this->_path($src));
2479
+ }
2480
+
2481
+ $dst = $this->_joinPath($dst, $name);
2482
+
2483
+ foreach ($this->getScandir($src) as $stat) {
2484
+ if (empty($stat['hidden'])) {
2485
+ $name = $stat['name'];
2486
+ if (!$this->copy($this->_joinPath($src, $name), $dst, $name)) {
2487
+ $this->remove($dst, true); // fall back
2488
+ return false;
2489
+ }
2490
+ }
2491
+ }
2492
+ $this->clearcache();
2493
+ return $dst;
2494
+ }
2495
+
2496
+ return $this->_copy($src, $dst, $name)
2497
+ ? $this->_joinPath($dst, $name)
2498
+ : $this->setError(elFinder::ERROR_COPY, $this->_path($src));
2499
+ }
2500
+
2501
+ /**
2502
+ * Move file
2503
+ * Return new file path or false.
2504
+ *
2505
+ * @param string $src source path
2506
+ * @param string $dst destination dir path
2507
+ * @param string $name new file name
2508
+ * @return string|false
2509
+ * @author Dmitry (dio) Levashov
2510
+ **/
2511
+ protected function move($src, $dst, $name) {
2512
+ $stat = $this->stat($src);
2513
+ $stat['realpath'] = $src;
2514
+ $this->rmTmb($stat); // can not do rmTmb() after _move()
2515
+ $this->clearcache();
2516
+
2517
+ if ($this->_move($src, $dst, $name)) {
2518
+ $this->removed[] = $stat;
2519
+
2520
+ return $this->_joinPath($dst, $name);
2521
+ }
2522
+
2523
+ return $this->setError(elFinder::ERROR_MOVE, $this->_path($src));
2524
+ }
2525
+
2526
+ /**
2527
+ * Copy file from another volume.
2528
+ * Return new file path or false.
2529
+ *
2530
+ * @param Object $volume source volume
2531
+ * @param string $src source file hash
2532
+ * @param string $destination destination dir path
2533
+ * @param string $name file name
2534
+ * @return string|false
2535
+ * @author Dmitry (dio) Levashov
2536
+ **/
2537
+ protected function copyFrom($volume, $src, $destination, $name) {
2538
+
2539
+ if (($source = $volume->file($src)) == false) {
2540
+ return $this->setError(elFinder::ERROR_COPY, '#'.$src, $volume->error());
2541
+ }
2542
+
2543
+ $errpath = $volume->path($src);
2544
+
2545
+ if (!$this->nameAccepted($source['name'])) {
2546
+ return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_INVALID_NAME);
2547
+ }
2548
+
2549
+ if (!$source['read']) {
2550
+ return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_PERM_DENIED);
2551
+ }
2552
+
2553
+ if ($source['mime'] == 'directory') {
2554
+ $stat = $this->stat($this->_joinPath($destination, $name));
2555
+ $this->clearcache();
2556
+ if ((!$stat || $stat['mime'] != 'directory') && !$this->_mkdir($destination, $name)) {
2557
+ return $this->setError(elFinder::ERROR_COPY, $errpath);
2558
+ }
2559
+
2560
+ $path = $this->_joinPath($destination, $name);
2561
+
2562
+ foreach ($volume->scandir($src) as $entr) {
2563
+ if (!$this->copyFrom($volume, $entr['hash'], $path, $entr['name'])) {
2564
+ return false;
2565
+ }
2566
+ }
2567
+
2568
+ } else {
2569
+ // $mime = $source['mime'];
2570
+ // $w = $h = 0;
2571
+ if (($dim = $volume->dimensions($src))) {
2572
+ $s = explode('x', $dim);
2573
+ $source['width'] = $s[0];
2574
+ $source['height'] = $s[1];
2575
+ }
2576
+
2577
+ if (($fp = $volume->open($src)) == false
2578
+ || ($path = $this->_save($fp, $destination, $name, $source)) == false) {
2579
+ $fp && $volume->close($fp, $src);
2580
+ return $this->setError(elFinder::ERROR_COPY, $errpath);
2581
+ }
2582
+ $volume->close($fp, $src);
2583
+ }
2584
+
2585
+ return $path;
2586
+ }
2587
+
2588
+ /**
2589
+ * Remove file/ recursive remove dir
2590
+ *
2591
+ * @param string $path file path
2592
+ * @param bool $force try to remove even if file locked
2593
+ * @return bool
2594
+ * @author Dmitry (dio) Levashov
2595
+ **/
2596
+ protected function remove($path, $force = false) {
2597
+ $stat = $this->stat($path);
2598
+ $stat['realpath'] = $path;
2599
+ $this->rmTmb($stat);
2600
+ $this->clearcache();
2601
+
2602
+ if (empty($stat)) {
2603
+ return $this->setError(elFinder::ERROR_RM, $this->_path($path), elFinder::ERROR_FILE_NOT_FOUND);
2604
+ }
2605
+
2606
+ if (!$force && !empty($stat['locked'])) {
2607
+ return $this->setError(elFinder::ERROR_LOCKED, $this->_path($path));
2608
+ }
2609
+
2610
+ if ($stat['mime'] == 'directory') {
2611
+ foreach ($this->_scandir($path) as $p) {
2612
+ $name = $this->_basename($p);
2613
+ if ($name != '.' && $name != '..' && !$this->remove($p)) {
2614
+ return false;
2615
+ }
2616
+ }
2617
+ if (!$this->_rmdir($path)) {
2618
+ return $this->setError(elFinder::ERROR_RM, $this->_path($path));
2619
+ }
2620
+
2621
+ } else {
2622
+ if (!$this->_unlink($path)) {
2623
+ return $this->setError(elFinder::ERROR_RM, $this->_path($path));
2624
+ }
2625
+ }
2626
+
2627
+ $this->removed[] = $stat;
2628
+ return true;
2629
+ }
2630
+
2631
+
2632
+ /************************* thumbnails **************************/
2633
+
2634
+ /**
2635
+ * Return thumbnail file name for required file
2636
+ *
2637
+ * @param array $stat file stat
2638
+ * @return string
2639
+ * @author Dmitry (dio) Levashov
2640
+ **/
2641
+ protected function tmbname($stat) {
2642
+ return $stat['hash'].$stat['ts'].'.png';
2643
+ }
2644
+
2645
+ /**
2646
+ * Return thumnbnail name if exists
2647
+ *
2648
+ * @param string $path file path
2649
+ * @param array $stat file stat
2650
+ * @return string|false
2651
+ * @author Dmitry (dio) Levashov
2652
+ **/
2653
+ protected function gettmb($path, $stat) {
2654
+ if ($this->tmbURL && $this->tmbPath) {
2655
+ // file itself thumnbnail
2656
+ if (strpos($path, $this->tmbPath) === 0) {
2657
+ return basename($path);
2658
+ }
2659
+
2660
+ $name = $this->tmbname($stat);
2661
+ if (file_exists($this->tmbPath.DIRECTORY_SEPARATOR.$name)) {
2662
+ return $name;
2663
+ }
2664
+ }
2665
+ return false;
2666
+ }
2667
+
2668
+ /**
2669
+ * Return true if thumnbnail for required file can be created
2670
+ *
2671
+ * @param string $path thumnbnail path
2672
+ * @param array $stat file stat
2673
+ * @return string|bool
2674
+ * @author Dmitry (dio) Levashov
2675
+ **/
2676
+ protected function canCreateTmb($path, $stat) {
2677
+ return $this->tmbPathWritable
2678
+ && strpos($path, $this->tmbPath) === false // do not create thumnbnail for thumnbnail
2679
+ && $this->imgLib
2680
+ && strpos($stat['mime'], 'image') === 0
2681
+ && ($this->imgLib == 'gd' ? $stat['mime'] == 'image/jpeg' || $stat['mime'] == 'image/png' || $stat['mime'] == 'image/gif' : true);
2682
+ }
2683
+
2684
+ /**
2685
+ * Return true if required file can be resized.
2686
+ * By default - the same as canCreateTmb
2687
+ *
2688
+ * @param string $path thumnbnail path
2689
+ * @param array $stat file stat
2690
+ * @return string|bool
2691
+ * @author Dmitry (dio) Levashov
2692
+ **/
2693
+ protected function canResize($path, $stat) {
2694
+ return $this->canCreateTmb($path, $stat);
2695
+ }
2696
+
2697
+ /**
2698
+ * Create thumnbnail and return it's URL on success
2699
+ *
2700
+ * @param string $path file path
2701
+ * @param string $mime file mime type
2702
+ * @return string|false
2703
+ * @author Dmitry (dio) Levashov
2704
+ **/
2705
+ protected function createTmb($path, $stat) {
2706
+ if (!$stat || !$this->canCreateTmb($path, $stat)) {
2707
+ return false;
2708
+ }
2709
+
2710
+ $name = $this->tmbname($stat);
2711
+ $tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$name;
2712
+
2713
+ // copy image into tmbPath so some drivers does not store files on local fs
2714
+ if (($src = $this->_fopen($path, 'rb')) == false) {
2715
+ return false;
2716
+ }
2717
+
2718
+ if (($trg = fopen($tmb, 'wb')) == false) {
2719
+ $this->_fclose($src, $path);
2720
+ return false;
2721
+ }
2722
+
2723
+ while (!feof($src)) {
2724
+ fwrite($trg, fread($src, 8192));
2725
+ }
2726
+
2727
+ $this->_fclose($src, $path);
2728
+ fclose($trg);
2729
+
2730
+ $result = false;
2731
+
2732
+ $tmbSize = $this->tmbSize;
2733
+
2734
+ if (($s = getimagesize($tmb)) == false) {
2735
+ return false;
2736
+ }
2737
+
2738
+ /* If image smaller or equal thumbnail size - just fitting to thumbnail square */
2739
+ if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) {
2740
+ $result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );
2741
+ } else {
2742
+
2743
+ if ($this->options['tmbCrop']) {
2744
+
2745
+ /* Resize and crop if image bigger than thumbnail */
2746
+ if (!(($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize) ) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) {
2747
+ $result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png');
2748
+ }
2749
+
2750
+ if (($s = getimagesize($tmb)) != false) {
2751
+ $x = $s[0] > $tmbSize ? intval(($s[0] - $tmbSize)/2) : 0;
2752
+ $y = $s[1] > $tmbSize ? intval(($s[1] - $tmbSize)/2) : 0;
2753
+ $result = $this->imgCrop($tmb, $tmbSize, $tmbSize, $x, $y, 'png');
2754
+ }
2755
+
2756
+ } else {
2757
+ $result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, 'png');
2758
+ }
2759
+
2760
+ $result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' );
2761
+ }
2762
+
2763
+ if (!$result) {
2764
+ unlink($tmb);
2765
+ return false;
2766
+ }
2767
+
2768
+ return $name;
2769
+ }
2770
+
2771
+ /**
2772
+ * Resize image
2773
+ *
2774
+ * @param string $path image file
2775
+ * @param int $width new width
2776
+ * @param int $height new height
2777
+ * @param bool $keepProportions crop image
2778
+ * @param bool $resizeByBiggerSide resize image based on bigger side if true
2779
+ * @param string $destformat image destination format
2780
+ * @return string|false
2781
+ * @author Dmitry (dio) Levashov
2782
+ * @author Alexey Sukhotin
2783
+ **/
2784
+ protected function imgResize($path, $width, $height, $keepProportions = false, $resizeByBiggerSide = true, $destformat = null) {
2785
+ if (($s = @getimagesize($path)) == false) {
2786
+ return false;
2787
+ }
2788
+
2789
+ $result = false;
2790
+
2791
+ list($size_w, $size_h) = array($width, $height);
2792
+
2793
+ if ($keepProportions == true) {
2794
+
2795
+ list($orig_w, $orig_h, $new_w, $new_h) = array($s[0], $s[1], $width, $height);
2796
+
2797
+ /* Calculating image scale width and height */
2798
+ $xscale = $orig_w / $new_w;
2799
+ $yscale = $orig_h / $new_h;
2800
+
2801
+ /* Resizing by biggest side */
2802
+
2803
+ if ($resizeByBiggerSide) {
2804
+
2805
+ if ($orig_w > $orig_h) {
2806
+ $size_h = $orig_h * $width / $orig_w;
2807
+ $size_w = $width;
2808
+ } else {
2809
+ $size_w = $orig_w * $height / $orig_h;
2810
+ $size_h = $height;
2811
+ }
2812
+
2813
+ } else {
2814
+ if ($orig_w > $orig_h) {
2815
+ $size_w = $orig_w * $height / $orig_h;
2816
+ $size_h = $height;
2817
+ } else {
2818
+ $size_h = $orig_h * $width / $orig_w;
2819
+ $size_w = $width;
2820
+ }
2821
+ }
2822
+ }
2823
+
2824
+ switch ($this->imgLib) {
2825
+ case 'imagick':
2826
+
2827
+ try {
2828
+ $img = new imagick($path);
2829
+ } catch (Exception $e) {
2830
+
2831
+ return false;
2832
+ }
2833
+
2834
+ $img->resizeImage($size_w, $size_h, Imagick::FILTER_LANCZOS, true);
2835
+
2836
+ $result = $img->writeImage($path);
2837
+
2838
+ return $result ? $path : false;
2839
+
2840
+ break;
2841
+
2842
+ case 'gd':
2843
+ $img = self::gdImageCreate($path,$s['mime']);
2844
+
2845
+ if ($img && false != ($tmp = imagecreatetruecolor($size_w, $size_h))) {
2846
+
2847
+ self::gdImageBackground($tmp,$this->options['tmbBgColor']);
2848
+
2849
+ if (!imagecopyresampled($tmp, $img, 0, 0, 0, 0, $size_w, $size_h, $s[0], $s[1])) {
2850
+ return false;
2851
+ }
2852
+
2853
+ $result = self::gdImage($tmp, $path, $destformat, $s['mime']);
2854
+
2855
+ imagedestroy($img);
2856
+ imagedestroy($tmp);
2857
+
2858
+ return $result ? $path : false;
2859
+
2860
+ }
2861
+ break;
2862
+ }
2863
+
2864
+ return false;
2865
+ }
2866
+
2867
+ /**
2868
+ * Crop image
2869
+ *
2870
+ * @param string $path image file
2871
+ * @param int $width crop width
2872
+ * @param int $height crop height
2873
+ * @param bool $x crop left offset
2874
+ * @param bool $y crop top offset
2875
+ * @param string $destformat image destination format
2876
+ * @return string|false
2877
+ * @author Dmitry (dio) Levashov
2878
+ * @author Alexey Sukhotin
2879
+ **/
2880
+ protected function imgCrop($path, $width, $height, $x, $y, $destformat = null) {
2881
+ if (($s = @getimagesize($path)) == false) {
2882
+ return false;
2883
+ }
2884
+
2885
+ $result = false;
2886
+
2887
+ switch ($this->imgLib) {
2888
+ case 'imagick':
2889
+
2890
+ try {
2891
+ $img = new imagick($path);
2892
+ } catch (Exception $e) {
2893
+
2894
+ return false;
2895
+ }
2896
+
2897
+ $img->cropImage($width, $height, $x, $y);
2898
+
2899
+ $result = $img->writeImage($path);
2900
+
2901
+ return $result ? $path : false;
2902
+
2903
+ break;
2904
+
2905
+ case 'gd':
2906
+ $img = self::gdImageCreate($path,$s['mime']);
2907
+
2908
+ if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) {
2909
+
2910
+ self::gdImageBackground($tmp,$this->options['tmbBgColor']);
2911
+
2912
+ $size_w = $width;
2913
+ $size_h = $height;
2914
+
2915
+ if ($s[0] < $width || $s[1] < $height) {
2916
+ $size_w = $s[0];
2917
+ $size_h = $s[1];
2918
+ }
2919
+
2920
+ if (!imagecopy($tmp, $img, 0, 0, $x, $y, $size_w, $size_h)) {
2921
+ return false;
2922
+ }
2923
+
2924
+ $result = self::gdImage($tmp, $path, $destformat, $s['mime']);
2925
+
2926
+ imagedestroy($img);
2927
+ imagedestroy($tmp);
2928
+
2929
+ return $result ? $path : false;
2930
+
2931
+ }
2932
+ break;
2933
+ }
2934
+
2935
+ return false;
2936
+ }
2937
+
2938
+ /**
2939
+ * Put image to square
2940
+ *
2941
+ * @param string $path image file
2942
+ * @param int $width square width
2943
+ * @param int $height square height
2944
+ * @param int $align reserved
2945
+ * @param int $valign reserved
2946
+ * @param string $bgcolor square background color in #rrggbb format
2947
+ * @param string $destformat image destination format
2948
+ * @return string|false
2949
+ * @author Dmitry (dio) Levashov
2950
+ * @author Alexey Sukhotin
2951
+ **/
2952
+ protected function imgSquareFit($path, $width, $height, $align = 'center', $valign = 'middle', $bgcolor = '#0000ff', $destformat = null) {
2953
+ if (($s = @getimagesize($path)) == false) {
2954
+ return false;
2955
+ }
2956
+
2957
+ $result = false;
2958
+
2959
+ /* Coordinates for image over square aligning */
2960
+ $y = ceil(abs($height - $s[1]) / 2);
2961
+ $x = ceil(abs($width - $s[0]) / 2);
2962
+
2963
+ switch ($this->imgLib) {
2964
+ case 'imagick':
2965
+ try {
2966
+ $img = new imagick($path);
2967
+ } catch (Exception $e) {
2968
+ return false;
2969
+ }
2970
+
2971
+ $img1 = new Imagick();
2972
+ $img1->newImage($width, $height, new ImagickPixel($bgcolor));
2973
+ $img1->setImageColorspace($img->getImageColorspace());
2974
+ $img1->setImageFormat($destformat != null ? $destformat : $img->getFormat());
2975
+ $img1->compositeImage( $img, imagick::COMPOSITE_OVER, $x, $y );
2976
+ $result = $img1->writeImage($path);
2977
+ return $result ? $path : false;
2978
+
2979
+ break;
2980
+
2981
+ case 'gd':
2982
+ $img = self::gdImageCreate($path,$s['mime']);
2983
+
2984
+ if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) {
2985
+
2986
+ self::gdImageBackground($tmp,$bgcolor);
2987
+
2988
+ if (!imagecopy($tmp, $img, $x, $y, 0, 0, $s[0], $s[1])) {
2989
+ return false;
2990
+ }
2991
+
2992
+ $result = self::gdImage($tmp, $path, $destformat, $s['mime']);
2993
+
2994
+ imagedestroy($img);
2995
+ imagedestroy($tmp);
2996
+
2997
+ return $result ? $path : false;
2998
+ }
2999
+ break;
3000
+ }
3001
+
3002
+ return false;
3003
+ }
3004
+
3005
+ /**
3006
+ * Rotate image
3007
+ *
3008
+ * @param string $path image file
3009
+ * @param int $degree rotete degrees
3010
+ * @param string $bgcolor square background color in #rrggbb format
3011
+ * @param string $destformat image destination format
3012
+ * @return string|false
3013
+ * @author nao-pon
3014
+ * @author Troex Nevelin
3015
+ **/
3016
+ protected function imgRotate($path, $degree, $bgcolor = '#ffffff', $destformat = null) {
3017
+ if (($s = @getimagesize($path)) == false) {
3018
+ return false;
3019
+ }
3020
+
3021
+ $result = false;
3022
+
3023
+ switch ($this->imgLib) {
3024
+ case 'imagick':
3025
+ try {
3026
+ $img = new imagick($path);
3027
+ } catch (Exception $e) {
3028
+ return false;
3029
+ }
3030
+
3031
+ $img->rotateImage(new ImagickPixel($bgcolor), $degree);
3032
+ $result = $img->writeImage($path);
3033
+ return $result ? $path : false;
3034
+
3035
+ break;
3036
+
3037
+ case 'gd':
3038
+ $img = self::gdImageCreate($path,$s['mime']);
3039
+
3040
+ $degree = 360 - $degree;
3041
+ list($r, $g, $b) = sscanf($bgcolor, "#%02x%02x%02x");
3042
+ $bgcolor = imagecolorallocate($img, $r, $g, $b);
3043
+ $tmp = imageRotate($img, $degree, (int)$bgcolor);
3044
+
3045
+ $result = self::gdImage($tmp, $path, $destformat, $s['mime']);
3046
+
3047
+ imageDestroy($img);
3048
+ imageDestroy($tmp);
3049
+
3050
+ return $result ? $path : false;
3051
+
3052
+ break;
3053
+ }
3054
+
3055
+ return false;
3056
+ }
3057
+
3058
+ /**
3059
+ * Execute shell command
3060
+ *
3061
+ * @param string $command command line
3062
+ * @param array $output stdout strings
3063
+ * @param array $return_var process exit code
3064
+ * @param array $error_output stderr strings
3065
+ * @return int exit code
3066
+ * @author Alexey Sukhotin
3067
+ **/
3068
+ protected function procExec($command , array &$output = null, &$return_var = -1, array &$error_output = null) {
3069
+
3070
+ $descriptorspec = array(
3071
+ 0 => array("pipe", "r"), // stdin
3072
+ 1 => array("pipe", "w"), // stdout
3073
+ 2 => array("pipe", "w") // stderr
3074
+ );
3075
+
3076
+ $process = proc_open($command, $descriptorspec, $pipes, null, null);
3077
+
3078
+ if (is_resource($process)) {
3079
+
3080
+ fclose($pipes[0]);
3081
+
3082
+ $tmpout = '';
3083
+ $tmperr = '';
3084
+
3085
+ $output = stream_get_contents($pipes[1]);
3086
+ $error_output = stream_get_contents($pipes[2]);
3087
+
3088
+ fclose($pipes[1]);
3089
+ fclose($pipes[2]);
3090
+ $return_var = proc_close($process);
3091
+
3092
+
3093
+ }
3094
+
3095
+ return $return_var;
3096
+
3097
+ }
3098
+
3099
+ /**
3100
+ * Remove thumbnail, also remove recursively if stat is directory
3101
+ *
3102
+ * @param string $stat file stat
3103
+ * @return void
3104
+ * @author Dmitry (dio) Levashov
3105
+ * @author Naoki Sawada
3106
+ * @author Troex Nevelin
3107
+ **/
3108
+ protected function rmTmb($stat) {
3109
+ if ($stat['mime'] === 'directory') {
3110
+ foreach ($this->_scandir($this->decode($stat['hash'])) as $p) {
3111
+ $name = $this->_basename($p);
3112
+ $name != '.' && $name != '..' && $this->rmTmb($this->stat($p));
3113
+ }
3114
+ } else if (!empty($stat['tmb']) && $stat['tmb'] != "1") {
3115
+ $tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$stat['tmb'];
3116
+ file_exists($tmb) && @unlink($tmb);
3117
+ clearstatcache();
3118
+ }
3119
+ }
3120
+
3121
+ /**
3122
+ * Create an gd image according to the specified mime type
3123
+ *
3124
+ * @param string $path image file
3125
+ * @param string $mime
3126
+ * @return gd image resource identifier
3127
+ */
3128
+ protected function gdImageCreate($path,$mime){
3129
+ switch($mime){
3130
+ case 'image/jpeg':
3131
+ return imagecreatefromjpeg($path);
3132
+
3133
+ case 'image/png':
3134
+ return imagecreatefrompng($path);
3135
+
3136
+ case 'image/gif':
3137
+ return imagecreatefromgif($path);
3138
+
3139
+ case 'image/xbm':
3140
+ return imagecreatefromxbm($path);
3141
+ }
3142
+ return false;
3143
+ }
3144
+
3145
+ /**
3146
+ * Output gd image to file
3147
+ *
3148
+ * @param resource $image gd image resource
3149
+ * @param string $filename The path to save the file to.
3150
+ * @param string $destformat The Image type to use for $filename
3151
+ * @param string $mime The original image mime type
3152
+ */
3153
+ protected function gdImage($image, $filename, $destformat, $mime ){
3154
+
3155
+ if ($destformat == 'jpg' || ($destformat == null && $mime == 'image/jpeg')) {
3156
+ return imagejpeg($image, $filename, 100);
3157
+ }
3158
+
3159
+ if ($destformat == 'gif' || ($destformat == null && $mime == 'image/gif')) {
3160
+ return imagegif($image, $filename, 7);
3161
+ }
3162
+
3163
+ return imagepng($image, $filename, 7);
3164
+ }
3165
+
3166
+ /**
3167
+ * Assign the proper background to a gd image
3168
+ *
3169
+ * @param resource $image gd image resource
3170
+ * @param string $bgcolor background color in #rrggbb format
3171
+ */
3172
+ protected function gdImageBackground($image, $bgcolor){
3173
+
3174
+ if( $bgcolor == 'transparent' ){
3175
+ imagesavealpha($image,true);
3176
+ $bgcolor1 = imagecolorallocatealpha($image, 255, 255, 255, 127);
3177
+
3178
+ }else{
3179
+ list($r, $g, $b) = sscanf($bgcolor, "#%02x%02x%02x");
3180
+ $bgcolor1 = imagecolorallocate($image, $r, $g, $b);
3181
+ }
3182
+
3183
+ imagefill($image, 0, 0, $bgcolor1);
3184
+ }
3185
+
3186
+ /*********************** misc *************************/
3187
+
3188
+ /**
3189
+ * Return smart formatted date
3190
+ *
3191
+ * @param int $ts file timestamp
3192
+ * @return string
3193
+ * @author Dmitry (dio) Levashov
3194
+ **/
3195
+ // protected function formatDate($ts) {
3196
+ // if ($ts > $this->today) {
3197
+ // return 'Today '.date($this->options['timeFormat'], $ts);
3198
+ // }
3199
+ //
3200
+ // if ($ts > $this->yesterday) {
3201
+ // return 'Yesterday '.date($this->options['timeFormat'], $ts);
3202
+ // }
3203
+ //
3204
+ // return date($this->options['dateFormat'], $ts);
3205
+ // }
3206
+
3207
+ /**
3208
+ * Find position of first occurrence of string in a string with multibyte support
3209
+ *
3210
+ * @param string $haystack The string being checked.
3211
+ * @param string $needle The string to find in haystack.
3212
+ * @param int $offset The search offset. If it is not specified, 0 is used.
3213
+ * @return int|bool
3214
+ * @author Alexey Sukhotin
3215
+ **/
3216
+ protected function stripos($haystack , $needle , $offset = 0) {
3217
+ if (function_exists('mb_stripos')) {
3218
+ return mb_stripos($haystack , $needle , $offset);
3219
+ } else if (function_exists('mb_strtolower') && function_exists('mb_strpos')) {
3220
+ return mb_strpos(mb_strtolower($haystack), mb_strtolower($needle), $offset);
3221
+ }
3222
+ return stripos($haystack , $needle , $offset);
3223
+ }
3224
+
3225
+ /**==================================* abstract methods *====================================**/
3226
+
3227
+ /*********************** paths/urls *************************/
3228
+
3229
+ /**
3230
+ * Return parent directory path
3231
+ *
3232
+ * @param string $path file path
3233
+ * @return string
3234
+ * @author Dmitry (dio) Levashov
3235
+ **/
3236
+ abstract protected function _dirname($path);
3237
+
3238
+ /**
3239
+ * Return file name
3240
+ *
3241
+ * @param string $path file path
3242
+ * @return string
3243
+ * @author Dmitry (dio) Levashov
3244
+ **/
3245
+ abstract protected function _basename($path);
3246
+
3247
+ /**
3248
+ * Join dir name and file name and return full path.
3249
+ * Some drivers (db) use int as path - so we give to concat path to driver itself
3250
+ *
3251
+ * @param string $dir dir path
3252
+ * @param string $name file name
3253
+ * @return string
3254
+ * @author Dmitry (dio) Levashov
3255
+ **/
3256
+ abstract protected function _joinPath($dir, $name);
3257
+
3258
+ /**
3259
+ * Return normalized path
3260
+ *
3261
+ * @param string $path file path
3262
+ * @return string
3263
+ * @author Dmitry (dio) Levashov
3264
+ **/
3265
+ abstract protected function _normpath($path);
3266
+
3267
+ /**
3268
+ * Return file path related to root dir
3269
+ *
3270
+ * @param string $path file path
3271
+ * @return string
3272
+ * @author Dmitry (dio) Levashov
3273
+ **/
3274
+ abstract protected function _relpath($path);
3275
+
3276
+ /**
3277
+ * Convert path related to root dir into real path
3278
+ *
3279
+ * @param string $path rel file path
3280
+ * @return string
3281
+ * @author Dmitry (dio) Levashov
3282
+ **/
3283
+ abstract protected function _abspath($path);
3284
+
3285
+ /**
3286
+ * Return fake path started from root dir.
3287
+ * Required to show path on client side.
3288
+ *
3289
+ * @param string $path file path
3290
+ * @return string
3291
+ * @author Dmitry (dio) Levashov
3292
+ **/
3293
+ abstract protected function _path($path);
3294
+
3295
+ /**
3296
+ * Return true if $path is children of $parent
3297
+ *
3298
+ * @param string $path path to check
3299
+ * @param string $parent parent path
3300
+ * @return bool
3301
+ * @author Dmitry (dio) Levashov
3302
+ **/
3303
+ abstract protected function _inpath($path, $parent);
3304
+
3305
+ /**
3306
+ * Return stat for given path.
3307
+ * Stat contains following fields:
3308
+ * - (int) size file size in b. required
3309
+ * - (int) ts file modification time in unix time. required
3310
+ * - (string) mime mimetype. required for folders, others - optionally
3311
+ * - (bool) read read permissions. required
3312
+ * - (bool) write write permissions. required
3313
+ * - (bool) locked is object locked. optionally
3314
+ * - (bool) hidden is object hidden. optionally
3315
+ * - (string) alias for symlinks - link target path relative to root path. optionally
3316
+ * - (string) target for symlinks - link target path. optionally
3317
+ *
3318
+ * If file does not exists - returns empty array or false.
3319
+ *
3320
+ * @param string $path file path
3321
+ * @return array|false
3322
+ * @author Dmitry (dio) Levashov
3323
+ **/
3324
+ abstract protected function _stat($path);
3325
+
3326
+
3327
+ /***************** file stat ********************/
3328
+
3329
+
3330
+ /**
3331
+ * Return true if path is dir and has at least one childs directory
3332
+ *
3333
+ * @param string $path dir path
3334
+ * @return bool
3335
+ * @author Dmitry (dio) Levashov
3336
+ **/
3337
+ abstract protected function _subdirs($path);
3338
+
3339
+ /**
3340
+ * Return object width and height
3341
+ * Ususaly used for images, but can be realize for video etc...
3342
+ *
3343
+ * @param string $path file path
3344
+ * @param string $mime file mime type
3345
+ * @return string
3346
+ * @author Dmitry (dio) Levashov
3347
+ **/
3348
+ abstract protected function _dimensions($path, $mime);
3349
+
3350
+ /******************** file/dir content *********************/
3351
+
3352
+ /**
3353
+ * Return files list in directory
3354
+ *
3355
+ * @param string $path dir path
3356
+ * @return array
3357
+ * @author Dmitry (dio) Levashov
3358
+ **/
3359
+ abstract protected function _scandir($path);
3360
+
3361
+ /**
3362
+ * Open file and return file pointer
3363
+ *
3364
+ * @param string $path file path
3365
+ * @param bool $write open file for writing
3366
+ * @return resource|false
3367
+ * @author Dmitry (dio) Levashov
3368
+ **/
3369
+ abstract protected function _fopen($path, $mode="rb");
3370
+
3371
+ /**
3372
+ * Close opened file
3373
+ *
3374
+ * @param resource $fp file pointer
3375
+ * @param string $path file path
3376
+ * @return bool
3377
+ * @author Dmitry (dio) Levashov
3378
+ **/
3379
+ abstract protected function _fclose($fp, $path='');
3380
+
3381
+ /******************** file/dir manipulations *************************/
3382
+
3383
+ /**
3384
+ * Create dir and return created dir path or false on failed
3385
+ *
3386
+ * @param string $path parent dir path
3387
+ * @param string $name new directory name
3388
+ * @return string|bool
3389
+ * @author Dmitry (dio) Levashov
3390
+ **/
3391
+ abstract protected function _mkdir($path, $name);
3392
+
3393
+ /**
3394
+ * Create file and return it's path or false on failed
3395
+ *
3396
+ * @param string $path parent dir path
3397
+ * @param string $name new file name
3398
+ * @return string|bool
3399
+ * @author Dmitry (dio) Levashov
3400
+ **/
3401
+ abstract protected function _mkfile($path, $name);
3402
+
3403
+ /**
3404
+ * Create symlink
3405
+ *
3406
+ * @param string $source file to link to
3407
+ * @param string $targetDir folder to create link in
3408
+ * @param string $name symlink name
3409
+ * @return bool
3410
+ * @author Dmitry (dio) Levashov
3411
+ **/
3412
+ abstract protected function _symlink($source, $targetDir, $name);
3413
+
3414
+ /**
3415
+ * Copy file into another file (only inside one volume)
3416
+ *
3417
+ * @param string $source source file path
3418
+ * @param string $target target dir path
3419
+ * @param string $name file name
3420
+ * @return bool
3421
+ * @author Dmitry (dio) Levashov
3422
+ **/
3423
+ abstract protected function _copy($source, $targetDir, $name);
3424
+
3425
+ /**
3426
+ * Move file into another parent dir.
3427
+ * Return new file path or false.
3428
+ *
3429
+ * @param string $source source file path
3430
+ * @param string $target target dir path
3431
+ * @param string $name file name
3432
+ * @return string|bool
3433
+ * @author Dmitry (dio) Levashov
3434
+ **/
3435
+ abstract protected function _move($source, $targetDir, $name);
3436
+
3437
+ /**
3438
+ * Remove file
3439
+ *
3440
+ * @param string $path file path
3441
+ * @return bool
3442
+ * @author Dmitry (dio) Levashov
3443
+ **/
3444
+ abstract protected function _unlink($path);
3445
+
3446
+ /**
3447
+ * Remove dir
3448
+ *
3449
+ * @param string $path dir path
3450
+ * @return bool
3451
+ * @author Dmitry (dio) Levashov
3452
+ **/
3453
+ abstract protected function _rmdir($path);
3454
+
3455
+ /**
3456
+ * Create new file and write into it from file pointer.
3457
+ * Return new file path or false on error.
3458
+ *
3459
+ * @param resource $fp file pointer
3460
+ * @param string $dir target dir path
3461
+ * @param string $name file name
3462
+ * @param array $stat file stat (required by some virtual fs)
3463
+ * @return bool|string
3464
+ * @author Dmitry (dio) Levashov
3465
+ **/
3466
+ abstract protected function _save($fp, $dir, $name, $stat);
3467
+
3468
+ /**
3469
+ * Get file contents
3470
+ *
3471
+ * @param string $path file path
3472
+ * @return string|false
3473
+ * @author Dmitry (dio) Levashov
3474
+ **/
3475
+ abstract protected function _getContents($path);
3476
+
3477
+ /**
3478
+ * Write a string to a file
3479
+ *
3480
+ * @param string $path file path
3481
+ * @param string $content new file content
3482
+ * @return bool
3483
+ * @author Dmitry (dio) Levashov
3484
+ **/
3485
+ abstract protected function _filePutContents($path, $content);
3486
+
3487
+ /**
3488
+ * Extract files from archive
3489
+ *
3490
+ * @param string $path file path
3491
+ * @param array $arc archiver options
3492
+ * @return bool
3493
+ * @author Dmitry (dio) Levashov,
3494
+ * @author Alexey Sukhotin
3495
+ **/
3496
+ abstract protected function _extract($path, $arc);
3497
+
3498
+ /**
3499
+ * Create archive and return its path
3500
+ *
3501
+ * @param string $dir target dir
3502
+ * @param array $files files names list
3503
+ * @param string $name archive name
3504
+ * @param array $arc archiver options
3505
+ * @return string|bool
3506
+ * @author Dmitry (dio) Levashov,
3507
+ * @author Alexey Sukhotin
3508
+ **/
3509
+ abstract protected function _archive($dir, $files, $name, $arc);
3510
+
3511
+ /**
3512
+ * Detect available archivers
3513
+ *
3514
+ * @return void
3515
+ * @author Dmitry (dio) Levashov,
3516
+ * @author Alexey Sukhotin
3517
+ **/
3518
+ abstract protected function _checkArchivers();
3519
+
3520
+ } // END class