caboose-cms 0.9.228 → 0.9.229

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/caboose/admin.js +1 -1
  3. data/app/assets/javascripts/caboose/admin_main.js +1 -13
  4. data/app/assets/javascripts/caboose/admin_media_index.js +161 -158
  5. data/app/assets/javascripts/caboose/application.js +8 -7
  6. data/app/assets/javascripts/caboose/block_content_controller_dragdrop.js +60 -4
  7. data/app/assets/javascripts/caboose/block_modal_controllers/block_dd_modal_controller.js +3 -2
  8. data/app/assets/javascripts/caboose/block_modal_controllers/media_modal_controller.js +17 -6
  9. data/app/assets/javascripts/caboose/model/all.js +5 -1
  10. data/app/assets/stylesheets/caboose/admin_block_edit_image.css.scss +2 -1
  11. data/app/assets/stylesheets/caboose/admin_edit_page_content_dragdrop.scss +71 -15
  12. data/app/assets/stylesheets/caboose/admin_main.css.scss +25 -29
  13. data/app/assets/stylesheets/caboose/admin_media_index.css.scss +26 -5
  14. data/app/assets/stylesheets/caboose/application.css +11 -5
  15. data/app/assets/stylesheets/caboose/login.scss +1 -0
  16. data/app/assets/stylesheets/caboose/model_binder.css +13 -4
  17. data/app/assets/stylesheets/caboose/page_bar_generator.css +2 -1
  18. data/app/controllers/caboose/admin_controller.rb +3 -4
  19. data/app/controllers/caboose/application_controller.rb +16 -19
  20. data/app/controllers/caboose/block_types_controller.rb +8 -6
  21. data/app/controllers/caboose/cart_controller.rb +2 -2
  22. data/app/controllers/caboose/change_logs_controller.rb +13 -0
  23. data/app/controllers/caboose/fonts_controller.rb +139 -2
  24. data/app/controllers/caboose/invoices_controller.rb +5 -4
  25. data/app/controllers/caboose/login_logs_controller.rb +5 -7
  26. data/app/controllers/caboose/media_categories_controller.rb +16 -2
  27. data/app/controllers/caboose/media_controller.rb +14 -11
  28. data/app/controllers/caboose/pages_controller.rb +104 -42
  29. data/app/controllers/caboose/posts_controller.rb +53 -7
  30. data/app/controllers/caboose/products_controller.rb +1 -1
  31. data/app/controllers/caboose/sites_controller.rb +25 -6
  32. data/app/controllers/caboose/sns_controller.rb +3 -3
  33. data/app/controllers/caboose/themes_controller.rb +30 -0
  34. data/app/controllers/caboose/users_controller.rb +17 -10
  35. data/app/controllers/caboose/variants_controller.rb +9 -9
  36. data/app/models/caboose/block.rb +98 -22
  37. data/app/models/caboose/block_type.rb +2 -1
  38. data/app/models/caboose/block_type_parser.rb +1 -1
  39. data/app/models/caboose/calendar_event_group.rb +2 -2
  40. data/app/models/caboose/change_log.rb +97 -0
  41. data/app/models/caboose/core_plugin.rb +4 -3
  42. data/app/models/caboose/font.rb +7 -2
  43. data/app/models/caboose/font_variant.rb +12 -0
  44. data/app/models/caboose/media.rb +15 -4
  45. data/app/models/caboose/media_category.rb +2 -4
  46. data/app/models/caboose/page.rb +316 -45
  47. data/app/models/caboose/page_bar_generator.rb +20 -10
  48. data/app/models/caboose/post.rb +108 -8
  49. data/app/models/caboose/product.rb +1 -1
  50. data/app/models/caboose/role.rb +2 -2
  51. data/app/models/caboose/schema.rb +73 -72
  52. data/app/models/caboose/site.rb +203 -1
  53. data/app/models/caboose/theme.rb +70 -5
  54. data/app/views/caboose/block_types/admin_edit.html.erb +6 -8
  55. data/app/views/caboose/blocks/_cached_block.html.erb +28 -0
  56. data/app/views/caboose/blocks/_file.html.erb +2 -2
  57. data/app/views/caboose/blocks/_ga.html.erb +1 -2
  58. data/app/views/caboose/blocks/_image.html.erb +4 -0
  59. data/app/views/caboose/blocks/_render_function.html.erb +9 -4
  60. data/app/views/caboose/change_logs/admin_index.html.erb +65 -0
  61. data/app/views/caboose/fonts/admin_family_edit.html.erb +63 -0
  62. data/app/views/caboose/fonts/admin_family_index.html.erb +42 -0
  63. data/app/views/caboose/fonts/admin_index.html.erb +55 -10
  64. data/app/views/caboose/fonts/admin_variant_edit.html.erb +84 -0
  65. data/app/views/caboose/invoices_mailer/customer_status_updated.html.erb +5 -14
  66. data/app/views/caboose/login_logs/admin_index_for_user.html.erb +1 -1
  67. data/app/views/caboose/media/admin_index.html.erb +14 -24
  68. data/app/views/caboose/my_account/index.html.erb +1 -0
  69. data/app/views/caboose/pages/_admin_header.html.erb +5 -0
  70. data/app/views/caboose/pages/admin_change_logs.html.erb +56 -0
  71. data/app/views/caboose/pages/admin_edit_content.html.erb +6 -2
  72. data/app/views/caboose/pages/admin_edit_general.html.erb +32 -4
  73. data/app/views/caboose/pages/compiled_asset.css.erb +0 -0
  74. data/app/views/caboose/pages/compiled_asset.js.erb +0 -0
  75. data/app/views/caboose/posts/_admin_header.html.erb +5 -0
  76. data/app/views/caboose/posts/admin_change_logs.html.erb +56 -0
  77. data/app/views/caboose/posts/admin_delete_form.html.erb +1 -1
  78. data/app/views/caboose/posts/admin_edit_content.html.erb +6 -2
  79. data/app/views/caboose/products/admin_group_variants.html.erb +1 -1
  80. data/app/views/caboose/products/admin_sort.html copy.erb +1 -1
  81. data/app/views/caboose/sites/admin_edit.html.erb +21 -0
  82. data/app/views/caboose/sites/compiled_asset.css.erb +0 -0
  83. data/app/views/caboose/sites/compiled_asset.js.erb +0 -0
  84. data/app/views/caboose/themes/admin_edit.html.erb +7 -3
  85. data/app/views/caboose/themes/admin_error_log.html.erb +9 -0
  86. data/app/views/caboose/themes/admin_js.html.erb +131 -0
  87. data/app/views/caboose/users/_admin_header.html.erb +4 -0
  88. data/app/views/caboose/users/admin_change_logs.html.erb +63 -0
  89. data/app/views/caboose/users/admin_edit_roles.html.erb +1 -0
  90. data/app/views/caboose/variants/admin_group.html.erb +1 -1
  91. data/app/views/layouts/caboose/admin.html.erb +9 -2
  92. data/app/views/layouts/caboose/application.html.erb +62 -92
  93. data/app/views/layouts/caboose/css.css.erb +44 -0
  94. data/app/views/layouts/caboose/footer_css.css.erb +41 -0
  95. data/app/views/layouts/caboose/footer_js.js.erb +31 -0
  96. data/app/views/layouts/caboose/js.js.erb +34 -0
  97. data/lib/caboose/version.rb +1 -1
  98. data/lib/tasks/caboose.rake +3 -14
  99. metadata +23 -27
  100. data/app/controllers/caboose/assets_controller.rb +0 -65
  101. data/app/models/caboose/asset.rb +0 -23
  102. data/app/models/caboose/asset_manifest.rb +0 -91
  103. data/app/models/caboose/block_cache.rb +0 -105
  104. data/app/models/caboose/block_cache_file.rb +0 -22
  105. data/app/models/caboose/block_cache_image.rb +0 -53
  106. data/app/models/caboose/page_cache.rb +0 -12
  107. data/app/models/caboose/page_cacher.rb +0 -137
  108. data/app/views/caboose/pages/admin_new_old.html.erb +0 -46
  109. data/app/views/caboose/pages/test.html.erb +0 -64
@@ -32,6 +32,7 @@ class Caboose::BlockType < ActiveRecord::Base
32
32
  :default_included,
33
33
  :custom_sass,
34
34
  :latest_error,
35
+ :is_dynamic,
35
36
  :share, # Whether or not to share the block type in the existing block store.
36
37
  :downloaded # Whether the full block type has been download or just the name and description.
37
38
 
@@ -75,7 +76,7 @@ class Caboose::BlockType < ActiveRecord::Base
75
76
  end
76
77
 
77
78
  def parse_api_hash(h)
78
- Caboose.log(h)
79
+ #Caboose.log(h)
79
80
  self.name = h['name']
80
81
  self.description = h['description']
81
82
  self.block_type_category_id = h['block_type_category_id']
@@ -132,7 +132,7 @@ module Caboose
132
132
  cv.margin_right = img.styles['margin-right' ] if img.styles['margin-right' ]
133
133
  cv.margin_top = img.styles['margin-top' ] if img.styles['margin-top' ]
134
134
 
135
- Caboose.log(cv)
135
+ # Caboose.log(cv)
136
136
 
137
137
  v = StdClass.new({
138
138
  :name => name,
@@ -51,12 +51,12 @@ module Caboose
51
51
  while d <= self.date_end
52
52
  (0..6).each do |i|
53
53
  d = d + 1
54
- Caboose.log("d = #{d}")
54
+ # Caboose.log("d = #{d}")
55
55
  next if d < self.date_start
56
56
  break if d > self.date_end
57
57
  w = d.strftime('%w').to_i
58
58
  if (w == 0 && self.sun) || (w == 1 && self.mon) || (w == 2 && self.tue) || (w == 3 && self.wed) || (w == 4 && self.thu) || (w == 5 && self.fri) || (w == 6 && self.sat)
59
- Caboose.log("Found a day")
59
+ # Caboose.log("Found a day")
60
60
  if !CalendarEvent.where("calendar_event_group_id = ? and cast(begin_date as date) = ?", self.id, d).exists?
61
61
  e.duplicate(d)
62
62
  end
@@ -0,0 +1,97 @@
1
+ module Caboose
2
+ class ChangeLog < ActiveRecord::Base
3
+ self.table_name = 'change_logs'
4
+
5
+ belongs_to :site
6
+ belongs_to :page
7
+ belongs_to :post
8
+ belongs_to :block
9
+ belongs_to :user
10
+ belongs_to :media
11
+
12
+ attr_accessible :id,
13
+ :site_id,
14
+ :page_id,
15
+ :post_id,
16
+ :block_id,
17
+ :block_parent_id,
18
+ :media_id,
19
+ :user_id,
20
+ :is_field,
21
+ :description,
22
+ :action,
23
+ :timestamp,
24
+ :old_value,
25
+ :new_value,
26
+ :old_parent_id,
27
+ :new_parent_id,
28
+ :old_sort_order,
29
+ :new_sort_order
30
+
31
+
32
+ def describe_old_position
33
+ b = self.block
34
+ par = self.old_parent_id.blank? ? false : Caboose::Block.where(:id => self.old_parent_id).first
35
+ desc = ""
36
+ pos = par && par.block_type && par.block_type.name == 'flex_grid_unit' ? par.sort_order + 1 : nil
37
+ desc += par.block_type.description + " #{pos} -> " if par && par.block_type
38
+ desc += "position #{self.old_sort_order}"
39
+ return desc
40
+ end
41
+
42
+ def describe_new_position
43
+ b = self.block
44
+ par = self.new_parent_id.blank? ? Caboose::Block.where(:id => self.old_parent_id).first : Caboose::Block.where(:id => self.new_parent_id).first
45
+ desc = ""
46
+ pos = par && par.block_type && par.block_type.name == 'flex_grid_unit' ? par.sort_order + 1 : nil
47
+ desc += par.block_type.description + " #{pos} -> " if par && par.block_type
48
+ desc += "position #{self.new_sort_order}"
49
+ return desc
50
+ end
51
+
52
+ def describe_action
53
+ return 'added' if self.action == 'added'
54
+ if !self.old_value.nil? && !self.new_value.nil? && self.old_value != self.new_value
55
+ return 'edited'
56
+ elsif !self.old_sort_order.nil? && !self.new_sort_order.nil? && self.old_sort_order != self.new_sort_order
57
+ return 'moved'
58
+ elsif !self.old_parent_id.nil? && !self.new_parent_id.nil? && self.old_parent_id != self.new_parent_id
59
+ return 'moved'
60
+ else
61
+ return self.action
62
+ end
63
+ end
64
+
65
+ def describe_old
66
+ if self.describe_action == 'moved'
67
+ return self.describe_old_position
68
+ elsif self.describe_action == 'edited'
69
+ return self.old_value == 'EMPTY' ? '' : self.old_value
70
+ elsif self.describe_action == 'deleted'
71
+ ov = self.old_value == 'EMPTY' ? '' : self.old_value
72
+ opts = ['Title','Text']
73
+ desc = Caboose::ChangeLog.where("block_parent_id is not null").where(:block_parent_id => self.block_id).where(:description => opts).first
74
+ return desc ? desc.old_value : ov
75
+ end
76
+ end
77
+
78
+ def describe_new
79
+ block = Caboose::Block.where(:id => self.block_id).first if !self.block_id.blank?
80
+ if self.describe_action == 'moved'
81
+ return self.describe_new_position
82
+ elsif self.describe_action == 'edited'
83
+ return self.new_value == 'EMPTY' ? '' : self.new_value
84
+ elsif self.describe_action == 'added'
85
+ nv = self.new_value.blank? ? (self.old_value == 'EMPTY' ? '' : self.old_value) : (self.new_value == 'EMPTY' ? '' : self.new_value)
86
+ if block
87
+ nv = block.cv(false,'text') if block.child('text')
88
+ nv = block.cv(false,'title') if block.child('title')
89
+ nv = Caboose::Media.title_for_id(block.child('image_src').media_id) if block.child('image_src') && block.child('image_src').media_id && !block.child('image_src').media_id.blank?
90
+ nv = block.cv(false,'heading_text') if block.child('heading_text')
91
+ end
92
+ return nv
93
+ end
94
+ end
95
+
96
+ end
97
+ end
@@ -14,9 +14,10 @@ class Caboose::CorePlugin < Caboose::CaboosePlugin
14
14
  nav << item if item['children'].count > 0
15
15
 
16
16
  item = { 'id' => 'core', 'text' => 'Settings', 'children' => [] }
17
- item['children'] << { 'id' => 'settings' , 'icon' => 'settings', 'text' => 'Site Settings' , 'href' => "/admin/sites/#{site.id}" , 'modal' => false } if user.is_super_admin?
17
+ item['children'] << { 'id' => 'settings' , 'icon' => 'settings', 'text' => 'Site Settings' , 'href' => "/admin/sites/#{site.id}" , 'modal' => false } if user.is_allowed('site_settings', 'edit')
18
18
  item['children'] << { 'id' => 'theme-files' , 'icon' => 'custom', 'text' => 'Theme Files' , 'href' => '/admin/theme-files' , 'modal' => false } if user.is_super_admin? && site.is_master == true
19
19
  item['children'] << { 'id' => 'blocktypes' , 'text' => 'Block Types' , 'href' => '/admin/block-types' , 'modal' => false } if user.is_allowed('blocktypes' , 'view') && site.is_master == true
20
+ item['children'] << { 'id' => 'font-families' , 'text' => 'Font Families' , 'icon' => 'info', 'href' => '/admin/font-families' , 'modal' => false } if user.is_allowed('fonts' , 'view') && site.is_master == true
20
21
  item['children'] << { 'icon' => 'star', 'id' => 'fonts' , 'text' => 'Fonts' , 'href' => '/admin/fonts' , 'modal' => false } if user.is_allowed('fonts' , 'view') && site.use_fonts == true
21
22
  item['children'] << { 'id' => 'redirects' , 'text' => 'Permanent Redirects' , 'href' => '/admin/redirects' , 'modal' => false } if user.is_allowed('redirects' , 'view')
22
23
  item['children'] << { 'id' => 'permissions' , 'text' => 'Permissions' , 'href' => '/admin/permissions' , 'modal' => false } if user.is_allowed('permissions' , 'view') && site.is_master == true
@@ -31,8 +32,8 @@ class Caboose::CorePlugin < Caboose::CaboosePlugin
31
32
  item['children'] << { 'id' => 'users' , 'text' => 'Users' , 'href' => '/admin/users' , 'modal' => false } if user.is_allowed('users' , 'view')
32
33
  item['children'] << { 'id' => 'code' , 'icon' => 'stack', 'text' => 'Custom Code' , 'href' => '/admin/code' , 'modal' => false } if user.is_allowed('code' , 'edit')
33
34
  item['children'] << { 'id' => 'contactinfo' , 'icon' => 'plane', 'text' => 'Contact Information' , 'href' => "/admin/sites/#{site.id}/contact" , 'modal' => false } if user.is_allowed('contactinfo' , 'edit')
34
- item['children'] << { 'id' => 'theme' , 'icon' => 'sites', 'text' => 'Theme' , 'href' => '/admin/theme' , 'modal' => false } if user.is_allowed('theme' , 'view') if !site.theme.nil? && user.is_super_admin?
35
- # item['children'] << { 'id' => 'variables' , 'text' => 'Variables' , 'href' => '/admin/settings' , 'modal' => false } if user.is_allowed('settings' , 'view')
35
+ item['children'] << { 'id' => 'theme' , 'icon' => 'sites', 'text' => 'Theme' , 'href' => '/admin/theme' , 'modal' => false } if user.is_allowed('theme', 'edit') && !site.theme.nil?
36
+ item['children'] << { 'id' => 'logs' , 'icon' => 'monitor', 'text' => 'Change Logs' , 'href' => '/admin/logs' , 'modal' => false } if user.is_allowed('logs' , 'view') && site.use_change_logs
36
37
  item['children'] << { 'id' => 'my-account' , 'text' => 'My Account' , 'href' => '/my-account' , 'modal' => false }
37
38
  nav << item if item['children'].count > 0
38
39
 
@@ -1,7 +1,12 @@
1
1
  class Caboose::Font < ActiveRecord::Base
2
2
  self.table_name = "fonts"
3
3
 
4
- belongs_to :site, :class_name => 'Caboose::Site'
5
- attr_accessible :id, :site_id, :name, :family, :variant, :url
4
+ belongs_to :site, :class_name => 'Caboose::Site'
5
+
6
+ attr_accessible :id, :site_id, :name, :family, :variant, :url, :variant_id
7
+
8
+ def var
9
+ Caboose::FontVariant.where(:id => self.variant_id).first
10
+ end
6
11
 
7
12
  end
@@ -1,5 +1,17 @@
1
1
  class Caboose::FontVariant < ActiveRecord::Base
2
+
2
3
  self.table_name = "font_variants"
4
+
3
5
  belongs_to :font_family, :class_name => 'Caboose::FontFamily'
6
+
7
+ has_attached_file :ttf_file,
8
+ :path => 'caboose_fonts/:id_ttf.:extension'
9
+ do_not_validate_attachment_file_type :ttf_file
10
+
11
+ has_attached_file :woff_file,
12
+ :path => 'caboose_fonts/:id_woff.:extension'
13
+ do_not_validate_attachment_file_type :woff_file
14
+
4
15
  attr_accessible :id, :ttf_url, :font_family_id, :variant, :weight, :style, :sort_order
16
+
5
17
  end
@@ -33,7 +33,8 @@ class Caboose::Media < ActiveRecord::Base
33
33
  :image_updated_at,
34
34
  :file_file_name,
35
35
  :file_file_size,
36
- :file_updated_at
36
+ :file_updated_at,
37
+ :deleted
37
38
 
38
39
  has_attached_file :sample
39
40
 
@@ -42,6 +43,11 @@ class Caboose::Media < ActiveRecord::Base
42
43
  # self.sample.options.merge({ :s3_headers => { "Content-Disposition" => "attachment; filename=#{self.name}" }})
43
44
  #end
44
45
 
46
+ # def self.delete_id(media_id)
47
+ # ProductImage.where(:media_id => media_id).destroy_all
48
+ # Media.where(:id => media_id).destroy_all
49
+ # end
50
+
45
51
  def process
46
52
  #return if self.processed
47
53
 
@@ -123,7 +129,7 @@ class Caboose::Media < ActiveRecord::Base
123
129
  end
124
130
 
125
131
  def download_file_from_url(url)
126
- self.image = URI.parse(url)
132
+ self.file = URI.parse(url)
127
133
  self.processed = true
128
134
  self.save
129
135
  end
@@ -172,6 +178,11 @@ class Caboose::Media < ActiveRecord::Base
172
178
  def reprocess_image
173
179
  self.image.reprocess!
174
180
  end
181
+
182
+ def self.title_for_id(mid)
183
+ m = Caboose::Media.where(:id => mid).first
184
+ return m ? m.original_name : nil
185
+ end
175
186
 
176
187
  def duplicate(site_id)
177
188
  cat = Caboose::MediaCategory.top_category(site_id)
@@ -190,8 +201,8 @@ class Caboose::Media < ActiveRecord::Base
190
201
  :file_updated_at => self.file_updated_at ,
191
202
  :processed => false
192
203
  )
193
- m.delay(:queue => 'caboose_media').download_image_from_url(self.image.url(:original)) if self.image
194
- m.delay(:queue => 'caboose_media').download_file_from_url(self.file.url) if self.file
204
+ m.delay(:queue => 'general').download_image_from_url(self.image.url(:original)) if self.image
205
+ m.delay(:queue => 'general').download_file_from_url(self.file.url) if self.file
195
206
  return m
196
207
  end
197
208
 
@@ -24,7 +24,7 @@ class Caboose::MediaCategory < ActiveRecord::Base
24
24
  end
25
25
 
26
26
  def self.tree(site_id)
27
- return self.where(:parent_id => nil, :site_id => site_id).reorder("name").all
27
+ return Caboose::MediaCategory.where(:parent_id => nil, :site_id => site_id).reorder("name").all
28
28
  end
29
29
 
30
30
  def self.flat_tree(site_id, prefix = '-')
@@ -44,8 +44,7 @@ class Caboose::MediaCategory < ActiveRecord::Base
44
44
  :id => cat.id,
45
45
  :parent_id => cat.parent_id,
46
46
  :site_id => cat.site_id,
47
- :name => cat.name,
48
- :media_count => cat.media.count
47
+ :name => cat.name
49
48
  }]
50
49
  cat.children.each do |cat2|
51
50
  arr += self.flat_tree_helper(cat2, prefix, "#{str}#{prefix}")
@@ -64,7 +63,6 @@ class Caboose::MediaCategory < ActiveRecord::Base
64
63
  return {
65
64
  :id => cat.id,
66
65
  :name => cat.name,
67
- :media_count => cat.media.count,
68
66
  :children => (cat.name == 'Products' ? [] : cat.children.collect{ |kid| self.tree_hash_helper(kid) })
69
67
  }
70
68
  end
@@ -8,7 +8,6 @@ class Caboose::Page < ActiveRecord::Base
8
8
  has_many :page_permissions
9
9
  has_many :blocks, :order => 'sort_order'
10
10
  has_many :page_tags, :class_name => 'Caboose::PageTag', :dependent => :delete_all, :order => 'tag'
11
- has_one :page_cache
12
11
  has_many :page_custom_field_values
13
12
  attr_accessible :id ,
14
13
  :site_id ,
@@ -20,13 +19,10 @@ class Caboose::Page < ActiveRecord::Base
20
19
  :uri ,
21
20
  :redirect_url ,
22
21
  :hide ,
23
- :content_format ,
24
22
  :custom_css ,
25
23
  :custom_css_files ,
26
24
  :custom_js ,
27
25
  :custom_js_files ,
28
- :linked_resources ,
29
- :layout ,
30
26
  :sort_order ,
31
27
  :custom_sort_children ,
32
28
  :seo_title ,
@@ -36,11 +32,8 @@ class Caboose::Page < ActiveRecord::Base
36
32
  :canonical_url ,
37
33
  :fb_description ,
38
34
  :gp_description ,
39
- :status
40
-
41
- CONTENT_FORMAT_HTML = 1
42
- CONTENT_FORMAT_TEXT = 2
43
- CONTENT_FORMAT_RUBY = 3
35
+ :css_digest ,
36
+ :js_digest
44
37
 
45
38
  def order_title
46
39
  return "" + menu_title + title unless menu_title.nil? || title.nil?
@@ -52,15 +45,15 @@ class Caboose::Page < ActiveRecord::Base
52
45
  def block
53
46
  Caboose::Block.where("page_id = ? and parent_id is null", self.id).first
54
47
  end
48
+
49
+ def self.title_for_id(page_id)
50
+ p = Caboose::Page.where(:id => page_id).first
51
+ return p ? p.title : nil
52
+ end
55
53
 
56
54
  def top_level_blocks
57
55
  Caboose::Block.where("page_id = ? and parent_id is null", self.id).reorder(:sort_order).all
58
56
  end
59
-
60
- #def content
61
- # return "" if self.blocks.nil? || self.blocks.count == 0
62
- # self.blocks.collect { |b| b.render }.join("\n")
63
- #end
64
57
 
65
58
  def self.find_with_fields(page_id, fields)
66
59
  return self.where(:id => page_id).select(fields).first
@@ -74,9 +67,143 @@ class Caboose::Page < ActiveRecord::Base
74
67
  Caboose::Block.where(:page_id => self.id).where('status != ?','published').count == 0 if !self.id.nil?
75
68
  end
76
69
 
77
- def publish
70
+ # Returns an array of block IDs for all descendant blocks of the homepage footer
71
+ def self.home_page_footer_block_ids(page)
72
+ home_page = Caboose::Page.index_page(page.site_id)
73
+ home_footer = home_page ? home_page.block.child('footer') : nil
74
+ if home_footer
75
+ footer_ids = [home_footer.id]
76
+ home_footer.children.where("name is null").each do |f1|
77
+ footer_ids << f1.id
78
+ f1.children.where("name is null").each do |f2|
79
+ footer_ids << f2.id
80
+ f2.children.where("name is null").each do |f3|
81
+ footer_ids << f3.id
82
+ f3.children.where("name is null").each do |f4|
83
+ footer_ids << f4.id
84
+ f4.children.where("name is null").each do |f5|
85
+ footer_ids << f5.id
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ return footer_ids
92
+ else
93
+ return [0]
94
+ end
95
+ end
96
+
97
+ def update_cached_blocks(block_ids)
98
+ blocks = block_ids && block_ids.count > 0 ? Caboose::Block.where("id in (?)", block_ids).order(:id).all : []
99
+ blocks.each do |b|
100
+ b.use_cache = false
101
+ b.save
102
+ b.delay(:queue => 'caching', :priority => 6).update_cache
103
+ end
104
+ end
105
+
106
+ def cached_css
107
+ str = ''
108
+ return str if self.site.nil? || !self.site.use_caching
109
+ blocks = Caboose::Block.includes(:block_type).where("blocks.page_id = ?",self.id).where("blocks.cached_css IS NOT NULL").where("block_types.is_dynamic = false").order("blocks.id").all
110
+ blocks.each do |b|
111
+ str << b.cached_css
112
+ end
113
+
114
+ # Add any CSS for referenced Block Copy blocks
115
+ bt = Caboose::BlockType.where(:name => 'source_block_id').first
116
+ if bt
117
+ ref_ids = Caboose::Block.where("value is not null").where(:block_type_id => bt.id, :page_id => self.id).pluck(:value)
118
+ if ref_ids && ref_ids.count > 0
119
+ Caboose::Block.includes(:block_type).where("blocks.id in (?)", ref_ids).order("blocks.id").all.each do |b|
120
+ str << b.cached_css if !b.cached_css.blank? && !b.block_type.is_dynamic
121
+ b.children.where("name is null").each do |b1|
122
+ str << b1.cached_css if !b1.cached_css.blank? && !b1.block_type.is_dynamic
123
+ b1.children.where("name is null").each do |b2|
124
+ str << b2.cached_css if !b2.cached_css.blank? && !b2.block_type.is_dynamic
125
+ b2.children.where("name is null").each do |b3|
126
+ str << b3.cached_css if !b3.cached_css.blank? && !b3.block_type.is_dynamic
127
+ b3.children.where("name is null").each do |b4|
128
+ str << b4.cached_css if !b4.cached_css.blank? && !b4.block_type.is_dynamic
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ return str.blank? ? '' : str.gsub(/<\/style>(\s*)<style>/,'')
138
+ end
139
+
140
+ def cached_js
141
+ str = ''
142
+ return str if self.site.nil? || !self.site.use_caching
143
+ blocks = Caboose::Block.includes(:block_type).where("blocks.page_id = ?",self.id).where("blocks.cached_js IS NOT NULL").where("block_types.is_dynamic = false").order("blocks.id").all
144
+ blocks.each do |b|
145
+ str << b.cached_js
146
+ end
147
+
148
+ # Add any JS for referenced Block Copy blocks
149
+ bt = Caboose::BlockType.where(:name => 'source_block_id').first
150
+ if bt
151
+ ref_ids = Caboose::Block.where("value is not null").where(:block_type_id => bt.id, :page_id => self.id).pluck(:value)
152
+ if ref_ids && ref_ids.count > 0
153
+ Caboose::Block.includes(:block_type).where("blocks.id in (?)", ref_ids).order("blocks.id").all.each do |b|
154
+ str << b.cached_js if !b.cached_js.blank? && !b.block_type.is_dynamic
155
+ b.children.where("name is null").each do |b1|
156
+ str << b1.cached_js if !b1.cached_js.blank? && !b1.block_type.is_dynamic
157
+ b1.children.where("name is null").each do |b2|
158
+ str << b2.cached_js if !b2.cached_js.blank? && !b2.block_type.is_dynamic
159
+ b2.children.where("name is null").each do |b3|
160
+ str << b3.cached_js if !b3.cached_js.blank? && !b3.block_type.is_dynamic
161
+ b3.children.where("name is null").each do |b4|
162
+ str << b4.cached_js if !b4.cached_js.blank? && !b4.block_type.is_dynamic
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ host = Rails.env.production? ? "https://#{ActionController::Base.asset_host}" : ""
172
+ return str.blank? ? '' : str.gsub('"/assets/',"\"#{host}/assets/")
173
+ end
174
+
175
+ def publish(user_id)
78
176
  if !self.id.nil?
177
+ use_caching = self.site.use_caching
178
+ changed_ids = []
79
179
  Caboose::Block.where(:page_id => self.id).where('status = ? OR status = ?','edited','added').all.each do |b|
180
+ if self.site && self.site.use_change_logs
181
+ if b.new_parent_id.blank? && b.new_value.blank? && b.new_media_id.blank? && b.sort_order == b.new_sort_order && b.status == 'edited'
182
+ # This one just got moved because something else was added
183
+ else
184
+ cl = Caboose::ChangeLog.create(:site_id => self.site_id, :user_id => user_id, :page_id => self.id, :block_id => b.id, :block_parent_id => b.parent_id, :timestamp => DateTime.now, :action => b.status)
185
+ desc = ""
186
+ desc += b.parent.parent.block_type.description + " -> " if b.parent && b.parent.parent && b.parent.parent.block_type && b.parent.parent.block_type.description != "Content" && !b.parent.parent.block_type.name.include?('layout')
187
+ pos = b.parent && b.parent.block_type && b.parent.block_type.name == 'flex_grid_unit' ? b.parent.sort_order + 1 : nil
188
+ desc += b.parent.block_type.description + " #{pos} -> " if b.parent && b.parent.block_type && b.parent.block_type.description != "Content" && !b.parent.block_type.name.include?('layout')
189
+ desc += b.block_type.description if b.block_type
190
+ cl.description = desc
191
+ cl.is_field = true if !b.name.blank?
192
+ ov = ['page','page_id'].include?(b.name) ? Caboose::Page.title_for_id(b.value) : b.value
193
+ nv = ['page','page_id'].include?(b.name) ? Caboose::Page.title_for_id(b.new_value) : b.new_value
194
+ if b.new_value.blank? && !b.new_media_id.blank?
195
+ ov = Caboose::Media.title_for_id(b.media_id)
196
+ nv = Caboose::Media.title_for_id(b.new_media_id)
197
+ end
198
+ cl.old_value = ov
199
+ cl.new_value = nv
200
+ cl.old_sort_order = b.sort_order
201
+ cl.new_sort_order = b.new_sort_order
202
+ cl.old_parent_id = b.parent_id
203
+ cl.new_parent_id = b.new_parent_id
204
+ cl.save
205
+ end
206
+ end
80
207
  if b.new_value == 'EMPTY'
81
208
  b.value = nil
82
209
  elsif !b.new_value.blank?
@@ -92,16 +219,41 @@ class Caboose::Page < ActiveRecord::Base
92
219
  b.status = 'published'
93
220
  b.new_value = nil
94
221
  b.new_media_id = nil
95
- b.new_sort_order = nil
222
+ b.new_sort_order = b.sort_order
96
223
  b.new_parent_id = nil
97
224
  b.save
225
+ # Update cached value for the closest cached ancestor of this block
226
+ changed_ids << b.cached_ancestor if use_caching
227
+ end
228
+ if use_caching # Catch published blocks that have never been cached before
229
+ content = self.block.child('content')
230
+ Caboose::Block.includes(:block_type).where(:parent_id => content.id, :status => 'published', :cached_value => nil, :name => nil).where("block_types.is_dynamic = false").all.each do |b|
231
+ changed_ids << b.cached_ancestor
232
+ end
98
233
  end
99
234
  deleted_blocks = Caboose::Block.where(:page_id => self.id, :status => 'deleted').pluck(:id)
100
235
  dids = deleted_blocks.blank? ? 0 : deleted_blocks
236
+ if self.site && self.site.use_change_logs
237
+ Caboose::Block.where("id in (?)",dids).all.each do |b|
238
+ cl = Caboose::ChangeLog.create(:site_id => self.site_id, :user_id => user_id, :page_id => self.id, :block_id => b.id, :block_parent_id => b.parent_id, :timestamp => DateTime.now, :action => 'deleted')
239
+ cl.old_value = b.new_value.blank? ? b.value : b.new_value
240
+ cl.description = b.block_type.description if b.block_type
241
+ cl.is_field = true if !b.name.blank?
242
+ cl.save
243
+ end
244
+ end
101
245
  Caboose::Block.where("id in (?) or parent_id in (?)",dids,dids).destroy_all
102
246
  Caboose::Block.where(:page_id => self.id, :status => nil).update_all(:status => 'published')
103
- self.status = 'published'
104
- self.save
247
+ if use_caching
248
+ index_page = Caboose::Page.index_page(self.site_id)
249
+ self.update_cached_blocks(changed_ids)
250
+ self.delay(:queue => 'caching', :priority => 7).update_css_file
251
+ self.delay(:queue => 'caching', :priority => 7).update_js_file
252
+ if index_page && self.id == index_page.id
253
+ self.site.delay(:queue => 'caching', :priority => 8).update_footer_css_file
254
+ self.site.delay(:queue => 'caching', :priority => 8).update_footer_js_file
255
+ end
256
+ end
105
257
  end
106
258
  end
107
259
 
@@ -109,8 +261,28 @@ class Caboose::Page < ActiveRecord::Base
109
261
  if !self.id.nil?
110
262
  Caboose::Block.where(:page_id => self.id).where(:status => 'added').destroy_all
111
263
  Caboose::Block.where(:page_id => self.id).update_all("status = 'published', new_value = null, new_media_id = null, new_sort_order = sort_order, new_parent_id = null")
112
- self.status = 'published'
113
- self.save
264
+ end
265
+ end
266
+
267
+ def refresh_css
268
+ begin
269
+ rad = rand(999)
270
+ dom = Rails.env.production? ? self.site.public_domain : self.site.dev_domain.domain
271
+ uri = URI("http://#{dom}/api/page_#{self.id}.css?#{rad}")
272
+ css = Net::HTTP.get(uri)
273
+ rescue
274
+ Caboose.log("Couldn't generate page CSS")
275
+ end
276
+ end
277
+
278
+ def refresh_js
279
+ begin
280
+ rad = rand(999)
281
+ dom = Rails.env.production? ? self.site.public_domain : self.site.dev_domain.domain
282
+ uri = URI("http://#{dom}/api/page_#{self.id}.js?#{rad}")
283
+ css = Net::HTTP.get(uri)
284
+ rescue
285
+ Caboose.log("Couldn't generate page JS")
114
286
  end
115
287
  end
116
288
 
@@ -257,13 +429,13 @@ class Caboose::Page < ActiveRecord::Base
257
429
  user = Caboose::User.find(user)
258
430
  end
259
431
  ids = []
260
- user.roles.each do |role|
261
- ids + Caboose::PagePermission.where({
432
+ user.roles.each do |role|
433
+ ids << Caboose::PagePermission.where({
262
434
  :role_id => role.id,
263
435
  :action => action
264
436
  }).pluck(:page_id)
265
437
  end
266
- return ids.uniq
438
+ return ids.flatten
267
439
  end
268
440
 
269
441
  def self.crumb_trail(page)
@@ -339,6 +511,119 @@ class Caboose::Page < ActiveRecord::Base
339
511
  end
340
512
  return block
341
513
  end
514
+
515
+
516
+ def css_path(digest = self.css_digest)
517
+ return "assets/pages/page_#{self.id}_#{digest}.css"
518
+ end
519
+
520
+ def css_url
521
+ rad = rand(999)
522
+ old = "/api/page_#{self.id}.css?#{rad}"
523
+ return old if self.css_digest.blank?
524
+ if Rails.env.production?
525
+ return "https://#{Caboose::cdn_domain}/#{css_path}"
526
+ else
527
+ path = File.join(Rails.root, 'public', "#{css_path}")
528
+ if File.file?(path)
529
+ return "#{ActionController::Base.asset_host}/#{css_path}"
530
+ else
531
+ return "https://#{Caboose::cdn_domain}/#{css_path}"
532
+ end
533
+ end
534
+ end
535
+
536
+ def update_css_file
537
+ str = ""
538
+ css_digest = SecureRandom.urlsafe_base64.to_s
539
+ old_digest = self.css_digest
540
+ css = self.refresh_css
541
+ if css && !css.blank?
542
+ begin
543
+ if Rails.env.production?
544
+ config = YAML.load(File.read(Rails.root.join('config', 'aws.yml')))[Rails.env]
545
+ AWS.config(:access_key_id => config['access_key_id'], :secret_access_key => config['secret_access_key'])
546
+ bucket = AWS::S3.new.buckets[config['bucket']]
547
+ bucket.objects[self.css_path(css_digest)].write(css, :acl => 'public-read', :content_type => 'text/css', :cache_control => 'public, max-age=86400')
548
+ if !old_digest.blank? && old_digest != 'empty'
549
+ key = self.css_path(old_digest)
550
+ obj = bucket.objects[key]
551
+ obj.delete
552
+ end
553
+ else
554
+ file_path = File.join(Rails.root, 'public', 'assets', 'pages')
555
+ FileUtils.mkdir_p(file_path) unless File.directory?(file_path)
556
+ File.open(File.join(Rails.root, 'public', self.css_path(css_digest)), 'wb+') { |f| f.write( css ) }
557
+ if !old_digest.blank? && old_digest != 'empty'
558
+ path = File.join(Rails.root, 'public', self.css_path(old_digest))
559
+ File.delete(path) if File.file?(path)
560
+ end
561
+ end
562
+ self.update_column('css_digest', css_digest)
563
+ rescue
564
+ self.update_column('css_digest', old_digest)
565
+ end
566
+ else
567
+ self.update_column('css_digest', 'empty')
568
+ end
569
+ end
570
+
571
+ def js_path(digest = self.js_digest)
572
+ return "assets/pages/page_#{self.id}_#{digest}.js"
573
+ end
574
+
575
+ def js_url
576
+ rad = rand(999)
577
+ old = "/api/page_#{self.id}.js?#{rad}"
578
+ return old if self.js_digest.blank?
579
+ if Rails.env.production?
580
+ return "https://#{Caboose::cdn_domain}/#{js_path}"
581
+ else
582
+ path = File.join(Rails.root, 'public', "#{js_path}")
583
+ if File.file?(path)
584
+ return "#{ActionController::Base.asset_host}/#{js_path}"
585
+ else
586
+ return "https://#{Caboose::cdn_domain}/#{js_path}"
587
+ end
588
+ end
589
+ end
590
+
591
+ def update_js_file
592
+ str = ""
593
+ js_digest = SecureRandom.urlsafe_base64.to_s
594
+ old_digest = self.js_digest
595
+ js = self.refresh_js
596
+ if js && !js.blank?
597
+ begin
598
+ if Rails.env.production?
599
+ config = YAML.load(File.read(Rails.root.join('config', 'aws.yml')))[Rails.env]
600
+ AWS.config(:access_key_id => config['access_key_id'], :secret_access_key => config['secret_access_key'])
601
+ bucket = AWS::S3.new.buckets[config['bucket']]
602
+ bucket.objects[self.js_path(js_digest)].write(js, :acl => 'public-read', :content_type => 'text/javascript', :cache_control => 'public, max-age=86400')
603
+ if !old_digest.blank? && old_digest != 'empty'
604
+ key = self.js_path(old_digest)
605
+ obj = bucket.objects[key]
606
+ obj.delete
607
+ end
608
+ else
609
+ file_path = File.join(Rails.root, 'public', 'assets', 'pages')
610
+ FileUtils.mkdir_p(file_path) unless File.directory?(file_path)
611
+ File.open(File.join(Rails.root, 'public', self.js_path(js_digest)), 'wb+') { |f| f.write( js ) }
612
+ if !old_digest.blank? && old_digest != 'empty'
613
+ path = File.join(Rails.root, 'public', self.js_path(old_digest))
614
+ File.delete(path) if File.file?(path)
615
+ end
616
+ end
617
+ self.update_column('js_digest', js_digest)
618
+ rescue
619
+ self.update_column('js_digest', old_digest)
620
+ end
621
+ else
622
+ self.update_column('js_digest', 'empty')
623
+ end
624
+ end
625
+
626
+
342
627
 
343
628
  def self.url(page_id)
344
629
  arr = []
@@ -392,21 +677,6 @@ class Caboose::Page < ActiveRecord::Base
392
677
  def is_child_of?(parent_id)
393
678
  return Caboose::Page.is_child(parent_id, self.id)
394
679
  end
395
-
396
- def linked_resources_map
397
- resources = { js: [], css: [] }
398
- return resources if self.linked_resources.nil?
399
- self.linked_resources.each_line do |r|
400
- r.chomp!
401
- case r
402
- when /\.js$/
403
- resources[:js] << r
404
- when /\.css$/
405
- resources[:css] << r
406
- end
407
- end
408
- return resources
409
- end
410
680
 
411
681
  def head_title
412
682
  str = ""
@@ -444,7 +714,7 @@ class Caboose::Page < ActiveRecord::Base
444
714
  end
445
715
  end
446
716
 
447
- def duplicate(site_id, parent_id, duplicate_children = false, block_type_id = nil, child_block_type_id = nil)
717
+ def duplicate(site_id, parent_id, duplicate_children = false, block_type_id = nil, child_block_type_id = nil, user_id = nil)
448
718
 
449
719
  if parent_id.to_i == -1
450
720
  p = Caboose::Page.index_page(site_id)
@@ -459,16 +729,15 @@ class Caboose::Page < ActiveRecord::Base
459
729
  p = Caboose::Page.create(:site_id => site_id, :parent_id => parent_id)
460
730
  end
461
731
 
732
+ site = Caboose::Site.where(:id => site_id).first
733
+
462
734
  p.title = "Copy of " + self.title
463
735
  p.menu_title = self.menu_title
464
736
  p.alias = self.alias
465
737
  p.redirect_url = self.redirect_url
466
- p.hide = true
467
- p.content_format = self.content_format
738
+ p.hide = true
468
739
  p.custom_css = self.custom_css
469
- p.custom_js = self.custom_js
470
- p.linked_resources = self.linked_resources
471
- p.layout = self.layout
740
+ p.custom_js = self.custom_js
472
741
  p.sort_order = self.sort_order
473
742
  p.custom_sort_children = self.custom_sort_children
474
743
  p.seo_title = self.seo_title
@@ -488,6 +757,8 @@ class Caboose::Page < ActiveRecord::Base
488
757
  end while (Caboose::Page.where(:uri => p.uri, :site_id => site_id).count > 0 && i < 10)
489
758
 
490
759
  p.save
760
+
761
+ Caboose::ChangeLog.create(:site_id => site_id, :description => p.title, :user_id => user_id, :page_id => p.id, :timestamp => DateTime.now, :action => 'created') if site && site.use_change_logs
491
762
 
492
763
  self.page_tags.each{ |tag| Caboose::PageTag.create(:page_id => p.id, :tag => tag.tag) }
493
764
 
@@ -506,7 +777,7 @@ class Caboose::Page < ActiveRecord::Base
506
777
 
507
778
  if duplicate_children && !p.is_child_of?(self.id)
508
779
  self.children.each do |p2|
509
- p2.duplicate(site_id, p.id, duplicate_children, child_block_type_id, child_block_type_id)
780
+ p2.duplicate(site_id, p.id, duplicate_children, child_block_type_id, child_block_type_id, user_id)
510
781
  end
511
782
  end
512
783
  return p