my_admin 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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