trusty-multi-site-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/README.markdown +116 -0
  2. data/Rakefile +120 -0
  3. data/app/assets/images/admin/move_higher.png +0 -0
  4. data/app/assets/images/admin/move_lower.png +0 -0
  5. data/app/assets/images/admin/move_to_bottom.png +0 -0
  6. data/app/assets/images/admin/move_to_top.png +0 -0
  7. data/app/assets/images/admin/remove.png +0 -0
  8. data/app/assets/stylesheets/admin/multi_site.scss +121 -0
  9. data/app/assets/stylesheets/admin/site_chooser.scss +0 -0
  10. data/app/controllers/admin/sites_controller.rb +14 -0
  11. data/app/helpers/scoped_helper.rb +19 -0
  12. data/app/helpers/sites_helper.rb +10 -0
  13. data/app/models/site.rb +86 -0
  14. data/app/views/admin/layouts/_choose_site.html.haml +8 -0
  15. data/app/views/admin/layouts/_site_chooser.html.haml +2 -0
  16. data/app/views/admin/sites/_form.haml +43 -0
  17. data/app/views/admin/sites/edit.haml +7 -0
  18. data/app/views/admin/sites/index.haml +43 -0
  19. data/app/views/admin/sites/new.haml +7 -0
  20. data/app/views/admin/snippets/_choose_site.html.haml +6 -0
  21. data/app/views/admin/users/_choose_site.html.haml +8 -0
  22. data/app/views/site/not_configured.html.haml +7 -0
  23. data/config/initializers/radiant_config.rb +5 -0
  24. data/config/routes.rb +13 -0
  25. data/db/migrate/001_create_sites.rb +13 -0
  26. data/db/migrate/002_add_order_to_sites.rb +9 -0
  27. data/db/migrate/003_add_base_domain_to_sites.rb +9 -0
  28. data/db/migrate/004_add_admin_fields_to_sites.rb +17 -0
  29. data/db/migrate/005_add_sites.rb +13 -0
  30. data/db/migrate/006_remove_user_login_index.rb +8 -0
  31. data/db/migrate/20090810145840_site_abbreviation.rb +9 -0
  32. data/db/migrate/201411031415046078_recreate_non_unique_index_on_snippets_name.rb +11 -0
  33. data/lib/multi_site/admin_ui.rb +46 -0
  34. data/lib/multi_site/application_controller_extensions.rb +40 -0
  35. data/lib/multi_site/application_controller_filter_extensions.rb +21 -0
  36. data/lib/multi_site/engine.rb +5 -0
  37. data/lib/multi_site/page_extensions.rb +43 -0
  38. data/lib/multi_site/pages_controller_extensions.rb +48 -0
  39. data/lib/multi_site/resource_controller_extensions.rb +41 -0
  40. data/lib/multi_site/route_extensions.rb +21 -0
  41. data/lib/multi_site/route_set_extensions.rb +16 -0
  42. data/lib/multi_site/scoped_model.rb +145 -0
  43. data/lib/multi_site/scoped_validation.rb +32 -0
  44. data/lib/multi_site/site_chooser_helper.rb +14 -0
  45. data/lib/multi_site/site_controller_extensions.rb +12 -0
  46. data/lib/tasks/multi_site_extension_tasks.rake +28 -0
  47. data/lib/tasks/scoped_admin_extension_tasks.rake +28 -0
  48. data/lib/trusty-multi-site-extension.rb +1 -0
  49. data/multi_site_extension.rb +66 -0
  50. data/spec/controllers/extended_site_controller_spec.rb +61 -0
  51. data/spec/datasets/site_pages_dataset.rb +13 -0
  52. data/spec/datasets/sites_dataset.rb +10 -0
  53. data/spec/functional/multi_site_routing_spec.rb +37 -0
  54. data/spec/lib/multi_site/admin_ui_spec.rb +35 -0
  55. data/spec/lib/multi_site/scoped_model_spec.rb +182 -0
  56. data/spec/matchers/route_matcher.rb +38 -0
  57. data/spec/models/extended_page_spec.rb +48 -0
  58. data/spec/models/site_spec.rb +83 -0
  59. data/spec/spec.opts +6 -0
  60. data/spec/spec_helper.rb +36 -0
  61. data/trusty-multi-site-extension.gemspec +28 -0
  62. metadata +164 -0
@@ -0,0 +1,13 @@
1
+ class CreateSites < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :sites do |t|
4
+ t.column :name, :string
5
+ t.column :domain, :string
6
+ t.column :homepage_id, :integer
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :sites
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ class AddOrderToSites < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :position, :integer, :default => 0
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sites, :position
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddBaseDomainToSites < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :base_domain, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sites, :base_domain
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ class AddAdminFieldsToSites < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :created_by_id, :integer
4
+ add_column :sites, :created_at, :datetime
5
+ add_column :sites, :updated_by_id, :integer
6
+ add_column :sites, :updated_at, :datetime
7
+ add_column :sites, :subtitle, :string
8
+ end
9
+
10
+ def self.down
11
+ remove_column :sites, :created_by_id
12
+ remove_column :sites, :created_at
13
+ remove_column :sites, :udpated_by_id
14
+ remove_column :sites, :updated_at
15
+ remove_column :sites, :subtitle
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ class AddSites < ActiveRecord::Migration
2
+ def self.up
3
+ [:layouts, :snippets, :users].each do |table|
4
+ add_column table, :site_id, :integer
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ [:layouts, :snippets, :users].each do |table|
10
+ add_column table, :site_id, :integer
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ class RemoveUserLoginIndex < ActiveRecord::Migration
2
+ def self.up
3
+ remove_index "users", :name => "login"
4
+ end
5
+
6
+ def self.down
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ class SiteAbbreviation < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :abbreviation, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sites, :abbreviation
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class RecreateNonUniqueIndexOnSnippetsName < ActiveRecord::Migration
2
+ def self.up
3
+ remove_index :snippets, :name => "name"
4
+ add_index :snippets, [:name, :site_id ], :name => "name_site_id", :unique => true
5
+ end
6
+
7
+ def self.down
8
+ remove_index :snippets, :name => "name_site_id"
9
+ add_index :snippets, :name, :name => "name", :unique => true
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ # This is included into AdminUI and defines editing regions for the site administration pages.
2
+ # Note that the AdminUI object is a singleton and it is not sufficient to add to its initialization routines: you also have to call load_default_site_regions on the admin singleton that has already been defined.
3
+
4
+ module MultiSite::AdminUI
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+
9
+ attr_accessor :site
10
+ alias_method :sites, :site
11
+
12
+ protected
13
+
14
+ # The site-admin pages have these regions:
15
+
16
+ # Edit view:
17
+ # * main: edit_header, edit_form
18
+ # * form: edit_name edit_domain edit_homepage
19
+ # * form_bottom: edit_timestamp edit_buttons
20
+
21
+ # Index view
22
+ # * thead: title_header domain_header basedomain_header modify_header order_header
23
+ # * tbody: title_cell domain_cell basedomain_cell modify_cell order_cell (repeating row)
24
+ # * bottom: new_button
25
+
26
+ def load_default_site_regions
27
+ OpenStruct.new.tap do |site|
28
+ site.edit = TrustyCms::AdminUI::RegionSet.new do |edit|
29
+ edit.main.concat %w{edit_header edit_form}
30
+ edit.form.concat %w{edit_name edit_domain edit_homepage}
31
+ edit.form_bottom.concat %w{edit_timestamp edit_buttons}
32
+ end
33
+ site.index = TrustyCms::AdminUI::RegionSet.new do |index|
34
+ index.thead.concat %w{title_header domain_header basedomain_header modify_header order_header}
35
+ index.tbody.concat %w{title_cell domain_cell basedomain_cell modify_cell order_cell}
36
+ index.bottom.concat %w{new_button}
37
+ end
38
+ site.remove = site.index
39
+ site.new = site.edit
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,40 @@
1
+ module MultiSite::ApplicationControllerExtensions
2
+
3
+ def current_site
4
+ Page.current_site
5
+ end
6
+
7
+ def current_site=(site=nil)
8
+ Page.current_site = site
9
+ end
10
+
11
+ # this is overridden in Admin::ResourceController to respond correctly
12
+
13
+ def sited_model?
14
+ false
15
+ end
16
+
17
+
18
+ def set_site
19
+ true if self.current_site = discover_current_site
20
+ end
21
+
22
+ # chains will attach here
23
+
24
+ def discover_current_site
25
+ site_from_host
26
+ end
27
+
28
+ # and add more ways to determine the current site
29
+
30
+ def site_from_host
31
+ Site.find_for_host(request.host)
32
+ end
33
+
34
+ def self.included(base)
35
+ base.class_eval {
36
+ helper_method :current_site, :current_site=
37
+ }
38
+ end
39
+
40
+ end
@@ -0,0 +1,21 @@
1
+ module MultiSite::ApplicationControllerFilterExtensions
2
+
3
+ def self.included(base)
4
+ base.class_eval {
5
+ prepend_before_filter :set_site
6
+ alias_method_chain :authenticate, :site
7
+ }
8
+ end
9
+
10
+ protected
11
+
12
+ def authenticate_with_site
13
+ self.current_site = discover_current_site
14
+ authenticate_without_site
15
+ end
16
+
17
+ def set_site
18
+ true if self.current_site = discover_current_site
19
+ end
20
+
21
+ end
@@ -0,0 +1,5 @@
1
+ module MultiSite
2
+ class Engine < Rails::Engine
3
+ paths["app/helpers"] = []
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ # Unlike other scoped classes, there is no site association in the Page class. Instead, Site has a homepage association and Page has some retrieval methods that turn a page request into site information.
2
+
3
+ module MultiSite::PageExtensions
4
+ def self.included(base)
5
+ base.class_eval {
6
+ alias_method_chain :url, :sites
7
+ mattr_accessor :current_site
8
+ has_one :site, :foreign_key => "homepage_id", :dependent => :nullify
9
+ }
10
+ base.extend ClassMethods
11
+ class << base
12
+ def find_by_path(path, live=true)
13
+ root = homepage
14
+ raise Page::MissingRootPageError unless root
15
+ root.find_by_path(path, live)
16
+ end
17
+ def current_site
18
+ @current_site ||= Site.default
19
+ end
20
+ def current_site=(site)
21
+ @current_site = site
22
+ end
23
+ end
24
+ end
25
+
26
+ module ClassMethods
27
+ def homepage
28
+ if current_site.is_a?(Site)
29
+ homepage = self.current_site.homepage
30
+ end
31
+ homepage ||= find_by_parent_id(nil)
32
+ end
33
+ end
34
+
35
+ def url_with_sites
36
+ if parent
37
+ parent.child_url(self)
38
+ else
39
+ "/"
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,48 @@
1
+ module MultiSite::PagesControllerExtensions
2
+ def self.included(base)
3
+ base.class_eval {
4
+ alias_method_chain :discover_current_site, :root
5
+ alias_method_chain :index, :site
6
+ alias_method_chain :continue_url, :site
7
+ alias_method_chain :remove, :back
8
+ responses.destroy.default do
9
+ return_url = session[:came_from]
10
+ session[:came_from] = nil
11
+ if model.class == Page
12
+ redirect_to return_url || admin_pages_url(:root => model.root.id)
13
+ else
14
+ redirect_to continue_url(params)
15
+ end
16
+ end
17
+ }
18
+ end
19
+
20
+ # for compatibility with the standard issue of multi_site,
21
+ # a root parameter overrides other ways of setting site
22
+
23
+ def discover_current_site_with_root
24
+ site_from_root || discover_current_site_without_root
25
+ end
26
+
27
+ def site_from_root
28
+ if params[:root] && @homepage = Page.find(params[:root])
29
+ @site = @homepage.root.site
30
+ end
31
+ end
32
+
33
+ def index_with_site
34
+ @site ||= Page.current_site
35
+ @homepage ||= @site.homepage if @site
36
+ @homepage ||= Page.homepage
37
+ response_for :plural
38
+ end
39
+
40
+ def remove_with_back
41
+ session[:came_from] = request.env["HTTP_REFERER"]
42
+ remove_without_back
43
+ end
44
+
45
+ def continue_url_with_site(options={})
46
+ options[:redirect_to] || (params[:continue] ? edit_admin_page_url(model) : admin_pages_url(:root => model.root.id))
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ module MultiSite::ResourceControllerExtensions
2
+
3
+ def self.included(base)
4
+ base.class_eval {
5
+ alias_method_chain :discover_current_site, :input
6
+ }
7
+ end
8
+
9
+ def current_site=(site=nil)
10
+ Page.current_site = site
11
+ set_session_site
12
+ end
13
+
14
+ # among other things this determines whether the site chooser is shown in the submenu
15
+
16
+ def sited_model?
17
+ model_class == Page || model_class.is_site_scoped?
18
+ end
19
+
20
+ protected
21
+
22
+ def discover_current_site_with_input
23
+ site_from_param || site_from_session || discover_current_site_without_input
24
+ end
25
+
26
+ # for interface consistency we want to be able to remember site choices between requests
27
+
28
+ def set_session_site(site_id=nil)
29
+ site_id ||= current_site.id.to_s if current_site.is_a? Site
30
+ session[:site_id] = site_id
31
+ end
32
+
33
+ def site_from_session
34
+ session[:site_id] && Site.find(session[:site_id]) rescue nil
35
+ end
36
+
37
+ def site_from_param
38
+ params[:site_id] && Site.find(params[:site_id]) rescue nil
39
+ end
40
+
41
+ end
@@ -0,0 +1,21 @@
1
+ module MultiSite
2
+ module RouteExtensions
3
+
4
+ def self.included(base)
5
+ base.alias_method_chain(:recognition_conditions, :site)
6
+ end
7
+
8
+ def recognition_conditions_with_site
9
+ result = recognition_conditions_without_site
10
+ if site_names = conditions.delete(:site)
11
+ domains = [*site_names].map{ |site| Regexp.compile(::Site.find_by_name(site).domain) }
12
+ conditions[:site] = Regexp.union(*domains)
13
+ result << "conditions[:site] === env[:site]"
14
+ end
15
+ result
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+ ActionController::Routing::Route.send :include, MultiSite::RouteExtensions
@@ -0,0 +1,16 @@
1
+ module MultiSite
2
+ module RouteSetExtensions
3
+
4
+ def self.included(base)
5
+ base.alias_method_chain :extract_request_environment, :site
6
+ end
7
+
8
+ def extract_request_environment_with_site(request)
9
+ env = extract_request_environment_without_site(request)
10
+ env.merge! :site => request.host
11
+ end
12
+
13
+ end
14
+ end
15
+
16
+ ActionController::Routing::RouteSet.send :include, MultiSite::RouteSetExtensions
@@ -0,0 +1,145 @@
1
+ module MultiSite
2
+
3
+ module ScopedModel
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def is_site_scoped?
10
+ false
11
+ end
12
+
13
+ # only option at the moment is :shareable, which we take to mean that sites are optional:
14
+ # if true it causes us not to set the site automatically or to validate its presence,
15
+ # and to extend the scoping conditions so that objects with no site are returned as
16
+ # well as objects with the specified site
17
+ # that is, anything without a site is considered to be shared among all sites
18
+ # the default is false
19
+
20
+ def is_site_scoped(options={})
21
+ return if is_site_scoped?
22
+
23
+ options = {
24
+ :shareable => false
25
+ }.merge(options)
26
+
27
+ class_eval <<-EO
28
+ extend MultiSite::ScopedModel::ScopedClassMethods
29
+ include MultiSite::ScopedModel::ScopedInstanceMethods
30
+ EO
31
+
32
+ belongs_to :site
33
+ Site.send(:has_many, plural_symbol_for_class)
34
+
35
+ before_validation :set_site
36
+ validates_presence_of :site unless options[:shareable]
37
+
38
+ class << self
39
+ attr_accessor :shareable
40
+ alias_method_chain :all, :site
41
+ alias_method_chain :where, :site
42
+ alias_method_chain :paginate, :site
43
+ %w{count average minimum maximum sum}.each do |getter|
44
+ alias_method_chain getter.intern, :site
45
+ end
46
+ end
47
+
48
+ self.shareable = options[:shareable]
49
+ end
50
+ end
51
+
52
+ module ScopedClassMethods
53
+ def all_with_site(options = {})
54
+ return all_without_site(options) unless sites?
55
+ with_scope(:find => {:conditions => site_scope_condition}) do
56
+ all_without_site(options)
57
+ end
58
+ end
59
+
60
+ def where_with_site(options = {})
61
+ return where_without_site(options) unless sites?
62
+ with_scope(:find => {:conditions => site_scope_condition}) do
63
+ where_without_site(options)
64
+ end
65
+ end
66
+
67
+ def paginate_with_site(options={})
68
+ return paginate_without_site(options) unless sites?
69
+ with_scope(:find => {:conditions => site_scope_condition}) do
70
+ paginate_without_site(options)
71
+ end
72
+ end
73
+
74
+ %w{count average minimum maximum sum}.each do |getter|
75
+ define_method("#{getter}_with_site") do |*args|
76
+ return send("#{getter}_without_site".intern, *args) unless sites?
77
+ with_scope(:find => {:conditions => site_scope_condition}) do
78
+ send "#{getter}_without_site".intern, *args
79
+ end
80
+ end
81
+ end
82
+
83
+ # this only works with :all and :first
84
+ # and should only be used in odd cases like migration.
85
+ def find_without_site(*args)
86
+ options = args.extract_options!
87
+ #set_readonly_option!(options)
88
+
89
+ case args.first
90
+ when :first then find_initial_without_site(options) # defined here
91
+ when :all then all_without_site(options) # already defined by the alias chain
92
+ end
93
+ end
94
+
95
+ def find_initial_without_site(options)
96
+ options.update(:limit => 1)
97
+ all_without_site(options).first
98
+ end
99
+
100
+ def sites?
101
+ Site.table_exists? && Site.several?
102
+ end
103
+
104
+ def current_site!
105
+ raise(ActiveRecord::SiteNotFound, "#{self} is site-scoped but current_site is #{self.current_site.inspect}", caller) if sites? && !self.current_site && !self.is_shareable?
106
+ self.current_site
107
+ end
108
+
109
+ def current_site
110
+ Page.current_site
111
+ end
112
+
113
+ def site_scope_condition
114
+ if self.shareable
115
+ condition = ""
116
+ condition << "#{self.table_name}.site_id = #{self.current_site.id} OR " if self.current_site
117
+ condition << "#{self.table_name}.site_id IS NULL"
118
+ else
119
+ condition = "#{self.table_name}.site_id = #{self.current_site!.id}"
120
+ end
121
+ condition
122
+ end
123
+
124
+ def plural_symbol_for_class
125
+ self.to_s.pluralize.underscore.intern
126
+ end
127
+
128
+ def is_site_scoped?
129
+ true
130
+ end
131
+
132
+ def is_shareable?
133
+ !!self.shareable
134
+ end
135
+ end
136
+
137
+ module ScopedInstanceMethods
138
+ protected
139
+ def set_site
140
+ self.site ||= self.class.current_site! unless self.class.is_shareable?
141
+ end
142
+ end
143
+ end
144
+ end
145
+
@@ -0,0 +1,32 @@
1
+ module MultiSite::ScopedValidation
2
+
3
+ def self.included(base)
4
+
5
+ base.class_eval do
6
+ # scoping validations to the site should be very simple
7
+ # all you would normally need is something like this:
8
+ #
9
+ # validates_uniqueness_of :email, :scope => :site_id
10
+ #
11
+ # but if you want to scope core trusty classes, you have a problem:
12
+ # their uniqueness validations have already been declared
13
+ # The only answer is to reach right back and change the validates_uniqueness_of method
14
+ # and to make it more awkward, that has to happen so early that we can't reflect on the site association.
15
+ # Hence the check for a site_id column. It's a hack, but a fairly harmless one.
16
+
17
+ def validates_uniqueness_of_with_site(*attr)
18
+ if table_exists? && column_names.include?('site_id')
19
+ configuration = attr.extract_options!
20
+ configuration[:scope] ||= :site_id
21
+ attr.push(configuration)
22
+ end
23
+ validates_uniqueness_of_without_site(*attr)
24
+ end
25
+
26
+ alias_method_chain :validates_uniqueness_of, :site
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ ActiveRecord::Validations::ClassMethods.send :include, MultiSite::ScopedValidation
@@ -0,0 +1,14 @@
1
+ module MultiSite::SiteChooserHelper
2
+
3
+ def sites_chooser_thing
4
+ return "" unless admin? && defined?(Site) && defined?(controller) && controller.sited_model? && controller.template_name == 'index' && Site.several?
5
+ options = Site.find(:all).map{ |site| "<li>" + link_to( site.name, "#{request.path}?site_id=#{site.id}", :class => site == current_site ? 'fg' : '') + "</li>" }.join("")
6
+ chooser = %{<div id="site_chooser">}
7
+ #chooser << link_to("sites", admin_sites_url, {:id => 'show_site_list', :class => 'expandable'})
8
+ chooser << %{<ul id="nav"><li>Current Site: #{current_site.name}}
9
+ chooser << %{<ul class="expansion">#{options}</ul></li></ul>}
10
+ chooser << %{</div>}
11
+ chooser
12
+ end
13
+
14
+ end
@@ -0,0 +1,12 @@
1
+ module MultiSite::SiteControllerExtensions
2
+ def self.included(base)
3
+ base.class_eval do
4
+ before_filter :set_site
5
+ end
6
+ end
7
+
8
+ def set_site
9
+ Page.current_site = Site.find_for_host(request.host)
10
+ true
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ namespace :trusty do
2
+ namespace :extensions do
3
+ namespace :multi_site do
4
+
5
+ desc "Runs the migration of the Multi Site extension"
6
+ task :migrate => :environment do
7
+ require 'trusty_cms/extension_migrator'
8
+ if ENV["VERSION"]
9
+ MultiSiteExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ MultiSiteExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Multi Site to the instance public/ directory."
16
+ task :update => :environment do
17
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
18
+ puts "Copying assets from MultiSiteExtension"
19
+ Dir[MultiSiteExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(MultiSiteExtension.root, '')
21
+ directory = File.dirname(path)
22
+ mkdir_p RAILS_ROOT + directory, :verbose => false
23
+ cp file, RAILS_ROOT + path, :verbose => false
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :scoped_admin do
4
+
5
+ desc "Runs the migration of the Scoped Admin extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ ScopedAdminExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ ScopedAdminExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Scoped Admin to the instance public/ directory."
16
+ task :update => :environment do
17
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
18
+ puts "Copying assets from ScopedAdminExtension"
19
+ Dir[ScopedAdminExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(ScopedAdminExtension.root, '')
21
+ directory = File.dirname(path)
22
+ mkdir_p RAILS_ROOT + directory
23
+ cp file, RAILS_ROOT + path
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1 @@
1
+ # Nothing to see here