imagine_cms 3.0.0.beta6 → 3.0.0.beta7

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 (278) hide show
  1. data/README.rdoc +1 -1
  2. data/app/assets/images/codepress/line-numbers.png +0 -0
  3. data/app/assets/images/cropper/marqueeHoriz.gif +0 -0
  4. data/app/assets/images/cropper/marqueeVert.gif +0 -0
  5. data/app/assets/images/management/btn_add.gif +0 -0
  6. data/app/assets/images/management/btn_archive.gif +0 -0
  7. data/app/assets/images/management/btn_delete.gif +0 -0
  8. data/app/assets/images/management/btn_duplicate.gif +0 -0
  9. data/app/assets/images/management/btn_edit.gif +0 -0
  10. data/app/assets/images/management/btn_help.gif +0 -0
  11. data/app/assets/images/management/btn_new_page.gif +0 -0
  12. data/app/assets/images/management/btn_preview.gif +0 -0
  13. data/app/assets/images/management/btn_properties.gif +0 -0
  14. data/app/assets/images/management/btn_restore.gif +0 -0
  15. data/app/assets/images/management/btn_top_delete.gif +0 -0
  16. data/app/assets/images/management/btn_top_duplicate.gif +0 -0
  17. data/app/assets/images/management/btn_top_edit.gif +0 -0
  18. data/app/assets/images/management/btn_top_new.gif +0 -0
  19. data/app/assets/images/management/btn_top_preview.gif +0 -0
  20. data/app/assets/images/management/btn_top_properties.gif +0 -0
  21. data/app/assets/{manage → images/management}/bullet.gif +0 -0
  22. data/app/assets/images/management/cvv2_graphic.gif +0 -0
  23. data/app/assets/images/management/error.gif +0 -0
  24. data/app/assets/images/management/gallery_index.gif +0 -0
  25. data/app/assets/images/management/gallery_preview_overlay.png +0 -0
  26. data/app/assets/images/management/gallery_small_drag_overlay.png +0 -0
  27. data/app/assets/images/management/gallery_small_overlay.png +0 -0
  28. data/app/assets/images/management/gallery_sort.gif +0 -0
  29. data/app/assets/images/management/icon_download.gif +0 -0
  30. data/app/assets/images/management/icon_locked.png +0 -0
  31. data/app/assets/images/management/icon_page.gif +0 -0
  32. data/app/assets/images/management/icon_time.gif +0 -0
  33. data/app/assets/images/management/icon_unlocked.png +0 -0
  34. data/app/assets/images/management/page_loading.gif +0 -0
  35. data/app/assets/{manage → images/management}/start.gif +0 -0
  36. data/app/assets/images/management/vcard.gif +0 -0
  37. data/app/assets/javascripts/builder.js +101 -0
  38. data/app/assets/javascripts/codepress/codepress.html +36 -0
  39. data/app/assets/javascripts/codepress/codepress.js +130 -0
  40. data/app/assets/javascripts/codepress/engines/gecko.js +240 -0
  41. data/{vendor/gems/acts_as_tree/test/abstract_unit.rb → app/assets/javascripts/codepress/engines/khtml.js} +0 -0
  42. data/app/assets/javascripts/codepress/engines/msie.js +263 -0
  43. data/{vendor/gems/acts_as_tree/test/database.yml → app/assets/javascripts/codepress/engines/older.js} +0 -0
  44. data/app/assets/javascripts/codepress/engines/opera.js +259 -0
  45. data/app/assets/javascripts/codepress/languages/css.js +23 -0
  46. data/app/assets/javascripts/codepress/languages/generic.js +25 -0
  47. data/app/assets/javascripts/codepress/languages/html.js +63 -0
  48. data/app/assets/javascripts/codepress/languages/java.js +24 -0
  49. data/app/assets/javascripts/codepress/languages/javascript.js +30 -0
  50. data/app/assets/javascripts/codepress/languages/perl.js +27 -0
  51. data/app/assets/javascripts/codepress/languages/php.js +60 -0
  52. data/app/assets/javascripts/codepress/languages/ruby.js +26 -0
  53. data/app/assets/javascripts/codepress/languages/sql.js +30 -0
  54. data/app/assets/javascripts/codepress/languages/text.js +9 -0
  55. data/app/assets/javascripts/cropper.js +568 -0
  56. data/app/assets/javascripts/dojo/dojo.js +14155 -0
  57. data/app/assets/javascripts/dojo/src/html/images/shadowB.png +0 -0
  58. data/app/assets/javascripts/dojo/src/html/images/shadowBL.png +0 -0
  59. data/app/assets/javascripts/dojo/src/html/images/shadowBR.png +0 -0
  60. data/app/assets/javascripts/dojo/src/html/images/shadowL.png +0 -0
  61. data/app/assets/javascripts/dojo/src/html/images/shadowR.png +0 -0
  62. data/app/assets/javascripts/dojo/src/html/images/shadowT.png +0 -0
  63. data/app/assets/javascripts/dojo/src/html/images/shadowTL.png +0 -0
  64. data/app/assets/javascripts/dojo/src/html/images/shadowTR.png +0 -0
  65. data/app/assets/javascripts/dojo/src/widget/templates/Editor2/showtableborder_gecko.css +19 -0
  66. data/app/assets/javascripts/dojo/src/widget/templates/HslColorPicker.svg +30 -0
  67. data/app/assets/javascripts/dojo/src/widget/templates/buttons/aggregate.gif +0 -0
  68. data/app/assets/javascripts/dojo/src/widget/templates/buttons/aggregate.psd +0 -0
  69. data/app/assets/javascripts/dojo/src/widget/templates/buttons/backcolor.gif +0 -0
  70. data/app/assets/javascripts/dojo/src/widget/templates/buttons/bg-fade.png +0 -0
  71. data/app/assets/javascripts/dojo/src/widget/templates/buttons/bold.gif +0 -0
  72. data/app/assets/javascripts/dojo/src/widget/templates/buttons/cancel.gif +0 -0
  73. data/app/assets/javascripts/dojo/src/widget/templates/buttons/copy.gif +0 -0
  74. data/app/assets/javascripts/dojo/src/widget/templates/buttons/createlink.gif +0 -0
  75. data/app/assets/javascripts/dojo/src/widget/templates/buttons/cut.gif +0 -0
  76. data/app/assets/javascripts/dojo/src/widget/templates/buttons/delete.gif +0 -0
  77. data/app/assets/javascripts/dojo/src/widget/templates/buttons/forecolor.gif +0 -0
  78. data/app/assets/javascripts/dojo/src/widget/templates/buttons/hilitecolor.gif +0 -0
  79. data/app/assets/javascripts/dojo/src/widget/templates/buttons/indent.gif +0 -0
  80. data/app/assets/javascripts/dojo/src/widget/templates/buttons/inserthorizontalrule.gif +0 -0
  81. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertimage.gif +0 -0
  82. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertorderedlist.gif +0 -0
  83. data/app/assets/javascripts/dojo/src/widget/templates/buttons/inserttable.gif +0 -0
  84. data/app/assets/javascripts/dojo/src/widget/templates/buttons/insertunorderedlist.gif +0 -0
  85. data/app/assets/javascripts/dojo/src/widget/templates/buttons/italic.gif +0 -0
  86. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifycenter.gif +0 -0
  87. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyfull.gif +0 -0
  88. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyleft.gif +0 -0
  89. data/app/assets/javascripts/dojo/src/widget/templates/buttons/justifyright.gif +0 -0
  90. data/app/assets/javascripts/dojo/src/widget/templates/buttons/left_to_right.gif +0 -0
  91. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_bullet_indent.gif +0 -0
  92. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_bullet_outdent.gif +0 -0
  93. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_num_indent.gif +0 -0
  94. data/app/assets/javascripts/dojo/src/widget/templates/buttons/list_num_outdent.gif +0 -0
  95. data/app/assets/javascripts/dojo/src/widget/templates/buttons/outdent.gif +0 -0
  96. data/app/assets/javascripts/dojo/src/widget/templates/buttons/paste.gif +0 -0
  97. data/app/assets/javascripts/dojo/src/widget/templates/buttons/redo.gif +0 -0
  98. data/app/assets/javascripts/dojo/src/widget/templates/buttons/removeformat.gif +0 -0
  99. data/app/assets/javascripts/dojo/src/widget/templates/buttons/right_to_left.gif +0 -0
  100. data/app/assets/javascripts/dojo/src/widget/templates/buttons/save.gif +0 -0
  101. data/app/assets/javascripts/dojo/src/widget/templates/buttons/sep.gif +0 -0
  102. data/app/assets/javascripts/dojo/src/widget/templates/buttons/space.gif +0 -0
  103. data/app/assets/javascripts/dojo/src/widget/templates/buttons/strikethrough.gif +0 -0
  104. data/app/assets/javascripts/dojo/src/widget/templates/buttons/subscript.gif +0 -0
  105. data/app/assets/javascripts/dojo/src/widget/templates/buttons/superscript.gif +0 -0
  106. data/app/assets/javascripts/dojo/src/widget/templates/buttons/underline.gif +0 -0
  107. data/app/assets/javascripts/dojo/src/widget/templates/buttons/undo.gif +0 -0
  108. data/app/assets/javascripts/dojo/src/widget/templates/buttons/wikiword.gif +0 -0
  109. data/app/assets/javascripts/dojo/src/widget/templates/check.gif +0 -0
  110. data/app/assets/javascripts/dojo/src/widget/templates/decrementMonth.gif +0 -0
  111. data/app/assets/javascripts/dojo/src/widget/templates/decrementWeek.gif +0 -0
  112. data/app/assets/javascripts/dojo/src/widget/templates/grabCorner.gif +0 -0
  113. data/app/assets/javascripts/dojo/src/widget/templates/images/floatingPaneClose.gif +0 -0
  114. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaAccordionOff.gif +0 -0
  115. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaAccordionSelected.gif +0 -0
  116. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-c.gif +0 -0
  117. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-l.gif +0 -0
  118. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaActive-r.gif +0 -0
  119. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaBarBg.gif +0 -0
  120. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-c.gif +0 -0
  121. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-l.gif +0 -0
  122. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaButton-r.gif +0 -0
  123. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-c.gif +0 -0
  124. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-l.gif +0 -0
  125. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaDisabled-r.gif +0 -0
  126. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaMenuBg.gif +0 -0
  127. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-c.gif +0 -0
  128. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-l.gif +0 -0
  129. data/app/assets/javascripts/dojo/src/widget/templates/images/soriaPressed-r.gif +0 -0
  130. data/app/assets/javascripts/dojo/src/widget/templates/images/tab_close.gif +0 -0
  131. data/app/assets/javascripts/dojo/src/widget/templates/images/toolbar-bg.gif +0 -0
  132. data/app/assets/javascripts/dojo/src/widget/templates/incrementMonth.gif +0 -0
  133. data/app/assets/javascripts/dojo/src/widget/templates/incrementWeek.gif +0 -0
  134. data/app/assets/javascripts/dojo/src/widget/templates/richtextframe.html +24 -0
  135. data/app/assets/javascripts/imagine.js +1385 -0
  136. data/app/assets/javascripts/jquery_no_conflict.js +9405 -0
  137. data/app/assets/stylesheets/codepress/codepress.css +7 -0
  138. data/app/assets/stylesheets/codepress/languages/css.css +10 -0
  139. data/app/assets/stylesheets/codepress/languages/generic.css +9 -0
  140. data/app/assets/stylesheets/codepress/languages/html.css +18 -0
  141. data/app/assets/stylesheets/codepress/languages/java.css +7 -0
  142. data/app/assets/stylesheets/codepress/languages/javascript.css +8 -0
  143. data/app/assets/stylesheets/codepress/languages/perl.css +11 -0
  144. data/app/assets/stylesheets/codepress/languages/php.css +12 -0
  145. data/app/assets/stylesheets/codepress/languages/ruby.css +10 -0
  146. data/app/assets/stylesheets/codepress/languages/sql.css +10 -0
  147. data/app/assets/stylesheets/codepress/languages/text.css +5 -0
  148. data/app/assets/stylesheets/cropper.css +182 -0
  149. data/app/assets/stylesheets/management.css +96 -0
  150. data/app/assets/stylesheets/reset.css +58 -0
  151. data/app/controllers/cms/content_controller.rb +318 -2
  152. data/app/controllers/management/cms_controller.rb +1669 -0
  153. data/app/controllers/management/user_controller.rb +4 -4
  154. data/app/controllers/management/users_controller.rb +18 -4
  155. data/app/controllers/util_controller.rb +45 -0
  156. data/app/helpers/cms_application_helper.rb +662 -15
  157. data/app/models/cms_content_sweeper.rb +21 -0
  158. data/app/models/cms_page.rb +126 -0
  159. data/app/models/cms_page_object.rb +23 -0
  160. data/app/models/cms_page_tag.rb +5 -0
  161. data/app/models/cms_page_version.rb +3 -0
  162. data/app/models/cms_snippet.rb +16 -0
  163. data/app/models/cms_template.rb +29 -0
  164. data/app/models/user.rb +6 -3
  165. data/app/views/management/cms/_complete_gallery.html.erb +5 -0
  166. data/app/views/management/cms/_create_file_link.html.erb +21 -0
  167. data/app/views/management/cms/_crop_feature_image.html.erb +188 -0
  168. data/app/views/management/cms/_crop_image.html.erb +188 -0
  169. data/app/views/management/cms/_crop_results.html.erb +1 -0
  170. data/app/views/management/cms/_crop_results_feature_image.html.erb +1 -0
  171. data/app/views/management/cms/_crop_results_thumb.html.erb +1 -0
  172. data/app/views/management/cms/_crop_thumb.html.erb +188 -0
  173. data/app/views/management/cms/_dialogs.html.erb +39 -0
  174. data/app/views/management/cms/_edit_page.html.erb +176 -0
  175. data/app/views/management/cms/_gallery_index.html.erb +10 -0
  176. data/app/views/management/cms/_gallery_setup.html.erb +22 -0
  177. data/app/views/management/cms/_image.html.erb +3 -0
  178. data/app/views/management/cms/_image_details.html.erb +26 -0
  179. data/app/views/management/cms/_image_draggable.html.erb +4 -0
  180. data/app/views/management/cms/_list_page.html.erb +8 -0
  181. data/app/views/management/cms/_list_page_select.html.erb +8 -0
  182. data/app/views/management/cms/_list_pages.html.erb +1 -0
  183. data/app/views/management/cms/_list_pages_select.html.erb +1 -0
  184. data/app/views/management/cms/_page_attribute.html.erb +6 -0
  185. data/app/views/management/cms/_page_list.html.erb +171 -0
  186. data/app/views/management/cms/_page_list_source_folder.html.erb +20 -0
  187. data/app/views/management/cms/_page_list_source_tag.html.erb +18 -0
  188. data/app/views/management/cms/_select_gallery.html.erb +117 -0
  189. data/app/views/management/cms/_snippet.html.erb +3 -0
  190. data/app/views/management/cms/_sort_images.html.erb +15 -0
  191. data/app/views/management/cms/_temp.html.erb +3 -0
  192. data/app/views/management/cms/_template_options.html.erb +21 -0
  193. data/app/views/management/cms/_template_reference.html.erb +42 -0
  194. data/app/views/management/cms/_upload_feature_image.html.erb +35 -0
  195. data/app/views/management/cms/_upload_file.html.erb +31 -0
  196. data/app/views/management/cms/_upload_image.html.erb +74 -0
  197. data/app/views/management/cms/_upload_thumb.html.erb +35 -0
  198. data/app/views/management/cms/edit_master.html.erb +48 -0
  199. data/app/views/management/cms/edit_page_content.html.erb +4 -0
  200. data/app/views/management/cms/edit_snippet.html.erb +47 -0
  201. data/app/views/management/cms/edit_template.html.erb +48 -0
  202. data/app/views/management/cms/gallery_management.html.erb +108 -0
  203. data/app/views/management/cms/index.html.erb +20 -0
  204. data/app/views/management/cms/page_tags_for_lookup.html.erb +5 -0
  205. data/app/views/management/cms/pages.html.erb +99 -0
  206. data/app/views/management/cms/permission_denied.html.erb +1 -0
  207. data/app/views/management/cms/select_page.html.erb +57 -0
  208. data/app/views/management/cms/snippets.html.erb +14 -0
  209. data/app/views/management/cms/templates.html.erb +14 -0
  210. data/app/views/management/cms/toolbar_edit.html.erb +269 -0
  211. data/app/views/management/cms/toolbar_preview.html.erb +109 -0
  212. data/app/views/util/_calendar_days.html.erb +72 -0
  213. data/app/views/util/_calendar_month_year.html.erb +1 -0
  214. data/app/views/util/_date_picker.html.erb +56 -0
  215. data/app/views/util/_message.html.erb +1 -0
  216. data/app/views/util/_show_message.js.erb +6 -0
  217. data/app/views/util/_tab.html.erb +4 -0
  218. data/config/routes.rb +4 -1
  219. data/imagine_cms.gemspec +4 -0
  220. data/{vendor/gems → lib}/acts_as_versioned/.document +0 -0
  221. data/{vendor/gems → lib}/acts_as_versioned/.gitignore +2 -0
  222. data/{vendor/gems → lib}/acts_as_versioned/CHANGELOG +0 -0
  223. data/lib/acts_as_versioned/Gemfile +7 -0
  224. data/{vendor/gems → lib}/acts_as_versioned/MIT-LICENSE +0 -0
  225. data/{vendor/gems → lib}/acts_as_versioned/README +0 -0
  226. data/{vendor/gems → lib}/acts_as_versioned/RUNNING_UNIT_TESTS +0 -0
  227. data/{vendor/gems → lib}/acts_as_versioned/Rakefile +1 -1
  228. data/{vendor/gems → lib}/acts_as_versioned/acts_as_versioned.gemspec +4 -4
  229. data/{vendor/gems → lib}/acts_as_versioned/init.rb +0 -0
  230. data/{vendor/gems → lib}/acts_as_versioned/lib/acts_as_versioned.rb +109 -107
  231. data/{vendor/gems → lib}/acts_as_versioned/test/abstract_unit.rb +0 -0
  232. data/{vendor/gems → lib}/acts_as_versioned/test/database.yml +0 -0
  233. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/authors.yml +0 -0
  234. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmark.rb +0 -0
  235. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmark_versions.yml +0 -0
  236. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/landmarks.yml +0 -0
  237. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/locked_pages.yml +0 -0
  238. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/locked_pages_revisions.yml +0 -0
  239. data/{vendor/gems/acts_as_versioned/test/fixtures/migrations/1_add_versioned_tables.rb → lib/acts_as_versioned/test/fixtures/migrations/2_add_versioned_tables.rb} +0 -0
  240. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/page.rb +0 -0
  241. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/page_versions.yml +0 -0
  242. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/pages.yml +0 -0
  243. data/{vendor/gems → lib}/acts_as_versioned/test/fixtures/widget.rb +0 -0
  244. data/{vendor/gems → lib}/acts_as_versioned/test/migration_test.rb +0 -1
  245. data/{vendor/gems → lib}/acts_as_versioned/test/schema.rb +0 -0
  246. data/{vendor/gems → lib}/acts_as_versioned/test/versioned_test.rb +0 -0
  247. data/lib/extensions/action_controller.rb +154 -143
  248. data/lib/imagine_cms/engine.rb +33 -12
  249. data/lib/imagine_cms/version.rb +1 -1
  250. data/lib/imagine_cms.rb +30 -6
  251. data/lib/prototype_legacy_helper/README.markdown +13 -0
  252. data/lib/prototype_legacy_helper/init.rb +1 -0
  253. data/lib/prototype_legacy_helper/lib/prototype_legacy_helper.rb +430 -0
  254. data/lib/prototype_legacy_helper/test/test_prototype_helper.rb +297 -0
  255. data/lib/upload_progress/CHANGELOG +5 -0
  256. data/lib/upload_progress/MIT-LICENSE +20 -0
  257. data/lib/upload_progress/README +45 -0
  258. data/{vendor/gems/acts_as_tree → lib/upload_progress}/Rakefile +6 -5
  259. data/lib/upload_progress/init.rb +7 -0
  260. data/lib/upload_progress/lib/multipart_progress.rb +176 -0
  261. data/lib/upload_progress/lib/progress.rb +145 -0
  262. data/lib/upload_progress/lib/upload_progress.rb +303 -0
  263. data/lib/upload_progress/lib/upload_progress_helper.rb +425 -0
  264. data/lib/upload_progress/public/stylesheets/upload_progress.css +21 -0
  265. data/lib/upload_progress/test/multipart_progress_testx.rb +364 -0
  266. data/lib/upload_progress/test/upload_progress_helper_testx.rb +134 -0
  267. data/lib/upload_progress/test/upload_progress_testx.rb +88 -0
  268. metadata +305 -43
  269. data/app/assets/manage/btn_delete.gif +0 -0
  270. data/vendor/gems/.DS_Store +0 -0
  271. data/vendor/gems/acts_as_tree/README +0 -26
  272. data/vendor/gems/acts_as_tree/init.rb +0 -1
  273. data/vendor/gems/acts_as_tree/lib/active_record/acts/tree.rb +0 -96
  274. data/vendor/gems/acts_as_tree/test/acts_as_tree_test.rb +0 -219
  275. data/vendor/gems/acts_as_tree/test/fixtures/mixin.rb +0 -0
  276. data/vendor/gems/acts_as_tree/test/fixtures/mixins.yml +0 -0
  277. data/vendor/gems/acts_as_tree/test/schema.rb +0 -0
  278. data/vendor/gems/acts_as_versioned/Gemfile +0 -7
@@ -0,0 +1,1669 @@
1
+ class Management::CmsController < Management::ApplicationController # :nodoc:
2
+ before_filter :check_permissions
3
+ before_filter :block_basic_users, :except => [
4
+ :index, :edit_page_content,
5
+ :include_codepress, :disable_caching, :garbage_collect,
6
+ :select_page, :list_pages_select, :request_review,
7
+ :toolbar_preview, :toolbar_edit,
8
+
9
+ :create_file_link, :upload_file, :receive_file,
10
+
11
+ :upload_image, :receive_image, :crop_image, :save_crop, :upload_status,
12
+ :upload_thumb, :crop_thumb, :save_crop_thumb,
13
+ :upload_feature_image, :crop_feature_image, :save_crop_feature_image,
14
+
15
+ :receive_gallery, :complete_gallery, :gallery_setup, :add_to_gallery,
16
+ :gallery_management, :select_gallery, :set_gallery_order, :save_gallery_settings,
17
+ :sort_images, :sort_images_save,
18
+ :image_details, :update_caption,
19
+ :delete_photo, :delete_gallery,
20
+
21
+ :pages, :list_pages, :edit_page, :page_attribute, :set_page_version
22
+ ]
23
+
24
+ before_filter :convert_invalid_chars_in_params
25
+
26
+ upload_status_for :receive_image
27
+ upload_status_for :add_to_gallery
28
+
29
+ cache_sweeper :cms_content_sweeper
30
+
31
+ def check_permissions
32
+ if !user_has_permission?(:manage_cms)
33
+ render '/errors/permission_denied'
34
+ return false
35
+ end
36
+ end
37
+
38
+ def block_basic_users
39
+ return true unless UseCmsAccessLevels
40
+ unless user_has_permission?(:manage_cms_full_access) && @user.cms_allowed_sections.to_s.strip.blank?
41
+ render '/errors/permission_denied'
42
+ return false
43
+ end
44
+ end
45
+
46
+ def validate_user_access
47
+ unless @user.cms_allowed_sections.to_s.strip.blank?
48
+ allowed_sections = @user.cms_allowed_sections.split(',').map { |s| s.strip }.reject { |s| s.blank? }
49
+ if @pg
50
+ path = '/' + @pg.path
51
+ else
52
+ parent = CmsPage.find_by_id(params[:parent_id] || params[:pg][:parent_id]) rescue nil
53
+ return false if !parent
54
+ path = '/' + parent.path
55
+ end
56
+
57
+ allowed = false
58
+ allowed_sections.each { |s| allowed ||= (path =~ /^#{s}/) }
59
+
60
+ if !allowed
61
+ respond_to do |wants|
62
+ wants.js { render :text => "Sorry, you don't have permission to edit this page." }
63
+ wants.html { redirect_to "/#{@pg.path}#{@pg.path == '' ? '' : '/'}version/#{@pg.version}" }
64
+ end
65
+ return false
66
+ end
67
+ end
68
+
69
+ return true
70
+ end
71
+
72
+
73
+ def index
74
+ end
75
+
76
+ def templates
77
+ @temps = CmsTemplate.find(:all, :order => 'name')
78
+ end
79
+
80
+ def edit_template
81
+ @temp = CmsTemplate.find_by_id(params[:id]) || CmsTemplate.new
82
+
83
+ if request.post?
84
+ @temp.assign_attributes(params[:temp])
85
+
86
+ begin
87
+ @pg = CmsPage.new
88
+ @page_objects = HashObject.new
89
+ render_to_string :inline => @temp.content
90
+ rescue Exception => e
91
+ message = e.message
92
+ flash.now[:error] = "<pre>#{ERB::Util.html_escape(message)}</pre>".html_safe
93
+ logger.debug e
94
+ return
95
+ end
96
+
97
+ # this must come after the render_to_string so that we capture template
98
+ # options embedded in snippets
99
+ @temp.options = @template_options
100
+
101
+ if !@temp.save
102
+ flash.now[:error] = @temp.errors.full_messages.join('<br/>')
103
+ else
104
+ flash[:notice] = 'Template saved.'
105
+ redirect_to :action => 'edit_template', :id => @temp.id and return
106
+ end
107
+ end
108
+ end
109
+
110
+ def snippets
111
+ @snippets = CmsSnippet.find(:all, :order => 'name')
112
+ end
113
+
114
+ def edit_snippet
115
+ @snip = CmsSnippet.find_by_id(params[:id]) || CmsSnippet.new
116
+
117
+ if request.post?
118
+ @snip.assign_attributes(params[:snip])
119
+
120
+ begin
121
+ @pg = CmsPage.new
122
+ @page_objects = HashObject.new
123
+ render_to_string :inline => @snip.content
124
+ rescue Exception => e
125
+ message = e.message
126
+ flash.now[:error] = "<pre>#{ERB::Util.html_escape(message)}</pre>".html_safe
127
+ logger.debug e
128
+ return
129
+ end
130
+
131
+ if !@snip.save
132
+ @error = @snip.errors.full_messages.join('<br/>')
133
+ else
134
+ flash[:notice] = 'Snippet saved.'
135
+ redirect_to :action => 'edit_snippet', :id => @snip.id and return
136
+ end
137
+ end
138
+ end
139
+
140
+ def edit_master
141
+ @file_type = case params[:id]
142
+ when 'template' then 'html'
143
+ when 'web_stylesheet', 'print_stylesheet' then 'css'
144
+ else nil
145
+ end
146
+
147
+ filename = case params[:id]
148
+ when 'template' then File.join('app', 'views', 'layouts', 'application.rhtml')
149
+ when 'web_stylesheet' then File.join('public', 'stylesheets', 'default.css')
150
+ when 'print_stylesheet' then File.join('public', 'stylesheets', 'print.css')
151
+ when 'ie_stylesheet' then File.join('public', 'stylesheets', 'ie.css')
152
+ when 'ie6_stylesheet' then File.join('public', 'stylesheets', 'ie6.css')
153
+ end
154
+ filename = File.join(Rails.root, filename)
155
+
156
+ case request.method
157
+ when :get
158
+ @file_content = File.open(filename, 'r').read
159
+ when :post
160
+ begin
161
+ @pg = CmsPage.new
162
+ @page_objects = HashObject.new
163
+ render_to_string :inline => params[:file_content]
164
+ rescue Exception => e
165
+ message = e.message
166
+ flash.now[:error] = "<pre>#{ERB::Util.html_escape(message)}</pre>"
167
+ logger.debug e
168
+ return
169
+ end
170
+
171
+ begin
172
+ if params[:file_content].empty?
173
+ flash[:error] = 'An error occurred, please contact support.'
174
+ else
175
+ File.open(filename, 'w') { |f| f.write(params[:file_content]) }
176
+ flash[:notice] = 'File saved.'
177
+ end
178
+
179
+ CmsPage.find(:all).each do |page|
180
+ expire_page :controller => 'cms/content', :action => 'show', :content_path => page.path.split('/')
181
+ end
182
+
183
+ redirect_to :action => 'edit_master', :id => params[:id]
184
+ rescue Exception => e
185
+ message = e.message
186
+ flash.now[:error] = "<pre>#{ERB::Util.html_escape(message)}</pre>"
187
+ log_error(e)
188
+ end
189
+ end
190
+ end
191
+
192
+ def pages
193
+ @page_levels = [ '' ].concat((params[:path] || session[:cms_pages_path] || '').split('/').reject { |l| l.empty? })
194
+ @page_levels << ''
195
+ @path = ''
196
+ @page = nil
197
+ end
198
+
199
+ def list_pages
200
+ @page_level = params[:level].to_i
201
+ @parent = CmsPage.find_by_id(params[:parent_id])
202
+
203
+ if @page_level == 0
204
+ render :partial => 'list_page', :locals => { :list_page => CmsPage.find(1) } and return
205
+ else
206
+ if @parent
207
+ @pages = @parent.children
208
+ session[:cms_pages_path] = @parent.path
209
+ else
210
+ @pages = nil
211
+ end
212
+ end
213
+
214
+ render :partial => 'list_pages'
215
+ end
216
+
217
+ def edit_page
218
+ @pg = CmsPage.find_by_id(params[:id])
219
+ validate_user_access or return
220
+ @pg ||= CmsPage.new
221
+
222
+ @parent = @pg.parent || CmsPage.find_by_id(params[:parent_id])
223
+ if @parent
224
+ @pg.parent ||= @parent
225
+ @pg.template ||= @parent.template
226
+ end
227
+
228
+ @attrs = CmsPageObject.find(:all, :conditions => [ "obj_type = 'attribute'" ], :order => 'name').map { |attr| attr.name }.uniq
229
+
230
+ if params[:mode] == 'ajax_new' || params[:mode] == 'ajax_edit'
231
+ @pg.published_version = -1 if params[:mode] == 'ajax_new'
232
+ load_page_objects
233
+ load_template_options
234
+ render :partial => 'edit_page' and return
235
+ end
236
+
237
+ if request.post?
238
+ params[:pg] ||= {}
239
+
240
+ if params[:pg][:article_date_year]
241
+ params[:pg][:article_date] = Time.utc(params[:pg].delete(:article_date_year),
242
+ params[:pg].delete(:article_date_month),
243
+ params[:pg].delete(:article_date_day))
244
+ end
245
+ if params[:pg][:article_end_date_year]
246
+ params[:pg][:article_end_date] = Time.utc(params[:pg].delete(:article_end_date_year),
247
+ params[:pg].delete(:article_end_date_month),
248
+ params[:pg].delete(:article_end_date_day))
249
+ end
250
+ if params[:pg][:published_date_year]
251
+ params[:pg][:published_date] = Time.utc(params[:pg].delete(:published_date_year),
252
+ params[:pg].delete(:published_date_month),
253
+ params[:pg].delete(:published_date_day))
254
+ end
255
+ if params[:pg][:expires]
256
+ date = Time.utc(params[:pg].delete(:expiration_date_year),
257
+ params[:pg].delete(:expiration_date_month),
258
+ params[:pg].delete(:expiration_date_day))
259
+ params[:pg][:expiration_date] = date if params[:pg][:expires] == 'true'
260
+ end
261
+
262
+ @pg.assign_attributes(params[:pg])
263
+ unless params[:use_article_date_range].to_i > 0
264
+ @pg.article_end_date = nil
265
+ end
266
+ @pg.updated_by ||= session[:user_id]
267
+ @pg.updated_by_username ||= session[:user_username]
268
+
269
+ save_function = @pg.new_record? ? 'save' : 'save_without_revision'
270
+
271
+ if @pg.send(save_function)
272
+ # now try to save tags
273
+ begin
274
+ tags_to_delete = @pg.tags
275
+ params[:tags].split(',').map { |t| t.strip }.reject { |t| t.empty? }.compact.each do |t|
276
+ @pg.tags.create(:name => t) unless @pg.tags.find_by_name(t)
277
+ tags_to_delete.reject! { |tag| tag.name == t }
278
+ end
279
+ tags_to_delete.each { |t| t.destroy }
280
+ rescue Exception => e
281
+ logger.debug e
282
+ end
283
+
284
+ # now try to save page objects (just attributes in this case)
285
+ begin
286
+ objects_to_delete = @pg.objects.find(:all, :conditions => [ "obj_type = 'attribute' or obj_type = 'option'" ])
287
+
288
+ (params[:page_objects] || {}).each do |key,val|
289
+ next if key.empty? || val.empty?
290
+
291
+ key =~ /^obj-(\w+?)-(.+?)$/
292
+ obj = @pg.objects.find(:first, :conditions => [ "name = ? and obj_type = ?", $2, $1 ])
293
+ obj ||= @pg.objects.build(:name => $2, :obj_type => $1)
294
+ obj.content = val
295
+ obj.save
296
+ objects_to_delete.reject! { |obj| obj.name == $2 }
297
+ end
298
+
299
+ objects_to_delete.each { |t| t.destroy }
300
+ rescue Exception => e
301
+ logger.debug e
302
+ end
303
+
304
+ render :update do |page|
305
+ case params[:return_to]
306
+ when 'preview'
307
+ page.redirect_to "/#{@pg.path}"
308
+ else
309
+ flash[:notice] = 'Page saved.'
310
+ session[:cms_pages_path] = @pg.path
311
+ page.redirect_to :action => 'pages'
312
+ end
313
+ end
314
+
315
+ else
316
+ # save failed, display errors
317
+ render :update do |page|
318
+ page.replace_html 'save_errors', @pg.errors.full_messages.join('<br/>')
319
+ page << "try { $('btn_next').disabled = false; } catch (e) {}"
320
+ page << "try { $('btn_finish').disabled = false; } catch (e) {}"
321
+ page << "try { $('btn_save').disabled = false; $('btn_save').value = 'Save'; } catch (e) {}"
322
+ end and return
323
+ end
324
+ end
325
+ end
326
+
327
+ def delete_page
328
+ @pg = CmsPage.find_by_id(params[:id])
329
+
330
+ if !@pg
331
+ flash[:error] = "Sorry, couldn't find the requested page."
332
+ elsif @pg.children.size > 0
333
+ flash[:error] = "This page contains other pages. Please delete those first if you are sure you want to delete this page."
334
+ elsif @pg.id == 1
335
+ flash[:error] = "You cannot delete the home page."
336
+ else
337
+ flash[:notice] = "Page deleted."
338
+ session[:cms_pages_path] = @pg.parent.path rescue nil
339
+ @pg.destroy
340
+ end
341
+
342
+ redirect_to :action => 'pages'
343
+ end
344
+
345
+ def select_page
346
+ @page_levels = [ '' ].concat((params[:path] || session[:cms_pages_path] || '').split('/').reject { |l| l.empty? })
347
+ @page_levels << ''
348
+ @path = ''
349
+ @page = nil
350
+
351
+ render :layout => false
352
+ end
353
+
354
+ def list_pages_select
355
+ @page_level = params[:level].to_i
356
+ @parent = CmsPage.find_by_id(params[:parent_id])
357
+
358
+ if @page_level == 0
359
+ render :partial => 'list_page_select', :locals => { :list_page_select => CmsPage.find(1) } and return
360
+ else
361
+ if @parent
362
+ @pages = @parent.children
363
+ session[:cms_pages_path] = @parent.path
364
+ else
365
+ @pages = nil
366
+ end
367
+ end
368
+
369
+ render :partial => 'list_pages_select'
370
+ end
371
+
372
+ def show_template_options
373
+ @pg = CmsPage.find_by_id(params[:id]) || CmsPage.new
374
+ @pg.cms_template_id = params[:template_id]
375
+
376
+ load_page_objects
377
+ load_template_options
378
+
379
+ render :partial => 'template_options'
380
+ end
381
+
382
+ def page_attribute
383
+ render :nothing => true and return unless params[:name]
384
+
385
+ @page_objects = HashObject.new({ params[:name] => params[:value] })
386
+ render :partial => 'page_attribute', :locals => { :name => params[:name] }
387
+ end
388
+
389
+ def edit_page_content
390
+ @pg = CmsPage.find(params[:id])
391
+ validate_user_access or return
392
+
393
+ @page_objects = HashObject.new(params[:page_objects] || {})
394
+
395
+ if request.get?
396
+ @pg.revert_to(params[:version]) if params[:version]
397
+ @pg.objects.find(:all, :conditions => [ 'cms_page_version = ?', @pg.version ]).each do |obj|
398
+ key = "obj-#{obj.obj_type.to_s}-#{obj.name}"
399
+ @page_objects[key] = obj.content.html_safe
400
+ end
401
+
402
+ @dynamic_javascripts ||= []
403
+ @dynamic_javascripts << url_for(:action => 'page_tags_for_lookup')
404
+
405
+ @stylesheets ||= []
406
+ @stylesheets << 'imagine_ccs'
407
+
408
+ @template_content = substitute_placeholders(@pg.template.content, @pg)
409
+ render :layout => 'application'
410
+
411
+ elsif request.post?
412
+ CmsPage.transaction do
413
+ # need to revise this later if we implement deletion of page objects
414
+ old_objs = @pg.objects.find(:all, :conditions => [ 'cms_page_version = ?', @pg.version ])
415
+
416
+ @pg.updated_by = session[:user_id]
417
+ @pg.updated_by_username = session[:user_username]
418
+
419
+ # if basic user, make sure published version is not set to 'latest'
420
+ if (UseCmsAccessLevels && !user_has_permission?(:manage_cms_full_access)) && @pg.published_version == 0
421
+ @pg.published_version = @pg.version
422
+ end
423
+
424
+ @pg.save
425
+
426
+ # do a little bit of classification... for now, just identify page lists
427
+ page_lists = []
428
+ @page_objects.each do |key,val|
429
+ key =~ /^obj-(\w+?)-(\w+?)-sources-tag-count$/
430
+ if $1 == 'page_list'
431
+ page_lists << "obj-#{$1}-#{$2}"
432
+ end
433
+ end
434
+
435
+ # run through page lists and do a little housekeeping
436
+ page_lists.each do |key|
437
+ # optimize source lists: tags
438
+ if @page_objects["#{key}-sources-tag-count"].to_i > 0
439
+ tags = []
440
+ for i in 0...@page_objects["#{key}-sources-tag-count"].to_i
441
+ tags << @page_objects["#{key}-sources-tag#{i}"]
442
+ end
443
+ tags.reject! { |tag| tag.empty? }
444
+ @page_objects["#{key}-sources-tag-count"] = tags.size
445
+ tags.each_with_index do |tag, i|
446
+ @page_objects["#{key}-sources-tag#{i}"] = tag
447
+ end
448
+ end
449
+ # optimize source lists: folders
450
+ if @page_objects["#{key}-sources-folder-count"].to_i > 0
451
+ folders = []
452
+ for i in 0...@page_objects["#{key}-sources-folder-count"].to_i
453
+ folders << @page_objects["#{key}-sources-folder#{i}"]
454
+ end
455
+ folders.reject! { |folder| folder.empty? }
456
+ @page_objects["#{key}-sources-folder-count"] = folders.size
457
+ folders.each_with_index do |folder, i|
458
+ @page_objects["#{key}-sources-folder#{i}"] = folder
459
+ end
460
+ end
461
+
462
+ # consolidate date picker fields
463
+ if @page_objects["#{key}-date-range-custom-start_year"]
464
+ @page_objects["#{key}-date-range-custom-start"] =
465
+ Time.utc(@page_objects.delete("#{key}-date-range-custom-start_year"),
466
+ @page_objects.delete("#{key}-date-range-custom-start_month"),
467
+ @page_objects.delete("#{key}-date-range-custom-start_day"))
468
+ end
469
+ if @page_objects["#{key}-date-range-custom-end_year"]
470
+ @page_objects["#{key}-date-range-custom-end"] =
471
+ Time.utc(@page_objects.delete("#{key}-date-range-custom-end_year"),
472
+ @page_objects.delete("#{key}-date-range-custom-end_month"),
473
+ @page_objects.delete("#{key}-date-range-custom-end_day"))
474
+ end
475
+ end
476
+
477
+ @page_objects.each do |key,val|
478
+ key =~ /^obj-(\w+?)-(.+?)$/
479
+ obj = @pg.objects.build(:name => $2, :obj_type => $1)
480
+
481
+ # do a little bit of "censorship" to fix up Word pastes
482
+ if val.is_a?(String)
483
+ # all meta and link tags
484
+ val.gsub!(/(<\/?)(meta|link)(.*?)>/m, '')
485
+
486
+ # the dreaded MsoNormal
487
+ val.gsub!(' class="MsoNormal"', '')
488
+
489
+ # remove all font-family/font-size css styles, as well as font tags
490
+ val.gsub!(/font-(?:family|size):.*?(;|")/, '\3')
491
+ val.gsub!(/<font.*?>(.*?)<\/font>/, '\1')
492
+
493
+ # strange conditional IE stuff
494
+ val.gsub!(/<!--\[if(.*?)<!(--)?\[endif\]-->/m, '')
495
+
496
+ # not even sure what these are supposed to be
497
+ val.gsub!(/<xml>(.*?)<\/xml>/m, '')
498
+
499
+ # pirate styles not welcome
500
+ val.gsub!(/<style>(.*?)<\/style>/m, '')
501
+
502
+ # images pointing to the local drive??
503
+ val.gsub!(/<img src="file:(.*?)>/, '')
504
+
505
+ # miscellany
506
+ val.gsub!('<!--StartFragment-->', '')
507
+ val.gsub!('<!--EndFragment-->', '')
508
+ val.gsub!(/<span style="(?:;*)">(.*?)<\/span>/m, '\1')
509
+ val.gsub!(' style="(?:;*)"', '')
510
+ val.gsub!('<b></b>', '')
511
+
512
+ # we could try to catch all strange ms tags...
513
+ #val.gsub!(/(<\/?)(?:o|u1):p>/, '\1p>')
514
+ #val.gsub!(/(<\/?)(?:st1):(.*?)>/, '')
515
+
516
+ # but it's easier just remove all tags with colons in them
517
+ val.gsub!(/(<\/?)[\w\d]+:[\w\d]+(.*?)>/, '')
518
+ end
519
+
520
+ obj.content = val
521
+ obj.save
522
+ end
523
+
524
+ old_objs.each do |obj|
525
+ unless @pg.objects.find(:all, :conditions => [ 'name = ? and cms_page_version = ?', obj.name, @pg.version])
526
+ obj = @pg.objects.build(:name => obj.name, :obj_type => obj.type, :content => obj.content)
527
+ end
528
+ end
529
+
530
+ # update index for searching
531
+ @pg.update_index
532
+ @pg.save_without_revision
533
+ end
534
+
535
+ redirect_to "/#{@pg.path}#{@pg.path == '' ? '' : '/'}version/#{@pg.version}"
536
+ end
537
+ end
538
+
539
+ def insert_page_object_config
540
+ @pg = CmsPage.find(params[:id])
541
+
542
+ load_page_objects
543
+ @pg.revert_to(params[:version]) if params[:version]
544
+ @pg.objects.find(:all, :conditions => [ 'cms_page_version = ?', @pg.version]).each do |obj|
545
+ key = "obj-#{obj.obj_type.to_s}-#{obj.name}"
546
+ @page_objects[key] = obj.content
547
+ end
548
+
549
+ name = params[:name]
550
+ render :nothing => true and return unless name
551
+
552
+ parent_key = params[:parent_key]
553
+ type = params[:type]
554
+ render :nothing => true and return unless type == 'page_list'
555
+
556
+ key = "obj-#{type}-#{name.gsub(/[^\w]/, '_')}"
557
+
558
+ render :update do |page|
559
+ page.insert_html :bottom, "page_object_config_#{parent_key}", :partial => 'page_list',
560
+ :locals => { :name => name, :key => key }
561
+ end
562
+ end
563
+
564
+ def page_tags_for_lookup
565
+ @tags = CmsPageTag.find(:all, :order => 'name').map { |tag| tag.name }.uniq
566
+ headers['content-type'] = 'text/javascript'
567
+ render :layout => false
568
+ end
569
+
570
+ def page_attributes_for_lookup
571
+ @attrs = CmsPageObject.find(:all, :conditions => [ "obj_type = 'attribute'" ], :order => 'name').map { |attr| attr.name }.uniq
572
+ headers['content-type'] = 'text/javascript'
573
+ render :layout => false
574
+ end
575
+
576
+ def page_list_add_tag
577
+ render :partial => 'page_list_source_tag', :locals => { :i => params[:i], :key => params[:key] }
578
+ end
579
+
580
+ def page_list_add_folder
581
+ render :partial => 'page_list_source_folder', :locals => { :i => params[:i], :key => params[:key] }
582
+ end
583
+
584
+ def set_page_version
585
+ if (UseCmsAccessLevels && user_has_permission?(:manage_cms_publishing) || user_has_permission?(:manage_cms_full_access)) || user_has_permission?(:manage_cms)
586
+ if params[:id] && params[:pg]
587
+ @pg = CmsPage.find(params[:id])
588
+ validate_user_access or return
589
+ @pg.published_version = params[:pg][:published_version]
590
+ @pg.update_index
591
+ @pg.save_without_revision
592
+ end
593
+ end
594
+
595
+ render :nothing => true
596
+ end
597
+
598
+ def request_review
599
+ @pg = CmsPage.find(params[:id])
600
+ @version = params[:version].to_i
601
+
602
+ # send email to request administrative review
603
+ # find all users with email address set
604
+ User.find(:all).reject { |u| !u.active? || !u.can_manage_cms_publishing? || !u.cms_allowed_sections.blank? }.each do |u|
605
+ next unless valid_email_address?(u.email_address)
606
+ begin
607
+ Mailer.deliver_cms_request_review(url_for(:controller => '/cms/content', :action => 'show', :content_path => []) + @pg.path, @pg.title, @version, u, @user, params[:change_description].to_s)
608
+ rescue Exception => e
609
+ log_error(e)
610
+ end
611
+ end
612
+
613
+ render :nothing => true
614
+ end
615
+
616
+ #
617
+ # helpers
618
+ #
619
+
620
+ def insert_object(name, type = :text, options = {}, html_options = {})
621
+ extend ActionView::Helpers::FormHelper
622
+ extend ActionView::Helpers::JavaScriptHelper
623
+ extend ActionView::Helpers::PrototypeHelper
624
+ extend ActionView::Helpers::TagHelper
625
+ extend ActionView::Helpers::TextHelper
626
+
627
+ key = "obj-#{type.to_s}-#{name.gsub(/[^\w]/, '_')}"
628
+ @page_objects[key] ||= ''
629
+
630
+ case type.to_sym
631
+ when :string
632
+ @page_objects[key] = options[:content] if @page_objects[key].empty?
633
+ text_field(:page_objects, key, options)
634
+ when :text
635
+ @page_objects[key] = options[:content] if @page_objects[key].empty?
636
+ focusOnLoad = !defined?(@cms_text_editor_placed)
637
+ @cms_text_editor_placed = true
638
+ content = ''.html_safe
639
+ content << text_area(:page_objects, key, { :dojoType => 'Editor2', :toolbarGroup => 'main', :isToolbarGroupLeader => 'false',
640
+ :focusOnLoad => focusOnLoad.to_s, :style => 'border: 2px dashed gray; padding: 5px',
641
+ :minHeight => '100px' }.update(html_options))
642
+ content << content_tag(:div, ''.html_safe, :id => "page_object_config_#{key}")
643
+ content << javascript_tag("addLoadEvent(function () { scanForPageObjects(#{@pg.id}, '#{key}', #{@pg.version}); });")
644
+ content << observe_field("page_objects_#{key}", :function => "scanForPageObjects(#{@pg.id}, '#{key}', #{@pg.version});", :frequency => 2)
645
+ content
646
+ when :page_list
647
+ @page_objects["#{key}-min-item-count"] ||= 3 unless options[:item_min_count]
648
+ @page_objects["#{key}-max-item-count"] ||= 5 unless options[:item_count]
649
+ @page_objects["#{key}-item-offset"] ||= 0 unless options[:item_offset]
650
+ @page_objects["#{key}-sort-first-field"] ||= options[:primary_sort_key]
651
+ @page_objects["#{key}-sort-first-direction"] ||= options[:primary_sort_direction]
652
+ @page_objects["#{key}-sort-second-field"] ||= options[:secondary_sort_key]
653
+ @page_objects["#{key}-sort-second-direction"] ||= options[:secondary_sort_direction]
654
+
655
+ render_to_string(:partial => 'page_list', :locals => { :name => name, :key => key }).html_safe
656
+ when :snippet
657
+ @snippet = CmsSnippet.find_by_name(name)
658
+ if @snippet
659
+ erb_render(substitute_placeholders(@snippet.content, @pg))
660
+ else
661
+ 'Could not find snippet "' + name + '" in the database.'
662
+ end
663
+ else
664
+ "Unknown object type: #{type.to_s}"
665
+ end
666
+ end
667
+ helper_method :insert_object
668
+
669
+ def disable_caching ; end
670
+ helper_method :disable_caching
671
+
672
+ #
673
+ # cms toolbars
674
+ #
675
+
676
+ def toolbar_edit
677
+ @pg = CmsPage.find_by_id(params[:id])
678
+ render :layout => false
679
+ end
680
+
681
+ def toolbar_preview
682
+ @pg = CmsPage.find_by_id(params[:id])
683
+ render :layout => false
684
+ end
685
+
686
+ #
687
+ # image upload
688
+ #
689
+
690
+ def upload_image
691
+ @pg = CmsPage.find_by_id(params[:id])
692
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
693
+
694
+ if File.exists?(target_dir)
695
+ redirect_to :action => 'select_gallery', :id => @pg, :gallery_id => params[:gallery_id]
696
+ else
697
+ render :partial => 'upload_image'
698
+ end
699
+ end
700
+
701
+ def receive_image
702
+ @pg = CmsPage.find_by_id(params[:id])
703
+ begin
704
+ data = params[:file][:data]
705
+ original_filename = data.original_filename
706
+ target_dir = File.join(Rails.root, 'public', 'assets', 'content', @pg.path)
707
+ localfile = File.join(target_dir, original_filename)
708
+
709
+ begin
710
+ FileUtils.mkdir_p target_dir
711
+ rescue Exception => e
712
+ logger.debug "Exception: #{e}"
713
+ log_error(e)
714
+ finish_upload_status "''" and return
715
+ end
716
+
717
+ unless params[:overwrite].to_i == 1
718
+ count = 0
719
+ while File.exists?(localfile)
720
+ count += 1
721
+ localfile = File.join(target_dir, File.basename(original_filename, File.extname(original_filename))) + "-#{count}" + File.extname(original_filename)
722
+ end
723
+ end
724
+
725
+ begin
726
+ File.open(localfile, 'wb') { |f| f.write('test') }
727
+ rescue Exception => e
728
+ logger.debug "Exception: #{e}"
729
+ log_error(e)
730
+ finish_upload_status "''" and return
731
+ end
732
+
733
+ begin
734
+ File.open(localfile, 'wb') { |f| f.write(data.read) }
735
+ rescue Exception => e
736
+ logger.debug "Exception: #{e}"
737
+ log_error(e)
738
+ finish_upload_status "''" and return
739
+ end
740
+ rescue Exception => e
741
+ logger.debug params.inspect
742
+ # logger.debug "Exception: #{e}"
743
+ log_error(e)
744
+ finish_upload_status "''" and return
745
+ end
746
+
747
+ upload_progress.message = "File received successfully."
748
+ finish_upload_status "'#{File.basename(localfile)}'" and return
749
+ end
750
+
751
+ def crop_image
752
+ @pg = CmsPage.find_by_id(params[:id])
753
+ localfile = File.basename(params[:filename])
754
+
755
+ # get out now if user clicked finish
756
+ if params[:next_clicked].to_i != 1
757
+ @image_file = localfile
758
+ render :partial => 'crop_results' and return
759
+ end
760
+
761
+
762
+ # if we're still here... let's crop!
763
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
764
+ localfile = File.join(target_dir, localfile)
765
+ testfile = File.join(target_dir, File.basename(localfile, File.extname(localfile))) + '-croptest' + File.extname(localfile)
766
+
767
+ # make a smaller version to help with cropping
768
+ im = MiniMagick::Image.from_file(localfile)
769
+ im.resize "500x400>"
770
+ im.write(testfile)
771
+ File.chmod(0644, testfile)
772
+
773
+ @width = im[:width]
774
+ @height = im[:height]
775
+ @height = 1 if @height == 0
776
+ @image_file = File.basename(testfile)
777
+ @aspect_ratio = @width.to_f/@height
778
+
779
+ render :partial => 'crop_image'
780
+ end
781
+
782
+ def save_crop
783
+ @pg = CmsPage.find_by_id(params[:id])
784
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
785
+ testfile = File.join(target_dir, File.basename(params[:filename]))
786
+ localfile = testfile.split(/-croptest/).join('')
787
+
788
+ # need to scale up requested position/dimensions based on how big test image
789
+ # is relative to original image
790
+ orig_im = MiniMagick::Image.from_file(localfile)
791
+ test_im = MiniMagick::Image.from_file(testfile)
792
+ scale = orig_im[:width].to_f / test_im[:width]
793
+
794
+ x1 = params[:image][:x1].to_i * scale
795
+ y1 = params[:image][:y1].to_i * scale
796
+ width = params[:image][:width].to_i * scale
797
+ height = params[:image][:height].to_i * scale
798
+
799
+ max_width = params[:image][:max_width].to_i
800
+ max_height = params[:image][:max_height].to_i
801
+ dirty = false
802
+
803
+ # crop if user selected something
804
+ if params[:image][:width].to_i > 0
805
+ logger.debug "cropping @ (#{x1}, #{y1}) to size #{width} x #{height}"
806
+ orig_im.crop "#{width}x#{height}+#{x1}+#{y1}"
807
+ dirty = true
808
+ end
809
+
810
+ # resize if the resultant image is bigger than max dims
811
+ if max_width > 0 && max_height > 0
812
+ if orig_im[:width] > max_width || orig_im[:height] > max_height
813
+ logger.debug "resizing to max dims #{max_width} x #{max_height}"
814
+ orig_im.resize "#{max_width}x#{max_height}"
815
+ dirty = true
816
+ end
817
+ end
818
+
819
+ orig_im.write(localfile) if dirty
820
+ @image_file = localfile
821
+ File.unlink testfile
822
+
823
+ render :partial => 'crop_results'
824
+ end
825
+
826
+ def receive_gallery
827
+ require 'zip/zip'
828
+
829
+ @pg = CmsPage.find_by_id(params[:id])
830
+ begin
831
+ data = params[:gallery_file][:data]
832
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
833
+ localdir = File.join(target_dir, 'gallery_1')
834
+
835
+ begin
836
+ FileUtils.mkdir_p target_dir
837
+ rescue Exception => e
838
+ logger.debug "Exception: #{e}"
839
+ log_error(e)
840
+ finish_upload_status "''" and return
841
+ end
842
+
843
+ unless params[:overwrite].to_i == 1
844
+ count = 1
845
+ while File.exists?(localdir)
846
+ count += 1
847
+ localdir = File.join(target_dir, "gallery_#{count}")
848
+ end
849
+ end
850
+
851
+ begin
852
+ FileUtils.mkdir_p File.join(localdir, 'temp')
853
+ rescue Exception => e
854
+ logger.debug "Exception: #{e}"
855
+ log_error(e)
856
+ finish_upload_status "''" and return
857
+ end
858
+
859
+ # read zip file
860
+ entries = []
861
+ Zip::ZipFile.foreach(data.path) do |zipentry|
862
+ next if ![ '.jpg', '.jpeg', '.png', '.gif' ].include?(File.extname(zipentry.name).downcase) || zipentry.size < 1000
863
+ next if File.basename(zipentry.name) =~ /^\._/
864
+
865
+ entries << zipentry
866
+ end
867
+ entries.sort! { |a,b| File.basename(a.name).downcase <=> File.basename(b.name).downcase }
868
+
869
+ Zip::ZipFile.open(data.path) do |zipfile|
870
+ entries.each_with_index do |zipentry, index|
871
+ upload_progress.message = "Extracting #{File.basename(zipentry.name)}"
872
+ ext = File.extname(zipentry.name)
873
+ #name = File.basename(zipentry.name, ext)
874
+ #localfile = File.join(localdir, 'temp', name.downcase.gsub(/[^\w\d]/, '') + ext.downcase)
875
+ localfile = File.join(localdir, 'temp', (index+1).to_s + ext.downcase)
876
+ jpgfile = File.join(localdir, 'temp', (index+1).to_s + '.jpg')
877
+
878
+ begin
879
+ zipentry.extract(localfile)
880
+
881
+ im = MiniMagick::Image.from_file(localfile)
882
+ im.write(jpgfile)
883
+
884
+ File.unlink(localfile) if localfile != jpgfile
885
+
886
+ rescue Exception => e
887
+ log_error(e)
888
+ end
889
+ end
890
+ end
891
+ rescue Exception => e
892
+ logger.debug params.inspect
893
+ log_error(e)
894
+ finish_upload_status "''" and return
895
+ end
896
+
897
+ upload_progress.message = "File received successfully."
898
+ finish_upload_status "'#{File.basename(localdir)}'" and return
899
+ end
900
+
901
+ def gallery_setup
902
+ @pg = CmsPage.find_by_id(params[:id])
903
+ target_dir = File.join('images', 'content', @pg.path)
904
+ @dirname = File.join(target_dir, File.basename(params[:dirname]), 'temp')
905
+ Dir.chdir(File.join(Rails.root, 'public'))
906
+ @images = Dir.glob("#{@dirname}/*.{jpg,jpeg,png,gif}").sort
907
+ Dir.chdir(Rails.root)
908
+ @thumbs = []
909
+
910
+ @images.each do |img|
911
+ next if img.include?('-thumb')
912
+
913
+ thumbfile = File.join(Rails.root, 'public', @dirname, File.basename(img, File.extname(img))) + '-thumb.jpg'
914
+ #@thumbs << File.basename(img, File.extname(img))
915
+ @thumbs << File.join(@dirname, File.basename(img, File.extname(img))) +
916
+ '-thumb.jpg'
917
+
918
+ next if File.exists?(thumbfile)
919
+
920
+ im = MiniMagick::Image.from_file(File.join(Rails.root, 'public', img))
921
+ im.resize "80x80" # hardcoded!
922
+ im.write(thumbfile)
923
+ File.chmod(0644, thumbfile)
924
+ end
925
+
926
+ @thumbs.sort! { |a,b| File.basename(a, File.extname(a)).to_i <=> File.basename(b, File.extname(b)).to_i }
927
+ session[:gallery_thumbs_ordered] = @thumbs.map { |thumb| File.basename(thumb, File.extname(thumb)) }
928
+
929
+ render :partial => 'gallery_setup'
930
+ end
931
+
932
+ def complete_gallery
933
+ @pg = CmsPage.find(params[:id])
934
+ target_dir = File.join('images', 'content', @pg.path)
935
+ @dirname = File.join(target_dir, File.basename(params[:dirname]))
936
+ @thumbs = session[:gallery_thumbs_ordered]
937
+ max_width = params[:max_width].to_i
938
+ max_width = GalleryMaxWidth unless max_width > 0
939
+ max_height = params[:max_height].to_i
940
+ max_height = GalleryMaxHeight unless max_height > 0
941
+
942
+ create_captions_file(@pg.id, { :gallery_id => File.basename(params[:dirname]) })
943
+
944
+ @thumbs.each_with_index do |thumb, index|
945
+ thumb.gsub!(/-thumb/, '')
946
+ tempfile = File.join(Rails.root, 'public', @dirname, 'temp', thumb + '.jpg')
947
+ tempthumbfile = File.join(Rails.root, 'public', @dirname, 'temp', thumb + '-thumb.jpg')
948
+
949
+ localfile = File.join(Rails.root, 'public', @dirname, (index+1).to_s + '.jpg')
950
+ thumbfile = File.join(Rails.root, 'public', @dirname, (index+1).to_s + '-thumb.jpg')
951
+
952
+ im = MiniMagick::Image.from_file(tempfile)
953
+ if im[:width] > max_width || im[:height] > max_height
954
+ im.resize("#{max_width}x#{max_height}")
955
+ end
956
+ im.write(localfile)
957
+
958
+ small = MiniMagick::Image.from_file(tempfile)
959
+ small.crop_resized(GalleryThumbWidth, GalleryThumbHeight)
960
+ small.write(thumbfile)
961
+
962
+ File.chmod(0644, localfile, thumbfile)
963
+
964
+ begin
965
+ File.unlink(tempfile)
966
+ File.unlink(tempthumbfile)
967
+ rescue Exception => e
968
+ # not that big a deal if we can't delete
969
+ end
970
+ end
971
+
972
+ begin
973
+ Dir.rmdir(File.join(Rails.root, 'public', @dirname, 'temp'))
974
+ rescue Exception => e
975
+ # not that big a deal if we can't delete
976
+ end
977
+
978
+ create_preview_images
979
+
980
+ render :partial => 'complete_gallery'
981
+ end
982
+
983
+ def gallery_management
984
+ @pg = CmsPage.find_by_id(params[:id])
985
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
986
+ @galleries = Dir.glob("#{galleries_dir}/gallery_*")
987
+ gallery_dir = File.join(galleries_dir, params[:gallery_id].to_s)
988
+
989
+ @images = Dir.glob("#{gallery_dir}/*.{jpg,jpeg,png,gif}").reject { |img| img.include?('thumb') }.map { |img| File.basename(img).split('.').first.to_i }.sort
990
+
991
+ create_preview_images
992
+
993
+ if params[:gallery_id]
994
+ @gallery = load_gallery_settings_from_file(params[:gallery_id])
995
+ end
996
+
997
+ render :layout => false
998
+ end
999
+
1000
+ def set_gallery_order
1001
+ session[:gallery_thumbs_ordered] = params[:image_sorter]
1002
+ render :nothing => true
1003
+ end
1004
+
1005
+ def select_gallery
1006
+ @pg = CmsPage.find_by_id(params[:id])
1007
+ @target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1008
+ @galleries = Dir.glob("#{@target_dir}/gallery_*")
1009
+
1010
+ create_preview_images
1011
+
1012
+ if request.post?
1013
+ unless params[:gallery_id].downcase == "new"
1014
+ redirect_to :action => 'gallery_management', :id => @pg, :gallery_id => params[:gallery_id] and return
1015
+ else
1016
+ render :partial => 'upload_image' and return
1017
+ end
1018
+ else
1019
+ render :partial => 'select_gallery' and return
1020
+ end
1021
+ end
1022
+
1023
+ def save_gallery_settings
1024
+ if request.post?
1025
+ @pg = CmsPage.find_by_id(params[:id])
1026
+ save_gallery_settings_to_file(params[:gallery_id], params[:gallery])
1027
+
1028
+ render :nothing => true
1029
+ end
1030
+ end
1031
+
1032
+ def sort_images
1033
+ @pg = CmsPage.find_by_id(params[:id])
1034
+ gallery_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path, params[:gallery_id])
1035
+
1036
+ @images = Dir.glob("#{gallery_dir}/*.{jpg,jpeg,png,gif}").reject { |img| img.include?('thumb') }.map { |img| File.basename(img).split('.').first.to_i }.sort
1037
+
1038
+ if params[:images]
1039
+ session[:gallery_images_sorted] = params[:images]
1040
+ render :nothing => true
1041
+ else
1042
+ render :partial => 'sort_images'
1043
+ end
1044
+ end
1045
+
1046
+ def sort_images_save
1047
+ @pg = CmsPage.find_by_id(params[:id])
1048
+ gallery_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path, params[:gallery_id])
1049
+ temp_dir = File.join(gallery_dir, 'temp')
1050
+ sorted_images = session[:gallery_images_sorted] || []
1051
+
1052
+ if sorted_images == []
1053
+ redirect_to :action => 'gallery_management', :id => @pg, :gallery_id => params[:gallery_id]
1054
+ return
1055
+ end
1056
+
1057
+ FileUtils.rm_rf(temp_dir)
1058
+ Dir.mkdir(temp_dir)
1059
+
1060
+ # create blank captions.yml if it doesn't already exist
1061
+ create_captions_file(@pg.id)
1062
+
1063
+ original_captions = YAML.load_file(File.join(gallery_dir, 'captions.yml')).to_a
1064
+ captions = []
1065
+ captions << original_captions[0]
1066
+
1067
+ sorted_images.each_with_index do |img, i|
1068
+ localfile = File.join(gallery_dir, img)
1069
+ thumbfile = File.join(gallery_dir, img.split('.')[0] + '-thumb.jpg')
1070
+
1071
+ temp_localfile = File.join(temp_dir, (i + 1).to_s + '.jpg')
1072
+ temp_thumbfile = File.join(temp_dir, (i + 1).to_s + '-thumb.jpg')
1073
+
1074
+ begin ; FileUtils.cp(localfile, temp_localfile) ; rescue ; end
1075
+ begin ; FileUtils.cp(thumbfile, temp_thumbfile) ; rescue ; end
1076
+
1077
+ captions[i + 1] = original_captions[img.split('.')[0].to_i] || ''
1078
+ end
1079
+
1080
+ File.open(File.join(gallery_dir, 'captions.yml'), 'w') { |f| YAML.dump(captions, f) }
1081
+
1082
+ images = Dir.glob("#{gallery_dir}/*.{jpg,jpeg,png,gif}")
1083
+ temp_images = Dir.glob("#{temp_dir}/*.{jpg,jpeg,png,gif}")
1084
+
1085
+ images.each { |img| File.delete(img) }
1086
+ temp_images.each { |img| FileUtils.cp(img, File.join(gallery_dir, File.basename(img))) }
1087
+
1088
+ FileUtils.rm_rf(File.join(gallery_dir, 'management'))
1089
+ create_preview_images(:force => 1)
1090
+
1091
+ FileUtils.rm_rf(temp_dir)
1092
+ session[:gallery_images_sorted] = nil
1093
+
1094
+ redirect_to :action => 'gallery_management', :id => @pg, :gallery_id => params[:gallery_id]
1095
+ end
1096
+
1097
+ def image_details
1098
+ gallery_dir = File.join(Rails.root, 'public', 'images', 'content', params[:path].to_s, params[:gallery_id])
1099
+
1100
+ # create blank captions.yml if it doesn't already exist
1101
+ create_captions_file(params[:id])
1102
+
1103
+ captions = YAML.load(File.open(File.join(gallery_dir, 'captions.yml')).read)
1104
+ image_id = params[:image].split('.')[0].to_i
1105
+ @caption = captions[image_id]
1106
+
1107
+ render :partial => 'image_details'
1108
+ end
1109
+
1110
+ def update_caption
1111
+ if request.post?
1112
+ gallery_dir = File.join(Rails.root, 'public', 'images', 'content', params[:path].to_s, params[:gallery_id])
1113
+
1114
+ image_id = params[:image].split('.')[0].to_i
1115
+
1116
+ # create blank captions.yml if it doesn't already exist
1117
+ create_captions_file(params[:id])
1118
+
1119
+ captions = YAML.load_file(File.join(gallery_dir, 'captions.yml')).to_a
1120
+ captions[image_id] = params[:caption]
1121
+
1122
+ File.open(File.join(gallery_dir, 'captions.yml'), "w") { |f| YAML.dump(captions, f) }
1123
+ end
1124
+
1125
+ redirect_to :action => 'gallery_management', :id => params[:id], :gallery_id => params[:gallery_id]
1126
+ end
1127
+
1128
+ def add_to_gallery
1129
+ @pg = CmsPage.find_by_id(params[:id])
1130
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1131
+ @galleries = Dir.entries(galleries_dir).sort
1132
+ @gallery_dir = File.join(galleries_dir, params[:gallery_id])
1133
+ images = Dir.glob("#{@gallery_dir}/*-thumb.{jpg,jpeg,png,gif}")
1134
+
1135
+ temp_location = File.join(@gallery_dir ,'temp')
1136
+ FileUtils.rm_rf(temp_location)
1137
+ Dir.mkdir(temp_location)
1138
+
1139
+ data = params[:gallery_file][:data]
1140
+ data_dest = File.join(temp_location, data.original_filename)
1141
+ File.open(data_dest, "w") { |f| f.write(data.read) }
1142
+
1143
+ last_id = images.size
1144
+ ext = File.extname(data_dest).downcase
1145
+
1146
+ if ext != '.zip'
1147
+ localfile = File.join(@gallery_dir, (last_id + 1).to_s + ext)
1148
+ thumbfile = File.join(@gallery_dir, (last_id + 1).to_s + '-thumb' + ext)
1149
+
1150
+ File.open(localfile, "w") { |f| f.write(File.open(data_dest).read) }
1151
+
1152
+ # create blank captions.yml if it doesn't already exist
1153
+ create_captions_file(@pg.id)
1154
+
1155
+ localfile = resize_image(localfile)
1156
+
1157
+ small = MiniMagick::Image.from_file(localfile)
1158
+ small.crop_resized(GalleryThumbWidth, GalleryThumbHeight)
1159
+ small.write(thumbfile)
1160
+
1161
+ File.chmod(0644, localfile, thumbfile)
1162
+
1163
+ create_preview_images(:force => 1)
1164
+
1165
+ elsif ext == '.zip'
1166
+ require 'zip/zip'
1167
+
1168
+ begin
1169
+ Zip::ZipFile.foreach(data.path) do |zipentry|
1170
+ next if ![ '.jpg', '.jpeg', '.png', '.gif' ].include?(File.extname(zipentry.name).downcase) || zipentry.size < 1000
1171
+ upload_progress.message = "Extracting #{File.basename(zipentry.name)}"
1172
+ localfile = File.join(temp_location, ((last_id+1).to_s + File.extname(zipentry.name)).downcase)
1173
+
1174
+ begin
1175
+ zipentry.extract(localfile)
1176
+ last_id += 1
1177
+ rescue Exception => e
1178
+ log_error(e)
1179
+ end
1180
+ end
1181
+ rescue Exception => e
1182
+ logger.debug params.inspect
1183
+ log_error(e)
1184
+ finish_upload_status "''" and return
1185
+ end
1186
+
1187
+ @images = Dir.glob("#{temp_location}/*.{jpg,jpeg,png,gif}")
1188
+
1189
+ @images.each do |img|
1190
+ localfile = File.join(@gallery_dir, File.basename(img, File.extname(img))) + '.jpg'
1191
+ tempfile = File.join(temp_location, File.basename(img, File.extname(img))) + File.extname(img)
1192
+ thumbfile = File.join(@gallery_dir, File.basename(img, File.extname(img))) + '-thumb.jpg'
1193
+
1194
+ small = MiniMagick::Image.from_file(tempfile)
1195
+ small.crop_resized(GalleryThumbWidth, GalleryThumbHeight)
1196
+ small.write(thumbfile)
1197
+
1198
+ FileUtils.cp(tempfile, localfile)
1199
+ resize_image(localfile)
1200
+
1201
+ File.chmod(0644, localfile, thumbfile)
1202
+ end
1203
+
1204
+ # smaller images for gallery index
1205
+ management_dir = File.join(@gallery_dir, 'management')
1206
+
1207
+ preview_images = []
1208
+ Dir.glob("#{@gallery_dir}/*.{jpg,jpeg,png,gif}").each { |img| preview_images << img unless File.basename(img).include?('thumb') }
1209
+
1210
+ preview_images.each { |img| create_preview_image(img, management_dir, 1) }
1211
+ end
1212
+
1213
+ File.delete(data_dest)
1214
+
1215
+ upload_progress.message = "File received successfully."
1216
+ finish_upload_status "'#{File.basename(data_dest)}'" and return
1217
+ end
1218
+
1219
+ def delete_photo
1220
+ if request.post?
1221
+ gallery_dir = File.join(Rails.root, 'public', 'images', 'content', params[:path].to_s, params[:gallery_id])
1222
+
1223
+ image_id = params[:image].split('.')[0].to_i
1224
+
1225
+ begin ; File.delete(File.join(gallery_dir, image_id.to_s + '.jpg')) ; rescue ; end
1226
+ begin ; File.delete(File.join(gallery_dir, image_id.to_s + '-thumb.jpg')) ; rescue ; end
1227
+ begin ; File.delete(File.join(gallery_dir, 'management', image_id.to_s + '.jpg')) ; rescue ; end
1228
+
1229
+ all_images = Dir.glob(File.join(gallery_dir, '*.{jpg,jpeg,png,gif}'))
1230
+ images = []
1231
+ all_images.each { |img| images << img if !File.basename(img).include?('thumb') and File.basename(img).split('.')[0].to_i > image_id }
1232
+
1233
+ image_names = []
1234
+ images.each_with_index { |img, index| image_names << File.basename(img).split('.')[0].to_i }
1235
+ image_names.sort!
1236
+
1237
+ # create blank captions.yml if it doesn't already exist
1238
+ create_captions_file(params[:id])
1239
+ captions = YAML.load(File.open(File.join(gallery_dir, 'captions.yml')).read).to_a
1240
+
1241
+ new_captions = []
1242
+ for i in 0...image_id do
1243
+ new_captions[i] = captions[i] || ''
1244
+ end
1245
+
1246
+ image_names.each do |img|
1247
+ FileUtils.mv(File.join(gallery_dir, img.to_s + '.jpg'), File.join(gallery_dir, image_id.to_s + '.jpg'))
1248
+ FileUtils.mv(File.join(gallery_dir, img.to_s + '-thumb.jpg'), File.join(gallery_dir, image_id.to_s + '-thumb.jpg'))
1249
+ FileUtils.mv(File.join(gallery_dir, 'management', img.to_s + '.jpg'), File.join(gallery_dir, 'management', image_id.to_s + '.jpg'))
1250
+
1251
+ new_captions[image_id] = captions[img] || ''
1252
+
1253
+ image_id += 1
1254
+ end
1255
+
1256
+ File.open(File.join(gallery_dir, 'captions.yml'), "w") { |f| f.write(YAML.dump(new_captions)) }
1257
+ end
1258
+
1259
+ redirect_to :action => 'gallery_management', :id => params[:id], :gallery_id => params[:gallery_id]
1260
+ end
1261
+
1262
+ def delete_gallery
1263
+ @pg = CmsPage.find_by_id(params[:id])
1264
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1265
+ gallery_dir = File.join(galleries_dir, params[:gallery_id])
1266
+
1267
+ FileUtils.rm_rf(gallery_dir)
1268
+
1269
+ redirect_to :action => 'select_gallery', :id => params[:id]
1270
+ end
1271
+
1272
+
1273
+ def upload_file
1274
+ @pg = CmsPage.find_by_id(params[:id])
1275
+ render :partial => 'upload_file'
1276
+ end
1277
+
1278
+ def receive_file
1279
+ @pg = CmsPage.find_by_id(params[:id])
1280
+ begin
1281
+ data = params[:file][:data]
1282
+ original_filename = data.original_filename.downcase.gsub(/[^\.\w\d]+/, '_')
1283
+ target_dir = File.join(Rails.root, 'public', 'files', 'content', @pg.path)
1284
+ localfile = File.join(target_dir, original_filename)
1285
+
1286
+ begin
1287
+ FileUtils.mkdir_p target_dir
1288
+ rescue Exception => e
1289
+ logger.debug "Exception: #{e}"
1290
+ log_error(e)
1291
+ finish_upload_status "''" and return
1292
+ end
1293
+
1294
+ unless params[:overwrite].to_i == 1
1295
+ count = 0
1296
+ while File.exists?(localfile)
1297
+ count += 1
1298
+ localfile = File.join(target_dir, File.basename(original_filename, File.extname(original_filename))) + "-#{count}" + File.extname(original_filename)
1299
+ end
1300
+ end
1301
+
1302
+ begin
1303
+ File.open(localfile, 'wb') { |f| f.write('test') }
1304
+ rescue Exception => e
1305
+ logger.debug "Exception: #{e}"
1306
+ log_error(e)
1307
+ finish_upload_status "''" and return
1308
+ end
1309
+
1310
+ begin
1311
+ File.open(localfile, 'wb') { |f| f.write(data.read) }
1312
+ rescue Exception => e
1313
+ logger.debug "Exception: #{e}"
1314
+ log_error(e)
1315
+ finish_upload_status "''" and return
1316
+ end
1317
+ rescue Exception => e
1318
+ logger.debug params.inspect
1319
+ # logger.debug "Exception: #{e}"
1320
+ log_error(e)
1321
+ finish_upload_status "''" and return
1322
+ end
1323
+
1324
+ upload_progress.message = "File received successfully."
1325
+ finish_upload_status "'#{File.basename(localfile)}'" and return
1326
+ end
1327
+
1328
+ def create_file_link
1329
+ @pg = CmsPage.find_by_id(params[:id])
1330
+ target_dir = File.join('files', 'content', @pg.path)
1331
+ @filename = File.join(target_dir, File.basename(params[:filename]))
1332
+ render :partial => 'create_file_link'
1333
+ end
1334
+
1335
+
1336
+ def upload_thumb
1337
+ @pg = CmsPage.find_by_id(params[:id])
1338
+ render :partial => 'upload_thumb'
1339
+ end
1340
+
1341
+ def crop_thumb
1342
+ @pg = CmsPage.find_by_id(params[:id])
1343
+ localfile = File.basename(params[:filename])
1344
+
1345
+ # get out now if user clicked finish
1346
+ if params[:next_clicked].to_i != 1
1347
+ @image_file = localfile
1348
+ render :partial => 'crop_results_thumb' and return
1349
+ end
1350
+
1351
+
1352
+ # if we're still here... let's crop!
1353
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1354
+ localfile = File.join(target_dir, localfile)
1355
+ testfile = File.join(target_dir, File.basename(localfile, File.extname(localfile))) + '-croptest' + File.extname(localfile)
1356
+
1357
+ # make a smaller version to help with cropping
1358
+ im = MiniMagick::Image.from_file(localfile)
1359
+ im.resize("500x400>")
1360
+ im.write(testfile)
1361
+ File.chmod(0644, testfile)
1362
+
1363
+ @width = im[:width]
1364
+ @height = im[:height]
1365
+ @height = 1 if @height == 0
1366
+ @image_file = File.basename(testfile)
1367
+ @aspect_ratio = @width.to_f/@height
1368
+
1369
+ render :partial => 'crop_thumb'
1370
+ end
1371
+
1372
+ def save_crop_thumb
1373
+ @pg = CmsPage.find_by_id(params[:id])
1374
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1375
+ testfile = File.join(target_dir, File.basename(params[:filename]))
1376
+ localfile = testfile.split(/-croptest/).join('')
1377
+
1378
+ # need to scale up requested position/dimensions based on how big test image
1379
+ # is relative to original image
1380
+ orig_im = MiniMagick::Image.from_file(localfile)
1381
+ test_im = MiniMagick::Image::from_file(testfile)
1382
+ scale = orig_im[:width].to_f / test_im[:width]
1383
+
1384
+ x1 = params[:image][:x1].to_i * scale
1385
+ y1 = params[:image][:y1].to_i * scale
1386
+ # x2 = params[:image][:x2].to_i * scale
1387
+ # y2 = params[:image][:y2].to_i * scale
1388
+ width = params[:image][:width].to_i * scale
1389
+ height = params[:image][:height].to_i * scale
1390
+
1391
+ max_width = params[:image][:max_width].to_i
1392
+ max_height = params[:image][:max_height].to_i
1393
+ dirty = false
1394
+
1395
+ # crop if user selected something
1396
+ if params[:image][:width].to_i > 0
1397
+ logger.debug "cropping @ (#{x1}, #{y1}) to size #{width} x #{height}"
1398
+ orig_im.crop("#{width}x#{height}+#{x1}+#{y1}")
1399
+ dirty = true
1400
+ end
1401
+
1402
+ # resize if the resultant image is bigger than max dims
1403
+ if max_width > 0 && max_height > 0
1404
+ if orig_im[:width] > max_width || orig_im[:height] > max_height
1405
+ logger.debug "resizing to max dims #{max_width} x #{max_height}"
1406
+ orig_im.resize("#{max_width}x#{max_height}>")
1407
+ dirty = true
1408
+ end
1409
+ end
1410
+
1411
+ orig_im.write(localfile) if dirty
1412
+ File.chmod(0644, localfile)
1413
+
1414
+ @image_file = localfile
1415
+ File.unlink testfile
1416
+
1417
+ render :partial => 'crop_results_thumb'
1418
+ end
1419
+
1420
+ def upload_feature_image
1421
+ @pg = CmsPage.find_by_id(params[:id])
1422
+ render :partial => 'upload_feature_image'
1423
+ end
1424
+
1425
+ def crop_feature_image
1426
+ @pg = CmsPage.find_by_id(params[:id])
1427
+ localfile = File.basename(params[:filename])
1428
+
1429
+ # get out now if user clicked finish
1430
+ if params[:next_clicked].to_i != 1
1431
+ @image_file = localfile
1432
+ render :partial => 'crop_results_feature_image' and return
1433
+ end
1434
+
1435
+
1436
+ # if we're still here... let's crop!
1437
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1438
+ localfile = File.join(target_dir, localfile)
1439
+ testfile = File.join(target_dir, File.basename(localfile, File.extname(localfile))) + '-croptest' + File.extname(localfile)
1440
+
1441
+ # make a smaller version to help with cropping
1442
+ im = MiniMagick::Image.from_file(localfile)
1443
+ im.resize("500x400>")
1444
+ im.write(testfile)
1445
+ File.chmod(0644, testfile)
1446
+
1447
+ @width = im[:width]
1448
+ @height = im[:height]
1449
+ @height = 1 if @height == 0
1450
+ @image_file = File.basename(testfile)
1451
+ @aspect_ratio = @width.to_f/@height
1452
+
1453
+ render :partial => 'crop_feature_image'
1454
+ end
1455
+
1456
+ def save_crop_feature_image
1457
+ @pg = CmsPage.find_by_id(params[:id])
1458
+ target_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1459
+ testfile = File.join(target_dir, File.basename(params[:filename]))
1460
+ localfile = testfile.split(/-croptest/).join('')
1461
+
1462
+ # need to scale up requested position/dimensions based on how big test image
1463
+ # is relative to original image
1464
+ orig_im = MiniMagick::Image.from_file(localfile)
1465
+ test_im = MiniMagick::Image::from_file(testfile)
1466
+ scale = orig_im[:width].to_f / test_im[:width]
1467
+
1468
+ x1 = params[:image][:x1].to_i * scale
1469
+ y1 = params[:image][:y1].to_i * scale
1470
+ # x2 = params[:image][:x2].to_i * scale
1471
+ # y2 = params[:image][:y2].to_i * scale
1472
+ width = params[:image][:width].to_i * scale
1473
+ height = params[:image][:height].to_i * scale
1474
+
1475
+ max_width = params[:image][:max_width].to_i
1476
+ max_height = params[:image][:max_height].to_i
1477
+ dirty = false
1478
+
1479
+ # crop if user selected something
1480
+ if params[:image][:width].to_i > 0
1481
+ logger.debug "cropping @ (#{x1}, #{y1}) to size #{width} x #{height}"
1482
+ orig_im.crop("#{width}x#{height}+#{x1}+#{y1}")
1483
+ dirty = true
1484
+ end
1485
+
1486
+ # resize if the resultant image is bigger than max dims
1487
+ if max_width > 0 && max_height > 0
1488
+ if orig_im[:width] > max_width || orig_im[:height] > max_height
1489
+ logger.debug "resizing to max dims #{max_width} x #{max_height}"
1490
+ orig_im.resize("#{max_width}x#{max_height}>")
1491
+ dirty = true
1492
+ end
1493
+ end
1494
+
1495
+ orig_im.write(localfile) if dirty
1496
+ File.chmod(0644, localfile)
1497
+
1498
+ @image_file = localfile
1499
+ File.unlink testfile
1500
+
1501
+ render :partial => 'crop_results_feature_image'
1502
+ end
1503
+
1504
+
1505
+ private
1506
+
1507
+ def load_page_objects
1508
+ @page_objects = HashObject.new
1509
+ @template_options = HashObject.new
1510
+
1511
+ if @pg.new_record? && @parent
1512
+ # This does not appear to be a beneficial feature any longer
1513
+ # @tags = @parent.tags.collect { |t| t.name }.join(', ')
1514
+ @parent.objects.find(:all, :conditions => [ "obj_type = 'attribute'" ]).each do |obj|
1515
+ key = "obj-#{obj.obj_type.to_s}-#{obj.name}"
1516
+ @page_objects[key] = obj.content
1517
+ end
1518
+ @parent.objects.find(:all, :conditions => [ "obj_type = 'option'" ]).each do |obj|
1519
+ key = "obj-#{obj.obj_type.to_s}-#{obj.name}"
1520
+ @page_objects[key] = obj.content
1521
+ end
1522
+ else
1523
+ @tags = @pg.tags.collect { |t| t.name }.join(', ')
1524
+ @pg.objects.find(:all, :conditions => [ "obj_type = 'attribute'" ]).each do |obj|
1525
+ key = "obj-#{obj.obj_type.to_s}-#{obj.name}"
1526
+ @page_objects[key] = obj.content
1527
+ end
1528
+ @pg.objects.find(:all, :conditions => [ "obj_type = 'option'" ]).each do |obj|
1529
+ key = "obj-#{obj.obj_type.to_s}-#{obj.name}"
1530
+ @page_objects[key] = obj.content
1531
+ end
1532
+ end
1533
+ end
1534
+
1535
+ def load_template_options
1536
+ begin
1537
+ render_to_string :inline => @pg.template.content
1538
+ rescue Exception => e
1539
+ logger.debug e
1540
+ end
1541
+ end
1542
+
1543
+ def garbage_collect
1544
+ GC.start
1545
+ end
1546
+
1547
+ def create_captions_file(pg_id, options = {})
1548
+ gallery_id = (!options[:gallery_id] ? params[:gallery_id] : options[:gallery_id])
1549
+
1550
+ @pg = CmsPage.find_by_id(pg_id)
1551
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1552
+ gallery_dir = File.join(galleries_dir, gallery_id)
1553
+ captions_location = File.join(gallery_dir, 'captions.yml')
1554
+
1555
+ return if File.exists?(captions_location)
1556
+
1557
+ File.open(captions_location, 'w') { |f| YAML.dump([0], f) }
1558
+ end
1559
+
1560
+ # prerequisites: @pg (CmsPage)
1561
+ def load_gallery_settings_from_file(gallery_id, options = {})
1562
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1563
+ gallery_dir = File.join(galleries_dir, gallery_id)
1564
+ settings_location = File.join(gallery_dir, 'settings.yml')
1565
+
1566
+ ret = {}
1567
+
1568
+ if File.exists?(settings_location)
1569
+ File.open(settings_location, 'r') { |f| ret = YAML.load(f.read) }
1570
+ else
1571
+ File.open(settings_location, 'w') { |f| YAML.dump({}, f) }
1572
+ end
1573
+
1574
+ # set a few defaults
1575
+ ret[:slide_duration] ||= 0
1576
+ ret[:show_thumbs] ||= true
1577
+
1578
+ return HashObject.new(ret)
1579
+ end
1580
+
1581
+ # prerequisites: @pg (CmsPage)
1582
+ def save_gallery_settings_to_file(gallery_id, settings_hash, options = {})
1583
+ settings_hash = settings_hash.hash if settings_hash.kind_of?(HashObject)
1584
+
1585
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1586
+ gallery_dir = File.join(galleries_dir, gallery_id)
1587
+ settings_location = File.join(gallery_dir, 'settings.yml')
1588
+
1589
+ File.open(settings_location, 'w') { |f| YAML.dump(settings_hash, f) }
1590
+ end
1591
+
1592
+ def resize_image(localfile)
1593
+ ext = File.extname(localfile)
1594
+
1595
+ # AKN: this would change all files to jpeg format... commenting out for now
1596
+ # filename = File.join(File.dirname(localfile), File.basename(localfile, ext) + '.jpg')
1597
+ filename = localfile
1598
+
1599
+ im = MiniMagick::Image::from_file(localfile)
1600
+
1601
+ if im[:width] > GalleryMaxWidth || im[:height] > GalleryMaxHeight
1602
+ im.resize("#{GalleryMaxWidth}x#{GalleryMaxHeight}")
1603
+ im.write(filename)
1604
+ elsif filename != localfile
1605
+ im.write(filename)
1606
+ end
1607
+
1608
+ File.unlink(localfile) unless localfile == filename
1609
+
1610
+ filename
1611
+ end
1612
+
1613
+ def create_preview_image(src_file, dest, force = 0, overlay = 'gallery_small_overlay.png', thumb_size = 90)
1614
+ require 'RMagick'
1615
+
1616
+ dest = File.join(dest, File.basename(src_file)) if File.directory?(dest)
1617
+ if !File.exists?(dest) || force == 1
1618
+ im = Magick::Image::read(src_file)[0]
1619
+ im_overlay = Magick::Image::read(File.join(Rails.root, 'public', 'images', 'management', overlay))[0]
1620
+
1621
+ im.crop_resized!(thumb_size, thumb_size)
1622
+ im = im.composite(im_overlay, Magick::CenterGravity, Magick::OverCompositeOp)
1623
+
1624
+ im.write(dest)
1625
+ File.chmod(0644, dest)
1626
+
1627
+ im = im_overlay = nil
1628
+ GC.start
1629
+
1630
+ nil
1631
+ end
1632
+ end
1633
+
1634
+ def create_preview_images(options = {})
1635
+ # assumes @pg has already been set before calling
1636
+
1637
+ galleries_dir = File.join(Rails.root, 'public', 'images', 'content', @pg.path)
1638
+ session[:broken_galleries] = []
1639
+
1640
+ # create preview images if not already made
1641
+ Dir.glob("#{galleries_dir}/gallery_*").each do |g|
1642
+ begin
1643
+ management_dir = File.join(g, 'management')
1644
+ FileUtils.mkdir_p(management_dir) unless File.exists?(management_dir)
1645
+
1646
+ images = Dir.glob("#{g}/*.{jpg,jpeg,png,gif}")
1647
+ preview_images = []
1648
+ images.each { |img| preview_images << img unless File.basename(img).include?('thumb') }
1649
+
1650
+ # gallery preview image
1651
+ preview_image_location = File.join(management_dir, 'preview.jpg')
1652
+ unless File.exists?(preview_image_location)
1653
+ preview_image = preview_images.first
1654
+ create_preview_image(preview_image, preview_image_location, options[:force], 'gallery_preview_overlay.png', 130)
1655
+ end
1656
+
1657
+ # photo preview images
1658
+ preview_images.each { |img| create_preview_image(img, management_dir, options[:force]) }
1659
+
1660
+ rescue Exception => e
1661
+ # some error handling here
1662
+ session[:broken_galleries] << File.basename(g)
1663
+
1664
+ log_error(e)
1665
+ end
1666
+ end
1667
+ end
1668
+
1669
+ end