knitkit 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/GPL-3-LICENSE +674 -0
- data/README.md +6 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/knitkit/application.js +9 -0
- data/app/assets/stylesheets/knitkit/application.css +7 -0
- data/app/controllers/knitkit/articles_controller.rb +7 -0
- data/app/controllers/knitkit/base_controller.rb +45 -0
- data/app/controllers/knitkit/blogs_controller.rb +27 -0
- data/app/controllers/knitkit/comments_controller.rb +18 -0
- data/app/controllers/knitkit/erp_app/desktop/app_controller.rb +135 -0
- data/app/controllers/knitkit/erp_app/desktop/articles_controller.rb +144 -0
- data/app/controllers/knitkit/erp_app/desktop/comments_controller.rb +43 -0
- data/app/controllers/knitkit/erp_app/desktop/content_controller.rb +27 -0
- data/app/controllers/knitkit/erp_app/desktop/file_assets_controller.rb +145 -0
- data/app/controllers/knitkit/erp_app/desktop/image_assets_controller.rb +28 -0
- data/app/controllers/knitkit/erp_app/desktop/inquiries_controller.rb +68 -0
- data/app/controllers/knitkit/erp_app/desktop/position_controller.rb +20 -0
- data/app/controllers/knitkit/erp_app/desktop/theme_controller.rb +272 -0
- data/app/controllers/knitkit/erp_app/desktop/versions_controller.rb +135 -0
- data/app/controllers/knitkit/erp_app/desktop/website_controller.rb +177 -0
- data/app/controllers/knitkit/erp_app/desktop/website_nav_controller.rb +143 -0
- data/app/controllers/knitkit/erp_app/desktop/website_section_controller.rb +116 -0
- data/app/controllers/knitkit/unauthorized_controller.rb +8 -0
- data/app/controllers/knitkit/website_sections_controller.rb +17 -0
- data/app/helpers/application_helper.rb +132 -0
- data/app/models/article.rb +14 -0
- data/app/models/blog.rb +21 -0
- data/app/models/comment.rb +24 -0
- data/app/models/content.rb +158 -0
- data/app/models/extensions/user.rb +5 -0
- data/app/models/published_element.rb +9 -0
- data/app/models/published_website.rb +118 -0
- data/app/models/theme.rb +239 -0
- data/app/models/website.rb +457 -0
- data/app/models/website_host.rb +3 -0
- data/app/models/website_inquiry.rb +11 -0
- data/app/models/website_inquiry_mailer.rb +12 -0
- data/app/models/website_nav.rb +17 -0
- data/app/models/website_nav_item.rb +21 -0
- data/app/models/website_section.rb +152 -0
- data/app/models/website_section_content.rb +4 -0
- data/app/views/knitkit/articles/index.html.erb +3 -0
- data/app/views/knitkit/articles/show.html.erb +4 -0
- data/app/views/knitkit/blogs/_add_comment.html.erb +28 -0
- data/app/views/knitkit/blogs/_comment.html.erb +8 -0
- data/app/views/knitkit/blogs/index.html.erb +51 -0
- data/app/views/knitkit/blogs/index.rss.builder +23 -0
- data/app/views/knitkit/blogs/show.html.erb +22 -0
- data/app/views/knitkit/unauthorized/index.html.erb +4 -0
- data/app/views/knitkit/website_sections/index.html.erb +6 -0
- data/app/views/layouts/knitkit/base.html.erb +59 -0
- data/app/views/menus/knitkit/_default_menu.html.erb +23 -0
- data/app/views/menus/knitkit/_default_section_menu.html.erb +27 -0
- data/app/views/menus/knitkit/_default_sub_menu.html.erb +45 -0
- data/app/views/menus/knitkit/_default_sub_section_menu.html.erb +49 -0
- data/app/views/shared/knitkit/_bread_crumb.html.erb +7 -0
- data/app/views/shared/knitkit/_footer.html.erb +3 -0
- data/app/views/website_inquiry_mailer/inquiry.erb +3 -0
- data/app/widgets/contact_us/base.rb +86 -0
- data/app/widgets/contact_us/javascript/contact_us.js +13 -0
- data/app/widgets/contact_us/views/_contact_form.html.erb +36 -0
- data/app/widgets/contact_us/views/error.html.erb +10 -0
- data/app/widgets/contact_us/views/index.html.erb +1 -0
- data/app/widgets/contact_us/views/layouts/base.html.erb +7 -0
- data/app/widgets/contact_us/views/success.html.erb +4 -0
- data/app/widgets/google_map/base.rb +48 -0
- data/app/widgets/google_map/javascript/google_map.js +174 -0
- data/app/widgets/google_map/views/index.html.erb +41 -0
- data/app/widgets/login/base.rb +61 -0
- data/app/widgets/login/javascript/login.js +162 -0
- data/app/widgets/login/views/index.html.erb +37 -0
- data/app/widgets/login/views/layouts/base.html.erb +14 -0
- data/app/widgets/login/views/login_header.html.erb +9 -0
- data/app/widgets/login/views/reset_password.html.erb +26 -0
- data/app/widgets/manage_profile/base.rb +327 -0
- data/app/widgets/manage_profile/javascript/manage_profile.js +11 -0
- data/app/widgets/manage_profile/views/_contact_information_form.html.erb +180 -0
- data/app/widgets/manage_profile/views/_password_form.html.erb +20 -0
- data/app/widgets/manage_profile/views/_user_information_form.html.erb +30 -0
- data/app/widgets/manage_profile/views/contact_type_in_use.html.erb +4 -0
- data/app/widgets/manage_profile/views/default_type_error.html.erb +5 -0
- data/app/widgets/manage_profile/views/error.html.erb +3 -0
- data/app/widgets/manage_profile/views/index.html.erb +46 -0
- data/app/widgets/manage_profile/views/layouts/base.html.erb +1 -0
- data/app/widgets/manage_profile/views/password_blank.html.erb +4 -0
- data/app/widgets/manage_profile/views/password_invalid.html.erb +4 -0
- data/app/widgets/manage_profile/views/password_success.html.erb +3 -0
- data/app/widgets/manage_profile/views/success.html.erb +3 -0
- data/app/widgets/reset_password/base.rb +42 -0
- data/app/widgets/reset_password/javascript/reset_password.js +13 -0
- data/app/widgets/reset_password/views/index.html.erb +31 -0
- data/app/widgets/reset_password/views/layouts/base.html.erb +1 -0
- data/app/widgets/search/base.rb +80 -0
- data/app/widgets/search/javascript/search.js +31 -0
- data/app/widgets/search/views/_search.html.erb +39 -0
- data/app/widgets/search/views/index.html.erb +3 -0
- data/app/widgets/search/views/layouts/base.html.erb +24 -0
- data/app/widgets/search/views/show.html.erb +48 -0
- data/app/widgets/signup/base.rb +72 -0
- data/app/widgets/signup/javascript/signup.js +13 -0
- data/app/widgets/signup/views/_signup_form.html.erb +36 -0
- data/app/widgets/signup/views/error.html.erb +11 -0
- data/app/widgets/signup/views/index.html.erb +1 -0
- data/app/widgets/signup/views/layouts/base.html.erb +7 -0
- data/app/widgets/signup/views/success.html.erb +4 -0
- data/config/environment.rb +0 -0
- data/config/routes.rb +41 -0
- data/db/data_migrations/20110509223702_add_publisher_role.rb +11 -0
- data/db/data_migrations/20110816153456_add_knitkit_application.rb +31 -0
- data/db/data_migrations/upgrade/20111011203718_create_paths_for_sections.rb +13 -0
- data/db/data_migrations/upgrade/20111216192114_add_secured_models_to_menu_items.rb +18 -0
- data/db/data_migrations/upgrade/20111216202819_set_contents_iid_to_permalink_where_null.rb +12 -0
- data/db/migrate/20110211002317_setup_knitkit.rb +259 -0
- data/db/migrate/upgrade/20111014190442_update_contents.rb +25 -0
- data/db/migrate/upgrade/20111014201502_add_published_by_to_published_elements.rb +22 -0
- data/db/migrate/upgrade/20111017133851_add_iid_to_section.rb +21 -0
- data/db/migrate/upgrade/20111027145006_add_in_menu_to_section.rb +19 -0
- data/lib/knitkit.rb +12 -0
- data/lib/knitkit/engine.rb +26 -0
- data/lib/knitkit/extensions.rb +18 -0
- data/lib/knitkit/extensions/action_controller/theme_support/acts_as_themed_controller.rb +88 -0
- data/lib/knitkit/extensions/active_record/acts_as_commentable.rb +28 -0
- data/lib/knitkit/extensions/active_record/acts_as_publishable.rb +38 -0
- data/lib/knitkit/extensions/active_record/theme_support/has_many_themes.rb +34 -0
- data/lib/knitkit/extensions/compass/widgets/base.rb +53 -0
- data/lib/knitkit/extensions/core/array.rb +5 -0
- data/lib/knitkit/extensions/railties/action_view.rb +187 -0
- data/lib/knitkit/extensions/railties/theme_support/asset_tag_helper.rb +198 -0
- data/lib/knitkit/extensions/railties/theme_support/theme_file_resolver.rb +44 -0
- data/lib/knitkit/routing_filter/section_router.rb +55 -0
- data/lib/knitkit/syntax_validator.rb +32 -0
- data/lib/knitkit/version.rb +3 -0
- data/lib/tasks/knitkit_tasks.rake +4 -0
- data/public/images/knitkit/bullet.png +0 -0
- data/public/images/knitkit/content.png +0 -0
- data/public/images/knitkit/footer.png +0 -0
- data/public/images/knitkit/graphic.png +0 -0
- data/public/images/knitkit/greyFadeDown.png +0 -0
- data/public/images/knitkit/link.png +0 -0
- data/public/images/knitkit/logo.png +0 -0
- data/public/images/knitkit/menu.png +0 -0
- data/public/images/knitkit/menu_select.png +0 -0
- data/public/images/knitkit/search.png +0 -0
- data/public/javascripts/datepicker.js +440 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/articles_grid_panel.js +473 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/center_region.js +576 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/comments_grid_panel.js +217 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/east_region.js +26 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/file_assets_panel.js +109 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/image_assets_data_view.js +30 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/image_assets_panel.js +160 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/inquiries_grid_panel.js +46 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/module.js +46 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/publish_window.js +92 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/published_grid_panel.js +220 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/section_articles_grid_panel.js +613 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/themes_tree_panel.js +573 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/versions_grid_panel.js +664 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/west_region.js +2161 -0
- data/public/javascripts/erp_app/desktop/applications/knitkit/widgets_panel.js +52 -0
- data/public/stylesheets/datepicker.css +121 -0
- data/public/stylesheets/erp_app/desktop/applications/knitkit/knitkit.css +114 -0
- data/public/stylesheets/extjs/resources/css/knitkit_extjs_4.css +219 -0
- data/public/stylesheets/knitkit/style.css +394 -0
- metadata +289 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
class PublishedElement < ActiveRecord::Base
|
2
|
+
belongs_to :published_website
|
3
|
+
belongs_to :published_element_record, :polymorphic => true
|
4
|
+
belongs_to :published_by, :class_name => "User"
|
5
|
+
|
6
|
+
def published_by_username
|
7
|
+
self.published_by.username rescue ''
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class PublishedWebsite < ActiveRecord::Base
|
2
|
+
belongs_to :website
|
3
|
+
belongs_to :published_by, :class_name => "User"
|
4
|
+
has_many :published_elements, :dependent => :destroy
|
5
|
+
|
6
|
+
def published_by_username
|
7
|
+
self.published_by.username rescue ''
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.activate(website, version, current_user)
|
11
|
+
published_websites = self.where('website_id = ?', website.id).all
|
12
|
+
published_websites.each do |published_website|
|
13
|
+
if published_website.version == version
|
14
|
+
published_website.active = true
|
15
|
+
published_website.published_by = current_user
|
16
|
+
else
|
17
|
+
published_website.active = false
|
18
|
+
end
|
19
|
+
published_website.save
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def publish(comment, current_user)
|
24
|
+
new_publication = clone_publication(1, comment, current_user)
|
25
|
+
elements = []
|
26
|
+
|
27
|
+
#get a publish sections
|
28
|
+
website_sections = new_publication.website.website_sections
|
29
|
+
website_sections = website_sections | website_sections.collect{|section| section.descendants}.flatten
|
30
|
+
website_sections.each do |website_section|
|
31
|
+
if new_publication.published_elements.where('published_element_record_id = ? and (published_element_record_type = ? or published_element_record_type = ?)', website_section.id, website_section.class.to_s, website_section.class.superclass.to_s).first.nil?
|
32
|
+
published_element = PublishedElement.new
|
33
|
+
published_element.published_website = new_publication
|
34
|
+
published_element.published_element_record = website_section
|
35
|
+
published_element.version = website_section.version
|
36
|
+
published_element.published_by = current_user
|
37
|
+
published_element.save
|
38
|
+
end
|
39
|
+
|
40
|
+
elements = elements | website_section.contents
|
41
|
+
end
|
42
|
+
|
43
|
+
#make sure all elements have published_element objects
|
44
|
+
elements.each do |element|
|
45
|
+
if new_publication.published_elements.where('published_element_record_id = ? and (published_element_record_type = ? or published_element_record_type = ?)', element.id, element.class.to_s, element.class.superclass.to_s).first.nil?
|
46
|
+
published_element = PublishedElement.new
|
47
|
+
published_element.published_website = new_publication
|
48
|
+
published_element.published_element_record = element
|
49
|
+
published_element.version = element.version
|
50
|
+
published_element.published_by = current_user
|
51
|
+
published_element.save
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
#get latest version for all elements
|
56
|
+
new_publication.published_elements.each do |published_element|
|
57
|
+
published_element.version = published_element.published_element_record.version
|
58
|
+
published_element.save
|
59
|
+
end
|
60
|
+
|
61
|
+
#check if we want to auto active this publication
|
62
|
+
if new_publication.website.auto_activate_publication?
|
63
|
+
PublishedWebsite.activate(new_publication.website, new_publication.version, current_user)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def publish_element(comment, element, version, current_user)
|
68
|
+
new_publication = clone_publication(0.1, comment, current_user)
|
69
|
+
|
70
|
+
published_element = new_publication.published_elements.where('published_element_record_id = ? and (published_element_record_type = ? or published_element_record_type = ?)', element.id, element.class.to_s, element.class.superclass.to_s).first
|
71
|
+
|
72
|
+
unless published_element.nil?
|
73
|
+
published_element.version = version
|
74
|
+
published_element.published_by = current_user
|
75
|
+
published_element.save
|
76
|
+
else
|
77
|
+
new_published_element = PublishedElement.new
|
78
|
+
new_published_element.published_website = new_publication
|
79
|
+
new_published_element.published_element_record = element
|
80
|
+
new_published_element.version = version
|
81
|
+
new_published_element.published_by = current_user
|
82
|
+
new_published_element.save
|
83
|
+
end
|
84
|
+
|
85
|
+
#check if we want to auto active this publication
|
86
|
+
if new_publication.website.auto_activate_publication?
|
87
|
+
PublishedWebsite.activate(new_publication.website, new_publication.version, current_user)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def clone_publication(version_increment, comment, current_user)
|
94
|
+
#create new PublishedWebsite with comment
|
95
|
+
published_website = PublishedWebsite.new
|
96
|
+
published_website.website = self.website
|
97
|
+
if version_increment == 1
|
98
|
+
published_website.version = (self.version.to_i + version_increment)
|
99
|
+
else
|
100
|
+
published_website.version = (self.version + version_increment).round(6)
|
101
|
+
end
|
102
|
+
published_website.published_by = current_user
|
103
|
+
published_website.comment = comment
|
104
|
+
published_website.save
|
105
|
+
|
106
|
+
#create new PublishedWebsiteElements
|
107
|
+
published_elements.each do |published_element|
|
108
|
+
new_published_element = PublishedElement.new
|
109
|
+
new_published_element.published_website = published_website
|
110
|
+
new_published_element.published_element_record = published_element.published_element_record
|
111
|
+
new_published_element.version = published_element.version
|
112
|
+
new_published_element.published_by = current_user
|
113
|
+
new_published_element.save
|
114
|
+
end
|
115
|
+
|
116
|
+
published_website
|
117
|
+
end
|
118
|
+
end
|
data/app/models/theme.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
class Theme < ActiveRecord::Base
|
5
|
+
THEME_STRUCTURE = ['stylesheets', 'javascripts', 'images', 'templates']
|
6
|
+
BASE_LAYOUTS_VIEWS_PATH = "#{Knitkit::Engine.root.to_s}/app/views"
|
7
|
+
KNITKIT_WEBSITE_STYLESHEETS_PATH = "#{Knitkit::Engine.root.to_s}/public/stylesheets/knitkit"
|
8
|
+
KNITKIT_WEBSITE_IMAGES_PATH = "#{Knitkit::Engine.root.to_s}/public/images/knitkit"
|
9
|
+
|
10
|
+
has_file_assets
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def root_dir
|
14
|
+
@@root_dir ||= "#{Rails.root}/public"
|
15
|
+
end
|
16
|
+
|
17
|
+
def base_dir(website)
|
18
|
+
"#{root_dir}/sites/site-#{website.id}/themes"
|
19
|
+
end
|
20
|
+
|
21
|
+
def import(file, website)
|
22
|
+
name_and_id = file.original_filename.to_s.gsub(/(^.*(\\|\/))|(\.zip$)/, '')
|
23
|
+
theme_name = name_and_id.split('[').first
|
24
|
+
theme_id = name_and_id.split('[').last.gsub(']','')
|
25
|
+
return false unless valid_theme?(file)
|
26
|
+
Theme.create(:name => theme_name, :theme_id => theme_id, :website => website).tap do |theme|
|
27
|
+
theme.import(file)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def make_tmp_dir
|
32
|
+
random = Time.now.to_i.to_s.split('').sort_by { rand }
|
33
|
+
Pathname.new(Rails.root.to_s + "/tmp/themes/tmp_#{random}/").tap do |dir|
|
34
|
+
FileUtils.mkdir_p(dir) unless dir.exist?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid_theme?(file)
|
39
|
+
valid = false
|
40
|
+
Zip::ZipFile.open(file.path) do |zip|
|
41
|
+
zip.sort.each do |entry|
|
42
|
+
entry.name.split('/').each do |file|
|
43
|
+
valid = true if THEME_STRUCTURE.include?(file)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
valid
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
belongs_to :website
|
52
|
+
|
53
|
+
has_permalink :name, :theme_id, :scope => :website_id,
|
54
|
+
:only_when_blank => false, :sync_url => true
|
55
|
+
|
56
|
+
validates :name, :presence => {:message => 'Name cannot be blank'}
|
57
|
+
validates_uniqueness_of :theme_id, :scope => :website_id
|
58
|
+
|
59
|
+
before_destroy :delete_theme_files!
|
60
|
+
|
61
|
+
def path
|
62
|
+
"#{self.class.base_dir(website)}/#{theme_id}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def url
|
66
|
+
"sites/site-#{website.id}/themes/#{theme_id}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def activate!
|
70
|
+
update_attributes! :active => true
|
71
|
+
end
|
72
|
+
|
73
|
+
def deactivate!
|
74
|
+
update_attributes! :active => false
|
75
|
+
end
|
76
|
+
|
77
|
+
def themed_widgets
|
78
|
+
widgets = []
|
79
|
+
ErpApp::Widgets::Base.installed_widgets.each do |widget_name|
|
80
|
+
widgets << widget_name unless self.files.where("directory like '/#{File.join(self.url, 'widgets', widget_name)}%'").empty?
|
81
|
+
end
|
82
|
+
widgets
|
83
|
+
end
|
84
|
+
|
85
|
+
def non_themed_widgets
|
86
|
+
already_themed_widgets = self.themed_widgets
|
87
|
+
widgets = []
|
88
|
+
ErpApp::Widgets::Base.installed_widgets.each do |widget_name|
|
89
|
+
widgets << widget_name unless already_themed_widgets.include?(widget_name)
|
90
|
+
end
|
91
|
+
widgets
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_layouts_for_widget(widget)
|
95
|
+
file_support = ErpTechSvcs::FileSupport::Base.new
|
96
|
+
views_location = "::Widgets::#{widget.camelize}::Base".constantize.views_location
|
97
|
+
create_theme_files_for_directory_node(file_support.build_tree(views_location, :preload => true), :widgets, :path_to_replace => views_location, :widget_name => widget)
|
98
|
+
end
|
99
|
+
|
100
|
+
def about
|
101
|
+
%w(name author version homepage summary).inject({}) do |result, key|
|
102
|
+
result[key] = send(key)
|
103
|
+
result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def import(file)
|
108
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
109
|
+
file = ActionController::UploadedTempfile.new("uploaded-theme").tap do |f|
|
110
|
+
f.puts file.read
|
111
|
+
f.original_filename = file.original_filename
|
112
|
+
f.read # no idea why we need this here, otherwise the zip can't be opened
|
113
|
+
end unless file.path
|
114
|
+
|
115
|
+
theme_root = Theme.find_theme_root(file)
|
116
|
+
|
117
|
+
Zip::ZipFile.open(file.path) do |zip|
|
118
|
+
zip.each do |entry|
|
119
|
+
if entry.name == 'about.yml'
|
120
|
+
#TODO
|
121
|
+
#FIXME this does not work for some reason
|
122
|
+
data = ''
|
123
|
+
entry.get_input_stream { |io| data = io.read }
|
124
|
+
data = StringIO.new(data) if data.present?
|
125
|
+
about = YAML.load(data)
|
126
|
+
self.author = about['author'] if about['author']
|
127
|
+
self.version = about['version'] if about['version']
|
128
|
+
self.homepage = about['homepage'] if about['homepage']
|
129
|
+
self.summary = about['summary'] if about['summary']
|
130
|
+
else
|
131
|
+
name = entry.name.sub(/__MACOSX\//, '')
|
132
|
+
name = Theme.strip_path(entry.name, theme_root)
|
133
|
+
data = ''
|
134
|
+
entry.get_input_stream { |io| data = io.read }
|
135
|
+
data = StringIO.new(data) if data.present?
|
136
|
+
theme_file = self.files.where("name = ? and directory = ?", File.basename(name), File.join("",self.url,File.dirname(name))).first
|
137
|
+
unless theme_file.nil?
|
138
|
+
theme_file.data = data
|
139
|
+
theme_file.save
|
140
|
+
else
|
141
|
+
self.add_file(data, File.join(file_support.root,self.url,name)) rescue next
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def export
|
149
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
150
|
+
tmp_dir = Theme.make_tmp_dir
|
151
|
+
(tmp_dir + "#{name}[#{theme_id}].zip").tap do |file_name|
|
152
|
+
file_name.unlink if file_name.exist?
|
153
|
+
Zip::ZipFile.open(file_name, Zip::ZipFile::CREATE) do |zip|
|
154
|
+
files.each {|file|
|
155
|
+
contents = file_support.get_contents(File.join(file_support.root,file.directory,file.name))
|
156
|
+
relative_path = file.directory.sub("/#{url}",'')
|
157
|
+
path = FileUtils.mkdir_p(File.join(tmp_dir,relative_path))
|
158
|
+
full_path = File.join(path,file.name)
|
159
|
+
File.open(full_path, 'w+') {|f| f.puts(contents) }
|
160
|
+
zip.add(File.join(relative_path[1..relative_path.length],file.name), full_path) if ::File.exists?(full_path)
|
161
|
+
}
|
162
|
+
::File.open(tmp_dir + 'about.yml', 'w') { |f| f.puts(about.to_yaml) }
|
163
|
+
zip.add('about.yml', tmp_dir + 'about.yml')
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def has_template?(directory, name)
|
169
|
+
self.templates.find{|item| item.directory == File.join(path,directory).gsub(Rails.root.to_s, '') and item.name == name}
|
170
|
+
end
|
171
|
+
|
172
|
+
class << self
|
173
|
+
def find_theme_root(file)
|
174
|
+
theme_root = ''
|
175
|
+
Zip::ZipFile.open(file.path) do |zip|
|
176
|
+
zip.each do |entry|
|
177
|
+
entry.name.sub!(/__MACOSX\//, '')
|
178
|
+
if theme_root = root_in_path(entry.name)
|
179
|
+
break
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
theme_root
|
184
|
+
end
|
185
|
+
|
186
|
+
def root_in_path(path)
|
187
|
+
root_found = false
|
188
|
+
theme_root = ''
|
189
|
+
path.split('/').each do |piece|
|
190
|
+
if piece == 'about.yml' || THEME_STRUCTURE.include?(piece)
|
191
|
+
root_found = true
|
192
|
+
else
|
193
|
+
theme_root += piece + '/' if !piece.match('\.') && !root_found
|
194
|
+
end
|
195
|
+
end
|
196
|
+
root_found ? theme_root : false
|
197
|
+
end
|
198
|
+
|
199
|
+
def strip_path(file_name, path)
|
200
|
+
file_name.sub(path, '')
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def delete_theme_files!
|
205
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
206
|
+
file_support.delete_file(File.join(file_support.root,self.url), :force => true)
|
207
|
+
end
|
208
|
+
|
209
|
+
def create_theme_files!
|
210
|
+
file_support = ErpTechSvcs::FileSupport::Base.new
|
211
|
+
create_theme_files_for_directory_node(file_support.build_tree(BASE_LAYOUTS_VIEWS_PATH, :preload => true), :templates, :path_to_replace => BASE_LAYOUTS_VIEWS_PATH)
|
212
|
+
create_theme_files_for_directory_node(file_support.build_tree(KNITKIT_WEBSITE_STYLESHEETS_PATH, :preload => true), :stylesheets, :path_to_replace => KNITKIT_WEBSITE_STYLESHEETS_PATH)
|
213
|
+
create_theme_files_for_directory_node(file_support.build_tree(KNITKIT_WEBSITE_IMAGES_PATH, :preload => true), :images, :path_to_replace => KNITKIT_WEBSITE_IMAGES_PATH)
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def create_theme_files_for_directory_node(node, type, options={})
|
219
|
+
node[:children].each do |child_node|
|
220
|
+
child_node[:leaf] ? save_theme_file(child_node[:id], type, options) : create_theme_files_for_directory_node(child_node, type, options)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def save_theme_file(path, type, options)
|
225
|
+
contents = IO.read(path)
|
226
|
+
contents.gsub!("../../images/knitkit","../images") unless path.scan('style.css').empty?
|
227
|
+
contents.gsub!("<%= static_stylesheet_link_tag('knitkit/style.css') %>","<%= theme_stylesheet_link_tag('#{self.theme_id}','style.css') %>") unless path.scan('base.html.erb').empty?
|
228
|
+
|
229
|
+
path = case type
|
230
|
+
when :widgets
|
231
|
+
path.gsub(options[:path_to_replace], "/#{self.url}/widgets/#{options[:widget_name]}")
|
232
|
+
else
|
233
|
+
path.gsub(options[:path_to_replace], "/#{self.url}/#{type.to_s}")
|
234
|
+
end
|
235
|
+
|
236
|
+
self.add_file(contents, path)
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
@@ -0,0 +1,457 @@
|
|
1
|
+
class Website < ActiveRecord::Base
|
2
|
+
after_destroy :remove_sites_directory, :remove_website_role
|
3
|
+
after_create :setup_website
|
4
|
+
|
5
|
+
has_file_assets
|
6
|
+
|
7
|
+
has_many :published_websites, :dependent => :destroy
|
8
|
+
has_many :website_hosts, :dependent => :destroy
|
9
|
+
has_many :website_navs, :dependent => :destroy
|
10
|
+
has_many :website_inquiries, :dependent => :destroy
|
11
|
+
|
12
|
+
alias :hosts :website_hosts
|
13
|
+
|
14
|
+
has_many :website_sections, :dependent => :destroy, :order => :lft do
|
15
|
+
def paths
|
16
|
+
collect{|website_section| website_section.paths}.flatten
|
17
|
+
end
|
18
|
+
|
19
|
+
#have to do a sort by to override what awesome nested set does for the order by (lft)
|
20
|
+
def positioned
|
21
|
+
where('parent_id is null').sort_by!(&:position)
|
22
|
+
end
|
23
|
+
|
24
|
+
def update_paths!
|
25
|
+
all.each{|section| section.self_and_descendants.each{|_section| _section.update_path!}}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
alias :sections :website_sections
|
29
|
+
|
30
|
+
has_many :themes, :dependent => :destroy do
|
31
|
+
def active
|
32
|
+
where('active = 1')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def all_section_paths
|
37
|
+
ActiveRecord::Base.connection.execute("select path from website_sections where website_id = #{self.id}").collect{|row| row['path']}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.find_by_host(host)
|
41
|
+
website = nil
|
42
|
+
website_host = WebsiteHost.find_by_host(host)
|
43
|
+
website = website_host.website unless website_host.nil?
|
44
|
+
website
|
45
|
+
end
|
46
|
+
|
47
|
+
def deactivate_themes!
|
48
|
+
themes.each do |theme|
|
49
|
+
theme.deactivate!
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def publish_element(comment, element, version, current_user)
|
54
|
+
self.published_websites.last.publish_element(comment, element, version, current_user)
|
55
|
+
end
|
56
|
+
|
57
|
+
def publish(comment, current_user)
|
58
|
+
self.published_websites.last.publish(comment, current_user)
|
59
|
+
end
|
60
|
+
|
61
|
+
def set_publication_version(version, current_user)
|
62
|
+
PublishedWebsite.activate(self, version, current_user)
|
63
|
+
end
|
64
|
+
|
65
|
+
def active_publication
|
66
|
+
self.published_websites.all.find{|item| item.active}
|
67
|
+
end
|
68
|
+
|
69
|
+
def role
|
70
|
+
Role.iid(website_role_iid)
|
71
|
+
end
|
72
|
+
|
73
|
+
def setup_website
|
74
|
+
PublishedWebsite.create(:website => self, :version => 0, :active => true, :comment => 'New Site Created')
|
75
|
+
Role.create(:description => "Website #{self.title}", :internal_identifier => website_role_iid)
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_sites_directory
|
79
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
80
|
+
begin
|
81
|
+
file_support.delete_file(File.join(file_support.root,"sites/site-#{self.id}"), :force => true)
|
82
|
+
rescue
|
83
|
+
#do nothing it may not exist
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def remove_website_role
|
88
|
+
role.destroy if role
|
89
|
+
end
|
90
|
+
|
91
|
+
def setup_default_pages
|
92
|
+
# create default sections for each widget using widget layout
|
93
|
+
widget_classes = [
|
94
|
+
::Widgets::ContactUs::Base,
|
95
|
+
::Widgets::Search::Base,
|
96
|
+
::Widgets::ManageProfile::Base,
|
97
|
+
::Widgets::Login::Base,
|
98
|
+
::Widgets::Signup::Base,
|
99
|
+
::Widgets::ResetPassword::Base
|
100
|
+
]
|
101
|
+
widget_classes.each do |widget_class|
|
102
|
+
website_section = WebsiteSection.new
|
103
|
+
website_section.title = widget_class.title
|
104
|
+
website_section.in_menu = true unless ["Login", "Sign Up", "Reset Password"].include?(widget_class.title)
|
105
|
+
website_section.layout = widget_class.base_layout
|
106
|
+
website_section.save
|
107
|
+
#make manage profile secured
|
108
|
+
website_section.add_role(self.role) if widget_class.title == 'Manage Profile'
|
109
|
+
self.website_sections << website_section
|
110
|
+
end
|
111
|
+
self.save
|
112
|
+
self.website_sections.update_paths!
|
113
|
+
end
|
114
|
+
|
115
|
+
def export_setup
|
116
|
+
setup_hash = {
|
117
|
+
:name => name,
|
118
|
+
:hosts => hosts.collect(&:host),
|
119
|
+
:title => title,
|
120
|
+
:subtitle => subtitle,
|
121
|
+
:email => email,
|
122
|
+
:auto_activate_publication => auto_activate_publication,
|
123
|
+
:email_inquiries => email_inquiries,
|
124
|
+
:sections => [],
|
125
|
+
:images => [],
|
126
|
+
:files => [],
|
127
|
+
:website_navs => []
|
128
|
+
}
|
129
|
+
|
130
|
+
setup_hash[:sections] = sections.positioned.collect do |website_section|
|
131
|
+
build_section_hash(website_section)
|
132
|
+
end
|
133
|
+
|
134
|
+
setup_hash[:website_navs] = website_navs.collect do |website_nav|
|
135
|
+
{
|
136
|
+
:name => website_nav.name,
|
137
|
+
:items => website_nav.items.positioned.map{|website_nav_item| build_menu_item_hash(website_nav_item)}
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
self.files.where("directory like '%/sites/site-#{self.id}/images%'").all.each do |image_asset|
|
142
|
+
setup_hash[:images] << {:path => image_asset.directory, :name => image_asset.name}
|
143
|
+
end
|
144
|
+
|
145
|
+
self.files.where("directory like '%/sites/site-#{self.id}/file_assets%'").all.each do |file_asset|
|
146
|
+
setup_hash[:files] << {:path => file_asset.directory, :name => file_asset.name}
|
147
|
+
end
|
148
|
+
|
149
|
+
setup_hash
|
150
|
+
end
|
151
|
+
|
152
|
+
def export
|
153
|
+
tmp_dir = Website.make_tmp_dir
|
154
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
155
|
+
|
156
|
+
sections_path = Pathname.new(File.join(tmp_dir,'sections'))
|
157
|
+
FileUtils.mkdir_p(sections_path) unless sections_path.exist?
|
158
|
+
|
159
|
+
articles_path = Pathname.new(File.join(tmp_dir,'articles'))
|
160
|
+
FileUtils.mkdir_p(articles_path) unless articles_path.exist?
|
161
|
+
|
162
|
+
excerpts_path = Pathname.new(File.join(tmp_dir,'excerpts'))
|
163
|
+
FileUtils.mkdir_p(excerpts_path) unless excerpts_path.exist?
|
164
|
+
|
165
|
+
image_assets_path = Pathname.new(File.join(tmp_dir,'images'))
|
166
|
+
FileUtils.mkdir_p(image_assets_path) unless image_assets_path.exist?
|
167
|
+
|
168
|
+
file_assets_path = Pathname.new(File.join(tmp_dir,'files'))
|
169
|
+
FileUtils.mkdir_p(file_assets_path) unless file_assets_path.exist?
|
170
|
+
|
171
|
+
sections.each do |website_section|
|
172
|
+
unless website_section.layout.blank?
|
173
|
+
File.open(File.join(sections_path,"#{website_section.title}.rhtml"), 'w+') {|f| f.puts(website_section.layout) }
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
contents = sections.collect(&:contents).flatten.uniq
|
178
|
+
contents.each do |content|
|
179
|
+
File.open(File.join(articles_path,"#{content.title}.html"), 'w+') {|f| f.puts(content.body_html) }
|
180
|
+
unless content.excerpt_html.blank?
|
181
|
+
File.open(File.join(excerpts_path,"#{content.title}.html"), 'w+') {|f| f.puts(content.excerpt_html) }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
self.files.where("directory like '%/sites/site-#{self.id}/images%'").all.each do |image_asset|
|
186
|
+
contents = file_support.get_contents(File.join(file_support.root,image_asset.directory,image_asset.name))
|
187
|
+
File.open(File.join(image_assets_path,image_asset.name), 'w+') {|f| f.puts(contents) }
|
188
|
+
end
|
189
|
+
|
190
|
+
self.files.where("directory like '%/sites/site-#{self.id}/file_assets%'").all.each do |file_asset|
|
191
|
+
contents = file_support.get_contents(File.join(file_support.root,file_asset.directory,file_asset.name))
|
192
|
+
File.open(File.join(file_assets_path,file_asset.name), 'w+') {|f| f.puts(contents) }
|
193
|
+
end
|
194
|
+
|
195
|
+
files = []
|
196
|
+
|
197
|
+
Dir.entries(sections_path).each do |entry|
|
198
|
+
next if entry =~ /^\./
|
199
|
+
files << {:path => File.join(sections_path,entry), :name => File.join('sections/',File.basename(entry))}
|
200
|
+
end
|
201
|
+
|
202
|
+
Dir.entries(articles_path).each do |entry|
|
203
|
+
next if entry =~ /^\./
|
204
|
+
files << {:path => File.join(articles_path,entry), :name => File.join('articles/',File.basename(entry))}
|
205
|
+
end
|
206
|
+
|
207
|
+
Dir.entries(excerpts_path).each do |entry|
|
208
|
+
next if entry =~ /^\./
|
209
|
+
files << {:path => File.join(excerpts_path,entry), :name => File.join('excerpts/',File.basename(entry))}
|
210
|
+
end
|
211
|
+
|
212
|
+
Dir.entries(image_assets_path).each do |entry|
|
213
|
+
next if entry =~ /^\./
|
214
|
+
files << {:path => File.join(image_assets_path,entry), :name => File.join('images/',File.basename(entry))}
|
215
|
+
end
|
216
|
+
|
217
|
+
Dir.entries(file_assets_path).each do |entry|
|
218
|
+
next if entry =~ /^\./
|
219
|
+
files << {:path => File.join(file_assets_path,entry), :name => File.join('files/',File.basename(entry))}
|
220
|
+
end
|
221
|
+
|
222
|
+
files.uniq!
|
223
|
+
|
224
|
+
(tmp_dir + "#{name}.zip").tap do |file_name|
|
225
|
+
file_name.unlink if file_name.exist?
|
226
|
+
Zip::ZipFile.open(file_name, Zip::ZipFile::CREATE) do |zip|
|
227
|
+
files.each { |file| zip.add(file[:name], file[:path]) if File.exists?(file[:path]) }
|
228
|
+
File.open(tmp_dir + 'setup.yml', 'w') { |f| f.puts(export_setup.to_yaml) }
|
229
|
+
zip.add('setup.yml', tmp_dir + 'setup.yml')
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class << self
|
235
|
+
def make_tmp_dir
|
236
|
+
random = Time.now.to_i.to_s.split('').sort_by { rand }
|
237
|
+
Pathname.new(Rails.root + "/tmp/website_export/tmp_#{random}/").tap do |dir|
|
238
|
+
FileUtils.mkdir_p(dir) unless dir.exist?
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def import(file, current_user)
|
243
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::FileSupport.options[:storage])
|
244
|
+
message = ''
|
245
|
+
success = true
|
246
|
+
|
247
|
+
file = ActionController::UploadedTempfile.new("uploaded-theme").tap do |f|
|
248
|
+
f.puts file.read
|
249
|
+
f.original_filename = file.original_filename
|
250
|
+
f.read # no idea why we need this here, otherwise the zip can't be opened
|
251
|
+
end unless file.path
|
252
|
+
|
253
|
+
entries = []
|
254
|
+
setup_hash = nil
|
255
|
+
|
256
|
+
Zip::ZipFile.open(file.path) do |zip|
|
257
|
+
zip.each do |entry|
|
258
|
+
next if entry.name =~ /__MACOSX\//
|
259
|
+
if entry.name =~ /setup.yml/
|
260
|
+
data = ''
|
261
|
+
entry.get_input_stream { |io| data = io.read }
|
262
|
+
data = StringIO.new(data) if data.present?
|
263
|
+
setup_hash = YAML.load(data)
|
264
|
+
else
|
265
|
+
type = entry.name.split('/')[(entry.name.split('/').count - 2)]
|
266
|
+
name = entry.name.split('/').last
|
267
|
+
next if name.nil?
|
268
|
+
data = ''
|
269
|
+
entry_hash = {:type => type, :name => name}
|
270
|
+
entries << entry_hash unless name == 'sections' || name == 'articles' || name == 'excerpts'
|
271
|
+
entries.uniq!
|
272
|
+
data = entry.get_input_stream.read
|
273
|
+
entry_hash[:data] = data
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
if Website.find_by_name(setup_hash[:name]).nil?
|
279
|
+
website = Website.create(
|
280
|
+
:name => setup_hash[:name],
|
281
|
+
:title => setup_hash[:title],
|
282
|
+
:subtitle => setup_hash[:subtitle],
|
283
|
+
:email => setup_hash[:email],
|
284
|
+
:email_inquiries => setup_hash[:email_inquiries],
|
285
|
+
:auto_activate_publication => setup_hash[:auto_activate_publication]
|
286
|
+
)
|
287
|
+
|
288
|
+
#set default publication published by user
|
289
|
+
first_publication = website.published_websites.first
|
290
|
+
first_publication.published_by = current_user
|
291
|
+
first_publication.save
|
292
|
+
|
293
|
+
begin
|
294
|
+
|
295
|
+
#handle images
|
296
|
+
setup_hash[:images].each do |image_asset|
|
297
|
+
content = entries.find{|entry| entry[:type] == 'images' and entry[:name] == image_asset[:name]}[:data]
|
298
|
+
website.add_file(content, File.join(file_support.root, image_asset[:path].sub(/site-[0-9][0-9]*/, "site-#{website.id}"), image_asset[:name]))
|
299
|
+
end
|
300
|
+
|
301
|
+
#handle files
|
302
|
+
setup_hash[:files].each do |file_asset|
|
303
|
+
content = entries.find{|entry| entry[:type] == 'files' and entry[:name] == file_asset[:name]}[:data]
|
304
|
+
website.add_file(content, File.join(file_support.root, file_asset[:path].sub(/site-[0-9][0-9]*/, "site-#{website.id}"), file_asset[:name]))
|
305
|
+
end
|
306
|
+
|
307
|
+
#handle hosts
|
308
|
+
setup_hash[:hosts].each do |host|
|
309
|
+
website.hosts << WebsiteHost.create(:host => host)
|
310
|
+
website.save
|
311
|
+
end
|
312
|
+
|
313
|
+
#handle sections
|
314
|
+
setup_hash[:sections].each do |section_hash|
|
315
|
+
build_section(section_hash, entries, website)
|
316
|
+
end
|
317
|
+
website.website_sections.update_paths!
|
318
|
+
|
319
|
+
#handle website_navs
|
320
|
+
setup_hash[:website_navs].each do |website_nav_hash|
|
321
|
+
website_nav = WebsiteNav.new(:name => website_nav_hash[:name])
|
322
|
+
website_nav_hash[:items].each do |item|
|
323
|
+
website_nav.website_nav_items << build_menu_item(item)
|
324
|
+
end
|
325
|
+
website.website_navs << website_nav
|
326
|
+
end
|
327
|
+
|
328
|
+
website.publish("Website Imported", current_user)
|
329
|
+
|
330
|
+
rescue Exception=>ex
|
331
|
+
website.destroy unless website.nil?
|
332
|
+
raise ex
|
333
|
+
end
|
334
|
+
|
335
|
+
website.save
|
336
|
+
success = true
|
337
|
+
else
|
338
|
+
message = 'Website already exists with that name'
|
339
|
+
success = false
|
340
|
+
end
|
341
|
+
|
342
|
+
return success, message
|
343
|
+
end
|
344
|
+
|
345
|
+
protected
|
346
|
+
|
347
|
+
def build_menu_item(hash)
|
348
|
+
website_item = WebsiteNavItem.new(
|
349
|
+
:title => hash[:title],
|
350
|
+
:url => hash[:url],
|
351
|
+
:position => hash[:position]
|
352
|
+
)
|
353
|
+
unless hash[:linked_to_item_type].blank?
|
354
|
+
website_item.linked_to_item = WebsiteSection.find_by_path(hash[:linked_to_item_path])
|
355
|
+
end
|
356
|
+
website_item.save
|
357
|
+
hash[:items].each do |item|
|
358
|
+
child_website_item = build_menu_item(item)
|
359
|
+
child_website_item.move_to_child_of(website_item)
|
360
|
+
end
|
361
|
+
unless hash[:roles].empty?
|
362
|
+
hash[:roles].each do |role|
|
363
|
+
website_item.add_role(Role.find_by_internal_identifier(role)) rescue nil #do nothing if the role does not exist
|
364
|
+
end
|
365
|
+
end
|
366
|
+
website_item
|
367
|
+
end
|
368
|
+
|
369
|
+
def build_section(hash, entries, website)
|
370
|
+
klass = hash[:type].constantize
|
371
|
+
section = klass.new(:title => hash[:name], :in_menu => hash[:in_menu], :position => hash[:position])
|
372
|
+
section.permalink = hash[:permalink]
|
373
|
+
section.path = hash[:path]
|
374
|
+
unless entries.find{|entry| entry[:type] == 'sections' and entry[:name] == "#{hash[:name]}.rhtml"}.nil?
|
375
|
+
section.layout = entries.find{|entry| entry[:type] == 'sections' and entry[:name] == "#{hash[:name]}.rhtml"}[:data]
|
376
|
+
end
|
377
|
+
hash[:articles].each do |article_hash|
|
378
|
+
article = Article.find_by_title(article_hash[:name])
|
379
|
+
if article.nil?
|
380
|
+
article = Article.new(:title => article_hash[:name], :display_title => article_hash[:display_title])
|
381
|
+
article.tag_list = article_hash[:tag_list].split(',').collect{|t| t.strip() } unless article_hash[:tag_list].blank?
|
382
|
+
article.body_html = entries.find{|entry| entry[:type] == 'articles' and entry[:name] == "#{article_hash[:name]}.html"}[:data]
|
383
|
+
unless entries.find{|entry| entry[:type] == 'excerpts' and entry[:name] == "#{article_hash[:name]}.html"}.nil?
|
384
|
+
article.excerpt_html = entries.find{|entry| entry[:type] == 'excerpts' and entry[:name] == "#{article_hash[:name]}.html"}[:data]
|
385
|
+
end
|
386
|
+
end
|
387
|
+
section.contents << article
|
388
|
+
section.save
|
389
|
+
article.update_content_area_and_position_by_section(section, article_hash[:content_area], article_hash[:position])
|
390
|
+
end
|
391
|
+
website.website_sections << section
|
392
|
+
section.save
|
393
|
+
hash[:sections].each do |section_hash|
|
394
|
+
child_section = build_section(section_hash, entries, website)
|
395
|
+
child_section.move_to_child_of(section)
|
396
|
+
end
|
397
|
+
unless hash[:roles].empty?
|
398
|
+
hash[:roles].each do |role|
|
399
|
+
section.add_role(Role.find_by_internal_identifier(role)) rescue nil #do nothing if the role does not exist
|
400
|
+
end
|
401
|
+
end
|
402
|
+
section
|
403
|
+
end
|
404
|
+
|
405
|
+
end
|
406
|
+
|
407
|
+
private
|
408
|
+
|
409
|
+
def website_role_iid
|
410
|
+
"website_#{self.name.underscore.gsub("'","").gsub(",","")}_access"
|
411
|
+
end
|
412
|
+
|
413
|
+
def build_section_hash(section)
|
414
|
+
section_hash = {
|
415
|
+
:name => section.title,
|
416
|
+
:has_layout => !section.layout.blank?,
|
417
|
+
:type => section.class.to_s,
|
418
|
+
:in_menu => section.in_menu,
|
419
|
+
:articles => [],
|
420
|
+
:roles => section.roles.collect{|role| role.internal_identifier},
|
421
|
+
:path => section.path,
|
422
|
+
:permalink => section.permalink,
|
423
|
+
:internal_identifier => section.internal_identifier,
|
424
|
+
:position => section.position,
|
425
|
+
:sections => section.children.each.map{|child| build_section_hash(child)}
|
426
|
+
}
|
427
|
+
|
428
|
+
section.contents.each do |content|
|
429
|
+
content_area = content.content_area_by_website_section(section)
|
430
|
+
position = content.position_by_website_section(section)
|
431
|
+
section_hash[:articles] << {
|
432
|
+
:name => content.title,
|
433
|
+
:tag_list => content.tag_list.join(', '),
|
434
|
+
:content_area => content_area,
|
435
|
+
:position => position,
|
436
|
+
:display_title => content.display_title,
|
437
|
+
:internal_identifier => content.internal_identifier
|
438
|
+
}
|
439
|
+
end
|
440
|
+
|
441
|
+
section_hash
|
442
|
+
end
|
443
|
+
|
444
|
+
|
445
|
+
def build_menu_item_hash(menu_item)
|
446
|
+
{
|
447
|
+
:title => menu_item.title,
|
448
|
+
:url => menu_item.url,
|
449
|
+
:roles => menu_item.roles.collect{|role| role.internal_identifier},
|
450
|
+
:linked_to_item_type => menu_item.linked_to_item_type,
|
451
|
+
:linked_to_item_path => menu_item.linked_to_item.nil? ? nil : menu_item.linked_to_item.path,
|
452
|
+
:position => menu_item.position,
|
453
|
+
:items => menu_item.children.collect{|child| build_menu_item_hash(child)}
|
454
|
+
}
|
455
|
+
end
|
456
|
+
|
457
|
+
end
|