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.
- data/History.txt +25 -0
- data/app/controllers/documents_controller.rb +3 -25
- data/app/controllers/nodes_controller.rb +34 -24
- data/app/controllers/user_sessions_controller.rb +5 -4
- data/app/controllers/versions_controller.rb +44 -17
- data/app/models/acl.rb +2 -7
- data/app/models/group.rb +6 -2
- data/app/models/link.rb +14 -0
- data/app/models/node.rb +2 -2
- data/app/models/site.rb +13 -4
- data/app/models/text_document.rb +1 -1
- data/app/models/user.rb +11 -2
- data/app/models/virtual_class.rb +1 -1
- data/app/views/groups/_form.rhtml +6 -6
- data/app/views/nodes/render_error.rhtml +15 -0
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_import.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_template.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_text_document.rhtml +1 -1
- data/app/views/templates/edit_tabs/_title.rhtml +1 -1
- data/app/views/zafu/default/Node-admin.zafu +1 -1
- data/bricks/acls/zena/test/integration/acl_integration_test.rb +2 -2
- data/bricks/acls/zena/test/unit/acl_test.rb +2 -1
- data/bricks/fs_skin/zena/migrate/20110702010330_add_fs_skin_to_idx_templates.rb +1 -0
- data/bricks/fs_skin/zena/skins/blog/img/style.css +4 -4
- data/bricks/grid/lib/bricks/grid.rb +9 -3
- data/bricks/passenger/zena/deploy.rb +2 -1
- data/bricks/pdf/lib/bricks/pdf.rb +1 -1
- data/bricks/tags/zena/test/zafu/tags.yml +5 -1
- data/bricks/zena/zena/migrate/20120904071601_change_link_status_to_float.rb +13 -0
- data/config/bricks.yml +10 -10
- data/config/deploy.rb +1 -5
- data/config/gems.yml +2 -2
- data/db/init/base/skins/default/Node.zafu +7 -3
- data/db/init/base/skins/default/notes.zafu +3 -1
- data/lib/zafu/all.rb +0 -9
- data/lib/zafu/compiler.rb +0 -4
- data/lib/zafu/controller_methods.rb +0 -2
- data/lib/zafu/handler.rb +0 -5
- data/lib/zafu/markup.rb +4 -6
- data/lib/zafu/ordered_hash.rb +3 -2
- data/lib/zafu/parsing_rules.rb +1 -3
- data/lib/zafu/process/ajax.rb +4 -2
- data/lib/zafu/process/context.rb +34 -4
- data/lib/zafu/process/forms.rb +2 -2
- data/lib/zafu/process/ruby_less_processing.rb +5 -10
- data/lib/zafu/template.rb +0 -2
- data/lib/zafu/test_helper.rb +0 -2
- data/lib/zafu/view_methods.rb +0 -1
- data/lib/zafu.rb +1 -1
- data/lib/zena/acts/secure_node.rb +5 -4
- data/lib/zena/console.rb +19 -17
- data/lib/zena/core_ext/string.rb +3 -2
- data/lib/zena/deploy/app_init.rhtml +6 -1
- data/lib/zena/deploy/httpd.rhtml +16 -13
- data/lib/zena/deploy/stats.vhost.rhtml +1 -1
- data/lib/zena/deploy/vhost.rhtml +31 -11
- data/lib/zena/deploy/vhost_ssl_redir.rhtml +12 -0
- data/lib/zena/deploy/vhost_www.rhtml +1 -1
- data/lib/zena/deploy.rb +55 -11
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zazen_rules.rb +18 -9
- data/lib/zena/routes.rb +1 -3
- data/lib/zena/site_worker.rb +8 -1
- data/lib/zena/use/ajax.rb +29 -3
- data/lib/zena/use/ancestry.rb +2 -1
- data/lib/zena/use/authlogic.rb +12 -18
- data/lib/zena/use/context.rb +1 -1
- data/lib/zena/use/dates.rb +28 -18
- data/lib/zena/use/display.rb +49 -7
- data/lib/zena/use/forms.rb +51 -18
- data/lib/zena/use/html_tags.rb +6 -6
- data/lib/zena/use/i18n.rb +13 -4
- data/lib/zena/use/image_builder.rb +2 -0
- data/lib/zena/use/query_builder.rb +39 -14
- data/lib/zena/use/query_link.rb +57 -0
- data/lib/zena/use/query_node.rb +68 -32
- data/lib/zena/use/relations.rb +25 -15
- data/lib/zena/use/rendering.rb +66 -15
- data/lib/zena/use/upload.rb +34 -5
- data/lib/zena/use/urls.rb +28 -25
- data/lib/zena/use/version_hash.rb +14 -2
- data/lib/zena/use/zafu_safe_definitions.rb +72 -3
- data/lib/zena/use/zazen.rb +16 -4
- data/lib/zena.rb +1 -0
- data/public/javascripts/grid.js +213 -64
- data/public/javascripts/raphael.js +10 -0
- data/public/javascripts/zena.js +146 -22
- data/public/stylesheets/reset.css +12 -12
- data/public/stylesheets/zena.css +1 -1
- data/test/custom_queries/complex.host.yml +19 -0
- data/test/fixtures/files/TestNode.zafu +40 -4
- data/test/functional/nodes_controller_test.rb +84 -39
- data/test/functional/versions_controller_test.rb +2 -2
- data/test/integration/navigation_test.rb +61 -35
- data/test/integration/query_node/basic.yml +7 -7
- data/test/integration/query_node/comments.yml +1 -1
- data/test/integration/query_node/complex.yml +3 -3
- data/test/integration/query_node/filters.yml +32 -8
- data/test/integration/query_node/idx_key_value.yml +10 -10
- data/test/integration/query_node/idx_scope.yml +7 -7
- data/test/integration/query_node/relations.yml +4 -4
- data/test/integration/zafu_compiler/ajax.yml +19 -11
- data/test/integration/zafu_compiler/apphelper.yml +1 -1
- data/test/integration/zafu_compiler/asset.yml +2 -2
- data/test/integration/zafu_compiler/comments.yml +1 -1
- data/test/integration/zafu_compiler/dates.yml +1 -1
- data/test/integration/zafu_compiler/display.yml +49 -21
- data/test/integration/zafu_compiler/eval.yml +4 -4
- data/test/integration/zafu_compiler/forms.yml +25 -11
- data/test/integration/zafu_compiler/i18n.yml +5 -0
- data/test/integration/zafu_compiler/meta.yml +3 -3
- data/test/integration/zafu_compiler/query.yml +27 -9
- data/test/integration/zafu_compiler/relations.yml +9 -9
- data/test/integration/zafu_compiler/roles.yml +6 -6
- data/test/integration/zafu_compiler/rubyless.yml +7 -2
- data/test/integration/zafu_compiler/safe_definitions.yml +33 -4
- data/test/integration/zafu_compiler/security.yml +46 -1
- data/test/integration/zafu_compiler/urls.yml +28 -13
- data/test/integration/zafu_compiler/user.yml +12 -7
- data/test/integration/zafu_compiler/zafu_attributes.yml +1 -1
- data/test/integration/zafu_compiler/zazen.yml +5 -5
- data/test/integration/zafu_compiler_test.rb +18 -0
- data/test/selenium/Filter/filter3.rsel +20 -0
- data/test/selenium/Filter/filter4.rsel +20 -0
- data/test/sites/zena/versions.yml +2 -0
- data/test/unit/exif_data_test.rb +6 -1
- data/test/unit/group_test.rb +18 -3
- data/test/unit/node_test.rb +0 -7
- data/test/unit/project_test.rb +4 -0
- data/test/unit/relation_proxy_test.rb +2 -2
- data/test/unit/remote_test.rb +0 -9
- data/test/unit/role_test.rb +1 -1
- data/test/unit/string_hash_test.rb +1 -1
- data/test/unit/text_document_test.rb +13 -13
- data/test/unit/zena/use/html_tags_test.rb +6 -6
- data/test/unit/zena/use/rendering_test.rb +20 -10
- data/test/unit/zena/use/urls_test.rb +21 -18
- data/test/unit/zena/use/zafu_template_test.rb +0 -5
- data/test/unit/zena/use/zazen_test.rb +25 -25
- data/zena.gemspec +63 -57
- metadata +136 -130
- 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
|
-
|
|
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.
|
|
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
|
-
|
|
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']
|
|
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]
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
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}#{
|
|
37
|
+
redirect_to "http://#{current_site.host}#{params[:redirect] || home_path(:prefix => prefix)}"
|
|
37
38
|
else
|
|
38
|
-
redirect_to "http://#{current_site.host}#{
|
|
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
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
#
|
|
102
|
-
@node.instance_variable_set(:@version, nil)
|
|
103
|
-
end
|
|
104
|
-
target = @node.prop
|
|
117
|
+
# PROP DIFF
|
|
105
118
|
|
|
106
|
-
|
|
119
|
+
# source
|
|
120
|
+
source = @node.version.prop
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
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?
|
|
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
|
-
|
|
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
|
-
|
|
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', '
|
|
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 => '
|
|
140
|
-
raise Exception.new("Could not create
|
|
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]}
|
|
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.
|
|
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)
|
data/app/models/text_document.rb
CHANGED
|
@@ -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|
|
|
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?
|
data/app/models/virtual_class.rb
CHANGED
|
@@ -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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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='<%=
|
|
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='<%=
|
|
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='<%=
|
|
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='<%=
|
|
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
|
-
|
|
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
|
|
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
|
|
19
|
+
assert_match %r{there is "A plan to overrule Zeus"}, 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
|
|
51
|
+
assert_match %r{you can see "My Queen"}, 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
|
-
|
|
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
|
|