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
@@ -249,12 +249,12 @@ module ActiveRecord #:nodoc:
249
249
 
250
250
  versioned_class.cattr_accessor :original_class
251
251
  versioned_class.original_class = self
252
- versioned_class.set_table_name versioned_table_name
252
+ versioned_class.table_name = versioned_table_name
253
253
  versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym,
254
254
  :class_name => "::#{self.to_s}",
255
255
  :foreign_key => versioned_foreign_key
256
256
  versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
257
- versioned_class.set_sequence_name version_sequence_name if version_sequence_name
257
+ versioned_class.sequence_name = version_sequence_name if version_sequence_name
258
258
  end
259
259
 
260
260
  module Behaviors
@@ -268,134 +268,136 @@ module ActiveRecord #:nodoc:
268
268
  after_save :clear_old_versions
269
269
  end
270
270
 
271
- module InstanceMethods
272
- # Saves a version of the model in the versioned table. This is called in the after_save callback by default
273
- def save_version
274
- if @saving_version
275
- @saving_version = nil
276
- rev = self.class.versioned_class.new
277
- clone_versioned_model(self, rev)
278
- rev.send("#{self.class.version_column}=", send(self.class.version_column))
279
- rev.send("#{self.class.versioned_foreign_key}=", id)
280
- rev.save
281
- end
271
+ # Saves a version of the model in the versioned table. This is called in the after_save callback by default
272
+ def save_version
273
+ if @saving_version
274
+ @saving_version = nil
275
+ rev = self.class.versioned_class.new
276
+ clone_versioned_model(self, rev)
277
+ rev.send("#{self.class.version_column}=", send(self.class.version_column))
278
+ rev.send("#{self.class.versioned_foreign_key}=", id)
279
+ rev.save
282
280
  end
281
+ end
283
282
 
284
- # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
285
- # Override this method to set your own criteria for clearing old versions.
286
- def clear_old_versions
287
- return if self.class.max_version_limit == 0
288
- excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
289
- if excess_baggage > 0
290
- self.class.versioned_class.delete_all ["#{self.class.version_column} <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
291
- end
283
+ # Clears old revisions if a limit is set with the :limit option in <tt>acts_as_versioned</tt>.
284
+ # Override this method to set your own criteria for clearing old versions.
285
+ def clear_old_versions
286
+ return if self.class.max_version_limit == 0
287
+ excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
288
+ if excess_baggage > 0
289
+ self.class.versioned_class.delete_all ["#{self.class.version_column} <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
292
290
  end
291
+ end
293
292
 
294
- # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
295
- def revert_to(version)
296
- if version.is_a?(self.class.versioned_class)
297
- return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
298
- else
299
- return false unless version = versions.where(self.class.version_column => version).first
300
- end
301
- self.clone_versioned_model(version, self)
302
- send("#{self.class.version_column}=", version.send(self.class.version_column))
303
- true
293
+ # Reverts a model to a given version. Takes either a version number or an instance of the versioned model
294
+ def revert_to(version)
295
+ if version.is_a?(self.class.versioned_class)
296
+ return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
297
+ else
298
+ return false unless version = versions.where(self.class.version_column => version).first
304
299
  end
300
+ self.clone_versioned_model(version, self)
301
+ send("#{self.class.version_column}=", version.send(self.class.version_column))
302
+ true
303
+ end
305
304
 
306
- # Reverts a model to a given version and saves the model.
307
- # Takes either a version number or an instance of the versioned model
308
- def revert_to!(version)
309
- revert_to(version) ? save_without_revision : false
310
- end
305
+ # Reverts a model to a given version and saves the model.
306
+ # Takes either a version number or an instance of the versioned model
307
+ def revert_to!(version)
308
+ revert_to(version) ? save_without_revision : false
309
+ end
311
310
 
312
- # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
313
- def save_without_revision
314
- save_without_revision!
315
- true
316
- rescue
317
- false
318
- end
311
+ # Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.
312
+ def save_without_revision
313
+ save_without_revision!
314
+ true
315
+ rescue
316
+ false
317
+ end
319
318
 
320
- def save_without_revision!
321
- without_locking do
322
- without_revision do
323
- save!
324
- end
319
+ def save_without_revision!
320
+ without_locking do
321
+ without_revision do
322
+ save!
325
323
  end
326
324
  end
325
+ end
327
326
 
328
- def altered?
329
- track_altered_attributes ? (version_if_changed - changed).length < version_if_changed.length : changed?
330
- end
331
-
332
- # Clones a model. Used when saving a new version or reverting a model's version.
333
- def clone_versioned_model(orig_model, new_model)
334
- self.class.versioned_columns.each do |col|
335
- new_model[col.name] = orig_model.send(col.name) if orig_model.has_attribute?(col.name)
336
- end
327
+ def altered?
328
+ track_altered_attributes ? (version_if_changed - changed).length < version_if_changed.length : changed?
329
+ end
337
330
 
338
- if orig_model.is_a?(self.class.versioned_class)
339
- new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
340
- elsif new_model.is_a?(self.class.versioned_class)
341
- new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
342
- end
331
+ # Clones a model. Used when saving a new version or reverting a model's version.
332
+ def clone_versioned_model(orig_model, new_model)
333
+ self.class.versioned_columns.each do |col|
334
+ new_model[col.name] = orig_model.send(col.name) if orig_model.has_attribute?(col.name)
343
335
  end
344
336
 
345
- # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
346
- def save_version?
347
- version_condition_met? && altered?
337
+ clone_inheritance_column(orig_model, new_model)
338
+ end
339
+
340
+ def clone_inheritance_column(orig_model, new_model)
341
+ if orig_model.is_a?(self.class.versioned_class) && new_model.class.column_names.include?(new_model.class.inheritance_column.to_s)
342
+ new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
343
+ elsif new_model.is_a?(self.class.versioned_class) && new_model.class.column_names.include?(self.class.versioned_inheritance_column.to_s)
344
+ new_model[self.class.versioned_inheritance_column] = orig_model[orig_model.class.inheritance_column]
348
345
  end
346
+ end
349
347
 
350
- # Checks condition set in the :if option to check whether a revision should be created or not. Override this for
351
- # custom version condition checking.
352
- def version_condition_met?
353
- case
354
- when version_condition.is_a?(Symbol)
355
- send(version_condition)
356
- when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
357
- version_condition.call(self)
358
- else
359
- version_condition
360
- end
361
- end
348
+ # Checks whether a new version shall be saved or not. Calls <tt>version_condition_met?</tt> and <tt>changed?</tt>.
349
+ def save_version?
350
+ version_condition_met? && altered?
351
+ end
362
352
 
363
- # Executes the block with the versioning callbacks disabled.
364
- #
365
- # @foo.without_revision do
366
- # @foo.save
367
- # end
368
- #
369
- def without_revision(&block)
370
- self.class.without_revision(&block)
353
+ # Checks condition set in the :if option to check whether a revision should be created or not. Override this for
354
+ # custom version condition checking.
355
+ def version_condition_met?
356
+ case
357
+ when version_condition.is_a?(Symbol)
358
+ send(version_condition)
359
+ when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
360
+ version_condition.call(self)
361
+ else
362
+ version_condition
371
363
  end
364
+ end
372
365
 
373
- # Turns off optimistic locking for the duration of the block
374
- #
375
- # @foo.without_locking do
376
- # @foo.save
377
- # end
378
- #
379
- def without_locking(&block)
380
- self.class.without_locking(&block)
381
- end
366
+ # Executes the block with the versioning callbacks disabled.
367
+ #
368
+ # @foo.without_revision do
369
+ # @foo.save
370
+ # end
371
+ #
372
+ def without_revision(&block)
373
+ self.class.without_revision(&block)
374
+ end
382
375
 
383
- def empty_callback()
384
- end
376
+ # Turns off optimistic locking for the duration of the block
377
+ #
378
+ # @foo.without_locking do
379
+ # @foo.save
380
+ # end
381
+ #
382
+ def without_locking(&block)
383
+ self.class.without_locking(&block)
384
+ end
385
385
 
386
- #:nodoc:
386
+ def empty_callback()
387
+ end
387
388
 
388
- protected
389
- # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
390
- def set_new_version
391
- @saving_version = new_record? || save_version?
392
- self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
393
- end
389
+ #:nodoc:
394
390
 
395
- # Gets the next available version for the current record, or 1 for a new record
396
- def next_version
397
- (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
398
- end
391
+ protected
392
+ # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version.
393
+ def set_new_version
394
+ @saving_version = new_record? || save_version?
395
+ self.send("#{self.class.version_column}=", next_version) if new_record? || (!locking_enabled? && save_version?)
396
+ end
397
+
398
+ # Gets the next available version for the current record, or 1 for a new record
399
+ def next_version
400
+ (new_record? ? 0 : versions.calculate(:maximum, version_column).to_i) + 1
399
401
  end
400
402
 
401
403
  module ClassMethods
@@ -19,7 +19,6 @@ if ActiveRecord::Base.connection.supports_migrations?
19
19
 
20
20
  Thing.connection.drop_table "things" rescue nil
21
21
  Thing.connection.drop_table "thing_versions" rescue nil
22
- Thing.reset_column_information
23
22
  end
24
23
 
25
24
  def test_versioned_migration
@@ -1,172 +1,183 @@
1
1
  module ActionControllerExtensions
2
+
2
3
  module ClassMethods
3
4
  end
4
5
 
5
6
  module InstanceMethods
6
-
7
- # Saves the current request to the session so that it can be replayed later
8
- # (for example, after authentication). Only params of type String, Hash and
9
- # Array will be saved. save_request is called in a before_filter in
10
- # application.rb.
11
- #
12
- # Two levels of saved params are required so that params can be unsaved in
13
- # the event of a 404 or other event that would make the current param set an
14
- # unlikely or undesirable candidate for replaying.
15
- def save_user_request
16
- return if params[:action] == 'login'
17
-
18
- session[:old_saved_user_uri] = session[:saved_user_uri];
19
- session[:old_saved_user_params] = session[:saved_user_params] || {};
20
- saved_params = params.reject { |k, v| !(v.kind_of?(String) || v.kind_of?(Hash) || v.kind_of?(Array)) }
21
- saved_params.each { |key, val| saved_params[key] = val.reject { |k, v| !(v.kind_of?(String) || v.kind_of?(Hash) || v.kind_of?(Array)) } if val.kind_of?(Hash) }
22
- session[:saved_user_uri] = request.url
23
- session[:saved_user_params] = saved_params
24
- end
25
-
26
- # Returns a User object corresponding to the currently logged in user, or returns false
27
- # and redirects to the login page if not logged in.
28
- def authenticate_user
29
- # if user is not logged in, record the current request and redirect
30
- if !session[:user_authenticated]
31
- if User.find(:all).size == 0
32
- flash[:notice] = 'No users exist in the system. Please create one now.'
33
- redirect_to :controller => '/management/user', :action => 'create_first'
34
- else
35
- flash[:notice] = 'This is an admin-only function. To continue, please log in.'
36
- save_user_request
37
- redirect_to :controller => '/management/user', :action => 'login'
38
- end
7
+ def expire_session_data # :nodoc:
8
+ # make sure this is not the first run (session being initialized)
9
+ if session[:last_active]
10
+ idle_time = Time.now - session[:last_active]
39
11
 
40
- return false
12
+ # expire session data as necessary
13
+ # session_data = session.instance_variable_get("@data")
14
+ # session_data.select { |k,v| k.to_s !~ /_expiration$/ && v }.each do |k,v|
15
+ # idx = k.to_s + '_expiration'
16
+ # if (exp = (session[idx] || session[idx.to_sym]).to_i) > 0
17
+ # if idle_time > exp
18
+ # logger.debug "Expiring #{k} = #{v} (expiration #{exp} > idle time #{idle_time})"
19
+ # session[k] = nil
20
+ # else
21
+ # logger.debug "Retaining #{k} = #{v} (expiration #{exp} < idle time #{idle_time})"
22
+ # end
23
+ # else
24
+ # #logger.debug "Retaining #{k} = #{v} (does not expire)"
25
+ # end
26
+ # end
41
27
  end
42
28
 
43
- @user = User.find(session[:user_id]) rescue nil
44
- session[:user_is_superuser] = @user.is_superuser rescue nil
45
-
46
- @user
29
+ # bump/set last active time
30
+ session[:last_active] = Time.now
31
+ if is_logged_in_user?
32
+ cookies[:user_auth_status] = { :value => 'authenticated', :expires => 5.minutes.from_now }
33
+ end
47
34
  end
48
35
 
49
- # Takes a symbol/string or array of symbols/strings and returns true if user has all
50
- # of the named permissions.
51
- #
52
- # Result is stored in the session to speed up future checks.
53
- def user_has_permissions?(*permission_set)
54
- return false if !(@user ||= authenticate_user)
36
+
37
+ # valid options:
38
+ # * :include_tags => 'tags, to, include'
39
+ # * :exclude_tags => 'tags, to, exclude'
40
+ def insert_object(name, type = :text, options = {}, html_options = {})
41
+ extend ActionView::Helpers::TagHelper
42
+ extend ActionView::Helpers::TextHelper
55
43
 
56
- if !permission_set.is_a? Array
57
- permission_set = [ permission_set ]
58
- end
44
+ @page_objects ||= {}
59
45
 
60
- if session[:user_is_superuser]
61
- for perm in permission_set
62
- perm = perm.to_s
63
- session[('user_can_' + perm).to_sym] ||= true
46
+ key = "obj-#{type.to_s}-#{name.gsub(/[^\w]/, '_')}"
47
+ case type.to_sym
48
+ when :string
49
+ content = substitute_placeholders(@page_objects[key] || '', @pg)
50
+ content = erb_render(content)
51
+ content = auto_link(content, :all, :target => '_blank') unless options[:disable_auto_link]
52
+ content_tag :span, content, html_options
53
+ when :text
54
+ content = substitute_placeholders(@page_objects[key] || '', @pg)
55
+ content = erb_render(content)
56
+ # content = auto_link(content, :all, :target => '_blank') unless options[:disable_auto_link]
57
+ content_tag :div, content, html_options
58
+ when :page_list
59
+ @rss_feeds ||= []
60
+ @rss_feeds << name
61
+
62
+ case @page_objects["#{key}-style-display-as"]
63
+ when 'calendar'
64
+ pages = page_list_items(@pg, key, options).compact.uniq.
65
+ sort { |a,b| (a.position || 0) <=> (b.position || 0) }.
66
+ sort { |a,b| (b.article_date || b.published_date || Time.now) <=>
67
+ (a.article_date || a.published_date || Time.now) }
68
+ render :partial => 'page_list_calendar', :locals => { :key => key, :pages => pages }
69
+ else # display as 'list'
70
+ today = Time.utc(Time.now.year, Time.now.month, Time.now.day)
71
+ case @page_objects["#{key}-date-range"]
72
+ when 'all'
73
+ when 'past'
74
+ options[:end_date] ||= today
75
+ when 'future'
76
+ options[:start_date] ||= today
77
+ when 'custom'
78
+ options[:start_date] ||= @page_objects["#{key}-date-range-custom-start"]
79
+ options[:end_date] ||= @page_objects["#{key}-date-range-custom-end"]
80
+ end
81
+
82
+ pages = page_list_items(@pg, key, options).compact.uniq
83
+
84
+ options[:wrapper_div] = true
85
+
86
+ # make options specified in snippets and templates accessible to
87
+ # page list segments and rss feeds
88
+ @page_objects["#{key}-template"] = options[:template] if @page_objects["#{key}-template"].empty?
89
+
90
+ render_page_list_segment(name, pages, options, html_options)
64
91
  end
65
- return true
66
- end
67
-
68
- for perm in permission_set
69
- perm = perm.to_s
70
- session[('user_can_' + perm).to_sym] = @user.send('can_' + perm)
71
- # logger.debug "user_can_#{perm} = #{@user.send('can_' + perm)}"
72
- return session[('user_can_' + perm).to_sym]
92
+ when :snippet
93
+ @snippet = CmsSnippet.find_by_name(name)
94
+ if @snippet
95
+ erb_render(substitute_placeholders(@snippet.content, @pg))
96
+ else
97
+ 'Could not find snippet "' + name + '" in the database.'
98
+ end
99
+ when :photo_gallery
100
+ gallery_dir = File.join('images', 'content', @pg.path, File.basename(name))
101
+ Dir.chdir(File.join(Rails.root, 'public'))
102
+ all_images = Dir.glob("#{gallery_dir}/*.{jpg,jpeg,png,gif}")
103
+ Dir.chdir(Rails.root)
104
+ all_images.sort! { |a,b| File.basename(a).to_i <=> File.basename(b).to_i }
105
+ images = all_images.reject { |img| img =~ /-thumb/ }
106
+ thumbs = all_images.reject { |img| img !~ /-thumb/ }
107
+ render_to_string(:partial => 'photo_gallery', :locals => { :name => name, :images => images, :thumbs => thumbs }).html_safe
73
108
  end
74
109
  end
75
- alias :user_has_permission? :user_has_permissions?
76
110
 
77
- # Determines whether the input string is a valid email address per RFC specification
78
- def valid_email_address?(addr, perform_mx_lookup = false)
79
- valid = true
111
+ def render_page_list_segment(name, pages, options = {}, html_options = {})
112
+ extend ActionView::Helpers::TagHelper
113
+ extend ActionView::Helpers::TextHelper
114
+ extend ActionView::Helpers::JavaScriptHelper
115
+ extend ActionView::Helpers::PrototypeHelper
80
116
 
81
- # simplified regex for speed... the original can basically lock up the system on longish addresses
82
- # valid = valid && addr.to_s =~ /\A([\w\d]+(?:[\w\d\!\#\$\%\&\*\+\-\/\=\?\^\`\{\|\}\~\.]*[\w\d]+)*)@((?:[\w\d]+(?:[-]*[\w\d]+)*\.)+[\w]{2,})\z/
83
- valid = valid && addr.to_s =~ /\A([\w\d\!\#\$\%\&\*\+\-\/\=\?\^\`\{\|\}\~\.]+)@((?:[\w\d]+(?:[-]*[\w\d]+)*\.)+[\w]{2,})\z/
84
- user, host = $1, $2
117
+ key = "obj-page_list-#{name.gsub(/[^\w]/, '_')}"
85
118
 
86
- # blacklist
87
- # return false if ContactEmailBlacklist.include?(addr.to_s.strip)
119
+ offset = first_non_empty(params[:offset], 0).to_i
120
+ limit = first_non_empty(@page_objects["#{key}-max-item-count"], options[:item_count], pages.size).to_i
121
+ limit = 1 if limit < 1
122
+ page_subset = pages[offset, limit] || []
88
123
 
89
- if perform_mx_lookup
90
- begin
91
- # require 'net/dns'
92
- res = Net::DNS::Resolver.new
93
- valid = valid && res.mx(host).size > 0
94
- rescue Exception => e
95
- logger.error(e)
124
+ content = ''
125
+ content << substitute_placeholders(first_non_empty(@page_objects["#{key}-header"], options[:header]), @pg,
126
+ :count => page_subset.size, :total => pages.size,
127
+ :rss_feed_url => (@pg && @pg.id ? url_for(:action => 'rss_feed', :page_id => @pg.id,
128
+ :page_list_name => name) : nil))
129
+ if page_subset.empty?
130
+ content << substitute_placeholders(first_non_empty(@page_objects["#{key}-empty_message"],
131
+ options[:empty_message],
132
+ 'No pages found.'), @pg)
133
+ else
134
+ page_subset.each_with_index do |page, index|
135
+ content << substitute_placeholders(first_non_empty(@page_objects["#{key}-template"], options[:template], ''), page,
136
+ :index => index+1, :count => page_subset.size, :total => pages.size)
96
137
  end
97
138
  end
98
139
 
99
- valid
100
- end
101
-
102
- ### COMPAT: convert_content_path
103
- def convert_content_path
104
- logger.debug "DEPRECATION WARNING: convert_content_path called"
105
- params[:content_path] = params[:content_path].to_s.split('/') rescue []
106
- end
107
-
108
- ### COMPAT - template_exists?
109
- def template_exists?(template, extension = nil)
110
- # ignore extension
111
- logger.debug("DEPRECATION WARNING: template_exists? called")
112
- partial = File.join(File.dirname(template), '_' + File.basename(template))
113
- lookup_context.find_all(template).any? || lookup_context.find_all(partial).any?
114
- end
115
-
116
- ### COMPAT - template_exists?
117
- def url_for_current
118
- logger.debug("DEPRECATION WARNING: url_for_current called")
119
- request.fullpath
120
- end
121
-
122
- ### COMPAT - log_error
123
- def log_error(e)
124
- # noop
125
- logger.debug("DEPRECATION WARNING: log_error called")
126
- logger.error(e)
127
- end
128
-
129
- # Convert from GMT/UTC to local time (based on time zone setting in session[:time_zone])
130
- def gm_to_local(time)
131
- ActiveSupport::TimeZone.new(session[:time_zone] || 'UTC').utc_to_local(time)
132
- end
133
-
134
- # Convert from local time to GMT/UTC (based on time zone setting in session[:time_zone])
135
- def local_to_gm(time)
136
- ActiveSupport::TimeZone.new(session[:time_zone] || 'UTC').local_to_utc(time)
137
- end
138
-
139
- # Convert a time object into a formatted date/time string
140
- def ts_to_str(ts)
141
- return '' if ts == nil
142
- gm_to_local(ts).strftime('%a %b %d, %Y') + ' at ' +
143
- gm_to_local(ts).strftime('%I:%M%p').downcase + ' ' + (session[:time_zone_abbr] || '')
144
- end
145
-
146
- # Convert a time object into a formatted time string (no date)
147
- def ts_to_time_str(ts)
148
- return '' if ts == nil
149
- gm_to_local(ts).strftime('%I:%M:%S%p').downcase
150
- end
151
-
152
- # Convert times to a standard format (e.g. 1:35pm)
153
- def time_to_str(t, convert = true)
154
- return '' if t == nil
155
- if convert
156
- gm_to_local(t).strftime("%I").to_i.to_s + gm_to_local(t).strftime(":%M%p").downcase
140
+ content << substitute_placeholders(first_non_empty(@page_objects["#{key}-footer"], options[:footer]), @pg,
141
+ :count => page_subset.size, :total => pages.size,
142
+ :rss_feed_url => (@pg && @pg.id ? url_for(:action => 'rss_feed', :page_id => @pg.id,
143
+ :page_list_name => name) : nil))
144
+
145
+ num_segments = (pages.size.to_f / limit).ceil
146
+ if @page_objects["#{key}-use-pagination"].to_i == 1 && num_segments > 1
147
+ content << '<table style="margin-top: 4px;" align="right" cellpadding="0" cellspacing="0" border="0"><tr valign="bottom">'
148
+ content << '<td>Page:&nbsp;</td>'
149
+ num_segments.times do |seg|
150
+ start = seg * limit
151
+ content << "<td><div"
152
+ if offset >= start && offset < (start + limit)
153
+ content << " class=\"page_list_segment page_list_segment_selected\""
154
+ else
155
+ content << " class=\"page_list_segment\""
156
+ content << " onmouseover=\"this.className = 'page_list_segment page_list_segment_selected'\""
157
+ content << " onmouseout=\"this.className = 'page_list_segment'\""
158
+ content << " onclick=\"this.style.cursor = 'wait';"
159
+ content << remote_function(:update => key, :url => { :content_path => @pg.path.split('/').concat([ 'segment', start.to_s, name ]) })
160
+ content << "; return false;\""
161
+ end
162
+ content << ">#{seg+1}</div></td>"
163
+ end
164
+ content << '</tr></table>'
165
+ end
166
+
167
+ if options[:wrapper_div]
168
+ content_tag :div, erb_render(content), html_options.update(:id => key)
157
169
  else
158
- t.strftime("%I").to_i.to_s + t.strftime(":%M%p").downcase
170
+ erb_render(content)
159
171
  end
160
172
  end
161
173
 
162
- # Convert times to a standard format (e.g. 1:35pm)
163
- def date_to_str(t, convert = true)
164
- return '' if t == nil
165
- if convert
166
- gm_to_local(t).strftime("%m").to_i.to_s + '/' + gm_to_local(t).strftime("%d").to_i.to_s + gm_to_local(t).strftime("/%Y")
167
- else
168
- t.strftime("%m").to_i.to_s + '/' + t.strftime("%d").to_i.to_s + t.strftime("/%Y")
169
- end
174
+ def erb_render(content, safe_level = 3, rethrow_exceptions = false)
175
+ # sanitize possibly dangerous content before rendering
176
+ content.gsub!(/<(%.*?(exec|system)\s?\(.*?\s*%)>/, '&lt;\1&gt;')
177
+ content.gsub!(/<(%.*?\%x\s?\[.*?\s*%)>/, '&lt;\1&gt;')
178
+ content.gsub!(/<(%.*?\`.*?\s*%)>/, '&lt;\1&gt;')
179
+
180
+ render_to_string(:inline => content.to_s).html_safe
170
181
  end
171
182
 
172
183
  end