zena 1.2.2 → 1.2.3

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 (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