browsercms 3.5.7 → 4.0.0.alpha

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 (523) hide show
  1. checksums.yaml +7 -0
  2. data/COPYRIGHT.txt +2 -1
  3. data/README.markdown +3 -3
  4. data/app/assets/fonts/icomoon.dev.svg +61 -0
  5. data/app/assets/fonts/icomoon.eot +0 -0
  6. data/app/assets/fonts/icomoon.svg +61 -0
  7. data/app/assets/fonts/icomoon.ttf +0 -0
  8. data/app/assets/fonts/icomoon.woff +0 -0
  9. data/app/assets/images/ckeditor/plugins/delete_content/icons/deletecontent.png +0 -0
  10. data/app/assets/images/ckeditor/plugins/edit_content/icons/editcontent.png +0 -0
  11. data/app/assets/images/ckeditor/plugins/move_content/icons/movecontentdown.png +0 -0
  12. data/app/assets/images/ckeditor/plugins/move_content/icons/movecontentup.png +0 -0
  13. data/app/assets/images/cms/arrow-down.png +0 -0
  14. data/app/assets/images/cms/arrow-up.png +0 -0
  15. data/app/assets/images/cms/cogs.png +0 -0
  16. data/app/assets/images/cms/dashboard/home.png +0 -0
  17. data/app/assets/images/cms/home.png +0 -0
  18. data/app/assets/images/cms/logo.png +0 -0
  19. data/app/assets/images/cms/pencil.png +0 -0
  20. data/app/assets/images/cms/plus.png +0 -0
  21. data/app/assets/images/cms/user.png +0 -0
  22. data/app/assets/javascripts/bcms/ckeditor_inline.js +23 -0
  23. data/app/assets/javascripts/bcms/ckeditor_standard_config.js +1 -1
  24. data/app/assets/javascripts/ckeditor/plugins/delete_content/plugin.js +36 -0
  25. data/app/assets/javascripts/ckeditor/plugins/edit_content/plugin.js +24 -0
  26. data/app/assets/javascripts/ckeditor/plugins/move_content/plugin.js +25 -0
  27. data/app/assets/javascripts/cms/ajax.js +60 -0
  28. data/app/assets/javascripts/cms/application.js +6 -1
  29. data/app/assets/javascripts/cms/attachment_manager.js.erb +3 -10
  30. data/app/assets/javascripts/cms/content_library.js +31 -12
  31. data/app/assets/javascripts/cms/core_library.js.erb +68 -36
  32. data/app/assets/javascripts/cms/form_builder.js +250 -0
  33. data/app/assets/javascripts/cms/namespace.js +2 -0
  34. data/app/assets/javascripts/cms/new_content_button.js +27 -0
  35. data/app/assets/javascripts/cms/page_editor.js +188 -0
  36. data/app/assets/javascripts/cms/page_toolbar.js +13 -0
  37. data/app/assets/javascripts/cms/site.js +2 -0
  38. data/app/assets/javascripts/cms/sitemap.js +219 -0
  39. data/app/assets/javascripts/cms/toolbar.js +17 -1
  40. data/app/assets/javascripts/cms/user.js +40 -0
  41. data/app/assets/javascripts/jquery.exists.js +5 -0
  42. data/app/assets/javascripts/jquery.taglist.js +37 -23
  43. data/app/assets/stylesheets/cms/_assets.css.scss +55 -0
  44. data/app/assets/stylesheets/cms/_base.css.scss +42 -0
  45. data/app/assets/stylesheets/cms/_cms-buttons.css.scss +73 -0
  46. data/app/assets/stylesheets/cms/_cms-forms.css.scss +70 -0
  47. data/app/assets/stylesheets/cms/_colors.css.scss +20 -0
  48. data/app/assets/stylesheets/cms/_dashboard.css.scss +25 -0
  49. data/app/assets/stylesheets/cms/_glyph.css.scss +60 -0
  50. data/app/assets/stylesheets/cms/_main-area.css.scss +62 -0
  51. data/app/assets/stylesheets/cms/_nav.css.scss +197 -0
  52. data/app/assets/stylesheets/cms/_sidebar.css.scss +64 -0
  53. data/app/assets/stylesheets/cms/_sitemap.css.scss +196 -0
  54. data/app/assets/stylesheets/cms/_submenu.css.scss +48 -0
  55. data/app/assets/stylesheets/cms/application.css.scss +49 -0
  56. data/app/assets/stylesheets/cms/core.css.scss +96 -0
  57. data/app/assets/stylesheets/cms/default-forms.css.scss +3 -0
  58. data/app/assets/stylesheets/cms/includes/_animation.css.scss +2 -0
  59. data/app/assets/stylesheets/cms/includes/_rem.css.scss +120 -0
  60. data/app/assets/stylesheets/cms/includes/animation/_animate.css.scss +31 -0
  61. data/app/assets/stylesheets/cms/includes/animation/_core.css.scss +127 -0
  62. data/app/assets/stylesheets/cms/includes/animation/_shared.css.scss +22 -0
  63. data/app/assets/stylesheets/cms/includes/animation/animate/_attention-seekers.css.scss +152 -0
  64. data/app/assets/stylesheets/cms/includes/animation/animate/_bouncing.css.scss +3 -0
  65. data/app/assets/stylesheets/cms/includes/animation/animate/_classes.css.scss +21 -0
  66. data/app/assets/stylesheets/cms/includes/animation/animate/_fading.css.scss +3 -0
  67. data/app/assets/stylesheets/cms/includes/animation/animate/_flippers.css.scss +87 -0
  68. data/app/assets/stylesheets/cms/includes/animation/animate/_lightspeed.css.scss +24 -0
  69. data/app/assets/stylesheets/cms/includes/animation/animate/_rotating.css.scss +3 -0
  70. data/app/assets/stylesheets/cms/includes/animation/animate/_specials.css.scss +42 -0
  71. data/app/assets/stylesheets/cms/includes/animation/animate/bouncing/_bouncing-entrances.css.scss +68 -0
  72. data/app/assets/stylesheets/cms/includes/animation/animate/bouncing/_bouncing-exits.css.scss +60 -0
  73. data/app/assets/stylesheets/cms/includes/animation/animate/fading/_fading-entrances.css.scss +86 -0
  74. data/app/assets/stylesheets/cms/includes/animation/animate/fading/_fading-exits.css.scss +86 -0
  75. data/app/assets/stylesheets/cms/includes/animation/animate/rotating/_rotating-entrances.css.scss +58 -0
  76. data/app/assets/stylesheets/cms/includes/animation/animate/rotating/_rotating-exits.css.scss +58 -0
  77. data/app/assets/stylesheets/cms/page_content_editing.css.scss +4 -0
  78. data/app/assets/stylesheets/cms/page_editor.css.scss +4 -0
  79. data/app/assets/stylesheets/cms/style.css.scss +138 -0
  80. data/app/assets/stylesheets/cms/styles/_alerts.css.scss +150 -0
  81. data/app/assets/stylesheets/cms/styles/_base-grid.css.scss +299 -0
  82. data/app/assets/stylesheets/cms/styles/_buttons.css.scss +247 -0
  83. data/app/assets/stylesheets/cms/styles/_dropdown.css.scss +155 -0
  84. data/app/assets/stylesheets/cms/styles/_forms.css.scss +728 -0
  85. data/app/assets/stylesheets/cms/styles/_glyph.css.scss +86 -0
  86. data/app/assets/stylesheets/cms/styles/_images.css.scss +75 -0
  87. data/app/assets/stylesheets/cms/styles/_lists.css.scss +115 -0
  88. data/app/assets/stylesheets/cms/styles/_modal.css.scss +174 -0
  89. data/app/assets/stylesheets/cms/styles/_progress.css.scss +43 -0
  90. data/app/assets/stylesheets/cms/styles/_tables.css.scss +141 -0
  91. data/app/assets/stylesheets/cms/styles/_text.css.scss +134 -0
  92. data/app/controllers/cms/application_controller.rb +3 -68
  93. data/app/controllers/cms/attachments_controller.rb +5 -5
  94. data/app/controllers/cms/base_controller.rb +20 -13
  95. data/app/controllers/cms/cache_controller.rb +16 -17
  96. data/app/controllers/cms/category_types_controller.rb +6 -1
  97. data/app/controllers/cms/connectors_controller.rb +12 -7
  98. data/app/controllers/cms/content_block_controller.rb +128 -71
  99. data/app/controllers/cms/content_controller.rb +54 -56
  100. data/app/controllers/cms/dashboard_controller.rb +5 -6
  101. data/app/controllers/cms/dynamic_views_controller.rb +12 -9
  102. data/app/controllers/cms/email_messages_controller.rb +18 -13
  103. data/app/controllers/cms/form_entries_controller.rb +119 -0
  104. data/app/controllers/cms/form_fields_controller.rb +74 -0
  105. data/app/controllers/cms/forms_controller.rb +35 -0
  106. data/app/controllers/cms/groups_controller.rb +13 -16
  107. data/app/controllers/cms/html_blocks_controller.rb +2 -2
  108. data/app/controllers/cms/inline_content_controller.rb +48 -0
  109. data/app/controllers/cms/links_controller.rb +58 -46
  110. data/app/controllers/cms/page_components_controller.rb +20 -0
  111. data/app/controllers/cms/page_routes_controller.rb +44 -40
  112. data/app/controllers/cms/pages_controller.rb +111 -97
  113. data/app/controllers/cms/passwords_controller.rb +17 -0
  114. data/app/controllers/cms/portlet_controller.rb +0 -1
  115. data/app/controllers/cms/portlets_controller.rb +20 -27
  116. data/app/controllers/cms/redirects_controller.rb +13 -9
  117. data/app/controllers/cms/resource_controller.rb +15 -4
  118. data/app/controllers/cms/routes_controller.rb +2 -4
  119. data/app/controllers/cms/section_nodes_controller.rb +6 -37
  120. data/app/controllers/cms/sections_controller.rb +13 -8
  121. data/app/controllers/cms/sessions_controller.rb +8 -66
  122. data/app/controllers/cms/sites/passwords_controller.rb +27 -0
  123. data/app/controllers/cms/sites/sessions_controller.rb +20 -0
  124. data/app/controllers/cms/tags_controller.rb +12 -12
  125. data/app/controllers/cms/tasks_controller.rb +45 -46
  126. data/app/controllers/cms/user_controller.rb +8 -0
  127. data/app/controllers/cms/users_controller.rb +91 -68
  128. data/app/helpers/cms/application_helper.rb +58 -52
  129. data/app/helpers/cms/content_block_helper.rb +8 -7
  130. data/app/helpers/cms/form_tag_helper.rb +21 -25
  131. data/app/helpers/cms/menu_helper.rb +1 -3
  132. data/app/helpers/cms/mobile_helper.rb +12 -2
  133. data/app/helpers/cms/nav_menu_helper.rb +23 -0
  134. data/app/helpers/cms/page_helper.rb +72 -30
  135. data/app/helpers/cms/path_helper.rb +46 -70
  136. data/app/helpers/cms/rendering_helper.rb +68 -12
  137. data/app/helpers/cms/section_nodes_helper.rb +92 -31
  138. data/app/helpers/cms/sites/authentication_helper.rb +25 -0
  139. data/app/helpers/cms/sites/devise_shim_helper.rb +31 -0
  140. data/app/helpers/cms/template_support.rb +1 -7
  141. data/app/helpers/cms/ui_elements_helper.rb +147 -6
  142. data/app/helpers/forgot_password_portlet_helper.rb +9 -0
  143. data/app/helpers/login_portlet_helper.rb +10 -0
  144. data/app/inputs/attachments_input.rb +14 -0
  145. data/app/inputs/cms_text_area_input.rb +10 -0
  146. data/app/inputs/cms_text_field_input.rb +29 -0
  147. data/app/inputs/date_picker_input.rb +8 -0
  148. data/app/inputs/file_picker_input.rb +75 -0
  149. data/app/inputs/path_input.rb +18 -0
  150. data/app/inputs/tag_list_input.rb +3 -0
  151. data/app/inputs/template_editor_input.rb +24 -0
  152. data/app/inputs/text_editor_input.rb +19 -0
  153. data/app/models/cms/abstract_file_block.rb +10 -6
  154. data/app/models/cms/attachment.rb +20 -27
  155. data/app/models/cms/category.rb +17 -7
  156. data/app/models/cms/category_type.rb +8 -4
  157. data/app/models/cms/connector.rb +32 -20
  158. data/app/models/cms/content.rb +31 -0
  159. data/app/models/cms/content_type.rb +114 -62
  160. data/app/models/cms/dynamic_view.rb +19 -45
  161. data/app/models/cms/email_message.rb +32 -2
  162. data/app/models/cms/external_user.rb +60 -0
  163. data/app/models/cms/file_block.rb +1 -0
  164. data/app/models/cms/form.rb +47 -0
  165. data/app/models/cms/form_entry.rb +71 -0
  166. data/app/models/cms/form_field.rb +78 -0
  167. data/app/models/cms/group.rb +19 -9
  168. data/app/models/cms/group_permission.rb +1 -1
  169. data/app/models/cms/group_section.rb +1 -1
  170. data/app/models/cms/group_type.rb +5 -5
  171. data/app/models/cms/group_type_permission.rb +1 -1
  172. data/app/models/cms/html_block.rb +14 -19
  173. data/app/models/cms/image_block.rb +1 -0
  174. data/app/models/cms/link.rb +8 -6
  175. data/app/models/cms/page.rb +156 -59
  176. data/app/models/cms/page_component.rb +43 -0
  177. data/app/models/cms/page_partial.rb +16 -8
  178. data/app/models/cms/page_route.rb +1 -1
  179. data/app/models/cms/page_route_condition.rb +1 -1
  180. data/app/models/cms/page_route_option.rb +1 -1
  181. data/app/models/cms/page_route_requirement.rb +1 -1
  182. data/app/models/cms/page_template.rb +14 -9
  183. data/app/models/cms/permission.rb +4 -2
  184. data/app/models/cms/persistent_user.rb +208 -0
  185. data/app/models/cms/portlet.rb +56 -9
  186. data/app/models/cms/redirect.rb +1 -1
  187. data/app/models/cms/search_filter.rb +18 -0
  188. data/app/models/cms/section.rb +39 -28
  189. data/app/models/cms/section_node.rb +32 -5
  190. data/app/models/cms/site.rb +3 -3
  191. data/app/models/cms/tag.rb +14 -12
  192. data/app/models/cms/tagging.rb +2 -2
  193. data/app/models/cms/task.rb +14 -21
  194. data/app/models/cms/templates.rb +1 -2
  195. data/app/models/cms/user.rb +21 -160
  196. data/app/models/cms/user_group_membership.rb +2 -2
  197. data/app/portlets/deprecated_placeholder.rb +12 -0
  198. data/app/portlets/dynamic_portlet.rb +1 -1
  199. data/app/portlets/email_page_portlet.rb +10 -3
  200. data/app/portlets/forgot_password_portlet.rb +9 -28
  201. data/app/portlets/login_portlet.rb +8 -5
  202. data/app/portlets/tag_cloud_portlet.rb +3 -1
  203. data/app/presenters/cms/user_presenter.rb +24 -0
  204. data/app/views/cms/application/_add_content_modal.html.erb +3 -0
  205. data/app/views/cms/application/_buttons.html.erb +7 -0
  206. data/app/views/cms/{shared → application}/_exception.html.erb +0 -0
  207. data/app/views/cms/application/_form_errors.html.erb +7 -0
  208. data/app/views/cms/application/_form_with_buttons.html.erb +10 -0
  209. data/app/views/cms/application/_main_content.html.erb +3 -0
  210. data/app/views/cms/application/_main_with_sidebar.html.erb +8 -0
  211. data/app/views/cms/application/_mobile_toolbar.html.erb +16 -0
  212. data/app/views/cms/application/_page_title.html.erb +5 -0
  213. data/app/views/cms/application/_pagination.html.erb +26 -0
  214. data/app/views/cms/application/_row.html.erb +1 -0
  215. data/app/views/cms/application/_save_buttons.html.erb +7 -0
  216. data/app/views/cms/application/_sidebar_layout.html.erb +3 -0
  217. data/app/views/cms/application/_version.html.erb +23 -0
  218. data/app/views/cms/{shared → application}/_version_conflict_diff.html.erb +0 -0
  219. data/app/views/cms/{shared → application}/_version_conflict_error.html.erb +0 -0
  220. data/app/views/cms/attachments/_attachment_manager.html.erb +22 -0
  221. data/app/views/cms/attachments/_no_attachments_defined.html.erb +1 -0
  222. data/app/views/cms/cache/show.html.erb +5 -10
  223. data/app/views/cms/categories/_form.html.erb +15 -24
  224. data/app/views/cms/category_types/_form.html.erb +1 -1
  225. data/app/views/cms/connectors/new.html.erb +33 -64
  226. data/app/views/cms/content/editing_frame.html.erb +1 -0
  227. data/app/views/cms/content/no_page.html.erb +9 -27
  228. data/app/views/cms/content/show.html.erb +14 -15
  229. data/app/views/cms/content_block/_block_form.html.erb +15 -0
  230. data/app/views/cms/content_block/_buttonbar.html.erb +29 -0
  231. data/app/views/cms/content_block/_buttons.html.erb +13 -0
  232. data/app/views/cms/content_block/_hidden_fields.html.erb +13 -0
  233. data/app/views/cms/content_block/_sidebar.html.erb +35 -0
  234. data/app/views/cms/content_block/edit.html.erb +3 -0
  235. data/app/views/cms/content_block/index.html.erb +87 -0
  236. data/app/views/cms/content_block/new.html.erb +3 -0
  237. data/app/views/cms/content_block/render_block_in_main_container.html.erb +10 -0
  238. data/app/views/cms/content_block/show.html.erb +1 -0
  239. data/app/views/cms/content_block/show_in_isolation.html.erb +15 -0
  240. data/app/views/cms/content_block/versions.html.erb +24 -0
  241. data/app/views/cms/dashboard/_page_drafts.html.erb +12 -22
  242. data/app/views/cms/dashboard/_tasks.html.erb +32 -45
  243. data/app/views/cms/dashboard/index.html.erb +11 -13
  244. data/app/views/cms/dynamic_views/_form.html.erb +8 -10
  245. data/app/views/cms/dynamic_views/edit.html.erb +2 -3
  246. data/app/views/cms/dynamic_views/index.html.erb +22 -44
  247. data/app/views/cms/dynamic_views/new.html.erb +2 -3
  248. data/app/views/cms/email_messages/index.html.erb +31 -34
  249. data/app/views/cms/email_messages/show.html.erb +45 -52
  250. data/app/views/cms/file_blocks/_form.html.erb +2 -4
  251. data/app/views/cms/form_entries/_buttons.html.erb +2 -0
  252. data/app/views/cms/form_entries/_form.html.erb +7 -0
  253. data/app/views/cms/form_entries/_internal_form.html.erb +9 -0
  254. data/app/views/cms/form_entries/edit.html.erb +5 -0
  255. data/app/views/cms/form_entries/error.html.erb +3 -0
  256. data/app/views/cms/form_entries/index.html.erb +4 -0
  257. data/app/views/cms/form_entries/new.html.erb +5 -0
  258. data/app/views/cms/form_entries/show.html.erb +13 -0
  259. data/app/views/cms/form_entries/submit.html.erb +1 -0
  260. data/app/views/cms/form_fields/_form.html.erb +8 -0
  261. data/app/views/cms/form_fields/_select.html.erb +3 -0
  262. data/app/views/cms/form_fields/_text_area.html.erb +3 -0
  263. data/app/views/cms/form_fields/_text_field.html.erb +3 -0
  264. data/app/views/cms/form_fields/edit.html.erb +0 -0
  265. data/app/views/cms/form_fields/new.html.erb +26 -0
  266. data/app/views/cms/form_fields/preview.html.erb +16 -0
  267. data/app/views/cms/forms/_form.html.erb +66 -0
  268. data/app/views/cms/forms/render.html.erb +15 -0
  269. data/app/views/cms/forms/show.html.erb +6 -0
  270. data/app/views/cms/groups/_form.html.erb +32 -38
  271. data/app/views/cms/groups/_permissions.html.erb +11 -34
  272. data/app/views/cms/groups/_sections.html.erb +11 -17
  273. data/app/views/cms/groups/edit.html.erb +1 -3
  274. data/app/views/cms/groups/index.html.erb +10 -32
  275. data/app/views/cms/groups/new.html.erb +2 -4
  276. data/app/views/cms/html_blocks/_form.html.erb +2 -2
  277. data/app/views/cms/html_blocks/render.html.erb +1 -1
  278. data/app/views/cms/image_blocks/_form.html.erb +3 -3
  279. data/app/views/cms/links/_form.html.erb +6 -11
  280. data/app/views/cms/links/edit.html.erb +3 -12
  281. data/app/views/cms/links/new.html.erb +4 -13
  282. data/app/views/cms/page_components/_content.html.erb +18 -0
  283. data/app/views/cms/page_components/new.html.erb +12 -0
  284. data/app/views/cms/page_routes/_form.html.erb +11 -10
  285. data/app/views/cms/page_routes/edit.html.erb +2 -3
  286. data/app/views/cms/page_routes/index.html.erb +25 -48
  287. data/app/views/cms/page_routes/new.html.erb +2 -3
  288. data/app/views/cms/pages/_edit_content.html.erb +28 -0
  289. data/app/views/cms/pages/_form.html.erb +20 -37
  290. data/app/views/cms/pages/_main_form.html.erb +23 -0
  291. data/app/views/cms/pages/_simple_container.html.erb +8 -0
  292. data/app/views/cms/pages/edit.html.erb +2 -23
  293. data/app/views/cms/pages/new.html.erb +2 -16
  294. data/app/views/cms/pages/versions.html.erb +18 -87
  295. data/app/views/cms/redirects/_form.html.erb +6 -14
  296. data/app/views/cms/redirects/edit.html.erb +2 -3
  297. data/app/views/cms/redirects/index.html.erb +24 -50
  298. data/app/views/cms/redirects/new.html.erb +2 -3
  299. data/app/views/cms/routes/index.html.erb +15 -20
  300. data/app/views/cms/section_nodes/_children.html.erb +3 -0
  301. data/app/views/cms/section_nodes/_row_buttons.html.erb +11 -0
  302. data/app/views/cms/section_nodes/_section_node.html.erb +24 -10
  303. data/app/views/cms/section_nodes/_sitemap_buttons.html.erb +47 -0
  304. data/app/views/cms/section_nodes/_status.html.erb +5 -0
  305. data/app/views/cms/section_nodes/show.html.erb +9 -0
  306. data/app/views/cms/sections/_buttons.html.erb +6 -0
  307. data/app/views/cms/sections/_form.html.erb +22 -49
  308. data/app/views/cms/sections/edit.html.erb +3 -8
  309. data/app/views/cms/sections/new.html.erb +4 -20
  310. data/app/views/cms/sessions/new.html.erb +16 -31
  311. data/app/views/cms/shared/access_denied.html.erb +1 -2
  312. data/app/views/cms/shared/error.html.erb +5 -5
  313. data/app/views/cms/sites/_flash.html.erb +8 -0
  314. data/app/views/cms/sites/passwords/new.html.erb +2 -0
  315. data/app/views/cms/sites/sessions/new.html.erb +2 -0
  316. data/app/views/cms/tags/_form.html.erb +1 -1
  317. data/app/views/cms/tags/render.html.erb +0 -1
  318. data/app/views/cms/tasks/new.html.erb +18 -32
  319. data/app/views/cms/toolbar/_new_pages_menu.html.erb +10 -0
  320. data/app/views/cms/users/_form.html.erb +8 -11
  321. data/app/views/cms/users/_password.html.erb +2 -8
  322. data/app/views/cms/users/_user_fields.html.erb +7 -20
  323. data/app/views/cms/users/change_password.html.erb +12 -21
  324. data/app/views/cms/users/edit.html.erb +1 -15
  325. data/app/views/cms/users/index.html.erb +61 -58
  326. data/app/views/cms/users/new.html.erb +1 -12
  327. data/app/views/devise/confirmations/new.html.erb +16 -0
  328. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  329. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  330. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  331. data/app/views/devise/passwords/edit.html.erb +19 -0
  332. data/app/views/devise/passwords/new.html.erb +15 -0
  333. data/app/views/devise/registrations/edit.html.erb +28 -0
  334. data/app/views/devise/registrations/new.html.erb +18 -0
  335. data/app/views/devise/shared/_links.erb +25 -0
  336. data/app/views/devise/unlocks/new.html.erb +16 -0
  337. data/app/views/layouts/cms/_content_types.html.erb +13 -0
  338. data/app/views/layouts/cms/_footer.erb +2 -2
  339. data/app/views/layouts/cms/_head.html.erb +8 -18
  340. data/app/views/layouts/cms/_main_menu.html.erb +78 -0
  341. data/app/views/layouts/cms/application.html.erb +19 -24
  342. data/app/views/layouts/cms/content_page.html.erb +5 -0
  343. data/app/views/layouts/cms/page_editor.html.erb +90 -0
  344. data/app/views/portlets/deprecated_placeholders/_form.html.erb +1 -0
  345. data/app/views/portlets/deprecated_placeholders/render.html.erb +8 -0
  346. data/app/views/portlets/dynamic/_form.html.erb +3 -3
  347. data/app/views/portlets/email_page/_form.html.erb +5 -6
  348. data/app/views/portlets/forgot_password/_form.html.erb +2 -3
  349. data/app/views/portlets/forgot_password/render.html.erb +2 -14
  350. data/app/views/portlets/login/_form.html.erb +4 -6
  351. data/app/views/portlets/login/render.html.erb +8 -27
  352. data/app/views/portlets/portlets/_form.html.erb +7 -6
  353. data/app/views/portlets/tag_cloud/_form.html.erb +4 -4
  354. data/app/views/tests/pretend/open_with_layout.html.erb +1 -1
  355. data/bin/bcms +13 -16
  356. data/config/routes.rb +58 -29
  357. data/db/browsercms.seeds.rb +0 -6
  358. data/db/migrate/{20080815014337_browsercms_3_0_0.rb → 20080815014337_browsercms300.rb} +94 -73
  359. data/db/migrate/20130327184912_browsercms400.rb +90 -0
  360. data/db/migrate/20131206214021_devise_create_users.rb +47 -0
  361. data/db/migrate/20131211223908_kill_reset_password.rb +5 -0
  362. data/db/migrate/20131218222005_create_cms_external_users.rb +10 -0
  363. data/doc/features/design_integration.md +45 -0
  364. data/doc/features/external_user.md +7 -0
  365. data/doc/features/form_builder.md +40 -0
  366. data/doc/features/simple_form_refactor.md +60 -0
  367. data/doc/release_notes.md +224 -10
  368. data/lib/acts_as_list.rb +72 -71
  369. data/lib/browsercms.rb +41 -1
  370. data/lib/cms/acts/content_block.rb +12 -2
  371. data/lib/cms/acts/content_page.rb +3 -4
  372. data/lib/cms/admin_tab.rb +15 -0
  373. data/lib/cms/attachments/configuration.rb +1 -1
  374. data/lib/cms/authentication/controller.rb +83 -177
  375. data/lib/cms/authentication/test_password_strategy.rb +19 -0
  376. data/lib/cms/behaviors.rb +1 -0
  377. data/lib/cms/behaviors/archiving.rb +2 -2
  378. data/lib/cms/behaviors/attaching.rb +21 -45
  379. data/lib/cms/behaviors/connecting.rb +14 -4
  380. data/lib/cms/behaviors/dynamic_attributes.rb +3 -3
  381. data/lib/cms/behaviors/hiding.rb +2 -2
  382. data/lib/cms/behaviors/namespacing.rb +6 -36
  383. data/lib/cms/behaviors/publishing.rb +92 -45
  384. data/lib/cms/behaviors/rendering.rb +15 -7
  385. data/lib/cms/behaviors/searching.rb +5 -4
  386. data/lib/cms/behaviors/soft_deleting.rb +13 -16
  387. data/lib/cms/behaviors/taggable.rb +17 -10
  388. data/lib/cms/behaviors/versioning.rb +12 -16
  389. data/lib/cms/commands/to_version400.rb +10 -0
  390. data/lib/cms/concerns.rb +7 -0
  391. data/lib/cms/concerns/can_be_addressable.rb +326 -0
  392. data/lib/cms/concerns/has_content_type.rb +46 -0
  393. data/lib/cms/concerns/ignores_publishing.rb +9 -0
  394. data/lib/cms/configuration.rb +14 -4
  395. data/lib/cms/configuration/configurable_template.rb +24 -0
  396. data/lib/cms/configuration/devise.rb +256 -0
  397. data/lib/cms/configure_simple_form.rb +142 -0
  398. data/lib/cms/configure_simple_form_bootstrap.rb +49 -0
  399. data/lib/cms/content_filter.rb +18 -0
  400. data/lib/cms/content_page.rb +77 -0
  401. data/lib/cms/content_rendering_support.rb +25 -16
  402. data/lib/cms/controllers/admin_controller.rb +78 -0
  403. data/lib/cms/data_loader.rb +30 -11
  404. data/lib/cms/default_accessible.rb +6 -6
  405. data/lib/cms/domain_support.rb +0 -4
  406. data/lib/cms/engine.rb +52 -20
  407. data/lib/cms/engine_helper.rb +41 -51
  408. data/{app/controllers → lib}/cms/error_handling.rb +11 -5
  409. data/lib/cms/extensions.rb +2 -1
  410. data/lib/cms/extensions/active_model/name.rb +13 -0
  411. data/lib/cms/extensions/active_record/connection_adapters/abstract/schema_statements.rb +49 -89
  412. data/lib/cms/extensions/hash.rb +0 -12
  413. data/lib/cms/form_builder/content_block_form_builder.rb +45 -0
  414. data/lib/cms/form_builder/default_input.rb +13 -0
  415. data/lib/cms/form_builder/deprecated_inputs.rb +40 -0
  416. data/lib/cms/form_builder/workflow_buttons.rb +38 -0
  417. data/lib/cms/module.rb +1 -7
  418. data/lib/cms/polymorphic_single_table_inheritance.rb +19 -0
  419. data/lib/cms/publish_workflow.rb +26 -0
  420. data/lib/cms/responders/content_responder.rb +14 -0
  421. data/lib/cms/route_extensions.rb +112 -20
  422. data/lib/cms/version.rb +1 -1
  423. data/lib/generators/browser_cms/demo_site/templates/demo.seeds.rb +0 -2
  424. data/lib/generators/cms/content_block/content_block_generator.rb +19 -46
  425. data/lib/generators/cms/content_block/templates/_form.html.erb +22 -28
  426. data/lib/generators/cms/project/templates/devise.rb.erb +7 -0
  427. metadata +383 -150
  428. data/app/assets/javascripts/cms/sitemap.js.erb +0 -464
  429. data/app/assets/stylesheets/browsercms/application.css +0 -7
  430. data/app/assets/stylesheets/cms/administration.css.erb +0 -91
  431. data/app/assets/stylesheets/cms/application.css.erb +0 -171
  432. data/app/assets/stylesheets/cms/attachment_manager.css.scss +0 -28
  433. data/app/assets/stylesheets/cms/block.css +0 -26
  434. data/app/assets/stylesheets/cms/buttons.css.erb +0 -120
  435. data/app/assets/stylesheets/cms/content_library.css.erb +0 -139
  436. data/app/assets/stylesheets/cms/content_types.css +0 -4
  437. data/app/assets/stylesheets/cms/dashboard.css.erb +0 -118
  438. data/app/assets/stylesheets/cms/data_table.css.erb.erb +0 -156
  439. data/app/assets/stylesheets/cms/date_picker.css.erb +0 -82
  440. data/app/assets/stylesheets/cms/form_layout.css.erb +0 -282
  441. data/app/assets/stylesheets/cms/login.css.erb +0 -78
  442. data/app/assets/stylesheets/cms/menu.css.erb +0 -116
  443. data/app/assets/stylesheets/cms/nav.css.erb +0 -99
  444. data/app/assets/stylesheets/cms/page_toolbar.css.erb +0 -135
  445. data/app/assets/stylesheets/cms/reset.css +0 -46
  446. data/app/assets/stylesheets/cms/selectbox.css.erb +0 -56
  447. data/app/assets/stylesheets/cms/sitemap.css.erb +0 -390
  448. data/app/assets/stylesheets/cms/taglist.css +0 -18
  449. data/app/controllers/application_controller.rb +0 -14
  450. data/app/controllers/cms/content_types_controller.rb +0 -9
  451. data/app/helpers/application_helper.rb +0 -5
  452. data/app/helpers/cms/form_builder.rb +0 -241
  453. data/app/models/cms/content_type_group.rb +0 -15
  454. data/app/models/cms/forgot_password_mailer.rb +0 -14
  455. data/app/portlets/reset_password_portlet.rb +0 -28
  456. data/app/views/cms/blocks/_hidden_fields.html.erb +0 -10
  457. data/app/views/cms/blocks/_toolbar.html.erb +0 -9
  458. data/app/views/cms/blocks/_toolbar_for_collection.html.erb +0 -23
  459. data/app/views/cms/blocks/_toolbar_for_member.html.erb +0 -36
  460. data/app/views/cms/blocks/edit.html.erb +0 -28
  461. data/app/views/cms/blocks/index.html.erb +0 -86
  462. data/app/views/cms/blocks/new.html.erb +0 -19
  463. data/app/views/cms/blocks/show.html.erb +0 -43
  464. data/app/views/cms/blocks/usages.html.erb +0 -44
  465. data/app/views/cms/blocks/versions.html.erb +0 -90
  466. data/app/views/cms/content_types/index.html.erb +0 -14
  467. data/app/views/cms/form_builder/_cms_attachment_manager.html.erb +0 -27
  468. data/app/views/cms/form_builder/_cms_check_box.html.erb +0 -7
  469. data/app/views/cms/form_builder/_cms_date_picker.html.erb +0 -12
  470. data/app/views/cms/form_builder/_cms_datetime_select.html.erb +0 -12
  471. data/app/views/cms/form_builder/_cms_drop_down.html.erb +0 -12
  472. data/app/views/cms/form_builder/_cms_fancy_drop_down.html.erb +0 -9
  473. data/app/views/cms/form_builder/_cms_file_field.html.erb +0 -28
  474. data/app/views/cms/form_builder/_cms_instructions.html.erb +0 -4
  475. data/app/views/cms/form_builder/_cms_tag_list.html.erb +0 -15
  476. data/app/views/cms/form_builder/_cms_template_editor.html.erb +0 -9
  477. data/app/views/cms/form_builder/_cms_text_area.html.erb +0 -10
  478. data/app/views/cms/form_builder/_cms_text_editor.html.erb +0 -19
  479. data/app/views/cms/form_builder/_cms_text_field.html.erb +0 -12
  480. data/app/views/cms/links/destroy.js.rjs +0 -2
  481. data/app/views/cms/page_routes/show.html.erb +0 -10
  482. data/app/views/cms/pages/_edit_connector.html.erb +0 -19
  483. data/app/views/cms/pages/_edit_container.html.erb +0 -11
  484. data/app/views/cms/section_nodes/_link.html.erb +0 -14
  485. data/app/views/cms/section_nodes/_node.html.erb +0 -44
  486. data/app/views/cms/section_nodes/_page.html.erb +0 -20
  487. data/app/views/cms/section_nodes/_section.html.erb +0 -28
  488. data/app/views/cms/section_nodes/index.html.erb +0 -43
  489. data/app/views/cms/sections/_page.html.erb +0 -4
  490. data/app/views/cms/sections/_section.html.erb +0 -8
  491. data/app/views/cms/sections/destroy.js.rjs +0 -2
  492. data/app/views/cms/sections/index.html.erb +0 -23
  493. data/app/views/cms/shared/_admin_sidebar.html.erb +0 -36
  494. data/app/views/cms/shared/_pagination.html.erb +0 -31
  495. data/app/views/cms/toolbar/_mobile_toggle.html.erb +0 -33
  496. data/app/views/cms/toolbar/index.html.erb +0 -1
  497. data/app/views/cms/users/_groups.html.erb +0 -12
  498. data/app/views/cms/users/_toolbar.html.erb +0 -24
  499. data/app/views/cms/users/show.html.erb +0 -50
  500. data/app/views/layouts/_cms_toolbar.html.erb +0 -54
  501. data/app/views/layouts/_page_toolbar.html.erb +0 -119
  502. data/app/views/layouts/cms/administration.html.erb +0 -51
  503. data/app/views/layouts/cms/content_library.html.erb +0 -96
  504. data/app/views/layouts/cms/dashboard.html.erb +0 -16
  505. data/app/views/layouts/cms/login.html.erb +0 -31
  506. data/app/views/layouts/cms/section_nodes.html.erb +0 -20
  507. data/app/views/layouts/cms/toolbar.html.erb +0 -23
  508. data/app/views/portlets/reset_password/_form.html.erb +0 -3
  509. data/app/views/portlets/reset_password/render.html.erb +0 -22
  510. data/bin/bcms-upgrade +0 -332
  511. data/db/migrate/20091109175123_browsercms_3_0_5.rb +0 -9
  512. data/db/migrate/20100117144038_browsercms314.rb +0 -20
  513. data/db/migrate/20100117144039_browsercms315.rb +0 -95
  514. data/db/migrate/20100705083859_browsercms_3_3_0.rb +0 -56
  515. data/db/migrate/20111130221145_browsercms340.rb +0 -56
  516. data/db/migrate/20120329144406_browsercms350.rb +0 -32
  517. data/db/migrate/20120717182827_browsercms353.rb +0 -19
  518. data/db/migrate/20120813180110_browsercms354.rb +0 -9
  519. data/lib/cms/addressable.rb +0 -93
  520. data/lib/cms/authentication/model.rb +0 -116
  521. data/lib/cms/behaviors/pagination.rb +0 -212
  522. data/lib/cms/upgrades/v3_4_0.rb +0 -31
  523. data/lib/cms/upgrades/v3_5_0.rb +0 -227
@@ -0,0 +1,43 @@
1
+ module Cms
2
+
3
+ # Handles the conversion from Mercury editor (i.e. the JSON hash it submits) to a Cms Page and blocks
4
+ class PageComponent
5
+ extend ::ActiveModel::Naming
6
+
7
+ attr_accessor :page_id, :page_title, :blocks
8
+
9
+ def initialize(page_id, params)
10
+ params = HashWithIndifferentAccess.new(params)
11
+ self.page_title = params[:page_title]
12
+ self.blocks = params[:blocks] ? params[:blocks] : []
13
+ self.page_id = page_id
14
+ end
15
+
16
+
17
+ # Save the change to the underlying page (and its content)
18
+ def save
19
+ @page = Page.find(@page_id)
20
+ @page.title = page_title[:value]
21
+ blocks.each do |block_type|
22
+ content_block_class = block_type[0]
23
+ content_ids = block_type[1].keys
24
+
25
+ content_ids.each do |block_id|
26
+ block = content_block_class.constantize.find(block_id)
27
+ assignment_hash = convert_mercury_params_to_assignment_hash(block_id, block_type)
28
+ block.update_attributes(assignment_hash)
29
+ end
30
+ end
31
+ @page.save
32
+ end
33
+
34
+ def convert_mercury_params_to_assignment_hash(block_id, block_type)
35
+ block_attribute_names = block_type[1][block_id].keys
36
+ assignment_hash = {}
37
+ block_attribute_names.each do |attr_name|
38
+ assignment_hash[attr_name] = block_type[1][block_id][attr_name][:value]
39
+ end
40
+ assignment_hash
41
+ end
42
+ end
43
+ end
@@ -5,6 +5,10 @@ module Cms
5
5
 
6
6
  validates_format_of :name, :with => /\A_[a-z]+[a-z0-9_]*\Z/, :message => "can only contain lowercase letters, numbers and underscores and must begin with an underscore"
7
7
 
8
+ def self.relative_path
9
+ "partials"
10
+ end
11
+
8
12
  def file_path
9
13
  File.join(self.class.base_path, "partials", file_name)
10
14
  end
@@ -14,19 +18,23 @@ module Cms
14
18
  "#{name.sub(/^_/, '').titleize} (#{format}/#{handler})"
15
19
  end
16
20
 
17
- def self.resource_collection_name
18
- "page_partial"
19
- end
20
-
21
- def self.path_elements
22
- [Cms::PagePartial]
23
- end
24
-
25
21
  def prepend_underscore
26
22
  if !name.blank? && name[0, 1] != '_'
27
23
  self.name = "_#{name}"
28
24
  end
29
25
  end
30
26
 
27
+ def partial?
28
+ true
29
+ end
30
+
31
+ def placeholder
32
+ "_header"
33
+ end
34
+
35
+ # Generates hint for editing
36
+ def hint
37
+ "No spaces allowed. Must start with _."
38
+ end
31
39
  end
32
40
  end
@@ -21,7 +21,7 @@ class Cms::PageRoute < ActiveRecord::Base
21
21
  has_many :conditions, :class_name => 'Cms::PageRouteCondition'
22
22
  has_many :requirements, :class_name => 'Cms::PageRouteRequirement'
23
23
 
24
- attr_accessible :name, :pattern, :code, :page_id, :page
24
+ extend Cms::DefaultAccessible
25
25
 
26
26
  validates_presence_of :pattern, :page_id
27
27
  validates_uniqueness_of :pattern
@@ -1,5 +1,5 @@
1
1
  module Cms
2
2
  class PageRouteCondition < Cms::PageRouteOption
3
- include DefaultAccessible
3
+ extend DefaultAccessible
4
4
  end
5
5
  end
@@ -2,6 +2,6 @@ module Cms
2
2
  class PageRouteOption < ActiveRecord::Base
3
3
  belongs_to :page_route, :class_name => 'Cms::PageRoute'
4
4
 
5
- include DefaultAccessible
5
+ extend DefaultAccessible
6
6
  end
7
7
  end
@@ -1,5 +1,5 @@
1
1
  module Cms
2
2
  class PageRouteRequirement < Cms::PageRouteOption
3
- include DefaultAccessible
3
+ extend DefaultAccessible
4
4
  end
5
5
  end
@@ -17,15 +17,8 @@ module Cms
17
17
 
18
18
  def self.display_name(file_name)
19
19
  name, format, handler = file_name.split('.')
20
- "#{name.titleize} (#{format}/#{handler})"
21
- end
22
-
23
- def self.resource_collection_name
24
- "page_template"
25
- end
26
-
27
- def self.path_elements
28
- [Cms::PageTemplate]
20
+ content_type = handler ? "#{format}/#{handler}" : "#{format}"
21
+ "#{name.titleize} (#{content_type})"
29
22
  end
30
23
 
31
24
  # This is a combination of file system page templates
@@ -36,5 +29,17 @@ module Cms
36
29
  page_templates.map { |f| [display_name(f), f] }.sort.uniq
37
30
  end
38
31
 
32
+ def partial?
33
+ false
34
+ end
35
+
36
+ def placeholder
37
+ "subpage"
38
+ end
39
+
40
+ # Generates hint for editing
41
+ def hint
42
+ "No spaces allowed. Must start with lowercase letter."
43
+ end
39
44
  end
40
45
  end
@@ -1,7 +1,7 @@
1
1
  module Cms
2
2
  class Permission < ActiveRecord::Base
3
3
 
4
- attr_accessible :name, :full_name, :description
4
+ #attr_accessible :name, :full_name, :description
5
5
 
6
6
  has_many :group_permissions, :class_name => 'Cms::GroupPermission'
7
7
  has_many :groups, :through => :group_permissions, :class_name => 'Cms::Group'
@@ -9,7 +9,9 @@ module Cms
9
9
  validates_presence_of :name
10
10
  validates_uniqueness_of :name
11
11
 
12
- scope :named, lambda { |name| {:conditions => {:name => name}} }
12
+ def self.named(name)
13
+ where(name: name)
14
+ end
13
15
 
14
16
  end
15
17
  end
@@ -0,0 +1,208 @@
1
+ module Cms
2
+
3
+ # A parent class for users that need to be persisted in the CMS database.
4
+ class PersistentUser < ActiveRecord::Base
5
+
6
+ self.table_name = 'cms_users'
7
+
8
+ # Note that Chrome doesn't expire session cookies immediately so test this in other browsers.
9
+ # http://stackoverflow.com/questions/16817229/issues-with-devise-rememberable
10
+ devise :database_authenticatable,
11
+ # Note that Chrome doesn't expire session cookies immediately so test this in other browsers.
12
+ # http://stackoverflow.com/questions/16817229/issues-with-devise-rememberable
13
+ :rememberable,
14
+ :authentication_keys => [:login]
15
+
16
+
17
+ has_many :user_group_memberships, :class_name => 'Cms::UserGroupMembership', foreign_key: :user_id
18
+ has_many :groups, :through => :user_group_memberships, :class_name => 'Cms::Group', foreign_key: :user_id
19
+ has_many :tasks, :foreign_key => "assigned_to_id", :class_name => 'Cms::Task'
20
+
21
+ scope :active, -> { where(["expires_at IS NULL OR expires_at > ?", Time.now.utc]) }
22
+ extend DefaultAccessible
23
+
24
+
25
+ validates_presence_of :login
26
+ validates_uniqueness_of :login, :case_sensitive => false
27
+ validates_format_of :login, :with => /\A\w[\w\.\-_@]+\z/, :message => "use only letters, numbers, and .-_@ please."
28
+
29
+ # Class Methods
30
+ class << self
31
+
32
+ def permitted_params
33
+ super + [{:group_ids => []}]
34
+ end
35
+
36
+ # Returns all users that can :edit_content or :publish_content permissions.
37
+ #
38
+ # @return [ActiveRelation<Cms::User>] A scope which will find users with the correct permissions.
39
+ def able_to_edit_or_publish_content
40
+ where(["#{Permission.table_name}.name = ? OR #{Permission.table_name}.name = ?", "edit_content", "publish_content"]).includes({:groups => :permissions}).references(:permissions)
41
+ end
42
+
43
+ def current
44
+ Thread.current[:cms_user]
45
+ end
46
+
47
+ def current=(user)
48
+ Thread.current[:cms_user] = user
49
+ end
50
+
51
+ # Return a GuestUser with the given values.
52
+ def guest(options = {})
53
+ Cms::GuestUser.new(options)
54
+ end
55
+ end
56
+
57
+ # Determines if this user a Guest or not.
58
+ def guest?
59
+ !!@guest
60
+ end
61
+
62
+ # Determines if this user should have access to the CMS administration tools. Can be overridden by specific users (like GuestUser)
63
+ # which may not need to check the database for that information.
64
+ def cms_access?
65
+ groups.cms_access.count > 0
66
+ end
67
+
68
+ def disable
69
+ if self.class.where(["expires_at is null and id != ?", id]).count > 0
70
+ self.expires_at = Time.now - 2.minutes
71
+ else
72
+ false
73
+ end
74
+ end
75
+
76
+ def disable!
77
+ unless disable
78
+ raise "You must have at least 1 enabled user"
79
+ end
80
+ save!
81
+ end
82
+
83
+ # Determines if this user should be authenticated. Hook for Devise.
84
+ #
85
+ # @override Devise::Models::Authenticatable#active_for_authentication?
86
+ # @return [Boolean] true if this user has not expired.
87
+ def active_for_authentication?
88
+ is_active = !expired?
89
+ logger.error "Expired User '#{login}' failed to login. Account expired on #{expires_at_formatted}." unless is_active
90
+ is_active
91
+ end
92
+
93
+ # Determines if this User can have their password changed.
94
+ def password_changeable?
95
+ true
96
+ end
97
+
98
+ # Determines if this user has expired or has been disabled.
99
+ # @return [Boolean]
100
+ def expired?
101
+ expires_at && expires_at <= Time.now
102
+ end
103
+
104
+ def enable
105
+ self.expires_at = nil
106
+ end
107
+
108
+ def enable!
109
+ enable
110
+ save!
111
+ end
112
+
113
+ def full_name
114
+ [first_name, last_name].reject { |e| e.nil? }.join(" ")
115
+ end
116
+
117
+ def full_name_with_login
118
+ "#{full_name} (#{login})"
119
+ end
120
+
121
+ def full_name_or_login
122
+ if full_name.strip.blank?
123
+ login
124
+ else
125
+ full_name
126
+ end
127
+ end
128
+
129
+ # This is to show a formated date on the input form. I'm unsure that
130
+ # this is the best way to solve this, but it works.
131
+ def expires_at_formatted
132
+ expires_at ? (expires_at.strftime '%m/%d/%Y') : nil
133
+ end
134
+
135
+ def permissions
136
+ @permissions ||= Cms::Permission.where(["#{self.class.table_name}.id = ?", id]).includes({:groups => :users}).references(:users)
137
+ end
138
+
139
+ def viewable_sections
140
+ @viewable_sections ||= Cms::Section.where(["#{self.class.table_name}.id = ?", id]).includes(:groups => :users).references(:users)
141
+ end
142
+
143
+ def modifiable_sections
144
+ @modifiable_sections ||= Cms::Section.where(["#{self.class.table_name}.id = ? and #{GroupType.table_name}.cms_access = ?", id, true]).includes(:groups => [:group_type, :users]).references(:users, :groups)
145
+ end
146
+
147
+ # Expects a list of names of Permissions
148
+ # true if the user has any of the permissions
149
+ def able_to?(*required_permissions)
150
+ perms = required_permissions.map(&:to_sym)
151
+ permissions.any? do |p|
152
+ perms.include?(p.name.to_sym)
153
+ end
154
+ end
155
+
156
+ # Determine if this user has permission to view the specific object. Permissions
157
+ # are always tied to a specific section. This method can take different input parameters
158
+ # and will attempt to determine the relevant section to check.
159
+ # Expects object to be of type:
160
+ # 1. Section - Will check the user's groups to see if any of those groups can view this section.
161
+ # 2. Path - Will look up the section based on the path, then check it. (Note that section paths are not currently unique, so this will check the first one it finds).
162
+ # 3. Other - Assumes it has a section attribute and will call that and check the return value.
163
+ #
164
+ # Returns: true if the user can view this object, false otherwise.
165
+ # Raises: ActiveRecord::RecordNotFound if a path to a not existent section is passed in.
166
+ def able_to_view?(object)
167
+ section = object
168
+ if object.is_a?(String)
169
+ section = Cms::Section.find_by_path(object)
170
+ raise ActiveRecord::RecordNotFound.new("Could not find section with path = '#{object}'") unless section
171
+ elsif !object.is_a?(Cms::Section)
172
+ section = object.parent
173
+ end
174
+ viewable_sections.include?(section) || cms_access?
175
+ end
176
+
177
+ def able_to_modify?(object)
178
+ case object
179
+ when Cms::Section
180
+ modifiable_sections.include?(object)
181
+ when Cms::Page, Cms::Link
182
+ modifiable_sections.include?(object.section)
183
+ else
184
+ if object.class.respond_to?(:connectable?) && object.class.connectable?
185
+ object.connected_pages.all? { |page| able_to_modify?(page) }
186
+ else
187
+ true
188
+ end
189
+ end
190
+ end
191
+
192
+ # Expects node to be a Section, Page or Link
193
+ # Returns true if the specified node, or any of its ancestor sections, is editable by any of
194
+ # the user's 'CMS User' groups.
195
+ def able_to_edit?(object)
196
+ able_to?(:edit_content) && able_to_modify?(object)
197
+ end
198
+
199
+ def able_to_publish?(object)
200
+ able_to?(:publish_content) && able_to_modify?(object)
201
+ end
202
+
203
+ def able_to_edit_or_publish_content?
204
+ able_to?(:edit_content, :publish_content)
205
+ end
206
+
207
+ end
208
+ end
@@ -2,11 +2,26 @@ module Cms
2
2
  class Portlet < ActiveRecord::Base
3
3
  validates_presence_of :name
4
4
  is_searchable
5
+ uses_soft_delete
6
+ has_content_type :module => :core
5
7
 
6
8
  # These are here simply to temporarily hold these values
7
9
  # Makes it easy to pass them through the process of selecting a portlet type
8
10
  attr_accessor :connect_to_page_id, :connect_to_container, :controller
9
- attr_accessible :connect_to_page_id, :connect_to_container, :controller, :name
11
+
12
+ # Descriptions for portlets will be displayed when a user is adding one to page, or when editing the portlet.
13
+ # The goal is provide a more detailed overview of how a portlet should be used or what it does.
14
+ # @param [String] description (If supplied, it will set the new value)
15
+ # @return [String]
16
+ def self.description(description="")
17
+ unless description.blank?
18
+ @description = description
19
+ end
20
+ if @description.blank?
21
+ return "(No description available)"
22
+ end
23
+ @description
24
+ end
10
25
 
11
26
  delegate :request, :response, :session,
12
27
  :flash, :params, :cookies,
@@ -17,11 +32,11 @@ module Cms
17
32
  super if defined? super
18
33
  ensure
19
34
  subclass.class_eval do
35
+ extend Cms::PolymorphicSingleTableInheritance
20
36
 
21
- # Using the table prefix here is NOT tested, since unloading classes is hard during tests.
22
37
  has_dynamic_attributes :class_name => "CmsPortletAttribute",
23
38
  :foreign_key => "portlet_id",
24
- :table_name => Namespacing.prefix("portlet_attributes"),
39
+ :table_name => "cms_portlet_attributes",
25
40
  :relationship_name => :portlet_attributes
26
41
 
27
42
  acts_as_content_block(
@@ -33,7 +48,6 @@ module Cms
33
48
  # Portlets aren't verisonable but are connectable, so this will prevent the saving of portlets.
34
49
  attr_accessor :skip_callbacks
35
50
 
36
-
37
51
  def self.template_path
38
52
  default_template_path
39
53
  end
@@ -45,6 +59,13 @@ module Cms
45
59
  def self.helper_class
46
60
  "#{name}Helper".constantize
47
61
  end
62
+
63
+ # Portlets don't generally support inline editing. Subclasses can override this if they do though.
64
+ def supports_inline_editing?
65
+ false
66
+ end
67
+
68
+
48
69
  end
49
70
  end
50
71
 
@@ -52,14 +73,34 @@ module Cms
52
73
  false
53
74
  end
54
75
 
76
+ # Returns an alphabetical list of classes that descend from Cms::Portlet.
77
+ #
78
+ # @return [Array<Class>]
55
79
  def self.types
56
80
  @types ||= ActiveSupport::Dependencies.autoload_paths.map do |d|
57
81
  if d =~ /app\/portlets/
58
82
  Dir["#{d}/*_portlet.rb"].map do |p|
59
- File.basename(p, ".rb").classify
83
+ File.basename(p, ".rb").classify.constantize
60
84
  end
61
85
  end
62
- end.flatten.compact.uniq.sort
86
+ end.flatten.compact.uniq
87
+ @types.sort! { |a,b| a.name.downcase <=> b.name.downcase }
88
+ @types.select! { |type| !blacklist.include?(type.name)}
89
+ @types
90
+ end
91
+
92
+ # Determines if a content_type is blacklisted or not.
93
+ #
94
+ # @param [Symbol] type (:dynamic_portlet)
95
+ def self.blacklisted?(type_name)
96
+ blacklist.include?(type_name.to_s.camelize)
97
+ end
98
+
99
+ # Returns a blacklist of all content types that shouldn't be accessible. Includes both portlets and other CMS types.
100
+ #
101
+ # @return [Array<String>] List of class names ['DynamicPortlet', 'LoginPortlet']
102
+ def self.blacklist
103
+ @blacklist ||= Rails.configuration.cms.content_types.blacklist.map {|underscore_name| underscore_name.to_s.camelize }
63
104
  end
64
105
 
65
106
  def self.get_subclass(type)
@@ -137,15 +178,21 @@ module Cms
137
178
  true
138
179
  end
139
180
 
181
+ # For polymorphic permissions
182
+ # A generic portlet shouldn't be connected to pages.
183
+ def connected_pages
184
+ []
185
+ end
186
+
140
187
  #----- Portlet Action Related Methods ----------------------------------------
141
-
188
+
142
189
  # Used by portlets to set a custom title, typically in the render body.
143
- # For example, this allows a page with a single portlet that might display a content block to set the page name to
190
+ # For example, this allows a page with a single portlet that might display a content block to set the page name to
144
191
  # that block name.
145
192
  def page_title(new_title)
146
193
  controller.current_page.title = new_title
147
194
  end
148
-
195
+
149
196
  def instance_name
150
197
  "#{self.class.name.demodulize.underscore}_#{id}"
151
198
  end