zena 1.2.7 → 1.2.8

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 (407) hide show
  1. data/History.txt +80 -25
  2. data/Rakefile +2 -2
  3. data/app/controllers/columns_controller.rb +2 -2
  4. data/app/controllers/nodes_controller.rb +22 -29
  5. data/app/controllers/user_sessions_controller.rb +35 -10
  6. data/app/controllers/users_controller.rb +2 -2
  7. data/app/controllers/versions_controller.rb +2 -2
  8. data/app/models/group.rb +15 -1
  9. data/app/models/node.rb +109 -8
  10. data/app/models/role.rb +4 -0
  11. data/app/models/site.rb +64 -58
  12. data/app/models/template.rb +1 -1
  13. data/app/models/user.rb +135 -29
  14. data/app/models/user_session.rb +0 -1
  15. data/app/models/virtual_class.rb +11 -6
  16. data/app/views/columns/_form.html.erb +3 -1
  17. data/app/views/columns/_li.html.erb +1 -1
  18. data/app/views/columns/create.rjs +1 -1
  19. data/app/views/groups/_form.rhtml +16 -13
  20. data/app/views/relations/_form.erb +18 -6
  21. data/app/views/sites/_form.erb +12 -6
  22. data/app/views/users/_form.rhtml +23 -8
  23. data/app/views/users/_li.rhtml +14 -3
  24. data/app/views/users/index.rhtml +1 -1
  25. data/app/views/virtual_classes/_form.erb +12 -2
  26. data/app/views/zafu/default/Node-+login.zafu +8 -1
  27. data/app/views/zafu/default/Node-+search.zafu +1 -1
  28. data/bricks/acls/lib/bricks/acls.rb +1 -0
  29. data/bricks/acls/zena/migrate/20130903150356_longer_names_for_acl.rb +9 -0
  30. data/bricks/acls/zena/test/integration/acl_integration_test.rb +2 -2
  31. data/bricks/currency/lib/bricks/currency.rb +120 -0
  32. data/bricks/currency/zena/test/unit/currency_test.rb +43 -0
  33. data/bricks/fs_skin/lib/bricks/fs_skin.rb +1 -1
  34. data/bricks/fs_skin/zena/skins/blog/Node-+search.zafu +1 -1
  35. data/bricks/fs_skin/zena/skins/blog/Node.zafu +1 -1
  36. data/bricks/fs_skin/zena/test/unit/fs_skin_view_test.rb +35 -0
  37. data/bricks/pdf/lib/bricks/pdf.rb +1 -1
  38. data/bricks/sphinx/lib/bricks/sphinx.rb +2 -0
  39. data/bricks/sphinx/zena/init.rb +14 -0
  40. data/bricks/tags/zena/test/zafu/tags.yml +5 -1
  41. data/bricks/worker/lib/bricks/worker.rb +3 -2
  42. data/bricks/zena/zena/migrate/20130829093753_add_versioned_flag_to_column.rb +10 -0
  43. data/bricks/zena/zena/migrate/20130903084909_count_login_attempts.rb +11 -0
  44. data/bricks/zena/zena/migrate/20131104153126_index_fullpath.rb +10 -0
  45. data/bricks/zena/zena/migrate/20131104210011_rebuild_fullpath_after_change.rb +10 -0
  46. data/bricks/zena/zena/migrate/20131105160420_add_skin_id_to_sites.rb +9 -0
  47. data/bricks/zena/zena/migrate/20131105175822_add_profile_to_users.rb +11 -0
  48. data/bricks/zena/zena/migrate/20140213120038_fix_idx_scope.rb +13 -0
  49. data/bricks/zena/zena/migrate/20140628140247_add_site_readonly.rb +9 -0
  50. data/config/bricks.yml +8 -4
  51. data/config/gems.yml +5 -3
  52. data/db/init/base/skins/default/Node-+login.zafu +8 -1
  53. data/db/init/base/skins/default/Node-+search.zafu +1 -1
  54. data/lib/bricks/loader.rb +5 -5
  55. data/lib/gettext_strings.rb +3 -0
  56. data/lib/tasks/zena.rake +25 -22
  57. data/lib/zafu/process/context.rb +4 -0
  58. data/lib/zena/acts/secure_node.rb +3 -3
  59. data/lib/zena/app.rb +1 -0
  60. data/lib/zena/deploy.rb +1 -1
  61. data/lib/zena/deploy/template.rb +1 -1
  62. data/lib/zena/foxy_parser.rb +5 -2
  63. data/lib/zena/info.rb +1 -1
  64. data/lib/zena/site_worker.rb +2 -2
  65. data/lib/zena/test_controller.rb +5 -2
  66. data/lib/zena/use/action.rb +9 -2
  67. data/lib/zena/use/ajax.rb +20 -4
  68. data/lib/zena/use/ancestry.rb +89 -15
  69. data/lib/zena/use/authlogic.rb +8 -2
  70. data/lib/zena/use/context.rb +1 -0
  71. data/lib/zena/use/display.rb +1 -97
  72. data/lib/zena/use/forms.rb +28 -8
  73. data/lib/zena/use/html_tags.rb +16 -7
  74. data/lib/zena/use/i18n.rb +1 -1
  75. data/lib/zena/use/prop_eval.rb +6 -1
  76. data/lib/zena/use/query_node.rb +69 -4
  77. data/lib/zena/use/recursion.rb +1 -1
  78. data/lib/zena/use/refactor.rb +5 -2
  79. data/lib/zena/use/relations.rb +1 -0
  80. data/lib/zena/use/rendering.rb +7 -4
  81. data/lib/zena/use/test_helper.rb +8 -4
  82. data/lib/zena/use/upload.rb +14 -0
  83. data/lib/zena/use/urls.rb +39 -23
  84. data/lib/zena/use/version_hash.rb +5 -2
  85. data/lib/zena/use/workflow.rb +116 -70
  86. data/lib/zena/use/zafu_eval.rb +41 -0
  87. data/lib/zena/use/zafu_safe_definitions.rb +1 -0
  88. data/lib/zena/use/zafu_templates.rb +32 -26
  89. data/lib/zena/use/zazen.rb +8 -7
  90. data/locale/app.pot +5 -1
  91. data/locale/de/LC_MESSAGES/zena.mo +0 -0
  92. data/locale/de/zena.po +385 -281
  93. data/locale/en/LC_MESSAGES/zena.mo +0 -0
  94. data/locale/en/zena.po +378 -271
  95. data/locale/fr/LC_MESSAGES/zena.mo +0 -0
  96. data/locale/fr/zena.po +387 -272
  97. data/locale/it/LC_MESSAGES/zena.mo +0 -0
  98. data/locale/it/zena.po +433 -404
  99. data/locale/zena.pot +362 -268
  100. data/public/javascripts/grid.js +280 -104
  101. data/public/javascripts/zena.js +43 -15
  102. data/public/stylesheets/admin.css +8 -2
  103. data/public/stylesheets/grid.css +5 -2
  104. data/public/stylesheets/popup.css +1 -1
  105. data/test/fixtures/files/TestNode.zafu +51 -0
  106. data/test/functional/nodes_controller_test.rb +20 -5
  107. data/test/functional/user_sessions_controller_test.rb +41 -6
  108. data/test/functional/users_controller_test.rb +1 -2
  109. data/test/integration/navigation_test.rb +22 -4
  110. data/test/integration/query_node/basic.yml +7 -0
  111. data/test/integration/query_node/complex.yml +1 -1
  112. data/test/integration/query_node/errors.yml +1 -1
  113. data/test/integration/query_node/filters.yml +34 -1
  114. data/test/integration/query_node/relations.yml +6 -13
  115. data/test/integration/query_node_test.rb +22 -3
  116. data/test/integration/zafu_compiler/action.yml +1 -1
  117. data/test/integration/zafu_compiler/alias_site.yml +52 -0
  118. data/test/integration/zafu_compiler/complex.yml +1 -1
  119. data/test/integration/zafu_compiler/complex_ok.yml +5 -5
  120. data/test/integration/zafu_compiler/context.yml +1 -1
  121. data/test/integration/zafu_compiler/display.yml +56 -5
  122. data/test/integration/zafu_compiler/forms.yml +35 -2
  123. data/test/integration/zafu_compiler/meta.yml +4 -0
  124. data/test/integration/zafu_compiler/rubyless.yml +1 -1
  125. data/test/integration/zafu_compiler/safe_definitions.yml +4 -0
  126. data/test/integration/zafu_compiler/security.yml +10 -0
  127. data/test/integration/zafu_compiler/site.yml +5 -1
  128. data/test/integration/zafu_compiler/urls.yml +8 -2
  129. data/test/integration/zafu_compiler/zafu_attributes.yml +2 -1
  130. data/test/integration/zafu_compiler/zazen.yml +4 -0
  131. data/test/integration/zafu_compiler_test.rb +47 -4
  132. data/test/selenium/Grid/grid1.rsel +8 -8
  133. data/test/sites/complex/sites.yml +2 -2
  134. data/test/sites/complex/users.yml +1 -0
  135. data/test/sites/zena/columns.yml +4 -0
  136. data/test/sites/zena/sites.yml +1 -0
  137. data/test/sites/zena/users.yml +1 -0
  138. data/test/unit/node_test.rb +53 -5
  139. data/test/unit/note_test.rb +1 -1
  140. data/test/unit/relation_proxy_test.rb +20 -0
  141. data/test/unit/role_test.rb +2 -0
  142. data/test/unit/site_test.rb +28 -6
  143. data/test/unit/user_test.rb +332 -1
  144. data/test/unit/virtual_class_test.rb +55 -0
  145. data/test/unit/workflow_test.rb +175 -0
  146. data/test/unit/zena/use/ancestry_test.rb +52 -10
  147. data/test/unit/zena/use/prop_eval_test.rb +44 -0
  148. data/test/unit/zena/use/rendering_test.rb +48 -2
  149. data/test/unit/zena/use/upload_test.rb +15 -13
  150. data/test/unit/zena/use/urls_test.rb +1 -0
  151. data/vendor/plugins/ar_mysql_full_text/lib/ar_mysql_full_text.rb +39 -25
  152. data/zena.gemspec +69 -307
  153. metadata +143 -368
  154. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run 2.tmCommand +0 -24
  155. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run Context.tmCommand +0 -58
  156. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run Focused Should.tmCommand +0 -88
  157. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/Run.tmCommand +0 -27
  158. data/vendor/TextMate/Ruby Shoulda.tmbundle/Commands/YAML to Shoulda.tmCommand +0 -23
  159. data/vendor/TextMate/Ruby Shoulda.tmbundle/Preferences/Symbol List: Context.tmPreferences +0 -19
  160. data/vendor/TextMate/Ruby Shoulda.tmbundle/Preferences/Symbol List: Should.tmPreferences +0 -19
  161. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory attributes for.tmSnippet +0 -16
  162. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory build.tmSnippet +0 -16
  163. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory.tmSnippet +0 -16
  164. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_define with class.tmSnippet +0 -18
  165. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_define.tmSnippet +0 -18
  166. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_next.tmSnippet +0 -16
  167. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/Factory_sequence.tmSnippet +0 -18
  168. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_bad_value.tmSnippet +0 -16
  169. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_contains.tmSnippet +0 -16
  170. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_does_not_contain.tmSnippet +0 -16
  171. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_good_value.tmSnippet +0 -16
  172. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_same_elements.tmSnippet +0 -16
  173. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_save.tmSnippet +0 -16
  174. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_sent_email.tmSnippet +0 -18
  175. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/assert_valid.tmSnippet +0 -16
  176. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/association.tmSnippet +0 -17
  177. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/attribute.tmSnippet +0 -17
  178. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/before_should block.tmSnippet +0 -18
  179. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block get.tmSnippet +0 -22
  180. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block post.tmSnippet +0 -23
  181. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/context block with setup.tmSnippet +0 -25
  182. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/setup.tmSnippet +0 -18
  183. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should block with before proc.tmSnippet +0 -18
  184. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should block.tmSnippet +0 -18
  185. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_allow_values_for.tmSnippet +0 -16
  186. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_assign_to.tmSnippet +0 -16
  187. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_be_restful denied.tmSnippet +0 -20
  188. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_be_restful.tmSnippet +0 -20
  189. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_belong_to.tmSnippet +0 -16
  190. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_change by.tmSnippet +0 -16
  191. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_change from to.tmSnippet +0 -16
  192. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_at_least.tmSnippet +0 -16
  193. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_in_range.tmSnippet +0 -16
  194. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_length_is.tmSnippet +0 -16
  195. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_ensure_value_in_range.tmSnippet +0 -16
  196. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_eventually.tmSnippet +0 -18
  197. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_filter_params.tmSnippet +0 -16
  198. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_and_belong_to_many.tmSnippet +0 -16
  199. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_class_methods.tmSnippet +0 -16
  200. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_db_column.tmSnippet +0 -16
  201. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_db_columns.tmSnippet +0 -16
  202. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_index.tmSnippet +0 -16
  203. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_indices.tmSnippet +0 -16
  204. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_instance_methods.tmSnippet +0 -16
  205. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_many.tmSnippet +0 -16
  206. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_named_scope.tmSnippet +0 -16
  207. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_one.tmSnippet +0 -16
  208. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_have_readonly_attributes.tmSnippet +0 -16
  209. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_allow_mass_assignment_of.tmSnippet +0 -16
  210. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_allow_values_for.tmSnippet +0 -16
  211. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_assign_to.tmSnippet +0 -16
  212. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_change.tmSnippet +0 -16
  213. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_not_set_the_flash.tmSnippet +0 -16
  214. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_redirect_to.tmSnippet +0 -16
  215. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_a_form.tmSnippet +0 -16
  216. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_template.tmSnippet +0 -16
  217. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_with_layout.tmSnippet +0 -16
  218. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_render_without_layout.tmSnippet +0 -16
  219. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_respond_with.tmSnippet +0 -16
  220. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_respond_with_content_type.tmSnippet +0 -16
  221. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_return_from_session.tmSnippet +0 -16
  222. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_route.tmSnippet +0 -16
  223. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_set_the_flash_to.tmSnippet +0 -16
  224. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_acceptance_of.tmSnippet +0 -16
  225. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_numericality_of.tmSnippet +0 -16
  226. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_presence_of.tmSnippet +0 -16
  227. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_uniqueness_of with scope.tmSnippet +0 -16
  228. data/vendor/TextMate/Ruby Shoulda.tmbundle/Snippets/should_validate_uniqueness_of.tmSnippet +0 -16
  229. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/catch_exception.rb +0 -39
  230. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/run_script.rb +0 -104
  231. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/stdin_dialog.rb +0 -14
  232. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/test.rb +0 -17
  233. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/RubyMate/todo.txt +0 -13
  234. data/vendor/TextMate/Ruby Shoulda.tmbundle/Support/bin/yaml_to_shoulda.rb +0 -25
  235. data/vendor/TextMate/Ruby Shoulda.tmbundle/Syntaxes/Ruby on Rails (Shoulda).tmLanguage +0 -166
  236. data/vendor/TextMate/Ruby Shoulda.tmbundle/info.plist +0 -304
  237. data/vendor/TextMate/Zena.tmbundle/Commands/Run all yaml tests.tmCommand +0 -37
  238. data/vendor/TextMate/Zena.tmbundle/Commands/Run focused yaml test.tmCommand +0 -52
  239. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/catch_exception.rb +0 -39
  240. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/run_script.rb +0 -118
  241. data/vendor/TextMate/Zena.tmbundle/Support/RubyMate/stdin_dialog.rb +0 -14
  242. data/vendor/TextMate/Zena.tmbundle/info.plist +0 -17
  243. data/vendor/plugins/selenium-on-rails/CHANGELOG +0 -125
  244. data/vendor/plugins/selenium-on-rails/LICENSE-2.0.txt +0 -202
  245. data/vendor/plugins/selenium-on-rails/README.md +0 -202
  246. data/vendor/plugins/selenium-on-rails/Rakefile +0 -38
  247. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumController.html +0 -265
  248. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumHelper.html +0 -148
  249. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails.html +0 -126
  250. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/FixtureLoader.html +0 -231
  251. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/PartialsSupport.html +0 -195
  252. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Paths.html +0 -295
  253. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/RSelenese.html +0 -219
  254. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Renderer.html +0 -156
  255. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/Selenese.html +0 -179
  256. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/SuiteRenderer.html +0 -223
  257. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilder.html +0 -441
  258. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderAccessors.html +0 -3098
  259. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderActions.html +0 -2080
  260. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserAccessors.html +0 -116
  261. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRails/TestBuilderUserActions.html +0 -116
  262. data/vendor/plugins/selenium-on-rails/doc/classes/SeleniumOnRailsConfig.html +0 -150
  263. data/vendor/plugins/selenium-on-rails/doc/files/CHANGELOG.html +0 -422
  264. data/vendor/plugins/selenium-on-rails/doc/files/README.html +0 -321
  265. data/vendor/plugins/selenium-on-rails/doc/files/lib/controllers/selenium_controller_rb.html +0 -108
  266. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_helper_rb.html +0 -101
  267. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/acceptance_test_runner_rb.html +0 -222
  268. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/fixture_loader_rb.html +0 -109
  269. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/partials_support_rb.html +0 -111
  270. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/paths_rb.html +0 -101
  271. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/renderer_rb.html +0 -101
  272. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/rselenese_rb.html +0 -118
  273. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/selenese_rb.html +0 -101
  274. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/suite_renderer_rb.html +0 -101
  275. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_accessors_rb.html +0 -114
  276. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_actions_rb.html +0 -113
  277. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails/test_builder_rb.html +0 -120
  278. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_config_rb.html +0 -108
  279. data/vendor/plugins/selenium-on-rails/doc/files/lib/selenium_on_rails_rb.html +0 -115
  280. data/vendor/plugins/selenium-on-rails/doc/fr_class_index.html +0 -42
  281. data/vendor/plugins/selenium-on-rails/doc/fr_file_index.html +0 -43
  282. data/vendor/plugins/selenium-on-rails/doc/fr_method_index.html +0 -182
  283. data/vendor/plugins/selenium-on-rails/doc/index.html +0 -24
  284. data/vendor/plugins/selenium-on-rails/doc/rdoc-style.css +0 -208
  285. data/vendor/plugins/selenium-on-rails/generators/selenium/USAGE +0 -19
  286. data/vendor/plugins/selenium-on-rails/generators/selenium/selenium_generator.rb +0 -50
  287. data/vendor/plugins/selenium-on-rails/generators/selenium/templates/rhtml.rhtml +0 -16
  288. data/vendor/plugins/selenium-on-rails/generators/selenium/templates/rselenese.rhtml +0 -14
  289. data/vendor/plugins/selenium-on-rails/generators/selenium/templates/selenese.rhtml +0 -11
  290. data/vendor/plugins/selenium-on-rails/init.rb +0 -15
  291. data/vendor/plugins/selenium-on-rails/lib/controllers/selenium_controller.rb +0 -122
  292. data/vendor/plugins/selenium-on-rails/lib/controllers/switch_environment_controller.rb +0 -16
  293. data/vendor/plugins/selenium-on-rails/lib/selenium_helper.rb +0 -8
  294. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails.rb +0 -11
  295. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/acceptance_test_runner.rb +0 -215
  296. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/fixture_loader.rb +0 -57
  297. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/partials_support.rb +0 -36
  298. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/paths.rb +0 -61
  299. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/renderer.rb +0 -20
  300. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/rselenese.rb +0 -44
  301. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/selenese.rb +0 -87
  302. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/suite_renderer.rb +0 -56
  303. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder.rb +0 -116
  304. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_accessors.rb +0 -1002
  305. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_actions.rb +0 -514
  306. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_accessors.rb.example +0 -91
  307. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails/test_builder_user_actions.rb.example +0 -24
  308. data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb +0 -30
  309. data/vendor/plugins/selenium-on-rails/lib/views/layouts/layout.rhtml +0 -18
  310. data/vendor/plugins/selenium-on-rails/lib/views/record.rhtml +0 -5
  311. data/vendor/plugins/selenium-on-rails/lib/views/selenium_helper.rb +0 -9
  312. data/vendor/plugins/selenium-on-rails/lib/views/setup.rhtml +0 -67
  313. data/vendor/plugins/selenium-on-rails/lib/views/test_suite.rhtml +0 -26
  314. data/vendor/plugins/selenium-on-rails/routes.rb +0 -24
  315. data/vendor/plugins/selenium-on-rails/selenium-core/Blank.html +0 -7
  316. data/vendor/plugins/selenium-on-rails/selenium-core/InjectedRemoteRunner.html +0 -8
  317. data/vendor/plugins/selenium-on-rails/selenium-core/RemoteRunner.html +0 -110
  318. data/vendor/plugins/selenium-on-rails/selenium-core/SeleniumLog.html +0 -109
  319. data/vendor/plugins/selenium-on-rails/selenium-core/TestPrompt.html +0 -145
  320. data/vendor/plugins/selenium-on-rails/selenium-core/TestRunner-splash.html +0 -55
  321. data/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.hta +0 -177
  322. data/vendor/plugins/selenium-on-rails/selenium-core/TestRunner.html +0 -177
  323. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butmin.gif +0 -0
  324. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/butplus.gif +0 -0
  325. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.css +0 -298
  326. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/domviewer.html +0 -16
  327. data/vendor/plugins/selenium-on-rails/selenium-core/domviewer/selenium-domviewer.js +0 -205
  328. data/vendor/plugins/selenium-on-rails/selenium-core/icons/all.png +0 -0
  329. data/vendor/plugins/selenium-on-rails/selenium-core/icons/continue.png +0 -0
  330. data/vendor/plugins/selenium-on-rails/selenium-core/icons/continue_disabled.png +0 -0
  331. data/vendor/plugins/selenium-on-rails/selenium-core/icons/pause.png +0 -0
  332. data/vendor/plugins/selenium-on-rails/selenium-core/icons/pause_disabled.png +0 -0
  333. data/vendor/plugins/selenium-on-rails/selenium-core/icons/selected.png +0 -0
  334. data/vendor/plugins/selenium-on-rails/selenium-core/icons/step.png +0 -0
  335. data/vendor/plugins/selenium-on-rails/selenium-core/icons/step_disabled.png +0 -0
  336. data/vendor/plugins/selenium-on-rails/selenium-core/iedoc-core.xml +0 -1759
  337. data/vendor/plugins/selenium-on-rails/selenium-core/iedoc.xml +0 -1800
  338. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/cssQuery-p.js +0 -6
  339. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level2.js +0 -142
  340. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-level3.js +0 -150
  341. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery-standard.js +0 -53
  342. data/vendor/plugins/selenium-on-rails/selenium-core/lib/cssQuery/src/cssQuery.js +0 -356
  343. data/vendor/plugins/selenium-on-rails/selenium-core/lib/prototype.js +0 -2006
  344. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/builder.js +0 -101
  345. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/controls.js +0 -815
  346. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/dragdrop.js +0 -915
  347. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/effects.js +0 -958
  348. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/scriptaculous.js +0 -47
  349. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/slider.js +0 -283
  350. data/vendor/plugins/selenium-on-rails/selenium-core/lib/scriptaculous/unittest.js +0 -383
  351. data/vendor/plugins/selenium-on-rails/selenium-core/lib/snapsie.js +0 -91
  352. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/find_matching_child.js +0 -69
  353. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/htmlutils.js +0 -1616
  354. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/injection.html +0 -72
  355. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-api.js +0 -3184
  356. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserbot.js +0 -2300
  357. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-browserdetect.js +0 -153
  358. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-commandhandlers.js +0 -377
  359. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-executionloop.js +0 -175
  360. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-logging.js +0 -148
  361. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-remoterunner.js +0 -695
  362. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-testrunner.js +0 -1362
  363. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/selenium-version.js +0 -5
  364. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-doc.html +0 -803
  365. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-element.js +0 -1537
  366. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/ui-map-sample.js +0 -979
  367. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js +0 -3
  368. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/user-extensions.js.sample +0 -75
  369. data/vendor/plugins/selenium-on-rails/selenium-core/scripts/xmlextras.js +0 -153
  370. data/vendor/plugins/selenium-on-rails/selenium-core/selenium-logo.png +0 -0
  371. data/vendor/plugins/selenium-on-rails/selenium-core/selenium-test.css +0 -43
  372. data/vendor/plugins/selenium-on-rails/selenium-core/selenium.css +0 -316
  373. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/dom.js +0 -566
  374. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/javascript-xpath-0.1.11.js +0 -2816
  375. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/util.js +0 -549
  376. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/xmltoken.js +0 -149
  377. data/vendor/plugins/selenium-on-rails/selenium-core/xpath/xpath.js +0 -2450
  378. data/vendor/plugins/selenium-on-rails/tasks/test_acceptance.rake +0 -8
  379. data/vendor/plugins/selenium-on-rails/test/fixtures/config.yml +0 -37
  380. data/vendor/plugins/selenium-on-rails/test/fixtures/selenium.yml +0 -27
  381. data/vendor/plugins/selenium-on-rails/test/paths_test.rb +0 -72
  382. data/vendor/plugins/selenium-on-rails/test/renderer_test.rb +0 -157
  383. data/vendor/plugins/selenium-on-rails/test/rselenese_test.rb +0 -708
  384. data/vendor/plugins/selenium-on-rails/test/selenese_test.rb +0 -242
  385. data/vendor/plugins/selenium-on-rails/test/selenium_controller_test.rb +0 -67
  386. data/vendor/plugins/selenium-on-rails/test/selenium_on_rails_config_test.rb +0 -43
  387. data/vendor/plugins/selenium-on-rails/test/selenium_support_test.rb +0 -35
  388. data/vendor/plugins/selenium-on-rails/test/setup_test.rb +0 -31
  389. data/vendor/plugins/selenium-on-rails/test/suite_renderer_test.rb +0 -109
  390. data/vendor/plugins/selenium-on-rails/test/switch_environment_controller_test.rb +0 -17
  391. data/vendor/plugins/selenium-on-rails/test/test_builder_functions_authortest.rb +0 -51
  392. data/vendor/plugins/selenium-on-rails/test/test_helper.rb +0 -101
  393. data/vendor/plugins/selenium-on-rails/test_data/_partial.rsel +0 -1
  394. data/vendor/plugins/selenium-on-rails/test_data/own_layout.html +0 -12
  395. data/vendor/plugins/selenium-on-rails/test_data/partials/_html.html +0 -6
  396. data/vendor/plugins/selenium-on-rails/test_data/partials/_nesting.rsel +0 -2
  397. data/vendor/plugins/selenium-on-rails/test_data/partials/_rhtml.rhtml +0 -6
  398. data/vendor/plugins/selenium-on-rails/test_data/partials/_rsel.rsel +0 -1
  399. data/vendor/plugins/selenium-on-rails/test_data/partials/_sel.sel +0 -5
  400. data/vendor/plugins/selenium-on-rails/test_data/partials/all_partials.rsel +0 -5
  401. data/vendor/plugins/selenium-on-rails/test_data/rhtml.rhtml +0 -7
  402. data/vendor/plugins/selenium-on-rails/test_data/rselenese.rsel +0 -8
  403. data/vendor/plugins/selenium-on-rails/test_data/selenese.sel +0 -7
  404. data/vendor/plugins/selenium-on-rails/test_data/suite_one/subsuite/suite_one_subsuite_testcase.sel +0 -1
  405. data/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase1.sel +0 -1
  406. data/vendor/plugins/selenium-on-rails/test_data/suite_one/suite_one_testcase2.sel +0 -1
  407. data/vendor/plugins/selenium-on-rails/test_data/suite_two/suite_two_testcase.sel +0 -1
@@ -262,6 +262,10 @@ class Role < ActiveRecord::Base
262
262
  relation.save!
263
263
  end
264
264
  end
265
+
266
+ def db_columns
267
+ @original_columns || {}
268
+ end
265
269
 
266
270
  private
267
271
  def set_defaults
@@ -51,7 +51,7 @@ class Site < ActiveRecord::Base
51
51
  ['zips' , 'site_id = ?'],
52
52
  ['nodes' , 'site_id = ?'],
53
53
  ]
54
- ACTIONS = %w{clear_cache rebuild_index}
54
+ ACTIONS = %w{clear_cache rebuild_index rebuild_fullpath}
55
55
  PUBLIC_PATH = Bricks.raw_config['public_path'] || '/public'
56
56
  CACHE_PATH = Bricks.raw_config['cache_path'] || '/public'
57
57
 
@@ -59,10 +59,11 @@ class Site < ActiveRecord::Base
59
59
  safe_method :host => String, :lang_list => [String], :default_lang => String, :master_host => String
60
60
  safe_method :root => Proc.new {|h, r, s| {:method => 'root_node', :class => current_site.root_node.vclass, :nil => true}}
61
61
  safe_method :home => Proc.new {|h, r, s| {:method => 'home_node', :class => current_site.home_node.vclass, :nil => true}}
62
+ safe_method :readonly? => {:method => 'site_readonly?', :class => Boolean}
62
63
 
63
64
  validate :valid_site
64
65
  validates_uniqueness_of :host
65
- attr_accessible :name, :languages, :default_lang, :authentication, :http_auth, :ssl_on_auth, :auto_publish, :redit_time, :api_group_id, :home_zip
66
+ attr_accessible :name, :languages, :default_lang, :authentication, :http_auth, :ssl_on_auth, :site_readonly, :auto_publish, :redit_time, :api_group_id, :home_zip, :skin_zip
66
67
  has_many :groups, :order => "name"
67
68
  has_many :nodes
68
69
  has_many :users
@@ -76,7 +77,7 @@ class Site < ActiveRecord::Base
76
77
  include Zena::Use::MLIndex::SiteMethods
77
78
 
78
79
  @@attributes_for_form = {
79
- :bool => %w{authentication http_auth auto_publish ssl_on_auth},
80
+ :bool => %w{authentication http_auth auto_publish ssl_on_auth site_readonly},
80
81
  :text => %w{languages default_lang},
81
82
  }
82
83
 
@@ -155,7 +156,7 @@ class Site < ActiveRecord::Base
155
156
  site.groups << pub << sgroup << editors
156
157
 
157
158
  # Reload group_ids in admin
158
- admin_user.instance_variable_set(:@group_ids, nil)
159
+ admin_user.reload_groups!
159
160
 
160
161
  # =========== CREATE Anonymous User =====================
161
162
  # create anon user
@@ -251,7 +252,7 @@ class Site < ActiveRecord::Base
251
252
  end
252
253
  end
253
254
 
254
- property.string 'usr_prototype_attributes'
255
+ property.string 'usr_prototype_attributes'
255
256
  property.boolean 'expire_in_dev'
256
257
  property.boolean 'ssl_on_auth'
257
258
 
@@ -405,6 +406,30 @@ class Site < ActiveRecord::Base
405
406
  @home_zip_error = _('could not be found')
406
407
  end
407
408
  end
409
+
410
+ def skin_zip
411
+ skin ? skin.zip : nil
412
+ end
413
+
414
+ def skin_zip=(zip)
415
+ if zip.blank?
416
+ self[:skin_id] = nil
417
+ else
418
+ if id = secure(Node) { Node.translate_pseudo_id(zip) }
419
+ self[:skin_id] = id
420
+ else
421
+ @skin_zip_error = _('could not be found')
422
+ end
423
+ end
424
+ end
425
+
426
+ def skin
427
+ secure(Skin) { Skin.find_by_id(skin_id) }
428
+ end
429
+
430
+ def skin_id
431
+ @alias && @alias[:skin_id] || self[:skin_id]
432
+ end
408
433
 
409
434
  def create_alias(hostname)
410
435
  raise "Hostname '#{hostname}' already exists" if Site.find_by_host(hostname)
@@ -463,7 +488,7 @@ class Site < ActiveRecord::Base
463
488
  end
464
489
  end
465
490
 
466
- def clear_cache(clear_zafu = true)
491
+ def clear_cache(should_clear_zafu = true)
467
492
  paths = ["#{SITES_ROOT}#{self.cache_path}"]
468
493
  aliases = Site.all(:conditions => {:master_id => self.id})
469
494
  aliases.each do |site|
@@ -473,32 +498,30 @@ class Site < ActiveRecord::Base
473
498
 
474
499
  paths.each do |path|
475
500
  if File.exist?(path)
501
+ # First remove DB entries so that we do not risk race condition where a cached page is created during
502
+ # filesystem operation and before.
503
+ Zena::Db.execute "DELETE FROM caches WHERE site_id = #{self[:id]}"
504
+ Zena::Db.execute "DELETE FROM cached_pages_nodes WHERE cached_pages_nodes.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.site_id = #{self[:id]})"
505
+ Zena::Db.execute "DELETE FROM cached_pages WHERE site_id = #{self[:id]}"
506
+
476
507
  Dir.foreach(path) do |elem|
477
508
  next unless elem =~ /^(\w\w\.html|\w\w|login\.html)$/
478
509
  FileUtils.rmtree(File.join(path, elem))
479
510
  end
480
-
481
- Zena::Db.execute "DELETE FROM caches WHERE site_id = #{self[:id]}"
482
- Zena::Db.execute "DELETE FROM cached_pages_nodes WHERE cached_pages_nodes.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.site_id = #{self[:id]})"
483
- Zena::Db.execute "DELETE FROM cached_pages WHERE site_id = #{self[:id]}"
484
511
  end
485
512
  end
486
513
 
487
- # Clear zafu
488
- if clear_zafu
489
- paths = ["#{SITES_ROOT}#{self.zafu_path}"]
490
- aliases.each do |site|
491
- paths << "#{SITES_ROOT}#{site.cache_path}"
492
- end
493
- paths.each do |path|
494
- if File.exist?(path)
495
- FileUtils.rmtree(path)
496
- end
497
- end
498
- end
514
+ clear_zafu if should_clear_zafu
499
515
 
500
516
  true
501
517
  end
518
+
519
+ def clear_zafu
520
+ path = "#{SITES_ROOT}#{self.zafu_path}"
521
+ if File.exist?(path)
522
+ FileUtils.rmtree(path)
523
+ end
524
+ end
502
525
 
503
526
  # Rebuild vhash indices for the Site. This method uses the Worker thread to rebuild and works on
504
527
  # chunks of 50 nodes.
@@ -517,45 +540,23 @@ class Site < ActiveRecord::Base
517
540
  true
518
541
  end
519
542
 
520
- # Recreates the fullpath ('/zip/zip/zip').
521
- # TODO: find a way to use SiteWorker (need to remove get_nodes): fix rake when this is done.
522
- def rebuild_fullpath(parent_id = nil, parent_fullpath = "", parent_basepath = "", start=[])
523
- raise Zena::InvalidRecord, "Infinit loop in 'ancestors' (#{start.inspect} --> #{parent_id})" if start.include?(parent_id)
524
- start += [parent_id]
525
- i = 0
526
- batch_size = 100
527
- children = []
528
- while true
529
- rec = Zena::Db.fetch_attributes(['id', 'fullpath', 'basepath', 'custom_base', 'zip'], 'nodes', "parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"} AND site_id = #{self.id} ORDER BY id ASC LIMIT #{batch_size} OFFSET #{i * batch_size}")
530
- break if rec.empty?
531
- rec.each do |rec|
532
- if parent_id
533
- rec['fullpath'] = parent_fullpath == '' ? rec['zip'] : "#{parent_fullpath}/#{rec['zip']}"
534
- else
535
- # root node
536
- rec['fullpath'] = ''
537
- end
538
-
539
- if rec['custom_base'] == Zena::Db::TRUE_RESULT
540
- rec['basepath'] = rec['fullpath']
541
- else
542
- rec['basepath'] = parent_basepath
543
- end
544
-
545
- id = rec.delete('id')
546
- children << [id, rec['fullpath'], rec['basepath'], start]
547
- Zena::Db.execute "UPDATE nodes SET #{rec.map {|k,v| "#{Zena::Db.connection.quote_column_name(k)}=#{Zena::Db.quote(v)}"}.join(', ')} WHERE id = #{id}"
543
+ # Rebuild fullpath cache for the Site. This method uses the Worker thread to rebuild.
544
+ #
545
+ # The visitor used during index rebuild should be an admin user.
546
+ def rebuild_fullpath(nodes = nil, page = nil, page_count = nil)
547
+ if !page
548
+ Zena::SiteWorker.perform(self, :rebuild_fullpath)
549
+ else
550
+ if page == 1
551
+ Site.logger.error("\n----------------- REBUILD FULLPATH FOR SITE #{host} (#{Node.count(:conditions => {:site_id => id})} nodes)-----------------\n")
552
+ # Rebuild all paths at once (no pagination because of recursion)
553
+ Zena::Use::Ancestry.rebuild_all_paths(root_node)
548
554
  end
549
- # 50 more
550
- i += 1
551
- end
552
- children.each do |child|
553
- rebuild_fullpath(*child)
554
555
  end
555
556
 
556
557
  true
557
558
  end
558
-
559
+
559
560
  # Rebuild property indices for the Site. This method uses the Worker thread to rebuild and works on
560
561
  # chunks of 50 nodes.
561
562
  #
@@ -613,11 +614,16 @@ class Site < ActiveRecord::Base
613
614
  end
614
615
 
615
616
  if @home_zip_error
616
- errors.add('root_id', @home_zip_error)
617
+ errors.add('root_zip', @home_zip_error)
617
618
  @home_zip_error = nil
618
619
  end
620
+
621
+ if @skin_zip_error
622
+ errors.add('skin_zip', @skin_zip_error)
623
+ @skin_zip_error = nil
624
+ end
619
625
  end
620
626
 
621
627
  end
622
628
 
623
- Bricks.apply_patches
629
+ Bricks.apply_patches
@@ -95,7 +95,7 @@ class Template < TextDocument
95
95
  end
96
96
  end
97
97
 
98
- if version.edited?
98
+ if prop.changes.keys != []
99
99
  self.mode = mode.gsub(/[^a-zA-Z\+]/, '') if mode
100
100
 
101
101
  if !target_klass.blank?
@@ -29,6 +29,7 @@ class User < ActiveRecord::Base
29
29
  include Property
30
30
  RESCUE_SKIN_ID = -1
31
31
  ANY_SKIN_ID = 0
32
+ ATTRIBUTES_FROM_PROFILE = [:group_ids, :status]
32
33
 
33
34
  property do |p|
34
35
  # nil ==> no dev mode
@@ -65,15 +66,16 @@ class User < ActiveRecord::Base
65
66
 
66
67
  safe_attribute :login, :time_zone, :created_at, :updated_at, :lang, :id
67
68
  safe_method :status => Number, :status_name => String,
68
- :is_anon? => Boolean, :is_admin? => Boolean, :user? => Boolean, :commentator? => Boolean,
69
+ :is_anon? => Boolean, :is_admin? => Boolean, :is_manager? => Boolean, :user? => Boolean, :commentator? => Boolean,
69
70
  :moderated? => Boolean, :asset_host? => Boolean, [:in_group?, String] => Boolean,
70
- :group_names => [String]
71
+ :group_names => [String], [:group_id_to_name, Number] => String, :site => Site
71
72
 
72
73
  safe_context :node => node_user_proc,
73
74
  :to_publish => ['Version'], :redactions => ['Version'], :proposed => ['Version'],
74
75
  :comments_to_publish => ['Comment']
75
76
 
76
- attr_accessible :login, :lang, :node, :time_zone, :status, :group_ids, :site_ids, :crypted_password, :password, :dev_skin_id, :node_attributes
77
+ attr_accessible :login, :lang, :node, :time_zone, :status, :group_ids, :site_ids, :crypted_password, :password, :dev_skin_id, :node_attributes,
78
+ :login_attempt_count, :is_profile, :profile
77
79
  attr_accessor :visited_node_ids
78
80
  attr_accessor :ip
79
81
 
@@ -92,14 +94,16 @@ class User < ActiveRecord::Base
92
94
  before_destroy :dont_destroy_protected_users
93
95
  validates_presence_of :site_id
94
96
  before_create :create_node
97
+ after_save :user_after_save
95
98
 
96
99
  Status = {
97
- :su => 80,
98
- :admin => 60, # can create other users, manage site, etc
99
- :user => 50, # can write articles + publish (depends on access rights)
100
- :commentator => 40, # can write comments
101
- :moderated => 30, # can write comments (moderated)
102
- :reader => 20, # can read
100
+ :su => 80, # Not used
101
+ :admin => 60, # Is in all groups, can access admin interface, etc
102
+ :manager => 55, # Can manage other users. Cannot edit groups.
103
+ :user => 50, # Can write articles + publish (depends on access rights)
104
+ :commentator => 40, # Can write comments
105
+ :moderated => 30, # Can write comments (moderated)
106
+ :reader => 20, # Can read
103
107
  :deleted => 0,
104
108
  }.freeze
105
109
  Num_to_status = Hash[*Status.map{|k,v| [v,k]}.flatten].freeze
@@ -210,6 +214,11 @@ class User < ActiveRecord::Base
210
214
  def is_admin?
211
215
  status.to_i >= User::Status[:admin]
212
216
  end
217
+
218
+ # Has user administration rights
219
+ def is_manager?
220
+ status.to_i >= User::Status[:manager]
221
+ end
213
222
 
214
223
  # Return true if the user is the anonymous user for the current visited site
215
224
  def is_anon?
@@ -226,9 +235,20 @@ class User < ActiveRecord::Base
226
235
  end
227
236
  end
228
237
 
238
+ # Return the name of a group for a given id. If the visitor is not in the group,
239
+ # the method returns nil
240
+ def group_id_to_name(id)
241
+ (@group_ids_to_name ||= Hash[*all_groups.map{|g| [g.id, g.name]}.flatten])[id]
242
+ end
243
+
229
244
  def in_group?(name)
230
245
  group_names.include?(name)
231
246
  end
247
+
248
+ def reload_groups!
249
+ @group_ids = nil
250
+ @all_groups = nil
251
+ end
232
252
 
233
253
  # Return true if the user's status is high enough to start editing nodes.
234
254
  def user?
@@ -269,19 +289,15 @@ class User < ActiveRecord::Base
269
289
  # Zena::Db.fetch_ids("SELECT id FROM groups WHERE site_id = #{current_site.id} ORDER BY name ASC")
270
290
  # Zena::Db.fetch_ids("SELECT group_id FROM groups_users WHERE user_id = #{id} ORDER BY name ASC", 'group_id')
271
291
  def group_ids
272
- @group_ids ||= if is_admin?
273
- site.groups.map(&:id)
274
- else
275
- groups.all(:order=>'name').map(&:id)
276
- end
292
+ @group_ids ||= all_groups.map(&:id)
277
293
  end
278
-
279
- # Return all groups (used in forms) managed by the user.
294
+
295
+ # Return all groups in which the user belongs directly or indirectly (admin).
280
296
  def all_groups
281
- if is_admin?
282
- site.groups
297
+ @all_groups ||= if is_admin?
298
+ site.groups.all(:order => 'name')
283
299
  else
284
- groups.all(:order=>'name').map(&:id)
300
+ groups.all(:order => 'name')
285
301
  end
286
302
  end
287
303
 
@@ -338,7 +354,7 @@ class User < ActiveRecord::Base
338
354
  nil
339
355
  when ANY_SKIN_ID
340
356
  # normal skin
341
- node.skin || (node.parent ? node.parent.skin : nil)
357
+ current_site.skin || node.skin || (node.parent ? node.parent.skin : nil)
342
358
  else
343
359
  # find skin from zip
344
360
  secure(Skin) { Skin.find_by_zip(skin_zip)}
@@ -362,6 +378,31 @@ class User < ActiveRecord::Base
362
378
  def dev_mode?
363
379
  !dev_skin_id.blank?
364
380
  end
381
+
382
+ def profile=(m)
383
+ if !visitor.is_manager?
384
+ # Make sure the user is a manager before changing profile
385
+ @profile_error = _('Cannot be changed')
386
+ elsif m.blank?
387
+ self[:profile_id] = nil
388
+ else
389
+ # Try to find profile user
390
+ if profile = secure(User) { User.find_by_login_and_is_profile(m.to_s, true) }
391
+ # Copy access definitions from profile to current user done during validation
392
+ self[:profile_id] = profile.id
393
+ else
394
+ @profile_error = _('Cannot be found')
395
+ end
396
+ end
397
+ end
398
+
399
+ def profile_user
400
+ @profile_user ||= secure(User) { User.find(self[:profile_id]) }
401
+ end
402
+
403
+ def profile
404
+ profile_user ? profile_user.login : ''
405
+ end
365
406
 
366
407
  private
367
408
 
@@ -372,6 +413,8 @@ class User < ActiveRecord::Base
372
413
  def create_node
373
414
  # do not try to create a node if the root node is not created yet
374
415
  return unless visitor.site.root_id
416
+ # This happens if the user is created from the node[user] params.
417
+ return if self[:node_id]
375
418
  @node.version.status = Zena::Status::Pub
376
419
 
377
420
  unless @node.save
@@ -391,7 +434,24 @@ class User < ActiveRecord::Base
391
434
  return true if current_site.being_created?
392
435
 
393
436
  self[:site_id] = visitor.site[:id]
394
-
437
+
438
+ if self[:profile_id]
439
+ # Copy elements
440
+ profile = secure(User) { User.find(self[:profile_id] ) }
441
+ ATTRIBUTES_FROM_PROFILE.each do |k|
442
+ self.send(:"#{k}=", profile.send(k))
443
+ end
444
+
445
+ # Ignore setting (to avoid loops)
446
+ if self[:is_profile]
447
+ self[:profile_id] = nil
448
+ end
449
+ elsif @defined_group_ids && !visitor.is_admin?
450
+ # Do not allow direct edition of groups by non-admin (even manager cannot do this).
451
+ @defined_group_ids = nil
452
+ @defined_group_ids_error = true
453
+ end
454
+
395
455
  if new_record?
396
456
  self.status = site.anon.status if status.blank?
397
457
  self.lang = site.anon.lang if lang.blank?
@@ -400,7 +460,7 @@ class User < ActiveRecord::Base
400
460
  end
401
461
 
402
462
  if login.blank? && !is_anon?
403
- self.login = name
463
+ self.login = self.node.title.strip
404
464
  end
405
465
 
406
466
  if !is_admin?
@@ -414,9 +474,25 @@ class User < ActiveRecord::Base
414
474
  def valid_user
415
475
  self[:site_id] = visitor.site[:id]
416
476
 
417
- if !site.being_created? && !visitor.is_admin? && visitor[:id] != self[:id]
418
- errors.add('base', 'You do not have the rights to do this.')
419
- return false
477
+ if !site.being_created?
478
+ if !visitor.is_manager? && visitor[:id] != self[:id]
479
+ errors.add('base', 'You do not have the rights to do this.')
480
+ return false
481
+ elsif visitor.is_admin?
482
+ # All OK
483
+ elsif visitor.is_manager?
484
+ # Changing status of users above or equal to manager not allowed
485
+ if status_changed? && status >= User::Status[:manager]
486
+ errors.add('base', 'You cannot set this status (too high).')
487
+ return false
488
+ end
489
+
490
+ # Editing users above or equal to manager not allowed
491
+ if status_was.to_i >= User::Status[:manager] && visitor.id != self.id
492
+ errors.add('base', 'You cannot edit this user (high status).')
493
+ return false
494
+ end
495
+ end
420
496
  end
421
497
 
422
498
  errors.add('lang', 'not available') unless site.lang_list.include?(lang)
@@ -434,7 +510,7 @@ class User < ActiveRecord::Base
434
510
  old = User.find(self[:id])
435
511
  self[:crypted_password] = old[:crypted_password] if self[:crypted_password].nil? || self[:crypted_password] == ""
436
512
  errors.add(:login, "can't be blank") if self[:login].blank?
437
- errors.add(:status, 'You do not have the rights to do this.') if self[:id] == visitor[:id] && old.is_admin? && self.status.to_i != old.status
513
+ errors.add(:status, 'You cannot remove your own access rights.') if self[:id] == visitor[:id] && old.is_admin? && self.status.to_i != old.status
438
514
  end
439
515
  end
440
516
 
@@ -445,16 +521,34 @@ class User < ActiveRecord::Base
445
521
  errors.add(:time_zone, 'invalid')
446
522
  end
447
523
  end
448
-
524
+
525
+ if self.is_profile_was && !self.is_profile
526
+ # Make sure there are no dependant users
527
+ if secure(User) { User.all(:conditions => {:profile_id => self.id}) }
528
+ errors.add('is_profile', _('Cannot be removed (profile used).'))
529
+ end
530
+ end
531
+
532
+ if @profile_error
533
+ errors.add(:profile_id, @profile_error)
534
+ remove_instance_variable :@profile_error
535
+ end
536
+
449
537
  if @password_too_short
450
- errors.add(:password, 'too short')
538
+ errors.add(:password, _('Too short'))
451
539
  remove_instance_variable :@password_too_short
452
540
  end
541
+
542
+ if @defined_group_ids_error
543
+ errors.add(:group_ids, _('Only admin can change groups.'))
544
+ remove_instance_variable :@defined_group_ids_error
545
+ end
453
546
  end
454
547
 
455
548
  def valid_node
456
549
  return unless visitor.site[:root_id] # do not validate node if the root node is not created yet
457
- return if !new_record? && !@node
550
+
551
+ return if (!new_record? || self[:node_id]) && !@node
458
552
  if !@node
459
553
  # force creation of node, even if it is a plain copy of the prototype
460
554
  self.node_attributes = {'title' => login}
@@ -499,4 +593,16 @@ class User < ActiveRecord::Base
499
593
  def old
500
594
  @old ||= self.class.find(self[:id])
501
595
  end
596
+
597
+ def user_after_save
598
+ @node.save if @node
599
+ return unless is_profile?
600
+
601
+ if users = secure(User) { User.all(:conditions => {:profile_id => self.id}) }
602
+ users.each do |u|
603
+ u.save # this will trigger sync
604
+ end
605
+ end
606
+ true
607
+ end
502
608
  end