zena 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. data/History.txt +25 -0
  2. data/app/controllers/documents_controller.rb +3 -25
  3. data/app/controllers/nodes_controller.rb +34 -24
  4. data/app/controllers/user_sessions_controller.rb +5 -4
  5. data/app/controllers/versions_controller.rb +44 -17
  6. data/app/models/acl.rb +2 -7
  7. data/app/models/group.rb +6 -2
  8. data/app/models/link.rb +14 -0
  9. data/app/models/node.rb +2 -2
  10. data/app/models/site.rb +13 -4
  11. data/app/models/text_document.rb +1 -1
  12. data/app/models/user.rb +11 -2
  13. data/app/models/virtual_class.rb +1 -1
  14. data/app/views/groups/_form.rhtml +6 -6
  15. data/app/views/nodes/render_error.rhtml +15 -0
  16. data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
  17. data/app/views/templates/document_create_tabs/_import.rhtml +1 -1
  18. data/app/views/templates/document_create_tabs/_template.rhtml +1 -1
  19. data/app/views/templates/document_create_tabs/_text_document.rhtml +1 -1
  20. data/app/views/templates/edit_tabs/_title.rhtml +1 -1
  21. data/app/views/zafu/default/Node-admin.zafu +1 -1
  22. data/bricks/acls/zena/test/integration/acl_integration_test.rb +2 -2
  23. data/bricks/acls/zena/test/unit/acl_test.rb +2 -1
  24. data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +1 -0
  25. data/bricks/fs_skin/zena/skins/blog/img/style.css +4 -4
  26. data/bricks/grid/lib/bricks/grid.rb +9 -3
  27. data/bricks/passenger/zena/deploy.rb +2 -1
  28. data/bricks/pdf/lib/bricks/pdf.rb +1 -1
  29. data/bricks/tags/zena/test/zafu/tags.yml +5 -1
  30. data/bricks/zena/zena/migrate/20120904071601_change_link_status_to_float.rb +13 -0
  31. data/config/bricks.yml +10 -10
  32. data/config/deploy.rb +1 -5
  33. data/config/gems.yml +2 -2
  34. data/db/init/base/skins/default/Node.zafu +7 -3
  35. data/db/init/base/skins/default/notes.zafu +3 -1
  36. data/lib/zafu/all.rb +0 -9
  37. data/lib/zafu/compiler.rb +0 -4
  38. data/lib/zafu/controller_methods.rb +0 -2
  39. data/lib/zafu/handler.rb +0 -5
  40. data/lib/zafu/markup.rb +4 -6
  41. data/lib/zafu/ordered_hash.rb +3 -2
  42. data/lib/zafu/parsing_rules.rb +1 -3
  43. data/lib/zafu/process/ajax.rb +4 -2
  44. data/lib/zafu/process/context.rb +34 -4
  45. data/lib/zafu/process/forms.rb +2 -2
  46. data/lib/zafu/process/ruby_less_processing.rb +5 -10
  47. data/lib/zafu/template.rb +0 -2
  48. data/lib/zafu/test_helper.rb +0 -2
  49. data/lib/zafu/view_methods.rb +0 -1
  50. data/lib/zafu.rb +1 -1
  51. data/lib/zena/acts/secure_node.rb +5 -4
  52. data/lib/zena/console.rb +19 -17
  53. data/lib/zena/core_ext/string.rb +3 -2
  54. data/lib/zena/deploy/app_init.rhtml +6 -1
  55. data/lib/zena/deploy/httpd.rhtml +16 -13
  56. data/lib/zena/deploy/stats.vhost.rhtml +1 -1
  57. data/lib/zena/deploy/vhost.rhtml +31 -11
  58. data/lib/zena/deploy/vhost_ssl_redir.rhtml +12 -0
  59. data/lib/zena/deploy/vhost_www.rhtml +1 -1
  60. data/lib/zena/deploy.rb +55 -11
  61. data/lib/zena/info.rb +1 -1
  62. data/lib/zena/parser/zazen_rules.rb +18 -9
  63. data/lib/zena/routes.rb +1 -3
  64. data/lib/zena/site_worker.rb +8 -1
  65. data/lib/zena/use/ajax.rb +29 -3
  66. data/lib/zena/use/ancestry.rb +2 -1
  67. data/lib/zena/use/authlogic.rb +12 -18
  68. data/lib/zena/use/context.rb +1 -1
  69. data/lib/zena/use/dates.rb +28 -18
  70. data/lib/zena/use/display.rb +49 -7
  71. data/lib/zena/use/forms.rb +51 -18
  72. data/lib/zena/use/html_tags.rb +6 -6
  73. data/lib/zena/use/i18n.rb +13 -4
  74. data/lib/zena/use/image_builder.rb +2 -0
  75. data/lib/zena/use/query_builder.rb +39 -14
  76. data/lib/zena/use/query_link.rb +57 -0
  77. data/lib/zena/use/query_node.rb +68 -32
  78. data/lib/zena/use/relations.rb +25 -15
  79. data/lib/zena/use/rendering.rb +66 -15
  80. data/lib/zena/use/upload.rb +34 -5
  81. data/lib/zena/use/urls.rb +28 -25
  82. data/lib/zena/use/version_hash.rb +14 -2
  83. data/lib/zena/use/zafu_safe_definitions.rb +72 -3
  84. data/lib/zena/use/zazen.rb +16 -4
  85. data/lib/zena.rb +1 -0
  86. data/public/javascripts/grid.js +213 -64
  87. data/public/javascripts/raphael.js +10 -0
  88. data/public/javascripts/zena.js +146 -22
  89. data/public/stylesheets/reset.css +12 -12
  90. data/public/stylesheets/zena.css +1 -1
  91. data/test/custom_queries/complex.host.yml +19 -0
  92. data/test/fixtures/files/TestNode.zafu +40 -4
  93. data/test/functional/nodes_controller_test.rb +84 -39
  94. data/test/functional/versions_controller_test.rb +2 -2
  95. data/test/integration/navigation_test.rb +61 -35
  96. data/test/integration/query_node/basic.yml +7 -7
  97. data/test/integration/query_node/comments.yml +1 -1
  98. data/test/integration/query_node/complex.yml +3 -3
  99. data/test/integration/query_node/filters.yml +32 -8
  100. data/test/integration/query_node/idx_key_value.yml +10 -10
  101. data/test/integration/query_node/idx_scope.yml +7 -7
  102. data/test/integration/query_node/relations.yml +4 -4
  103. data/test/integration/zafu_compiler/ajax.yml +19 -11
  104. data/test/integration/zafu_compiler/apphelper.yml +1 -1
  105. data/test/integration/zafu_compiler/asset.yml +2 -2
  106. data/test/integration/zafu_compiler/comments.yml +1 -1
  107. data/test/integration/zafu_compiler/dates.yml +1 -1
  108. data/test/integration/zafu_compiler/display.yml +49 -21
  109. data/test/integration/zafu_compiler/eval.yml +4 -4
  110. data/test/integration/zafu_compiler/forms.yml +25 -11
  111. data/test/integration/zafu_compiler/i18n.yml +5 -0
  112. data/test/integration/zafu_compiler/meta.yml +3 -3
  113. data/test/integration/zafu_compiler/query.yml +27 -9
  114. data/test/integration/zafu_compiler/relations.yml +9 -9
  115. data/test/integration/zafu_compiler/roles.yml +6 -6
  116. data/test/integration/zafu_compiler/rubyless.yml +7 -2
  117. data/test/integration/zafu_compiler/safe_definitions.yml +33 -4
  118. data/test/integration/zafu_compiler/security.yml +46 -1
  119. data/test/integration/zafu_compiler/urls.yml +28 -13
  120. data/test/integration/zafu_compiler/user.yml +12 -7
  121. data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
  122. data/test/integration/zafu_compiler/zazen.yml +5 -5
  123. data/test/integration/zafu_compiler_test.rb +18 -0
  124. data/test/selenium/Filter/filter3.rsel +20 -0
  125. data/test/selenium/Filter/filter4.rsel +20 -0
  126. data/test/sites/zena/versions.yml +2 -0
  127. data/test/unit/exif_data_test.rb +6 -1
  128. data/test/unit/group_test.rb +18 -3
  129. data/test/unit/node_test.rb +0 -7
  130. data/test/unit/project_test.rb +4 -0
  131. data/test/unit/relation_proxy_test.rb +2 -2
  132. data/test/unit/remote_test.rb +0 -9
  133. data/test/unit/role_test.rb +1 -1
  134. data/test/unit/string_hash_test.rb +1 -1
  135. data/test/unit/text_document_test.rb +13 -13
  136. data/test/unit/zena/use/html_tags_test.rb +6 -6
  137. data/test/unit/zena/use/rendering_test.rb +20 -10
  138. data/test/unit/zena/use/urls_test.rb +21 -18
  139. data/test/unit/zena/use/zafu_template_test.rb +0 -5
  140. data/test/unit/zena/use/zazen_test.rb +25 -25
  141. data/zena.gemspec +63 -57
  142. metadata +136 -130
  143. data/test/functional/nodes_controller_commit_test.rb +0 -67
data/History.txt CHANGED
@@ -1,3 +1,28 @@
1
+ == 1.2.3 2013-03-11
2
+
3
+ * Major changes
4
+ * Better support for Passenger (deploy receipt, asset host)
5
+ * Support for 'sortable' <== TODO: Document
6
+ * html_escape all properties by default
7
+ * Better support for Passenger (default deployment method now)
8
+ * Simplified caching (using cachestamp in filename)
9
+ * Added preview='dom_id' to [form]. (Use preview_node to show preview content.) <== TODO: Document
10
+ * Added "in_group" zafu method on visitor. <== TODO: Document
11
+ * Added [upload_field] method to zafu to allow custom upload forms. <== TODO: Document
12
+ * Added support for custom images on nodes with the "img_tag_{mode}" string attribute or the 'img_tag' hash attribute. <== TODO: Document
13
+ * Added support for tag clouds through sqliss (<r:void do='tag_cloud from nodes in site' do='each' join=', '><r:name/> (<r:link_count/>)</r:void>). <== TODO: Document
14
+
15
+ * Minor changes
16
+ * Support for 'lang_list' when creating vhost file <== TODO: Document
17
+ * Support for Range in zafu. <== TODO: Document
18
+ * Added options to query_parse to ignore unwanted parameters <== TODO: Document
19
+ * Added 'hparams' option to only return Hash parameters from params. <== TODO: Document
20
+ * Fixed query_parse to convert dates to UTC.
21
+ * Fixed form preview inside block.
22
+ * Added unique id to img_tag_{mode} code generated 'UUID'. <== TODO: Document
23
+ * Added PATH_mode.format and [JS] marker to img_tag_{mode}.
24
+ * Fixed form preview with long text (use POST).
25
+
1
26
  == 1.2.2 2012-08-30
2
27
 
3
28
  * Major changes
@@ -52,30 +52,8 @@ class DocumentsController < ApplicationController
52
52
  # Create a document with upload progression (upload in mongrel)
53
53
  def upload
54
54
  create_document
55
-
56
- responds_to_parent do # execute the redirect in the iframe's parent window
57
- render :update do |page|
58
- if @node.new_record?
59
- page.replace_html 'form_errors', error_messages_for(:node, :object => @node)
60
- page.call 'UploadProgress.setAsError'
61
- else
62
- page.call 'UploadProgress.setAsFinished'
63
- page.delay(1) do # allow the progress bar fade to complete
64
- if params[:js]
65
- page << params[:js]
66
- end
67
- if params[:reload]
68
- page << "Zena.t().Zena.reload(#{params[:reload].inspect})"
69
- end
70
- if params[:redir]
71
- page << "Zena.reload_and_close(#{params[:redir].inspect})"
72
- else
73
- page.redirect_to document_url(@node[:zip], :reload => params[:reload], :js => params[:js])
74
- end
75
- end
76
- end
77
- end
78
- end
55
+
56
+ render_upload
79
57
  end
80
58
 
81
59
  def upload_progress
@@ -109,7 +87,7 @@ class DocumentsController < ApplicationController
109
87
  raise ActiveRecord::RecordNotFound
110
88
  end
111
89
  end
112
-
90
+
113
91
  def create_document
114
92
  attrs = params['node']
115
93
  file, error = get_attachment
@@ -20,9 +20,13 @@ Examples:
20
20
  class NodesController < ApplicationController
21
21
  before_filter :check_is_admin, :only => [:export]
22
22
  before_filter :check_api_group
23
+ if Bricks.raw_config['passenger']
24
+ before_filter :escape_path, :only => [:index, :show]
25
+ end
23
26
  before_filter :find_node, :except => [:index, :create, :not_found, :catch_all, :search]
24
27
  before_filter :check_can_drive, :only => [:edit]
25
28
  before_filter :check_path, :only => [:index, :show]
29
+
26
30
  layout :popup_layout, :only => [:edit, :import]
27
31
 
28
32
  def index
@@ -49,7 +53,7 @@ class NodesController < ApplicationController
49
53
  query_params_list = []
50
54
  query_params.each do |k,v|
51
55
  next if v.kind_of?(Hash) # FIXME: we should support nested hashes. Can't we use something in rails here ?
52
- query_params_list << "#{k}=#{CGI.escape(v)}"
56
+ query_params_list << "#{k}=#{CGI.escape(v.to_s)}"
53
57
  end
54
58
  redirect_to "/" + ([prefix]+params[:path]).flatten.join('/') + (query_params_list == [] ? '' : "?#{query_params_list.join('&')}")
55
59
  end
@@ -170,7 +174,7 @@ class NodesController < ApplicationController
170
174
  content_path = @node.asset_path(filename)
171
175
  content_type = (Zena::EXT_TO_TYPE[params[:format]] || ['application/octet-stream'])[0]
172
176
  send_file(content_path, :filename=>filename, :type => content_type, :disposition=>'inline', :x_sendfile => ENABLE_XSENDFILE)
173
- cache_page(:content_path => content_path, :authenticated => @node.public?) # content_path is used to cache by creating a symlink
177
+ cache_page(:content_path => content_path, :authenticated => @node.v_public?) # content_path is used to cache by creating a symlink
174
178
  elsif @node.kind_of?(Document) && params[:format] == @node.ext
175
179
  # Get document data (inline if possible)
176
180
  content_path = nil
@@ -192,7 +196,8 @@ class NodesController < ApplicationController
192
196
  send_file(content_path, :filename => @node.filename, :type => @node.content_type, :disposition => 'inline', :stream => false, :x_sendfile => ENABLE_XSENDFILE)
193
197
  end
194
198
 
195
- cache_page(:content_path => content_path, :authenticated => @node.public?) # content_path is used to cache by creating a symlink
199
+ # content_path is used to cache by creating a symlink
200
+ cache_page(:content_path => content_path, :authenticated => @node.v_public?)
196
201
  else
197
202
  render_and_cache
198
203
  # FIXME: redirect to document format should occur in render_and_cache
@@ -213,7 +218,7 @@ class NodesController < ApplicationController
213
218
  file, file_error = get_attachment
214
219
  if file
215
220
  attrs['file'] = file
216
- attrs['klass'] = 'Document'
221
+ attrs['klass'] ||= 'Document'
217
222
  end
218
223
 
219
224
  attrs = secure(Node) { Node.transform_attributes(attrs) }
@@ -229,6 +234,11 @@ class NodesController < ApplicationController
229
234
  end
230
235
  @node.errors.add('file', file_error) if file_error
231
236
 
237
+ if params[Zena::Use::Upload::UPLOAD_KEY]
238
+ # Respond in parent from iframe.
239
+ return render_upload
240
+ end
241
+
232
242
  respond_to do |format|
233
243
  if @node.errors.empty?
234
244
  flash.now[:notice] = 'Node was successfully created.'
@@ -574,6 +584,7 @@ class NodesController < ApplicationController
574
584
  # archive-1 ---> fullpath
575
585
  # archive ---> fullpath
576
586
  def find_node
587
+
577
588
  if path = params[:path]
578
589
  # We do not use params[:path] because Rails does url unescape
579
590
  # and we want to do this ourselves.
@@ -592,13 +603,14 @@ class NodesController < ApplicationController
592
603
  if path.last =~ Zena::Use::Urls::ALLOWED_REGEXP
593
604
  zip = $3
594
605
  name = $4
595
- params[:mode] = $5 == '' ? nil : $5[1..-1]
596
- asset_and_format = $6 == '' ? '' : $6[1..-1]
597
- if asset_and_format =~ /(\w+)\.(\w+)/
598
- params[:asset ] = $1
606
+ params[:mode] = $5 == '' ? nil : $5[1..-1]
607
+ params[:asset] = $6 == '' ? nil : $6[1..-1]
608
+ stamp_and_format = $7 == '' ? '' : $7[1..-1]
609
+ if stamp_and_format =~ /(\w+)\.(\w+)/
610
+ @cachestamp = $1
599
611
  set_format($2)
600
612
  else
601
- set_format(asset_and_format)
613
+ set_format(stamp_and_format)
602
614
  end
603
615
 
604
616
  # We use the visitor to find the node in order to ease implementation
@@ -618,6 +630,15 @@ class NodesController < ApplicationController
618
630
  end
619
631
  end
620
632
 
633
+ # Passenger unescapes url before passing it to Rails. We escape it back.
634
+ # FIXME: Performance: reverse this code (consider unescaped urls the norm and unescape if not using Passenger).
635
+ def escape_path
636
+ if params[:path]
637
+ params[:path].map! {|p| URI.escape(p) }
638
+ end
639
+ true
640
+ end
641
+
621
642
  def set_format(format)
622
643
  request.instance_eval do
623
644
  parameters[:format] = format
@@ -647,37 +668,26 @@ class NodesController < ApplicationController
647
668
  end
648
669
  when 'show'
649
670
 
650
- if params[:format] != 'html' && params[:cachestamp].nil?
651
- # maybe not seen, try to find it
652
- params.each do |k,v|
653
- if k =~ /\A\d+\Z/ && v.nil?
654
- params[:cachestamp] = k
655
- params.delete(k)
656
- break
657
- end
658
- end
659
- end
660
-
661
671
  if params[:prefix] != prefix && !avoid_prefix_redirect
662
672
  # lang changed
663
673
  set_visitor_lang(params[:prefix])
664
674
  redirect_to zen_path(@node, path_params) and return false
665
675
  end
666
676
 
667
- current_url = append_query_params("/#{params[:prefix]}/#{params[:path].join('/')}", :cachestamp => params[:cachestamp])
677
+ current_url = "/#{params[:prefix]}/#{params[:path].join('/')}"
668
678
  base_url = zen_path(@node,
669
679
  :prefix => params[:prefix],
670
680
  :format => params[:format],
671
681
  :mode => params[:mode],
672
682
  :asset => params[:asset])
673
-
683
+
674
684
  if current_url != base_url
675
685
  # Badly formed url, redirect
676
686
  redirect_to zen_path(@node, path_params) and return false
677
687
  end
678
-
688
+
679
689
  if should_cachestamp?(@node, params[:format], params[:asset]) &&
680
- params[:cachestamp] != make_cachestamp(@node, params[:mode])
690
+ @cachestamp != make_cachestamp(@node, params[:mode])
681
691
  # Invalid cachestamp, redirect
682
692
  redirect_to zen_path(@node, path_params) and return false
683
693
  end
@@ -3,7 +3,8 @@
3
3
  Create, destroy sessions by letting users login and logout. When the user does not login, he/she is considered to be the anonymous user.
4
4
  =end
5
5
  class UserSessionsController < ApplicationController
6
- skip_before_filter :set_after_login, :force_authentication?
6
+ skip_before_filter :set_after_login, :force_authentication?, :redirect_to_https
7
+ before_filter :session_redirect_to_https
7
8
 
8
9
  # /login
9
10
  def new
@@ -33,9 +34,9 @@ class UserSessionsController < ApplicationController
33
34
  @user_session.destroy
34
35
  reset_session
35
36
  #flash.now[:notice] = _("Successfully logged out.")
36
- redirect_to "http://#{current_site.host}#{port}#{params[:redirect] || home_path(:prefix => prefix)}"
37
+ redirect_to "http://#{current_site.host}#{params[:redirect] || home_path(:prefix => prefix)}"
37
38
  else
38
- redirect_to "http://#{current_site.host}#{port}#{home_path(:prefix => prefix)}"
39
+ redirect_to "http://#{current_site.host}#{home_path(:prefix => prefix)}"
39
40
  end
40
41
  end
41
42
 
@@ -55,7 +56,7 @@ class UserSessionsController < ApplicationController
55
56
  end
56
57
 
57
58
  # Overwrite redirect on https rules for this controller
58
- def redirect_to_https
59
+ def session_redirect_to_https
59
60
  if params[:action] == 'destroy'
60
61
  # ignore
61
62
  else
@@ -89,29 +89,56 @@ class VersionsController < ApplicationController
89
89
  end
90
90
 
91
91
  # TODO: test/improve or remove (experiments)
92
+ # https://github.com/samg/diffy
92
93
  def diff
93
- # source
94
- source = @node.version.prop
94
+ if false
95
+ # FULL PAGE DIFF
96
+
97
+ # Render with source
98
+ source_html = render_and_cache :as_string => true
99
+
100
+ # target
101
+ if params[:to].to_i > 0
102
+ version = secure!(Version) { Version.find(:first, :conditions => ['node_id = ? AND number = ?', @node.id, params[:to]])}
103
+ # Reload prop
104
+ @node.prop = version.prop
105
+ else
106
+ # default
107
+ @node.instance_variable_set(:@version, nil)
108
+ end
95
109
 
96
- # target
97
- if params[:to].to_i > 0
98
- version = secure!(Version) { Version.find(:first, :conditions => ['node_id = ? AND number = ?', @node.id, params[:to]])}
99
- @node.version = version
110
+ # Render with target
111
+ target_html = render_and_cache :as_string => true
112
+
113
+ result = Differ.diff_by_word(target_html, source_html).format_as(:html)
114
+
115
+ render :inline => result # Broken because Differ does not understand html...
100
116
  else
101
- # default
102
- @node.instance_variable_set(:@version, nil)
103
- end
104
- target = @node.prop
117
+ # PROP DIFF
105
118
 
106
- keys = (target.keys + source.keys).uniq
119
+ # source
120
+ source = @node.version.prop
107
121
 
108
- keys.each do |k|
109
- target[k] = Differ.diff_by_word(
110
- target[k] || '',
111
- source[k] || '').format_as(:html).gsub(/(\s+)<\/del>/, '</del>\1')
112
- end
122
+ # target
123
+ if params[:to].to_i > 0
124
+ version = secure!(Version) { Version.find(:first, :conditions => ['node_id = ? AND number = ?', @node.id, params[:to]])}
125
+ @node.version = version
126
+ else
127
+ # default
128
+ @node.instance_variable_set(:@version, nil)
129
+ end
130
+ target = @node.prop
131
+
132
+ keys = (target.keys + source.keys).uniq
113
133
 
114
- show
134
+ keys.each do |k|
135
+ target[k] = Differ.diff_by_word(
136
+ target[k] || '',
137
+ source[k] || '').format_as(:html).gsub(/(\s+)<\/del>/, '</del>\1')
138
+ end
139
+
140
+ show
141
+ end
115
142
  end
116
143
 
117
144
  # preview when editing node
data/app/models/acl.rb CHANGED
@@ -15,7 +15,7 @@ class Acl < ActiveRecord::Base
15
15
  include RubyLess
16
16
 
17
17
  safe_method :params => Zena::Use::ZafuSafeDefinitions::ParamsDictionary
18
- safe_method :asset_host? => Boolean
18
+ safe_method :asset_host? => {:class => Boolean, :method => 'visitor.asset_host?'}
19
19
  safe_method :visitor => User
20
20
 
21
21
  def safe_method_type(signature, receiver = nil)
@@ -45,11 +45,6 @@ class Acl < ActiveRecord::Base
45
45
  @exec_skin ||= secure(Skin) { Skin.find(exec_skin_id) }
46
46
  end
47
47
 
48
- # Returns true if we are on the asset host.
49
- def asset_host?
50
- @asset_host
51
- end
52
-
53
48
  # Make visitor public so that we can use 'visitor' in queries.
54
49
  def visitor
55
50
  super
@@ -76,7 +71,7 @@ class Acl < ActiveRecord::Base
76
71
  def make_query(node, params = {}, request = nil)
77
72
  @node = node
78
73
  @params = params
79
- @asset_host = request ? request.port.to_i == Zena::ASSET_PORT : false
74
+
80
75
  query_str = safe_eval(self.query)
81
76
 
82
77
  # We add a stupid order clause to avoid the 'order by title' thing.
data/app/models/group.rb CHANGED
@@ -50,7 +50,11 @@ class Group < ActiveRecord::Base
50
50
  end
51
51
 
52
52
  def user_ids=(list)
53
- @defined_user_ids = list
53
+ if public_group? || site_group?
54
+ # ignore
55
+ else
56
+ @defined_user_ids = list
57
+ end
54
58
  end
55
59
 
56
60
  alias o_users users
@@ -92,7 +96,7 @@ class Group < ActiveRecord::Base
92
96
  # Public and admin groups are special. They cannot be destroyed.
93
97
  def check_can_destroy
94
98
  # do not destroy admin or public groups
95
- raise Zena::AccessViolation.new("'admin', 'site' or 'public' groups cannot be destroyed") if visitor.site.protected_group_ids.include?( id )
99
+ raise Zena::AccessViolation.new("'admin', 'logged-in' or 'public' groups cannot be destroyed") if visitor.site.protected_group_ids.include?( id )
96
100
  return can_destroy?
97
101
  end
98
102
 
data/app/models/link.rb CHANGED
@@ -1,6 +1,11 @@
1
1
  class Link < ActiveRecord::Base
2
+ include Zena::Use::QueryLink::ModelMethods
3
+
2
4
  include RubyLess
3
5
  safe_attribute :status, :comment, :date
6
+ # Used in tag cloud
7
+ safe_method :name => String
8
+ safe_method :link_count => Number
4
9
 
5
10
  attr_reader :relation
6
11
  attr_accessor :start, :side
@@ -118,4 +123,13 @@ class Link < ActiveRecord::Base
118
123
  def role
119
124
  relation_proxy.other_role
120
125
  end
126
+
127
+ # Used by tags
128
+ def name
129
+ comment
130
+ end
131
+
132
+ def link_count
133
+ read_attribute('link_count') || 0
134
+ end
121
135
  end
data/app/models/node.rb CHANGED
@@ -1487,8 +1487,8 @@ class Node < ActiveRecord::Base
1487
1487
  export_keys[:dates].each do |k, v|
1488
1488
  hash[k] = visitor.tz.utc_to_local(v).strftime("%Y-%m-%d %H:%M:%S")
1489
1489
  end
1490
-
1491
- hash.merge!('class' => self.klass)
1490
+
1491
+ hash.merge!('class' => self.klass, 'position' => self.position)
1492
1492
  hash.to_yaml
1493
1493
  end
1494
1494
 
data/app/models/site.rb CHANGED
@@ -50,6 +50,9 @@ class Site < ActiveRecord::Base
50
50
  ['nodes' , 'site_id = ?'],
51
51
  ]
52
52
  ACTIONS = %w{clear_cache rebuild_index}
53
+ PUBLIC_PATH = Bricks.raw_config['public_path'] || '/public'
54
+ CACHE_PATH = Bricks.raw_config['cache_path'] || '/public'
55
+
53
56
  include RubyLess
54
57
  safe_method :host => String, :lang_list => [String], :default_lang => String
55
58
  safe_method :root => Proc.new {|h, r, s| {:method => 'root_node', :class => VirtualClass['Project'], :nil => true}}
@@ -136,8 +139,8 @@ class Site < ActiveRecord::Base
136
139
  editors.users << admin_user
137
140
 
138
141
  # create site group
139
- sgroup = site.send(:secure,Group) { Group.create( :name => 'site') }
140
- raise Exception.new("Could not create site group for site [#{host}] (site#{site[:id]})\n#{sgroup.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if sgroup.new_record?
142
+ sgroup = site.send(:secure,Group) { Group.create( :name => 'logged-in') }
143
+ raise Exception.new("Could not create logged-in group for site [#{host}] (site#{site[:id]})\n#{sgroup.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if sgroup.new_record?
141
144
 
142
145
  site.public_group_id = pub[:id]
143
146
  site.site_group_id = sgroup[:id]
@@ -231,7 +234,13 @@ class Site < ActiveRecord::Base
231
234
  # If you need to serve from another directory, we do not store the path into the sites table
232
235
  # for security reasons. The easiest way around this limitation is to symlink the 'public' directory.
233
236
  def public_path
234
- "/#{self[:host]}/public"
237
+ "/#{self[:host]}#{PUBLIC_PATH}"
238
+ end
239
+
240
+ # This is the place where cached files should be stored in case we do not want
241
+ # to store the cached file inside the public directory.
242
+ def cache_path
243
+ "/#{self[:host]}#{CACHE_PATH}"
235
244
  end
236
245
 
237
246
  # Return path for documents data: RAILS_ROOT/sites/_host_/data
@@ -374,7 +383,7 @@ class Site < ActiveRecord::Base
374
383
  end
375
384
 
376
385
  def clear_cache(clear_zafu = true)
377
- path = "#{SITES_ROOT}#{self.public_path}"
386
+ path = "#{SITES_ROOT}#{self.cache_path}"
378
387
  Site.logger.error("\n-----------------\nCLEAR CACHE FOR SITE #{host}\n-----------------\n")
379
388
 
380
389
  if File.exist?(path)
@@ -15,7 +15,7 @@ class TextDocument < Document
15
15
  class << self
16
16
  # Return true if a new text document can be created with the content_type. Used by the superclass Document to choose the corret subclass when creating a new object.
17
17
  def accept_content_type?(content_type)
18
- (content_type =~ /(^text|^image\/svg\+xml|x-javascript)/) &&
18
+ (content_type =~ /(^text|^image\/svg\+xml|javascript)/) &&
19
19
  (Zena::TYPE_TO_EXT[content_type.chomp] != ['rtf'])
20
20
  end
21
21
 
data/app/models/user.rb CHANGED
@@ -24,7 +24,7 @@ things they can/cannot do :
24
24
  TODO: when a user is 'destroyed', pass everything he owns to another user or just mark the user as 'deleted'...
25
25
  =end
26
26
  class User < ActiveRecord::Base
27
- attr_accessor :zafu_cache
27
+ attr_accessor :zafu_cache, :asset_host
28
28
 
29
29
  include Property
30
30
  RESCUE_SKIN_ID = -1
@@ -66,7 +66,7 @@ class User < ActiveRecord::Base
66
66
  safe_attribute :login, :time_zone, :created_at, :updated_at, :lang, :id
67
67
  safe_method :initials => String, :status => Number, :status_name => String,
68
68
  :is_anon? => Boolean, :is_admin? => Boolean, :user? => Boolean, :commentator? => Boolean,
69
- :moderated? => Boolean
69
+ :moderated? => Boolean, :asset_host? => Boolean, [:in_group?, String] => Boolean
70
70
 
71
71
  safe_context :node => node_user_proc,
72
72
  :to_publish => ['Version'], :redactions => ['Version'], :proposed => ['Version'],
@@ -215,6 +215,15 @@ class User < ActiveRecord::Base
215
215
  # tested in site_test
216
216
  user_site.anon_id == self[:id] && (!new_record? || self[:login].nil?) # (when creating a new site, anon_id == nil)
217
217
  end
218
+
219
+ # This is set on the user during login.
220
+ alias asset_host? asset_host
221
+
222
+ def in_group?(name)
223
+ @group_names ||= begin
224
+ groups.all(:order=>'name').map(&:name)
225
+ end.include?(name)
226
+ end
218
227
 
219
228
  # Return true if the user's status is high enough to start editing nodes.
220
229
  def user?
@@ -597,7 +597,7 @@ class VirtualClass < Role
597
597
  Zena::Db.execute "UPDATE roles SET kpath = '#{new_kpath}' WHERE kpath = '#{old_kpath}' AND site_id = #{current_site.id} AND (type = 'Role' or type IS NULL)"
598
598
  # ========================================= Update templates
599
599
  idx_templates = IdxTemplate.all(
600
- :conditions => ['tkpath = ? AND site_id = ?', old_kpath, site_id]
600
+ :conditions => ['tkpath = ? AND site_id = ? AND node_id IS NOT NULL', old_kpath, site_id]
601
601
  )
602
602
 
603
603
  if !idx_templates.empty?
@@ -33,12 +33,12 @@
33
33
  <tr><td class='label'><%= _('replace by') %></td><td><%= select('group', 'replace_by', @groups.map{|g| [g[:name], g[:id]]} , {:include_blank => true}) %></td></tr>
34
34
  <% end -%>
35
35
  <tr>
36
- <td class='label'><%= _('auto_publish') %></td>
37
- <td>
38
- <input type='hidden' name='group[auto_publish]' value=''/>
39
- <input type='checkbox' name='group[auto_publish]' value='1'<%= @group.auto_publish? ? " checked='checked'" : '' %>/> <%= _('auto_publish') %>
40
- </td>
41
- </tr>
36
+ <td class='label'><%= _('auto_publish') %></td>
37
+ <td>
38
+ <input type='hidden' name='group[auto_publish]' value=''/>
39
+ <input type='checkbox' name='group[auto_publish]' value='1'<%= @group.auto_publish? ? " checked='checked'" : '' %>/> <%= _('auto_publish') %>
40
+ </td>
41
+ </tr>
42
42
  <tr><td colspan='2'><input type='submit' class='btn_validate' value='<%= _('validate') %>'/></td></tr>
43
43
  </table>
44
44
  </form>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+
4
+ <html lang='en' xmlns='http://www.w3.org/1999/xhtml'>
5
+ <head>
6
+ <title>500 Error</title>
7
+ </head>
8
+
9
+ <body style='font-family:Helvetica, Arial, sans-serif; background:#eee;'>
10
+ <!-- The zena_error500 is used we running automated tests. Do not change -->
11
+ <div id='zena_error500' style='display:table; margin:50px auto; background:#aaa; height:200px; width:600px; border:1px solid black; border-radius:8px;'>
12
+ <%= @render_error %>
13
+ </div>
14
+ </body>
15
+ </html>
@@ -1,7 +1,7 @@
1
1
  <%= upload_form_tag(:action => 'upload') %>
2
2
  <%= hidden_field 'node', 'parent_id', :value=>@node.parent_zip %>
3
3
  <% [:redir, :js, :reload].each do |p|; next unless params[p] %>
4
- <input type='hidden' name='<%= p %>' value='<%= h params[p] %>'/>
4
+ <input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
5
5
  <% end %>
6
6
  <p class="btn_validate"><input type="submit" value='<%= _('validate') %>'/></p>
7
7
 
@@ -1,7 +1,7 @@
1
1
  <%= upload_form_tag( :controller => 'nodes', :action => 'import', :id => @node.parent_zip ) %>
2
2
  <p class="btn_validate"><input type="submit" value='<%= _('validate') %>'/></p>
3
3
  <% [:redir, :js, :reload].each do |p|; next unless params[p] %>
4
- <input type='hidden' name='<%= p %>' value='<%= h params[p] %>'/>
4
+ <input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
5
5
  <% end %>
6
6
 
7
7
  <%= upload_field %>
@@ -2,7 +2,7 @@
2
2
  <%= hidden_field 'node', 'parent_id', :value => @node.parent_zip %>
3
3
  <p class="btn_validate"><input type="submit" onclick="$('loader').style.visibility = 'visible';" value='<%= _('validate') %>'/></p>
4
4
  <% [:redir, :js, :reload].each do |p|; next unless params[p] %>
5
- <input type='hidden' name='<%= p %>' value='<%= h params[p] %>'/>
5
+ <input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
6
6
  <% end %>
7
7
 
8
8
  <input type='hidden' name='node[klass]' value='Template'/>
@@ -2,7 +2,7 @@
2
2
  <%= hidden_field 'node', 'parent_id', :value=>@node.parent_zip %>
3
3
  <p class="btn_validate"><input type="submit" onclick="$('loader').style.visibility = 'visible';" value='<%= _('validate') %>'/></p>
4
4
  <% [:redir, :js, :reload].each do |p|; next unless params[p] %>
5
- <input type='hidden' name='<%= p %>' value='<%= h params[p] %>'/>
5
+ <input type='hidden' name='<%= p %>' value='<%=h params[p] %>'/>
6
6
  <% end %>
7
7
 
8
8
  <label for='node_content_type'><%= _('content type') %></label>
@@ -7,7 +7,7 @@
7
7
  <label for='v_lang'><%= _("language") %></label>
8
8
  <% if @node.vclass.monolingual?
9
9
  if @node.new_record?
10
- selected = current_site.default_lang
10
+ selected = current_site.default_lang
11
11
  else
12
12
  selected = @node.v_lang == visitor.lang ? @node.v_lang : current_site.default_lang
13
13
  end
@@ -88,7 +88,7 @@
88
88
  <div id='form' do='form'>
89
89
  <r:if test='can_edit?' do='default' label='t'>
90
90
  <r:input type='submit'/>
91
- <input type='hidden' name='redir' value='#{path(this, :mode =&gt; "admin")}'/>
91
+ <input type='hidden' name='redir' value='#{path(this, :mode => "admin")}'/>
92
92
  <div do='vclass' do='roles'>
93
93
  <fieldset do='each'>
94
94
  <legend do='name'/>
@@ -16,7 +16,7 @@ class AclIntegrationTest < Zena::Integration::TestCase
16
16
  should 'find nodes' do
17
17
  get "http://erebus.host/oo/project#{nodes_zip(:over_zeus)}.html"
18
18
  assert_response :success
19
- assert_match %r{there is "A plan to overrule Zeus"}, response.body
19
+ assert_match %r{there is &quot;A plan to overrule Zeus&quot;}, response.body
20
20
  end
21
21
  end # with normal access
22
22
 
@@ -48,7 +48,7 @@ class AclIntegrationTest < Zena::Integration::TestCase
48
48
 
49
49
  should 'render with forced skin' do
50
50
  get "http://erebus.host/oo/project#{nodes_zip(:queen)}.html"
51
- assert_match %r{you can see \"My Queen\"}, response.body
51
+ assert_match %r{you can see &quot;My Queen&quot;}, response.body
52
52
  end
53
53
 
54
54
  should 'find items in view with exec_group' do
@@ -61,7 +61,8 @@ class AclTest < Zena::Unit::TestCase
61
61
  end
62
62
  assert subject.update_attributes(:query => "'nodes where 1 = \#{asset_host? ? 1 : 0} in site'")
63
63
  assert_nil subject.authorize?(base_node, {:id => nodes_zip(:over_zeus)}, mock_request)
64
- assert_equal 'A plan to overrule Zeus', subject.authorize?(base_node, {:id => nodes_zip(:over_zeus)}, mock_request(:get, {}, 80)).title
64
+ visitor.asset_host = true
65
+ assert_equal 'A plan to overrule Zeus', subject.authorize?(base_node, {:id => nodes_zip(:over_zeus)}, mock_request).title
65
66
  end
66
67
  end # saving an acl with asset_host in query
67
68
 
@@ -8,5 +8,6 @@ class AddFsSkinToIdxTemplates < ActiveRecord::Migration
8
8
  def self.down
9
9
  remove_index :idx_templates, :name => "index_idx_templates_on_fs_skin"
10
10
  remove_column :idx_templates, :fs_skin
11
+ remove_column :idx_templates, :path
11
12
  end
12
13
  end