infopark_fiona_connector 6.9.4 → 7.0.1.5.2.3.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/images/admin/minus.gif +0 -0
  3. data/app/assets/images/bg80.png +0 -0
  4. data/app/assets/images/edit.png +0 -0
  5. data/app/assets/images/icons/mm_generic.png +0 -0
  6. data/app/assets/images/icons/mm_menu.png +0 -0
  7. data/app/assets/javascripts/editmarker.js +240 -0
  8. data/app/assets/javascripts/infopark_rails_connector.js.erb +0 -0
  9. data/app/assets/stylesheets/editmarker.css +70 -0
  10. data/app/assets/stylesheets/infopark_rails_connector.css.erb +0 -0
  11. data/app/controllers/cms_controller.rb +7 -0
  12. data/app/controllers/rails_connector/default_cms_controller.rb +43 -0
  13. data/app/helpers/cms_helper.rb +7 -0
  14. data/app/helpers/cms_routing_helper.rb +7 -0
  15. data/app/helpers/rails_connector/cms_asset_helper.rb +2 -1
  16. data/app/helpers/rails_connector/default_cms_helper.rb +23 -0
  17. data/app/helpers/rails_connector/default_cms_routing_helper.rb +120 -0
  18. data/app/helpers/rails_connector/display_helper.rb +5 -5
  19. data/app/helpers/rails_connector/layout_helper.rb +29 -0
  20. data/app/helpers/rails_connector/marker_helper.rb +1 -3
  21. data/app/helpers/rails_connector/table_of_contents_helper.rb +22 -0
  22. data/app/models/named_link.rb +2 -0
  23. data/app/views/cms/_index.html.erb +7 -0
  24. data/app/views/cms/index.html.erb +1 -0
  25. data/app/views/errors/403_forbidden.html.erb +3 -0
  26. data/app/views/errors/410_gone.html.erb +7 -0
  27. data/config/cms_routes.rb +17 -0
  28. data/config/locales/de.rails_connector.errors.yml +11 -0
  29. data/config/locales/de.rails_connector.lib.yml +6 -0
  30. data/config/locales/de.rails_connector.views.yml +9 -0
  31. data/config/locales/en.rails_connector.errors.yml +10 -0
  32. data/config/locales/en.rails_connector.lib.yml +6 -0
  33. data/config/locales/en.rails_connector.views.yml +9 -0
  34. data/lib/gem_dependencies.rb +67 -0
  35. data/lib/infopark_fiona_connector.rb +26 -3
  36. data/lib/meta_eager_loader.rb +1 -0
  37. data/lib/obj.rb +3 -0
  38. data/lib/rails_connector/attr_dict.rb +31 -16
  39. data/lib/rails_connector/attribute.rb +96 -0
  40. data/lib/rails_connector/authenticable.rb +30 -0
  41. data/lib/rails_connector/basic_obj.rb +82 -95
  42. data/lib/rails_connector/blob.rb +14 -6
  43. data/lib/rails_connector/blob_mapping.rb +16 -0
  44. data/lib/rails_connector/blob_mysql.rb +1 -1
  45. data/lib/rails_connector/blob_oracle.rb +1 -1
  46. data/lib/rails_connector/channel.rb +19 -0
  47. data/lib/rails_connector/cms_accessible.rb +112 -0
  48. data/lib/rails_connector/cms_base_model.rb +9 -0
  49. data/lib/rails_connector/cms_dispatch_controller.rb +46 -0
  50. data/lib/rails_connector/cms_env.rb +68 -0
  51. data/lib/rails_connector/cms_test_request.rb +8 -0
  52. data/lib/rails_connector/configuration.rb +3 -1
  53. data/lib/rails_connector/content.rb +11 -0
  54. data/lib/rails_connector/core_extensions.rb +1 -0
  55. data/lib/rails_connector/core_extensions/time.rb +18 -0
  56. data/lib/rails_connector/date_attribute.rb +1 -1
  57. data/lib/rails_connector/engine.rb +68 -0
  58. data/lib/rails_connector/fiona_datetime.rb +14 -0
  59. data/lib/rails_connector/html_string.rb +19 -0
  60. data/lib/rails_connector/job.rb +13 -0
  61. data/lib/rails_connector/link_list.rb +32 -0
  62. data/lib/rails_connector/link_resolvable.rb +9 -0
  63. data/lib/rails_connector/markdown_string.rb +19 -0
  64. data/lib/rails_connector/meta.rb +148 -0
  65. data/lib/rails_connector/meta/eager_loader.rb +82 -0
  66. data/lib/rails_connector/named_link.rb +16 -1
  67. data/lib/rails_connector/news.rb +7 -3
  68. data/lib/rails_connector/obj_class.rb +140 -0
  69. data/lib/rails_connector/obj_class_attr.rb +5 -0
  70. data/lib/rails_connector/object_with_meta_data.rb +18 -0
  71. data/lib/rails_connector/rack_middlewares.rb +1 -2
  72. data/lib/rails_connector/string_tagging.rb +29 -0
  73. data/lib/version.rb +7 -0
  74. metadata +168 -42
  75. data/README +0 -5
@@ -0,0 +1,30 @@
1
+ module RailsConnector
2
+ module Authenticable
3
+ def self.included(mod)
4
+ %w(logged_in? admin? current_user).each do |method_name|
5
+ unless instance_method_defined?(mod, method_name)
6
+ mod.class_eval do
7
+ private
8
+ define_method(method_name, InstanceMethods.method(method_name).to_proc)
9
+ end
10
+ end
11
+
12
+ mod.send(:helper_method, method_name)
13
+ end
14
+ end
15
+
16
+ module InstanceMethods
17
+ def self.logged_in?; false; end
18
+ def self.admin?; false; end
19
+ def self.current_user; nil; end
20
+ end
21
+
22
+ private
23
+
24
+ def self.instance_method_defined?(mod, method_name)
25
+ (
26
+ mod.instance_methods + mod.protected_instance_methods + mod.private_instance_methods
27
+ ).map(&:to_s).include?(method_name)
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,6 @@
1
1
  require "json"
2
2
  require 'openssl'
3
+ require 'rails_connector/fiona_datetime'
3
4
 
4
5
  module RailsConnector
5
6
 
@@ -9,14 +10,23 @@ module RailsConnector
9
10
  # [parent] the Obj of which this one is a child - nil for the root object
10
11
  # @api public
11
12
  class BasicObj < CmsBaseModel
13
+ include RailsConnector::Meta
14
+
12
15
  CRYPT_KEY = "\xd7\x28\x9c\x63\xd6\x29\xdf\x20\xcd\x32\xcf\x30\xcf\x30\xcf\x30\xdf\x20\xb6\x49"\
13
16
  "\x91\x6e\x99\x66\x90\x6f\x8f\x70\x9e\x61\x8d\x72\x94\x6b\xdf\x20\xbe\x41\xb8\x47\xc4\x3b"\
14
17
  "\xdf\x20\xbd\x42\x9a\x65\x8d\x72\x93\x6c\x96\x69\x91\x6e".freeze
15
18
 
16
- include DateAttribute
19
+ PREDEFINED_ATTRIBUTES = %w(blob body title channels sort_key1 sort_type1 sort_key2 sort_type2
20
+ sort_key3 sort_type3 sort_order).freeze
21
+
17
22
 
18
23
  self.store_full_sti_class = false
19
24
 
25
+ def self.inherited(subclass)
26
+ super
27
+ subclass.delegate_attributes
28
+ end
29
+
20
30
  def self.configure_for_content(which)
21
31
  case which
22
32
  when :released then configure_column_information("objs", true)
@@ -36,10 +46,59 @@ module RailsConnector
36
46
  self.inheritance_column = "obj_class"
37
47
 
38
48
  @@use_cached_permissions = use_cached_permissions
49
+ descendants.each do |klass|
50
+ klass.reset_table_name
51
+ klass.initialize_attributes
52
+ end
53
+
54
+ RailsConnector::Meta::EagerLoader.instance.obj_classes.each do |class_name, obj_class|
55
+ next unless obj_class
56
+
57
+ if class_name =~ /^[A-Z]/
58
+ klass = class_name.safe_constantize
59
+ next unless klass
60
+ if klass < RailsConnector::BasicObj
61
+ klass.initialize_attributes
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def self.initialize_attributes
68
+ PREDEFINED_ATTRIBUTES.each do |attribute|
69
+ self.send(:define_attribute, attribute, ActiveRecord::Type::String.new)
70
+ end
71
+
72
+ return if obj_class_definition.blank?
73
+
74
+ obj_class_definition.custom_attributes.each_key do |attribute|
75
+ self.send(:define_attribute, attribute, ActiveRecord::Type::String.new)
76
+ end
77
+ end
78
+
79
+ def self.delegate_attributes
80
+ PREDEFINED_ATTRIBUTES.each do |attribute|
81
+ delegate attribute, to: :attr_dict
82
+ end
83
+
84
+ return if obj_class_definition.blank?
85
+
86
+ obj_class_definition.custom_attributes.each_key do |attribute|
87
+ delegate attribute, to: :attr_dict
88
+ end
39
89
  end
40
90
 
41
- # use released contents as a default
42
- configure_for_content(:released)
91
+ attribute :last_changed, :fiona_datetime
92
+ attribute :valid_from, :fiona_datetime
93
+ attribute :valid_until, :fiona_datetime
94
+ attribute :suppress_export, :boolean
95
+ attribute :is_edited, :boolean
96
+ attribute :is_released, :boolean
97
+
98
+ delegate :sort_keys, to: :attr_dict
99
+ delegate :body_data_path, to: :attr_dict
100
+ delegate :empty?, to: :attr_dict
101
+ delegate :text_links, to: :attr_dict
43
102
 
44
103
  # Patch to avoid a type_condition being added by ActiveRecord::Base.add_conditions! for Obj.find(params):
45
104
  def self.descends_from_active_record?
@@ -65,6 +124,11 @@ module RailsConnector
65
124
  # We don't cache types at all here.
66
125
  end
67
126
 
127
+ def self.reset_reflections
128
+ has_many :children, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
129
+ belongs_to :parent, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
130
+ end
131
+
68
132
  # @api public
69
133
  def permissions
70
134
  @@use_cached_permissions ? attr_dict.permissions : arel_permissions
@@ -101,12 +165,6 @@ module RailsConnector
101
165
  @@homepage_id = nil
102
166
  end
103
167
 
104
- # returns the obj's permalink.
105
- # @api public
106
- def permalink
107
- self[:permalink]
108
- end
109
-
110
168
  # This method determines the controller that should be invoked when the Obj is requested.
111
169
  # By default a controller matching the Obj's obj_class will be used.
112
170
  # If the controller does not exist, the CmsController will be used as a fallback.
@@ -208,13 +266,13 @@ module RailsConnector
208
266
  # and edited? will always return false in this case.
209
267
  # @api public
210
268
  def edited?
211
- (is_edited == 1)
269
+ is_edited
212
270
  end
213
271
 
214
272
  # Returns true if this object has released content
215
273
  # @api public
216
274
  def released?
217
- (is_released == 1)
275
+ is_released
218
276
  end
219
277
 
220
278
  # Returns true if the Obj is suppressed.
@@ -223,7 +281,7 @@ module RailsConnector
223
281
  # as a standalone web page.
224
282
  # @api public
225
283
  def suppressed?
226
- suppress_export == 1
284
+ suppress_export
227
285
  end
228
286
 
229
287
  # Returns true if the export of the object is not suppressed and the content is active?
@@ -253,16 +311,14 @@ module RailsConnector
253
311
  def root?
254
312
  parent_obj_id.nil?
255
313
  end
256
-
257
- has_many :children, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
258
- belongs_to :parent, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
314
+ #
259
315
 
260
316
  # Returns a list of exportable? children excluding the binary? ones unless :all is specfied.
261
317
  # This is mainly used for navigations.
262
318
  # @api public
263
319
  def toclist(*args)
264
320
  return [] unless publication?
265
- toclist = children.find(:all).select{ |toc| toc.exportable? }
321
+ toclist = children.to_a.select{ |toc| toc.exportable? }
266
322
  toclist = toclist.reject { |toc| toc.binary? } unless args.include?(:all)
267
323
  toclist
268
324
  end
@@ -300,18 +356,6 @@ module RailsConnector
300
356
  return self.sort_order == "descending" ? sorted_list.reverse : sorted_list
301
357
  end
302
358
 
303
- def sort_key1
304
- self[:sort_key1]
305
- end
306
-
307
- def sort_key2
308
- self[:sort_key2]
309
- end
310
-
311
- def sort_key3
312
- self[:sort_key3]
313
- end
314
-
315
359
  # Returns an Array of all the ancestor objects, starting at the root and ending at this object's parent.
316
360
  # @api public
317
361
  def ancestors
@@ -336,26 +380,17 @@ module RailsConnector
336
380
  # Passing an invalid key will not raise an error, but return nil.
337
381
  # @api public
338
382
  def [](key)
339
- # convenience access to name
340
- return name if key.to_sym == :name
383
+ if has_attribute?(key)
384
+ begin
385
+ if attr_dict.respond_to?(key)
386
+ return attr_dict.send(key)
387
+ end
341
388
 
342
- # regular activerecord attributes
343
- if @attributes.include?(key.to_s)
344
- if key == :valid_from or key == :valid_until or key == :last_changed
345
- return as_date(super(key))
346
- else
347
- return super(key)
389
+ read_attribute(key)
390
+ rescue NoMethodError
391
+ nil
348
392
  end
349
393
  end
350
-
351
- # Unknown Obj attributes are delegated to the corresponding instance of AttrDict.
352
- begin
353
- return (attr_dict.send key)
354
- rescue NoMethodError
355
- end
356
-
357
- # fallback
358
- return nil
359
394
  end
360
395
 
361
396
  # Reloads the attributes of this object from the database, invalidates custom attributes
@@ -384,9 +419,7 @@ module RailsConnector
384
419
  # for binary Objs body_length equals the file size
385
420
  # for non-binary Objs body_length equals the number of characters in the body (main content)
386
421
  # @api public
387
- def body_length
388
- attr_dict.body_length
389
- end
422
+ delegate :body_length, to: :attr_dict
390
423
 
391
424
  # Override this method to provide an external url
392
425
  # where the content (the body) of this Obj can be downloaded.
@@ -462,27 +495,6 @@ module RailsConnector
462
495
  rslt
463
496
  end
464
497
 
465
- # @api public
466
- def last_changed
467
- self[:last_changed]
468
- end
469
-
470
- # @api public
471
- def valid_from
472
- self[:valid_from]
473
- end
474
-
475
- # @api public
476
- def valid_until
477
- self[:valid_until]
478
- end
479
-
480
- # deprecated, use file_extension instead
481
- def content_type
482
- logger.warn "DEPRECATION WARNING: Obj#content_type is deprecated, use file_extension instead"
483
- file_extension
484
- end
485
-
486
498
  # Returns the MIME-type as determined from the file_extension - see MIME::Types
487
499
  # @api public
488
500
  def mime_type
@@ -503,30 +515,6 @@ module RailsConnector
503
515
 
504
516
  private
505
517
 
506
- def as_date(value)
507
- DateAttribute.parse(value) unless value.nil?
508
- end
509
-
510
- # Forwards any unknown method call to a corresponding instance
511
- # of AttrDict and thus provides access to object fields, i.e. content.
512
- #
513
- # In case of an invalid method call, an error is raised.
514
- #
515
- # Hint: Use [] instead to suppress error messages.
516
- def method_missing(method_id, *args)
517
- super
518
- rescue NoMethodError, NameError
519
- # prevent infinite recursion when calling "attr_*" below,
520
- # since rails checks the absence of an "_attr_*" method internally
521
- raise if %w(_attr_dict _attr_defs _attr_values).include?(method_id.to_s)
522
-
523
- if attr_dict.respond_to?(method_id)
524
- attr_dict.send method_id, *args
525
- else
526
- raise
527
- end
528
- end
529
-
530
518
  def fiona_fields
531
519
  @fiona_fields ||=
532
520
  ['name', 'obj_class', 'workflow', 'suppressexport', 'permalink'].inject({}) do |all,field|
@@ -566,7 +554,7 @@ module RailsConnector
566
554
 
567
555
  def self.try_type
568
556
  result = yield
569
- result if class_of_active_record_descendant(result)
557
+ result if result < CmsBaseModel
570
558
  rescue NameError, ActiveRecord::ActiveRecordError
571
559
  nil
572
560
  end
@@ -574,4 +562,3 @@ module RailsConnector
574
562
  end
575
563
 
576
564
  end
577
-
@@ -7,13 +7,13 @@ module RailsConnector
7
7
 
8
8
  class << self
9
9
  # Does not retrieve the column blob_data.
10
- def find_with_excluded_blob_data(*args)
11
- args << Hash.new unless Hash === args.last
12
- args.last[:select] = 'blob_name, blob_length'
13
- find_without_excluded_blob_data(*args)
10
+ def find_with_excluded_blob_data(primary_key)
11
+ select(:blob_name, :blob_length).find(primary_key)
14
12
  end
15
13
 
16
- alias_method_chain :find, :excluded_blob_data
14
+ alias_method :find_without_excluded_blob_data, :find
15
+ alias_method :find, :find_with_excluded_blob_data
16
+
17
17
  end
18
18
 
19
19
  def length
@@ -25,7 +25,7 @@ module RailsConnector
25
25
  end
26
26
 
27
27
  def path_of_stored_data(use_cached_file_if_older_than = Time.now)
28
- store_data if !File.exists?(path) || use_cached_file_if_older_than > File.mtime(path)
28
+ store_data if !File.exists?(path) || file_size_differs? || stale?(use_cached_file_if_older_than)
29
29
  path
30
30
  end
31
31
 
@@ -65,6 +65,14 @@ module RailsConnector
65
65
  File.open(tmp_file, "wb", &block)
66
66
  File.rename(tmp_file, path)
67
67
  end
68
+
69
+ def stale?(time)
70
+ time > File.mtime(path)
71
+ end
72
+
73
+ def file_size_differs?
74
+ blob_length != File.stat(path).size
75
+ end
68
76
  end
69
77
 
70
78
  end
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module RailsConnector
3
+ class BlobMapping < CmsBaseModel
4
+ def self.exists?
5
+ self.table_exists?
6
+ end
7
+
8
+ def self.get_fingerprint(name)
9
+ find_by_blob_name(name).fingerprint
10
+ end
11
+
12
+ def self.get_fingerprint_map(blob_names)
13
+ Hash[self.where(:blob_name => blob_names).select([:blob_name, :fingerprint]).map {|b| [b.blob_name, b.fingerprint] }]
14
+ end
15
+ end
16
+ end
@@ -13,7 +13,7 @@ module RailsConnector
13
13
  end
14
14
 
15
15
  def fetch_into_file(file)
16
- mysql2_client = connection.instance_variable_get '@connection'
16
+ mysql2_client = self.class.connection.raw_connection
17
17
  ActiveRecord::Base.logger.debug "Streaming blob from MySQL2 into #{file.path}"
18
18
 
19
19
  table_name = mysql2_client.escape(self.class.table_name)
@@ -31,7 +31,7 @@ module RailsConnector
31
31
  end
32
32
 
33
33
  def blob_handle
34
- con = connection.instance_variable_get '@connection'
34
+ con = self.class.connection.raw_connection
35
35
  con.exec(sql, id).fetch.first
36
36
  end
37
37
  end
@@ -0,0 +1,19 @@
1
+ module RailsConnector
2
+ class Channel < CmsBaseModel
3
+ self.primary_key = "channel_name"
4
+
5
+ def self.table_name
6
+ "#{table_name_prefix}" "channels"
7
+ end
8
+
9
+ has_many :news, :class_name => 'RailsConnector::News', :foreign_key => 'channel_name'
10
+ has_many :active_news,
11
+ lambda { where(['valid_from <= :now AND valid_until >= :now', {:now => Time.now.to_s(:number)}]) },
12
+ :class_name => 'RailsConnector::News', :foreign_key => 'channel_name'
13
+
14
+ has_many :objects, :through => :news
15
+
16
+ scope :with_prefix, -> (prefix) {where(["channel_name LIKE ?", "#{prefix}%"])}
17
+
18
+ end
19
+ end
@@ -0,0 +1,112 @@
1
+ module RailsConnector
2
+
3
+ # @api public
4
+ module CmsAccessible
5
+
6
+ protected
7
+
8
+ # Filter method to load a CMS object.
9
+ #
10
+ # To require the loading for all actions, use this in your controllers:
11
+ # before_action :load_object
12
+ def load_object
13
+ CmsEnv.new(request.env).load
14
+ loaded_obj = request.env[CmsEnv::OBJ_ENV_KEY]
15
+ raise loaded_obj if loaded_obj.is_a?(StandardError)
16
+ @obj = loaded_obj
17
+ end
18
+
19
+ # Filter method to check if the already loaded object is active. If it is
20
+ # not, a 410 Gone error message will be generate (by calling render_obj_error).
21
+ #
22
+ # To require the check for all actions, use this in your controllers:
23
+ # before_action :load_object
24
+ # before_action :ensure_object_is_active
25
+ def ensure_object_is_active
26
+ unless @obj.active?
27
+ @valid_from = @obj.valid_from
28
+ @valid_until = @obj.valid_until
29
+ @obj = nil
30
+ render_obj_error(410, "gone")
31
+ end
32
+ return true
33
+ end
34
+
35
+ # Filter method to check if access to the loaded object is permitted. If it is
36
+ # not, a 403 Forbidden error message will be generated (by calling render_obj_error)
37
+ #
38
+ # To require the check for all actions, use this in your controllers:
39
+ # before_action :load_object
40
+ # before_action :ensure_object_is_permitted
41
+ def ensure_object_is_permitted
42
+ unless is_permitted(@obj)
43
+ @obj = nil
44
+ render_obj_error(403, "forbidden")
45
+ end
46
+ return true
47
+ end
48
+
49
+ # This method is called when rendering an error caused by either {ensure_object_is_permitted}
50
+ # or {ensure_object_is_active} before filter. It renders an error template located in
51
+ # "errors/*.html.erb" with given HTTP status and content type "text/html" and with no layout.
52
+ # Overwrite this method to change the error page.
53
+ # @api public
54
+ def render_obj_error(status, name)
55
+ force_html_format
56
+ render(
57
+ :template => "errors/#{status}_#{name}",
58
+ :layout => false,
59
+ :status => status,
60
+ :content_type => Mime[:html]
61
+ )
62
+ end
63
+
64
+ # Enforce "html" as template format.
65
+ # @api public
66
+ def force_html_format
67
+ request.format = :html
68
+ end
69
+
70
+ # Inclusion hook to make is_permitted available as helper method.
71
+ def self.included(base)
72
+ base.__send__ :helper_method, :is_permitted
73
+ end
74
+
75
+ # Helper method to check live permissions
76
+ def is_permitted(obj)
77
+ obj.permitted_for_user?(current_user)
78
+ end
79
+
80
+ # Filter method which sets the header 'X-Robots-Tag: unavailable_after'
81
+ # to the valid_until date of the current object.
82
+ def set_google_expire_header
83
+ if @obj && (date = @obj.valid_until)
84
+ headers['X-Robots-Tag: unavailable_after'] = date.rfc822
85
+ end
86
+ end
87
+
88
+ # Deliver the obj's body as response by file or data.
89
+ # May respond with status 304 if a If-Modified-Since header is found.
90
+ # @api public
91
+ def deliver_file
92
+ if @obj.body_data_url
93
+ redirect_to enforce_protocol_from_request(@obj.body_data_url)
94
+ elsif stale?(:last_modified => @obj.last_changed.utc)
95
+ mime_type = @obj.mime_type
96
+ mime_type += '; charset=utf-8' if mime_type =~ /^text\//
97
+
98
+ if (filepath = @obj.body_data_path).present?
99
+ send_file(File.expand_path(filepath), {
100
+ :type => mime_type,
101
+ :filename => @obj.filename,
102
+ :disposition => 'inline',
103
+ })
104
+ else
105
+ # generics should send its body, empty files should be delivered as
106
+ # empty files - and not lead to an application error
107
+ send_data @obj.body || '', :type => mime_type, :filename => @obj.filename, :disposition => 'inline'
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end