zena 1.2.3 → 1.2.4
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 +29 -1
- data/Rakefile +0 -1
- data/app/controllers/documents_controller.rb +1 -1
- data/app/controllers/nodes_controller.rb +34 -8
- data/app/controllers/sites_controller.rb +8 -1
- data/app/controllers/user_sessions_controller.rb +13 -3
- data/app/models/acl.rb +16 -0
- data/app/models/document.rb +33 -14
- data/app/models/idx_nodes_integer.rb +5 -0
- data/app/models/image.rb +16 -4
- data/app/models/node.rb +16 -3
- data/app/models/relation_proxy.rb +3 -3
- data/app/models/site.rb +11 -1
- data/app/models/string_hash.rb +1 -1
- data/app/models/template.rb +1 -1
- data/app/models/user.rb +6 -1
- data/app/models/virtual_class.rb +36 -1
- data/app/views/acls/_form.rhtml +5 -1
- data/app/views/acls/_li.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -0
- data/app/views/templates/document_create_tabs/_template.rhtml +1 -1
- data/app/views/users/_form.rhtml +1 -0
- data/app/views/virtual_classes/_form.erb +8 -7
- data/bricks/acls/lib/bricks/acls.rb +43 -15
- data/bricks/acls/zena/migrate/20130313110443_add_create_kpath_to_acl.rb +13 -0
- data/bricks/acls/zena/migrate/20130429073432_fix_create_kpath_default.rb +8 -0
- data/bricks/acls/zena/test/integration/acl_integration_test.rb +53 -1
- data/bricks/acls/zena/test/sites/erebus/acls.yml +21 -0
- data/bricks/acls/zena/test/unit/acl_test.rb +35 -2
- data/bricks/math/lib/bricks/math.rb +1 -1
- data/bricks/sphinx/zena/tasks.rb +1 -1
- data/bricks/spreadsheet/lib/bricks/spreadsheet.rb +1 -1
- data/bricks/worker/zena/worker +25 -0
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +1 -1
- data/config/gems.yml +6 -5
- data/lib/bricks/requirements_validation.rb +1 -1
- data/lib/log_recorder/lib/log_recorder.rb +1 -1
- data/lib/tasks/zena.rake +10 -2
- data/lib/zena.rb +4 -3
- data/lib/zena/app.rb +1 -0
- data/lib/zena/deploy/httpd.rhtml +2 -2
- data/lib/zena/deploy/template.rb +15 -5
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zazen_rules.rb +9 -2
- data/lib/zena/remote/connection.rb +2 -2
- data/lib/zena/remote/interface.rb +8 -2
- data/lib/zena/remote/node.rb +1 -1
- data/lib/zena/routes.rb +2 -1
- data/lib/zena/use/action.rb +8 -2
- data/lib/zena/use/ajax.rb +31 -20
- data/lib/zena/use/calendar.rb +2 -0
- data/lib/zena/use/conditional.rb +15 -14
- data/lib/zena/use/dates.rb +5 -2
- data/lib/zena/use/display.rb +3 -2
- data/lib/zena/use/forms.rb +36 -9
- data/lib/zena/use/i18n.rb +8 -2
- data/lib/zena/use/image_builder.rb +7 -0
- data/lib/zena/use/query_node.rb +24 -8
- data/lib/zena/use/relations.rb +2 -6
- data/lib/zena/use/rendering.rb +10 -6
- data/lib/zena/use/upload.rb +6 -4
- data/lib/zena/use/urls.rb +13 -5
- data/lib/zena/use/zafu_safe_definitions.rb +1 -1
- data/public/javascripts/grid.js +11 -2
- data/public/javascripts/upload-progress.js +5 -3
- data/public/javascripts/zena.js +6 -2
- data/public/stylesheets/upload-progress.css +1 -0
- data/test/fixtures/files/TestNode.zafu +2 -2
- data/test/fixtures/files/translations_fr.yml +2 -1
- data/test/functional/acls_controller_test.rb +6 -0
- data/test/functional/nodes_controller_test.rb +1 -1
- data/test/functional/sites_controller_test.rb +19 -0
- data/test/integration/navigation_test.rb +7 -0
- data/test/integration/query_node/filters.yml +10 -0
- data/test/integration/zafu_compiler/action.yml +8 -4
- data/test/integration/zafu_compiler/ajax.yml +4 -4
- data/test/integration/zafu_compiler/calendar.yml +8 -15
- data/test/integration/zafu_compiler/context.yml +1 -1
- data/test/integration/zafu_compiler/dates.yml +5 -1
- data/test/integration/zafu_compiler/display.yml +1 -2
- data/test/integration/zafu_compiler/forms.yml +37 -10
- data/test/integration/zafu_compiler/query.yml +5 -5
- data/test/integration/zafu_compiler/relations.yml +8 -8
- data/test/integration/zafu_compiler/safe_definitions.yml +7 -2
- data/test/integration/zafu_compiler/urls.yml +24 -3
- data/test/integration/zafu_compiler/zazen.yml +9 -1
- data/test/selenium/Destroy/destroy1.rsel +2 -1
- data/test/selenium/Destroy/destroy2.rsel +17 -0
- data/test/unit/document_test.rb +17 -4
- data/test/unit/relation_proxy_test.rb +19 -8
- data/test/unit/string_hash_test.rb +1 -1
- data/test/unit/template_test.rb +3 -3
- data/test/unit/virtual_class_test.rb +77 -0
- data/test/unit/zena/use/urls_test.rb +9 -1
- data/vendor/plugins/selenium-on-rails/lib/selenium_on_rails_config.rb +1 -1
- data/zena.gemspec +60 -53
- metadata +145 -125
data/History.txt
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
|
+
== 1.2.4 2013-06-13
|
|
2
|
+
|
|
3
|
+
* Major changes
|
|
4
|
+
* Added class filtering to Acl in 'create' action. <== TODO: Document
|
|
5
|
+
* Uploading html files does not transform them into zafu (use .zafu ext for this)
|
|
6
|
+
* Added file upload support from zena remote API.
|
|
7
|
+
* Added 'content_type' regexp to force virtual class on Document creation. <== TODO: Document
|
|
8
|
+
* Extended "create group" in vclass to be "allow group" (edit).
|
|
9
|
+
* Added support for [versions_list] to display list of versions and status.
|
|
10
|
+
|
|
11
|
+
* Minor changes
|
|
12
|
+
* Support for raw html in zazen with '<notextile>' or '<html>' tag. Must be allowed with notextile='true' on [zazen] tag.
|
|
13
|
+
* Fixed preview of content with ACL (considering the POST on /zafu as a 'read').
|
|
14
|
+
* Added support for "class not like Image" or "class <> Image" to sqliss.
|
|
15
|
+
* Added url to clear cache with /sites/clear_cache (admin only). <== TODO: Document
|
|
16
|
+
* encode_params now supports arrays.
|
|
17
|
+
* Add 'id' to date input.
|
|
18
|
+
* Fixed 404 error.
|
|
19
|
+
* Toggle takes dynamic parameters for "js" and "arity".
|
|
20
|
+
* Fixed multiple toggles side-by-side.
|
|
21
|
+
* Fixed nested blocks and class scoping.
|
|
22
|
+
* Added support for "onUpdate" in [input] with date type.
|
|
23
|
+
* Hash 'keys' returns sorted elements in zafu.
|
|
24
|
+
* Improved computation of width and height in [img] when using 'forced' iformat.
|
|
25
|
+
* Image width and height properties auto-fix themselves (need to read file on each display if not fixed).
|
|
26
|
+
* Added support for 'mode' in encode_params.
|
|
27
|
+
* Fixed [link_name]_status, _comment and other relation proxy methods.
|
|
28
|
+
|
|
1
29
|
== 1.2.3 2013-03-11
|
|
2
30
|
|
|
3
31
|
* Major changes
|
|
4
32
|
* Better support for Passenger (deploy receipt, asset host)
|
|
5
|
-
* Support for 'sortable'
|
|
33
|
+
* Support for 'sortable'
|
|
6
34
|
* html_escape all properties by default
|
|
7
35
|
* Better support for Passenger (default deployment method now)
|
|
8
36
|
* Simplified caching (using cachestamp in filename)
|
data/Rakefile
CHANGED
|
@@ -13,7 +13,7 @@ class DocumentsController < ApplicationController
|
|
|
13
13
|
def new
|
|
14
14
|
# Use the Template class so that we can use the same object in forms which need the Template properties.
|
|
15
15
|
@node = @parent.new_child(:class => Template)
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
respond_to do |format|
|
|
18
18
|
format.html
|
|
19
19
|
end
|
|
@@ -23,7 +23,7 @@ class NodesController < ApplicationController
|
|
|
23
23
|
if Bricks.raw_config['passenger']
|
|
24
24
|
before_filter :escape_path, :only => [:index, :show]
|
|
25
25
|
end
|
|
26
|
-
before_filter :find_node, :except => [:index, :create, :not_found, :catch_all, :search]
|
|
26
|
+
before_filter :find_node, :except => [:index, :create, :update, :zafu, :not_found, :catch_all, :search]
|
|
27
27
|
before_filter :check_can_drive, :only => [:edit]
|
|
28
28
|
before_filter :check_path, :only => [:index, :show]
|
|
29
29
|
|
|
@@ -113,10 +113,23 @@ class NodesController < ApplicationController
|
|
|
113
113
|
end
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
-
# RJS method.
|
|
117
|
-
# FIXME: remove.
|
|
116
|
+
# RJS method. Enables using POST in JS for large text preview. Seen as 'read' in ACL.
|
|
118
117
|
def zafu
|
|
119
|
-
|
|
118
|
+
# We allow preview by using POST requests (long text in js) but they should appear as 'GET' in
|
|
119
|
+
# find_node.
|
|
120
|
+
request.method = 'GET' if request.method == 'POST'
|
|
121
|
+
|
|
122
|
+
@node = visitor.find_node(nil, params[:id], nil, request)
|
|
123
|
+
|
|
124
|
+
if params[:link_id]
|
|
125
|
+
@link = Link.find_through(@node, params[:link_id])
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# security risk with ACL (change an object before display with extended rights). Must check no ACL before
|
|
129
|
+
# preview. Only enable with proper security if this is really needed.
|
|
130
|
+
# if params['node']
|
|
131
|
+
# @node.attributes = secure(Node) {Node.transform_attributes(params['node'], @node, true)}
|
|
132
|
+
# end
|
|
120
133
|
respond_to do |format|
|
|
121
134
|
format.js { render :action => 'show' }
|
|
122
135
|
end
|
|
@@ -225,12 +238,20 @@ class NodesController < ApplicationController
|
|
|
225
238
|
|
|
226
239
|
begin
|
|
227
240
|
# Make sure we can load parent (also enables ACL to work for us here).
|
|
228
|
-
|
|
241
|
+
zip = attrs.delete('parent_zip')
|
|
242
|
+
parent = visitor.find_node(nil, zip, nil, request, true)
|
|
243
|
+
|
|
229
244
|
@node = parent.new_child(attrs, false)
|
|
230
|
-
@node.
|
|
245
|
+
if visitor.exec_acl && !(@node.kpath =~ %r{^#{visitor.exec_acl.create_kpath}})
|
|
246
|
+
# Document creation can change initial klass depending on mime type. Make sure it is still allowed.
|
|
247
|
+
@node.errors.add('klass', 'Not allowed')
|
|
248
|
+
else
|
|
249
|
+
@node.save
|
|
250
|
+
end
|
|
231
251
|
rescue ActiveRecord::RecordNotFound
|
|
232
252
|
# Let normal processing insert errors
|
|
233
|
-
@node =
|
|
253
|
+
@node = Node.new
|
|
254
|
+
@node.errors.add('base', 'Not allowed')
|
|
234
255
|
end
|
|
235
256
|
@node.errors.add('file', file_error) if file_error
|
|
236
257
|
|
|
@@ -388,6 +409,12 @@ class NodesController < ApplicationController
|
|
|
388
409
|
end
|
|
389
410
|
|
|
390
411
|
def update
|
|
412
|
+
@node = visitor.find_node(nil, params[:id], nil, request, true)
|
|
413
|
+
|
|
414
|
+
if params[:link_id]
|
|
415
|
+
@link = Link.find_through(@node, params[:link_id])
|
|
416
|
+
end
|
|
417
|
+
|
|
391
418
|
params['node'] ||= {}
|
|
392
419
|
file, file_error = get_attachment
|
|
393
420
|
params['node']['file'] = file if file
|
|
@@ -612,7 +639,6 @@ class NodesController < ApplicationController
|
|
|
612
639
|
else
|
|
613
640
|
set_format(stamp_and_format)
|
|
614
641
|
end
|
|
615
|
-
|
|
616
642
|
# We use the visitor to find the node in order to ease implementation
|
|
617
643
|
# of custom access rules (Acl).
|
|
618
644
|
@node = visitor.find_node(path, zip, name, request)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
# TODO: Cleanup sites_controller now that we only support visitors for a single site !!
|
|
1
2
|
class SitesController < ApplicationController
|
|
2
3
|
before_filter :remove_methods, :only => [:new, :create, :destroy]
|
|
3
|
-
before_filter :find_site, :except => [:index, :create, :new]
|
|
4
|
+
before_filter :find_site, :except => [:index, :create, :new, :clear_cache]
|
|
4
5
|
before_filter :visitor_node
|
|
5
6
|
before_filter :check_is_admin
|
|
6
7
|
layout :admin_layout
|
|
@@ -51,6 +52,12 @@ class SitesController < ApplicationController
|
|
|
51
52
|
end
|
|
52
53
|
end
|
|
53
54
|
end
|
|
55
|
+
|
|
56
|
+
def clear_cache
|
|
57
|
+
@site = secure!(Site) { Site.first }
|
|
58
|
+
@site.clear_cache
|
|
59
|
+
redirect_to '/'
|
|
60
|
+
end
|
|
54
61
|
|
|
55
62
|
def action
|
|
56
63
|
if Site::ACTIONS.include?(params[:do])
|
|
@@ -3,7 +3,7 @@
|
|
|
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 :
|
|
6
|
+
skip_before_filter :force_authentication?, :redirect_to_https
|
|
7
7
|
before_filter :session_redirect_to_https
|
|
8
8
|
|
|
9
9
|
# /login
|
|
@@ -28,15 +28,25 @@ class UserSessionsController < ApplicationController
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# Logout
|
|
31
32
|
def destroy
|
|
32
33
|
port = request.port == 80 ? '' : ":#{request.port}"
|
|
33
34
|
if @user_session = UserSession.find
|
|
34
35
|
@user_session.destroy
|
|
35
36
|
reset_session
|
|
37
|
+
if current_site.ssl_on_auth
|
|
38
|
+
# SSH only when authenticated
|
|
39
|
+
host = current_site.host
|
|
40
|
+
http = 'http'
|
|
41
|
+
else
|
|
42
|
+
# Keep current host and port settings
|
|
43
|
+
host = host_with_port
|
|
44
|
+
http = host =~ /:/ ? 'https' : 'http'
|
|
45
|
+
end
|
|
36
46
|
#flash.now[:notice] = _("Successfully logged out.")
|
|
37
|
-
redirect_to "http://#{
|
|
47
|
+
redirect_to "#{http}://#{host}#{params[:redirect] || home_path(:prefix => prefix)}"
|
|
38
48
|
else
|
|
39
|
-
redirect_to "http://#{
|
|
49
|
+
redirect_to "http://#{host}#{home_path(:prefix => prefix)}"
|
|
40
50
|
end
|
|
41
51
|
end
|
|
42
52
|
|
data/app/models/acl.rb
CHANGED
|
@@ -49,6 +49,18 @@ class Acl < ActiveRecord::Base
|
|
|
49
49
|
def visitor
|
|
50
50
|
super
|
|
51
51
|
end
|
|
52
|
+
|
|
53
|
+
def create_vclass_name
|
|
54
|
+
if create_kpath
|
|
55
|
+
if klass = VirtualClass.find_by_kpath(create_kpath)
|
|
56
|
+
klass.name
|
|
57
|
+
else
|
|
58
|
+
create_kpath
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
'Node'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
52
64
|
|
|
53
65
|
protected
|
|
54
66
|
def set_defaults
|
|
@@ -66,6 +78,10 @@ class Acl < ActiveRecord::Base
|
|
|
66
78
|
|
|
67
79
|
def validate_acl
|
|
68
80
|
make_query(visitor.prototype)
|
|
81
|
+
self[:create_kpath] = 'N' if self[:create_kpath].blank?
|
|
82
|
+
unless VirtualClass.find_by_kpath(create_kpath)
|
|
83
|
+
errors.add(:create_kpath, 'invalid (could not find class)')
|
|
84
|
+
end
|
|
69
85
|
end
|
|
70
86
|
|
|
71
87
|
def make_query(node, params = {}, request = nil)
|
data/app/models/document.rb
CHANGED
|
@@ -63,29 +63,34 @@ class Document < Node
|
|
|
63
63
|
def new(attrs = {}, vclass = nil)
|
|
64
64
|
attrs = attrs.stringify_keys
|
|
65
65
|
file = attrs['file'] || ((attrs['version_attributes'] || {})['content_attributes'] || {})['file']
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
elsif file && file.respond_to?(:content_type)
|
|
69
|
-
content_type = file.content_type
|
|
70
|
-
elsif ct = attrs['content_type']
|
|
66
|
+
|
|
67
|
+
if ct = attrs['content_type']
|
|
71
68
|
content_type = ct
|
|
69
|
+
elsif file && file.respond_to?(:content_type) && file.content_type != 'application/octet-stream'
|
|
70
|
+
content_type = file.content_type
|
|
72
71
|
elsif attrs['title'] =~ /^.*\.(\w+)$/ && types = Zena::EXT_TO_TYPE[$1.downcase]
|
|
73
72
|
content_type = types[0]
|
|
73
|
+
elsif file
|
|
74
|
+
content_type = 'application/octet-stream'
|
|
75
|
+
elsif attrs['target_klass'] || self <= Template
|
|
76
|
+
content_type = 'text/zafu'
|
|
77
|
+
else
|
|
78
|
+
content_type = 'text/plain'
|
|
74
79
|
end
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
klass = document_class_from_content_type(content_type)
|
|
82
|
+
real_class = klass.real_class
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
vclass = VirtualClass[real_class.to_s]
|
|
84
|
+
if vclass && vclass.kpath =~ /\A#{real_class.kpath}/ && vclass.content_type_re =~ content_type
|
|
85
|
+
klass = vclass
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
attrs['content_type'] = content_type
|
|
84
89
|
|
|
85
90
|
if real_class != self
|
|
86
|
-
secure(real_class) { real_class.o_new(attrs,
|
|
91
|
+
secure(real_class) { real_class.o_new(attrs, klass) }
|
|
87
92
|
else
|
|
88
|
-
super(attrs,
|
|
93
|
+
super(attrs, klass)
|
|
89
94
|
end
|
|
90
95
|
end
|
|
91
96
|
|
|
@@ -99,7 +104,7 @@ class Document < Node
|
|
|
99
104
|
|
|
100
105
|
# Return document class and content_type from content_type
|
|
101
106
|
def document_class_from_content_type(content_type)
|
|
102
|
-
if content_type
|
|
107
|
+
base = if content_type
|
|
103
108
|
if Image.accept_content_type?(content_type)
|
|
104
109
|
Image
|
|
105
110
|
elsif Template.accept_content_type?(content_type)
|
|
@@ -115,6 +120,18 @@ class Document < Node
|
|
|
115
120
|
else
|
|
116
121
|
self
|
|
117
122
|
end
|
|
123
|
+
|
|
124
|
+
# Try to find a virtual sub-class accepting the content type
|
|
125
|
+
vclass = nil
|
|
126
|
+
VirtualClass[base.to_s].sub_classes.each do |v|
|
|
127
|
+
next if v.real_class?
|
|
128
|
+
|
|
129
|
+
if content_type =~ v.content_type_re
|
|
130
|
+
vclass = v
|
|
131
|
+
break
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
vclass || VirtualClass[base.to_s]
|
|
118
135
|
end
|
|
119
136
|
|
|
120
137
|
# Return true if the content_type can change independantly from the file
|
|
@@ -156,7 +173,7 @@ class Document < Node
|
|
|
156
173
|
def filepath(format=nil)
|
|
157
174
|
version.attachment.filepath(format)
|
|
158
175
|
end
|
|
159
|
-
|
|
176
|
+
|
|
160
177
|
protected
|
|
161
178
|
def set_defaults
|
|
162
179
|
set_defaults_from_file
|
|
@@ -200,8 +217,10 @@ class Document < Node
|
|
|
200
217
|
end
|
|
201
218
|
|
|
202
219
|
klass = Document.document_class_from_content_type(content_type)
|
|
220
|
+
|
|
221
|
+
real_class = klass.real_class
|
|
203
222
|
|
|
204
|
-
if
|
|
223
|
+
if real_class != self.class
|
|
205
224
|
if @new_file
|
|
206
225
|
errors.add('file', 'incompatible with this class')
|
|
207
226
|
else
|
data/app/models/image.rb
CHANGED
|
@@ -82,8 +82,10 @@ class Image < Document
|
|
|
82
82
|
|
|
83
83
|
# Return the width in pixels for an image at the given format.
|
|
84
84
|
def width(format=nil)
|
|
85
|
-
if format.nil? || format
|
|
85
|
+
if format.nil? || format[:size] == :keep
|
|
86
86
|
prop['width']
|
|
87
|
+
elsif format[:size] == :force
|
|
88
|
+
format[:width]
|
|
87
89
|
else
|
|
88
90
|
if img = image_with_format(format)
|
|
89
91
|
img.width
|
|
@@ -95,8 +97,10 @@ class Image < Document
|
|
|
95
97
|
|
|
96
98
|
# Return the height in pixels for an image at the given format.
|
|
97
99
|
def height(format=nil)
|
|
98
|
-
if format.nil? || format
|
|
100
|
+
if format.nil? || format[:size] == :keep
|
|
99
101
|
prop['height']
|
|
102
|
+
elsif format[:size] == :force
|
|
103
|
+
format[:height]
|
|
100
104
|
else
|
|
101
105
|
if img = image_with_format(format)
|
|
102
106
|
img.height
|
|
@@ -147,7 +151,7 @@ class Image < Document
|
|
|
147
151
|
|
|
148
152
|
# Return a file with the data for the given format. It is the receiver's responsability to close the file.
|
|
149
153
|
def file(format=nil)
|
|
150
|
-
if format.nil? || format
|
|
154
|
+
if format.nil? || format[:size] == :keep
|
|
151
155
|
super()
|
|
152
156
|
else
|
|
153
157
|
if File.exist?(self.filepath(format)) || make_image(format)
|
|
@@ -199,6 +203,14 @@ class Image < Document
|
|
|
199
203
|
fname = "#{filename}.#{Zena::TYPE_TO_EXT[ctype][0]}"
|
|
200
204
|
uploaded_file(file, filename, ctype)
|
|
201
205
|
end
|
|
206
|
+
|
|
207
|
+
# This is called if the image's width and/or height is nil and image builder could
|
|
208
|
+
# compute the size.
|
|
209
|
+
def fix_sizes(w, h)
|
|
210
|
+
prop['width'] = w
|
|
211
|
+
prop['height'] = h
|
|
212
|
+
Zena::Db.set_attribute(version, 'properties', encode_properties(@properties))
|
|
213
|
+
end
|
|
202
214
|
|
|
203
215
|
private
|
|
204
216
|
|
|
@@ -234,7 +246,7 @@ class Image < Document
|
|
|
234
246
|
format ||= Iformat['full']
|
|
235
247
|
@formats ||= {}
|
|
236
248
|
@formats[format[:name]] ||= Zena::Use::ImageBuilder.new(:path => filepath,
|
|
237
|
-
:width => prop['width'], :height => prop['height']).transform!(format)
|
|
249
|
+
:width => prop['width'], :height => prop['height'], :node => self).transform!(format)
|
|
238
250
|
else
|
|
239
251
|
raise StandardError, "No image to work on"
|
|
240
252
|
end
|
data/app/models/node.rb
CHANGED
|
@@ -619,7 +619,9 @@ class Node < ActiveRecord::Base
|
|
|
619
619
|
def new_node(new_attributes, transform = true)
|
|
620
620
|
attributes = transform ? transform_attributes(new_attributes) : new_attributes
|
|
621
621
|
|
|
622
|
-
klass_name = attributes.delete('class') || attributes.delete('klass')
|
|
622
|
+
klass_name = attributes.delete('class') || attributes.delete('klass')
|
|
623
|
+
klass_name ||= attributes['file'] ? 'Document' : 'Page'
|
|
624
|
+
|
|
623
625
|
if klass_name.kind_of?(VirtualClass) || klass_name.kind_of?(Class)
|
|
624
626
|
klass = klass_name
|
|
625
627
|
else
|
|
@@ -633,6 +635,10 @@ class Node < ActiveRecord::Base
|
|
|
633
635
|
return node
|
|
634
636
|
end
|
|
635
637
|
end
|
|
638
|
+
|
|
639
|
+
if attributes['file'] && !(klass.kpath =~ %r{^ND})
|
|
640
|
+
klass = VirtualClass['Document']
|
|
641
|
+
end
|
|
636
642
|
|
|
637
643
|
if klass.kind_of?(VirtualClass)
|
|
638
644
|
node = secure(klass.real_class) { klass.new_instance(attributes) }
|
|
@@ -766,6 +772,7 @@ class Node < ActiveRecord::Base
|
|
|
766
772
|
if ['html','xhtml'].include?(attrs['ext']) && attrs['title'] == 'index'
|
|
767
773
|
attrs['ext'] = 'zafu'
|
|
768
774
|
attrs['title'] = 'Node'
|
|
775
|
+
attrs['content_type'] = 'text/zafu'
|
|
769
776
|
insert_zafu_headings = true
|
|
770
777
|
elsif attrs['ext'] == 'yml' && attrs['title'] == '_roles'
|
|
771
778
|
# import roles
|
|
@@ -908,7 +915,7 @@ class Node < ActiveRecord::Base
|
|
|
908
915
|
end
|
|
909
916
|
|
|
910
917
|
if !res['parent_id'] && p = attributes['parent_id']
|
|
911
|
-
res['parent_zip'] = p
|
|
918
|
+
res['parent_zip'] = p unless p.blank?
|
|
912
919
|
end
|
|
913
920
|
|
|
914
921
|
attributes.each do |key, value|
|
|
@@ -942,7 +949,7 @@ class Node < ActiveRecord::Base
|
|
|
942
949
|
elsif key =~ /^(\w+)_id$/
|
|
943
950
|
res["#{$1}_zip"] = value
|
|
944
951
|
elsif key =~ /^(\w+)_ids$/
|
|
945
|
-
res["#{$1}_zips"] = value.kind_of?(Array) ? value : value.split(',')
|
|
952
|
+
res["#{$1}_zips"] = value.kind_of?(Array) ? value : value.split(',').map(&:strip)
|
|
946
953
|
elsif key == 'v_status' || key == 'file'
|
|
947
954
|
res[key] = value unless value.blank?
|
|
948
955
|
elsif value.kind_of?(Hash)
|
|
@@ -1684,6 +1691,10 @@ class Node < ActiveRecord::Base
|
|
|
1684
1691
|
errors.add('klass', 'invalid') if !self.class.allowed_change_to_classes.include?(@new_klass)
|
|
1685
1692
|
end
|
|
1686
1693
|
end
|
|
1694
|
+
|
|
1695
|
+
if vclass.create_group_id
|
|
1696
|
+
errors.add('klass', 'unauthorized') if !visitor.group_ids.include?(vclass.create_group_id)
|
|
1697
|
+
end
|
|
1687
1698
|
end
|
|
1688
1699
|
|
|
1689
1700
|
# Called before destroy. An node must be empty to be destroyed
|
|
@@ -1811,8 +1822,10 @@ class Node < ActiveRecord::Base
|
|
|
1811
1822
|
def change_klass
|
|
1812
1823
|
if @new_klass
|
|
1813
1824
|
if !can_drive? || !self[:parent_id]
|
|
1825
|
+
# not allowed
|
|
1814
1826
|
return
|
|
1815
1827
|
elsif !self.class.allowed_change_to_classes.include?(@new_klass)
|
|
1828
|
+
# invalid class (unknown or visitor does have access)
|
|
1816
1829
|
return
|
|
1817
1830
|
end
|
|
1818
1831
|
end
|