spontaneous 0.2.0.beta4 → 0.2.0.beta5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/Gemfile +11 -6
- data/Readme.markdown +136 -69
- data/application/css/core.css.scss +27 -7
- data/application/css/editing.css.scss +4 -26
- data/application/css/schema_error.css.scss +22 -0
- data/application/js/content.js +11 -3
- data/application/js/edit_panel.js +1 -4
- data/application/js/field/file.js +17 -0
- data/application/js/field/image.js +30 -21
- data/application/js/field/string.js +4 -1
- data/application/js/field_preview.js +21 -16
- data/application/js/publish.js +6 -6
- data/application/js/types.js +5 -13
- data/application/js/views.js +2 -2
- data/application/js/views/box_view.js +3 -2
- data/application/js/views/page_piece_view.js +1 -1
- data/application/js/views/piece_view.js +1 -1
- data/application/views/schema_modification_error.html.erb +13 -3
- data/db/migrations/20131104101935_site_must_publish_all.rb +14 -0
- data/lib/spontaneous.rb +0 -1
- data/lib/spontaneous/box_style.rb +15 -9
- data/lib/spontaneous/capistrano/deploy.rb +13 -1
- data/lib/spontaneous/change.rb +11 -13
- data/lib/spontaneous/cli.rb +5 -2
- data/lib/spontaneous/cli/assets.rb +7 -1
- data/lib/spontaneous/cli/console.rb +7 -1
- data/lib/spontaneous/cli/content.rb +35 -0
- data/lib/spontaneous/cli/fields.rb +3 -2
- data/lib/spontaneous/cli/generate.rb +5 -2
- data/lib/spontaneous/cli/server.rb +12 -8
- data/lib/spontaneous/cli/site.rb +12 -12
- data/lib/spontaneous/cli/user.rb +28 -14
- data/lib/spontaneous/collections/box_set.rb +4 -4
- data/lib/spontaneous/collections/field_set.rb +4 -4
- data/lib/spontaneous/collections/prototype_set.rb +12 -4
- data/lib/spontaneous/data_mapper.rb +11 -7
- data/lib/spontaneous/data_mapper/content_model.rb +8 -0
- data/lib/spontaneous/data_mapper/content_model/associations.rb +1 -1
- data/lib/spontaneous/data_mapper/dataset.rb +14 -2
- data/lib/spontaneous/data_mapper/scope.rb +33 -13
- data/lib/spontaneous/facet.rb +4 -0
- data/lib/spontaneous/field.rb +12 -12
- data/lib/spontaneous/field/base.rb +27 -22
- data/lib/spontaneous/field/boolean.rb +4 -4
- data/lib/spontaneous/field/date.rb +2 -2
- data/lib/spontaneous/field/file.rb +24 -18
- data/lib/spontaneous/field/html.rb +1 -1
- data/lib/spontaneous/field/image.rb +6 -19
- data/lib/spontaneous/field/location.rb +1 -1
- data/lib/spontaneous/field/long_string.rb +3 -3
- data/lib/spontaneous/field/markdown.rb +3 -3
- data/lib/spontaneous/field/select.rb +2 -2
- data/lib/spontaneous/field/string.rb +2 -2
- data/lib/spontaneous/field/tags.rb +2 -2
- data/lib/spontaneous/field/update.rb +21 -20
- data/lib/spontaneous/field/webvideo.rb +6 -6
- data/lib/spontaneous/field/webvideo/fallback.rb +2 -2
- data/lib/spontaneous/field/webvideo/vimeo.rb +7 -7
- data/lib/spontaneous/generators/site.rb +2 -2
- data/lib/spontaneous/generators/site/Gemfile.tt +5 -1
- data/lib/spontaneous/layout.rb +2 -2
- data/lib/spontaneous/media.rb +1 -0
- data/lib/spontaneous/media/file.rb +6 -5
- data/lib/spontaneous/media/image/attributes.rb +4 -0
- data/lib/spontaneous/media/image/renderable.rb +4 -4
- data/lib/spontaneous/media/store.rb +22 -0
- data/lib/spontaneous/{storage → media/store}/backend.rb +1 -1
- data/lib/spontaneous/{storage → media/store}/cloud.rb +1 -1
- data/lib/spontaneous/{storage → media/store}/local.rb +1 -1
- data/lib/spontaneous/media/temp_file.rb +1 -1
- data/lib/spontaneous/model.rb +10 -7
- data/lib/spontaneous/model/action.rb +7 -0
- data/lib/spontaneous/model/action/clean.rb +87 -0
- data/lib/spontaneous/model/box/allowed_types.rb +15 -1
- data/lib/spontaneous/model/core.rb +10 -0
- data/lib/spontaneous/model/core/aliases.rb +1 -1
- data/lib/spontaneous/model/core/content_groups.rb +1 -1
- data/lib/spontaneous/model/core/fields.rb +1 -1
- data/lib/spontaneous/model/core/modifications.rb +2 -2
- data/lib/spontaneous/model/core/page_search.rb +4 -0
- data/lib/spontaneous/model/core/publishing.rb +4 -17
- data/lib/spontaneous/model/core/render.rb +4 -4
- data/lib/spontaneous/model/core/styles.rb +2 -2
- data/lib/spontaneous/model/core/visibility.rb +6 -2
- data/lib/spontaneous/model/page.rb +6 -2
- data/lib/spontaneous/model/page/controllers.rb +55 -17
- data/lib/spontaneous/model/page/formats.rb +12 -7
- data/lib/spontaneous/model/page/layouts.rb +2 -2
- data/lib/spontaneous/model/page/locks.rb +4 -1
- data/lib/spontaneous/model/page/page_tree.rb +40 -6
- data/lib/spontaneous/output.rb +14 -52
- data/lib/spontaneous/output/context.rb +11 -39
- data/lib/spontaneous/output/context/navigation.rb +31 -0
- data/lib/spontaneous/output/format.rb +15 -19
- data/lib/spontaneous/output/renderable.rb +99 -0
- data/lib/spontaneous/output/store.rb +24 -0
- data/lib/spontaneous/output/store/backend.rb +52 -0
- data/lib/spontaneous/output/store/file.rb +77 -0
- data/lib/spontaneous/output/store/moneta.rb +117 -0
- data/lib/spontaneous/output/store/revision.rb +34 -0
- data/lib/spontaneous/output/store/store.rb +15 -0
- data/lib/spontaneous/output/store/transaction.rb +44 -0
- data/lib/spontaneous/output/template/engine.rb +17 -7
- data/lib/spontaneous/output/template/renderer.rb +66 -40
- data/lib/spontaneous/page_lock.rb +5 -7
- data/lib/spontaneous/page_piece.rb +2 -2
- data/lib/spontaneous/permissions/user.rb +14 -7
- data/lib/spontaneous/plugins/application/features.rb +8 -4
- data/lib/spontaneous/plugins/application/state.rb +12 -6
- data/lib/spontaneous/prototypes/box_prototype.rb +9 -10
- data/lib/spontaneous/prototypes/field_prototype.rb +66 -15
- data/lib/spontaneous/publishing/immediate.rb +30 -26
- data/lib/spontaneous/rack.rb +12 -7
- data/lib/spontaneous/rack/back.rb +43 -37
- data/lib/spontaneous/rack/back/base.rb +4 -4
- data/lib/spontaneous/rack/back/changes.rb +2 -2
- data/lib/spontaneous/rack/back/file.rb +16 -24
- data/lib/spontaneous/rack/back/map.rb +5 -5
- data/lib/spontaneous/rack/back/preview.rb +3 -4
- data/lib/spontaneous/rack/back/schema.rb +1 -1
- data/lib/spontaneous/rack/back/site.rb +6 -7
- data/lib/spontaneous/rack/front.rb +19 -16
- data/lib/spontaneous/rack/middleware/authenticate.rb +3 -3
- data/lib/spontaneous/rack/middleware/reloader.rb +3 -2
- data/lib/spontaneous/rack/middleware/scope.rb +25 -19
- data/lib/spontaneous/rack/page_controller.rb +164 -13
- data/lib/spontaneous/rack/public.rb +23 -62
- data/lib/spontaneous/rack/static.rb +2 -3
- data/lib/spontaneous/schema.rb +27 -8
- data/lib/spontaneous/schema/schema_modification.rb +9 -1
- data/lib/spontaneous/schema/uid.rb +2 -2
- data/lib/spontaneous/schema/uid_map.rb +3 -2
- data/lib/spontaneous/search/database.rb +2 -2
- data/lib/spontaneous/search/field.rb +5 -3
- data/lib/spontaneous/search/index.rb +12 -7
- data/lib/spontaneous/search/results.rb +5 -3
- data/lib/spontaneous/server.rb +2 -2
- data/lib/spontaneous/site.rb +10 -3
- data/lib/spontaneous/site/features.rb +26 -6
- data/lib/spontaneous/site/helpers.rb +9 -12
- data/lib/spontaneous/site/level.rb +7 -9
- data/lib/spontaneous/site/map.rb +9 -11
- data/lib/spontaneous/site/paths.rb +5 -5
- data/lib/spontaneous/site/publishing.rb +83 -80
- data/lib/spontaneous/site/schema.rb +1 -7
- data/lib/spontaneous/site/search.rb +8 -18
- data/lib/spontaneous/site/selectors.rb +60 -54
- data/lib/spontaneous/site/state.rb +36 -30
- data/lib/spontaneous/site/storage.rb +10 -16
- data/lib/spontaneous/state.rb +8 -0
- data/lib/spontaneous/style.rb +32 -33
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +22 -21
- data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
- data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
- data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
- data/test/fixtures/search/config/indexes.rb +1 -1
- data/test/fixtures/serialisation/class_hash.yaml.erb +13 -1
- data/test/fixtures/serialisation/root_hash.yaml.erb +10 -0
- data/test/functional/test_application.rb +20 -24
- data/test/functional/test_back.rb +26 -27
- data/test/functional/test_cli.rb +146 -0
- data/test/functional/test_front.rb +287 -216
- data/test/functional/test_user_manager.rb +1 -1
- data/test/test_helper.rb +15 -11
- data/test/unit/test_alias.rb +32 -25
- data/test/unit/test_asset_bundler.rb +1 -1
- data/test/unit/test_assets.rb +34 -33
- data/test/unit/test_authentication.rb +1 -1
- data/test/unit/test_boxes.rb +16 -2
- data/test/unit/test_changesets.rb +23 -11
- data/test/unit/test_content.rb +15 -0
- data/test/unit/test_context.rb +139 -0
- data/test/unit/test_controllers.rb +374 -0
- data/test/{experimental → unit}/test_crypt.rb +0 -0
- data/test/unit/test_datamapper.rb +260 -237
- data/test/unit/test_datamapper_content.rb +42 -12
- data/test/{experimental → unit}/test_features.rb +85 -3
- data/test/unit/test_fields.rb +117 -42
- data/test/unit/test_formats.rb +11 -1
- data/test/unit/test_generators.rb +2 -2
- data/test/unit/test_helpers.rb +7 -8
- data/test/unit/test_images.rb +39 -2
- data/test/unit/test_layouts.rb +14 -12
- data/test/unit/test_media.rb +32 -23
- data/test/unit/test_output_store.rb +342 -0
- data/test/unit/test_page.rb +8 -1
- data/test/unit/test_permissions.rb +11 -7
- data/test/unit/test_plugins.rb +3 -3
- data/test/unit/test_prototype_set.rb +8 -1
- data/test/unit/test_publishing.rb +67 -54
- data/test/unit/test_render.rb +91 -38
- data/test/unit/test_revisions.rb +4 -4
- data/test/unit/test_schema.rb +109 -84
- data/test/unit/test_search.rb +42 -42
- data/test/unit/test_serialisation.rb +3 -2
- data/test/unit/test_site.rb +39 -27
- data/test/unit/test_storage.rb +9 -6
- data/test/unit/test_styles.rb +25 -32
- data/test/unit/test_templates.rb +8 -4
- metadata +89 -54
- data/lib/spontaneous/model/page/request.rb +0 -105
- data/lib/spontaneous/storage.rb +0 -22
@@ -7,8 +7,8 @@ module Spontaneous::Field
|
|
7
7
|
"fallback"
|
8
8
|
end
|
9
9
|
|
10
|
-
def to_html(
|
11
|
-
params = player_attributes(
|
10
|
+
def to_html(locals = {})
|
11
|
+
params = player_attributes(locals)
|
12
12
|
attributes = hash_to_attributes(params[:attr])
|
13
13
|
%(<iframe #{attributes}></iframe>)
|
14
14
|
end
|
@@ -25,18 +25,18 @@ module Spontaneous::Field
|
|
25
25
|
response = \
|
26
26
|
begin
|
27
27
|
open(url).read
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
rescue => e
|
29
|
+
logger.error("Unable to retrieve metadata for video ##{video_id} from Vimeo: '#{e}'")
|
30
|
+
fallback_response
|
31
|
+
end
|
32
32
|
metadata = Spontaneous.parse_json(response) rescue [{}]
|
33
|
-
metadata = metadata.first || {}
|
33
|
+
metadata = (metadata || [{}]).first || {}
|
34
34
|
end
|
35
35
|
|
36
36
|
def to_html(options = {})
|
37
37
|
params = player_attributes(options)
|
38
38
|
attributes = hash_to_attributes(params[:attr])
|
39
|
-
|
39
|
+
"<iframe #{attributes}></iframe>"
|
40
40
|
end
|
41
41
|
|
42
42
|
def as_json(options = {})
|
@@ -101,7 +101,7 @@ module Spontaneous::Field
|
|
101
101
|
"autoplay" => o[:autoplay],
|
102
102
|
"loop" => o[:loop],
|
103
103
|
"api" => o[:api],
|
104
|
-
|
104
|
+
"player_id" => o[:player_id] }
|
105
105
|
params.update("color" => o[:color]) if o.key?(:color)
|
106
106
|
params = ::Rack::Utils.build_query(params)
|
107
107
|
"http://player.vimeo.com/video/#{video_id}?#{params}"
|
@@ -6,8 +6,8 @@ module Spontaneous
|
|
6
6
|
module Generators
|
7
7
|
class Site < Thor::Group
|
8
8
|
def self.available_dbs
|
9
|
-
postgres = { :gem => "
|
10
|
-
{ "mysql"
|
9
|
+
postgres = { :gem => "sequel_pg", :adapter => "postgres", :user => nil }
|
10
|
+
{ "mysql" => { :gem => "mysql2", :adapter => "mysql2", :user => "root" },
|
11
11
|
"pg" => postgres, "postgresql" => postgres, "postgres" => postgres }
|
12
12
|
end
|
13
13
|
|
@@ -5,7 +5,11 @@ gem 'spontaneous', '~> <%= Spontaneous::VERSION %>'
|
|
5
5
|
# Or point it at a git repository to use the cutting edge or your custom version
|
6
6
|
# gem 'spontaneous', :git => "https://github.com/SpontaneousCMS/spontaneous.git"
|
7
7
|
|
8
|
-
gem '<%= @database[:gem].name %>', '<%= @database[:gem].requirement %>'
|
8
|
+
gem '<%= @database[:gem].name %>', '<%= @database[:gem].requirement %>'<%
|
9
|
+
if (requires = @database[:gem].autorequire) && (requires.length > 0)
|
10
|
+
requires = requires.first if requires.length == 1 -%>
|
11
|
+
, require: '<%= requires %>'
|
12
|
+
<%- end -%>
|
9
13
|
|
10
14
|
# Your favorite ExecJS compatible engine
|
11
15
|
gem 'therubyracer', '~> 0.11.1'
|
data/lib/spontaneous/layout.rb
CHANGED
@@ -11,7 +11,7 @@ module Spontaneous
|
|
11
11
|
# matching the class of our owner, then default to the 'standard'
|
12
12
|
# layout.
|
13
13
|
def try_paths
|
14
|
-
named_layout =
|
14
|
+
named_layout = to_directory_name(owner)
|
15
15
|
[["layouts", named_layout], ["layouts", "standard"]]
|
16
16
|
end
|
17
17
|
end
|
@@ -21,7 +21,7 @@ module Spontaneous
|
|
21
21
|
@templates = templates
|
22
22
|
end
|
23
23
|
|
24
|
-
def template(format = :html)
|
24
|
+
def template(format = :html, renderer)
|
25
25
|
template = @templates[format]
|
26
26
|
# a layout without a format is used as a fallback
|
27
27
|
template ||= @templates[nil]
|
data/lib/spontaneous/media.rb
CHANGED
@@ -8,9 +8,10 @@ module Spontaneous::Media
|
|
8
8
|
|
9
9
|
attr_reader :filename, :owner, :source
|
10
10
|
|
11
|
-
def initialize(owner, filename, headers = {})
|
11
|
+
def initialize(site, owner, filename, headers = {})
|
12
12
|
headers = { content_type: headers } if headers.is_a?(String)
|
13
|
-
|
13
|
+
headers ||= {}
|
14
|
+
@site, @owner, @filename, @headers = site, owner, Spontaneous::Media.to_filename(filename), headers
|
14
15
|
end
|
15
16
|
|
16
17
|
# Create a new File instance with a new name.
|
@@ -20,7 +21,7 @@ module Spontaneous::Media
|
|
20
21
|
def rename(new_filename)
|
21
22
|
headers = storage_headers
|
22
23
|
headers.delete(:content_type)
|
23
|
-
self.class.new(owner, new_filename, headers)
|
24
|
+
self.class.new(@site, owner, new_filename, headers)
|
24
25
|
end
|
25
26
|
|
26
27
|
def open(mode = 'wb', &block)
|
@@ -58,7 +59,7 @@ module Spontaneous::Media
|
|
58
59
|
end
|
59
60
|
|
60
61
|
def storage
|
61
|
-
@storage ||=
|
62
|
+
@storage ||= @site.storage(mimetype)
|
62
63
|
end
|
63
64
|
|
64
65
|
def padded_id
|
@@ -70,7 +71,7 @@ module Spontaneous::Media
|
|
70
71
|
end
|
71
72
|
|
72
73
|
def revision
|
73
|
-
|
74
|
+
@site.working_revision
|
74
75
|
end
|
75
76
|
|
76
77
|
def media_dir
|
@@ -3,10 +3,10 @@ module Spontaneous::Media::Image
|
|
3
3
|
module Renderable
|
4
4
|
attr_accessor :template_params
|
5
5
|
|
6
|
-
def render(format=:html,
|
6
|
+
def render(format=:html, params = {}, parent_context = nil)
|
7
7
|
case format
|
8
8
|
when "html", :html
|
9
|
-
to_html(
|
9
|
+
to_html(params)
|
10
10
|
else
|
11
11
|
value
|
12
12
|
end
|
@@ -19,8 +19,8 @@ module Spontaneous::Media::Image
|
|
19
19
|
:height => height,
|
20
20
|
:alt => ""
|
21
21
|
}
|
22
|
-
default_attr.delete(:width) if width.nil?
|
23
|
-
default_attr.delete(:height) if height.nil?
|
22
|
+
default_attr.delete(:width) if (width.nil? || width == 0)
|
23
|
+
default_attr.delete(:height) if (height.nil? || height == 0)
|
24
24
|
if template_params && template_params.length > 0 && template_params[0].is_a?(Hash)
|
25
25
|
attr = template_params[0].merge(attr)
|
26
26
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Spontaneous::Media
|
4
|
+
module Store
|
5
|
+
autoload :Backend, "spontaneous/media/store/backend"
|
6
|
+
autoload :Local, "spontaneous/media/store/local"
|
7
|
+
autoload :Cloud, "spontaneous/media/store/cloud"
|
8
|
+
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def create(config)
|
12
|
+
case config[:provider]
|
13
|
+
when "Local", "local"
|
14
|
+
Local.new(config[:local_root], config[:url], config[:accepts])
|
15
|
+
else
|
16
|
+
bucket = config.delete(:bucket)
|
17
|
+
accepts = config.delete(:accepts)
|
18
|
+
Cloud.new(config, bucket, accepts)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/spontaneous/model.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
module Spontaneous
|
2
2
|
|
3
3
|
module Model
|
4
|
-
autoload :Core,
|
5
|
-
autoload :Page,
|
6
|
-
autoload :Piece,
|
7
|
-
autoload :Box,
|
4
|
+
autoload :Core, "spontaneous/model/core"
|
5
|
+
autoload :Page, "spontaneous/model/page"
|
6
|
+
autoload :Piece, "spontaneous/model/piece"
|
7
|
+
autoload :Box, "spontaneous/model/box"
|
8
|
+
autoload :Action, "spontaneous/model/action"
|
8
9
|
end
|
9
10
|
|
10
11
|
def self.models
|
11
12
|
@models ||= {}
|
12
13
|
end
|
13
14
|
|
14
|
-
def self.Model(table_name
|
15
|
-
|
15
|
+
def self.Model(table_name)
|
16
|
+
Model!(table_name, Spontaneous.database, Spontaneous.instance.schema)
|
16
17
|
end
|
17
18
|
|
18
|
-
def self.
|
19
|
+
def self.Model!(table_name, database, schema)
|
19
20
|
model = Spontaneous::DataMapper::Model(table_name, database, schema) do
|
20
21
|
serialize_columns :field_store, :entry_store, :box_store, :serialized_modifications
|
21
22
|
include_all_types
|
@@ -42,6 +43,8 @@ module Spontaneous
|
|
42
43
|
class_variable_get(:@@content_model)
|
43
44
|
end
|
44
45
|
|
46
|
+
alias_method :model, :content_model
|
47
|
+
|
45
48
|
# This is fiddly because we want the Content.content_model to refer to the
|
46
49
|
# first subclass of the Spontaneous::Content call as that is going to be our
|
47
50
|
# ::Content model. In this particular instance I want the behaviour of Ruby's
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module Spontaneous::Model::Action
|
6
|
+
# Designed to be run after any schema modifications that delete types or boxes
|
7
|
+
# this action deletes all instances with invalid type ids and then cleans
|
8
|
+
# up the remaining content by testing the visibility path of each remaining instance
|
9
|
+
# and deletes any that are 'orphaned' i.e. they have a hole in their ancestry.
|
10
|
+
#
|
11
|
+
# This would normally be managed by the recursive destroy but when we're dealing
|
12
|
+
# with content that has no matching schema type it's hard to instantiate them & hence
|
13
|
+
# hard to invoke a destroy (and we resort to db level deletes)
|
14
|
+
#
|
15
|
+
# This is an argument for moving hierarcy maintenance into db level triggers
|
16
|
+
# rather than keeping them at the ORM level.
|
17
|
+
class Clean
|
18
|
+
extend Spontaneous::Concern
|
19
|
+
|
20
|
+
def self.run(site)
|
21
|
+
new(site).run
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :stats
|
25
|
+
|
26
|
+
def initialize(site)
|
27
|
+
@site = site
|
28
|
+
@model = site.model
|
29
|
+
@dirty = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
stats = {}
|
34
|
+
@model.db.transaction do
|
35
|
+
stats[:invalid] = delete_invalid_type_instances
|
36
|
+
stats[:orphans] = delete_orphans
|
37
|
+
stats[:publish] = configure_force_publish
|
38
|
+
end
|
39
|
+
stats
|
40
|
+
end
|
41
|
+
|
42
|
+
# Delete all instances whose schema id is invalid
|
43
|
+
def delete_invalid_type_instances
|
44
|
+
invalid = mapper.filter(nil).invert
|
45
|
+
count = invalid.delete
|
46
|
+
@dirty ||= (count > 0)
|
47
|
+
count
|
48
|
+
end
|
49
|
+
|
50
|
+
# Delete all orphaned content items i.e. entries that have an ancestor
|
51
|
+
# who is missing, probably as a result of a schema type deletion
|
52
|
+
def delete_orphans
|
53
|
+
count = 0
|
54
|
+
mapper.dataset.each do |content|
|
55
|
+
unless valid_path?(content)
|
56
|
+
content.destroy
|
57
|
+
count += 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@dirty ||= (count > 0)
|
61
|
+
count
|
62
|
+
end
|
63
|
+
|
64
|
+
# If we've deleted content items at the db level then we need to force
|
65
|
+
# a full publish to reset our change tracking and make sure the live
|
66
|
+
# site is a proper reflection of the edited content
|
67
|
+
def configure_force_publish
|
68
|
+
@site.must_publish_all! if @dirty
|
69
|
+
@site.must_publish_all?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Use our set of existing ids to check that every entry in an instance's
|
73
|
+
# visibility path exists.
|
74
|
+
def valid_path?(content)
|
75
|
+
content.visibility_ancestor_ids.all? { |id| existing_ids.include?(id) }
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get the id of every valid instance in the db
|
79
|
+
def existing_ids
|
80
|
+
@existing_ids ||= Set.new(mapper.select(nil, :id).map{ |row| row[:id] })
|
81
|
+
end
|
82
|
+
|
83
|
+
def mapper
|
84
|
+
@model.mapper
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -14,6 +14,10 @@ module Spontaneous::Model::Box
|
|
14
14
|
define_instance_class(definition) if definition
|
15
15
|
end
|
16
16
|
|
17
|
+
def schema
|
18
|
+
@box_class.mapper.schema
|
19
|
+
end
|
20
|
+
|
17
21
|
def check_instance_class
|
18
22
|
instance_class
|
19
23
|
end
|
@@ -84,6 +88,17 @@ module Spontaneous::Model::Box
|
|
84
88
|
end
|
85
89
|
end
|
86
90
|
|
91
|
+
def export
|
92
|
+
if allow_subclasses
|
93
|
+
# can't configure interface name using allow_subclasses
|
94
|
+
instance_class.subclasses.map { |c| { type: c.ui_class } }
|
95
|
+
else
|
96
|
+
exported = {type: instance_class.ui_class }
|
97
|
+
exported[:as] = @options[:as] if @options.key?(:as)
|
98
|
+
[exported]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
87
102
|
def prototype
|
88
103
|
@options[:prototype]
|
89
104
|
end
|
@@ -120,7 +135,6 @@ module Spontaneous::Model::Box
|
|
120
135
|
end
|
121
136
|
|
122
137
|
def instance_classes
|
123
|
-
schema = Spontaneous::Site.schema
|
124
138
|
names = groups.flat_map { |name| schema.groups[name] }
|
125
139
|
names.map { |name| resolve_instance_class(name) }.uniq
|
126
140
|
end
|
@@ -56,6 +56,16 @@ module Spontaneous::Model
|
|
56
56
|
ensure
|
57
57
|
mapper.logger = nil
|
58
58
|
end
|
59
|
+
|
60
|
+
# Provide a Content.to_proc implementation to
|
61
|
+
# enable filtering of content lists like so:
|
62
|
+
#
|
63
|
+
# Content.all.select(&ContentClass)
|
64
|
+
# => [#<ContentClass...>, #<ContentClass...>]
|
65
|
+
#
|
66
|
+
def to_proc
|
67
|
+
Proc.new { |obj| self === obj }
|
68
|
+
end
|
59
69
|
end
|
60
70
|
|
61
71
|
include Enumerable
|