zena 1.2.7 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
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