pageflow 12.0.4 → 12.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pageflow might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +158 -374
- data/README.md +24 -3
- data/Rakefile +2 -2
- data/admins/pageflow/accounts.rb +30 -4
- data/admins/pageflow/entry.rb +59 -9
- data/admins/pageflow/membership.rb +57 -6
- data/admins/pageflow/user.rb +25 -4
- data/app/assets/images/pageflow/themes/default/preview.png +0 -0
- data/app/assets/images/pageflow/themes/default/preview_thumbnail.png +0 -0
- data/app/assets/javascripts/pageflow/admin/entries.js +5 -3
- data/app/assets/javascripts/pageflow/admin/users.js +33 -0
- data/app/assets/javascripts/pageflow/admin.js +4 -1
- data/app/assets/javascripts/pageflow/audio_context.js +28 -0
- data/app/assets/javascripts/pageflow/audio_player/get_media_element_method.js +5 -0
- data/app/assets/javascripts/pageflow/audio_player.js +2 -0
- data/app/assets/javascripts/pageflow/base.js +4 -22
- data/app/assets/javascripts/pageflow/dist/react.js +323 -242
- data/app/assets/javascripts/pageflow/editor/api/widget_type.js +23 -0
- data/app/assets/javascripts/pageflow/editor/api/widget_types.js +53 -0
- data/app/assets/javascripts/pageflow/editor/api.js +9 -1
- data/app/assets/javascripts/pageflow/editor/base.js +0 -1
- data/app/assets/javascripts/pageflow/editor/collections/pages_collection.js +1 -0
- data/app/assets/javascripts/pageflow/editor/collections/subset_collection.js +21 -1
- data/app/assets/javascripts/pageflow/editor/collections/themes_collection.js +13 -0
- data/app/assets/javascripts/pageflow/editor/collections/widgets_collection.js +23 -8
- data/app/assets/javascripts/pageflow/editor/controllers/sidebar_controller.js +7 -1
- data/app/assets/javascripts/pageflow/editor/initializers/setup_collections.js +10 -3
- data/app/assets/javascripts/pageflow/editor/initializers/setup_widget_types.js +5 -1
- data/app/assets/javascripts/pageflow/editor/initializers/stylesheet_reloading.js +8 -3
- data/app/assets/javascripts/pageflow/editor/models/edit_lock_container.js +1 -1
- data/app/assets/javascripts/pageflow/editor/models/entry.js +7 -4
- data/app/assets/javascripts/pageflow/editor/models/entry_configuration.js +1 -1
- data/app/assets/javascripts/pageflow/editor/models/file_stage.js +1 -0
- data/app/assets/javascripts/pageflow/editor/models/page.js +3 -1
- data/app/assets/javascripts/pageflow/editor/models/preview_entry_data.js +2 -2
- data/app/assets/javascripts/pageflow/editor/models/theme.js +25 -0
- data/app/assets/javascripts/pageflow/editor/models/theming.js +1 -19
- data/app/assets/javascripts/pageflow/editor/models/widget.js +22 -1
- data/app/assets/javascripts/pageflow/editor/models/widget_configuration.js +5 -0
- data/app/assets/javascripts/pageflow/editor/routers/sidebar_router.js +1 -0
- data/app/assets/javascripts/pageflow/editor/templates/change_theme_dialog.jst.ejs +23 -0
- data/app/assets/javascripts/pageflow/editor/templates/edit_widget.jst.ejs +1 -2
- data/app/assets/javascripts/pageflow/editor/templates/inputs/reference.jst.ejs +2 -2
- data/app/assets/javascripts/pageflow/editor/templates/static_thumbnail.jst.ejs +1 -0
- data/app/assets/javascripts/pageflow/editor/templates/theme_item.jst.ejs +5 -0
- data/app/assets/javascripts/pageflow/editor/templates/widget_item.jst.ejs +3 -0
- data/app/assets/javascripts/pageflow/editor/utils/stylesheet.js +23 -0
- data/app/assets/javascripts/pageflow/editor/views/change_theme_dialog_view.js +76 -0
- data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/options.js +4 -2
- data/app/assets/javascripts/pageflow/editor/views/edit_meta_data_view.js +17 -4
- data/app/assets/javascripts/pageflow/editor/views/edit_widget_view.js +11 -21
- data/app/assets/javascripts/pageflow/editor/views/edit_widgets_view.js +1 -3
- data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_value_view.js +10 -1
- data/app/assets/javascripts/pageflow/editor/views/inputs/reference_input_view.js +36 -4
- data/app/assets/javascripts/pageflow/editor/views/inputs/theme_input_view.js +26 -0
- data/app/assets/javascripts/pageflow/editor/views/model_thumbnail_view.js +28 -14
- data/app/assets/javascripts/pageflow/editor/views/static_thumbnail_view.js +20 -0
- data/app/assets/javascripts/pageflow/editor/views/theme_item_view.js +41 -0
- data/app/assets/javascripts/pageflow/editor/views/widget_item_view.js +49 -0
- data/app/assets/javascripts/pageflow/history.js +7 -1
- data/app/assets/javascripts/pageflow/media_player/volume_fading/interval.js +65 -0
- data/app/assets/javascripts/pageflow/media_player/volume_fading/noop.js +5 -0
- data/app/assets/javascripts/pageflow/media_player/volume_fading/web_audio.js +109 -0
- data/app/assets/javascripts/pageflow/media_player/volume_fading.js +14 -65
- data/app/assets/javascripts/pageflow/slideshow/dom_order_scroll_navigator.js +5 -2
- data/app/assets/javascripts/pageflow/slideshow.js +19 -8
- data/app/assets/javascripts/pageflow/ui/views/configuration_editor_view.js +4 -0
- data/app/assets/javascripts/pageflow/ui/views/inputs/text_area_input_view.js +10 -5
- data/app/assets/javascripts/pageflow/ui/views/inputs/text_input_view.js +4 -48
- data/app/assets/javascripts/pageflow/ui/views/mixins/input_with_placeholder_text.js +58 -0
- data/app/assets/javascripts/pageflow/vendor.js +16 -0
- data/app/assets/javascripts/pageflow/video_player/get_media_element_method.js +6 -0
- data/app/assets/javascripts/pageflow/video_player.js +2 -0
- data/app/assets/stylesheets/pageflow/admin/entries.scss +1 -1
- data/app/assets/stylesheets/pageflow/admin/quotas.scss +1 -1
- data/app/assets/stylesheets/pageflow/admin.scss +2 -0
- data/app/assets/stylesheets/pageflow/base.scss +0 -1
- data/app/assets/stylesheets/pageflow/editor/base.scss +2 -0
- data/app/assets/stylesheets/pageflow/editor/change_theme.scss +114 -0
- data/app/assets/stylesheets/pageflow/editor/static_thumbnails.scss +4 -0
- data/app/assets/stylesheets/pageflow/editor/widgets.scss +26 -2
- data/app/assets/stylesheets/pageflow/page.scss +1 -14
- data/app/assets/stylesheets/pageflow/themes/default/indicators.scss +12 -0
- data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +11 -0
- data/app/assets/stylesheets/pageflow/themes/default/logo/alignment.scss +27 -0
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/background_image.scss +20 -2
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +4 -1
- data/app/assets/stylesheets/pageflow/themes/default/page/line_lengths.scss +113 -0
- data/app/assets/stylesheets/pageflow/themes/default/page.scss +1 -0
- data/app/controllers/pageflow/editor/widgets_controller.rb +15 -1
- data/app/controllers/pageflow/entries_controller.rb +1 -1
- data/app/helpers/pageflow/admin/entries_helper.rb +0 -9
- data/app/helpers/pageflow/admin/memberships_helper.rb +43 -123
- data/app/helpers/pageflow/admin/users_helper.rb +15 -0
- data/app/helpers/pageflow/entries_helper.rb +3 -1
- data/app/helpers/pageflow/entry_json_seed_helper.rb +9 -3
- data/app/helpers/pageflow/public_i18n_helper.rb +2 -2
- data/app/helpers/pageflow/quota_helper.rb +2 -2
- data/app/helpers/pageflow/social_share_helper.rb +3 -2
- data/app/helpers/pageflow/themes_helper.rb +11 -3
- data/app/helpers/pageflow/widgets_helper.rb +10 -2
- data/app/jobs/pageflow/prune_auto_snapshots_job.rb +9 -0
- data/app/mailers/pageflow/user_mailer.rb +11 -1
- data/app/models/concerns/pageflow/feature_target.rb +1 -1
- data/app/models/concerns/pageflow/hosted_file.rb +9 -0
- data/app/models/concerns/pageflow/output_source.rb +2 -1
- data/app/models/concerns/pageflow/serialization_blacklist.rb +19 -0
- data/app/models/concerns/pageflow/serialized_configuration.rb +17 -0
- data/app/models/concerns/pageflow/theme_referencer.rb +23 -0
- data/app/models/pageflow/account.rb +6 -1
- data/app/models/pageflow/account_member_query.rb +6 -12
- data/app/models/pageflow/account_role_query.rb +68 -0
- data/app/models/pageflow/application_query.rb +13 -0
- data/app/models/pageflow/application_record.rb +5 -0
- data/app/models/pageflow/audio_file.rb +1 -1
- data/app/models/pageflow/auto_snapshot_pruning.rb +26 -0
- data/app/models/pageflow/chapter.rb +4 -8
- data/app/models/pageflow/draft_entry.rb +2 -1
- data/app/models/pageflow/edit_lock.rb +11 -5
- data/app/models/pageflow/encoding_confirmation.rb +2 -1
- data/app/models/pageflow/entry.rb +13 -2
- data/app/models/pageflow/entry_publication.rb +2 -0
- data/app/models/pageflow/entry_role_query.rb +24 -9
- data/app/models/pageflow/entry_title_or_account_name_query.rb +33 -0
- data/app/models/pageflow/file_usage.rb +3 -7
- data/app/models/pageflow/folder.rb +1 -1
- data/app/models/pageflow/home_button.rb +1 -1
- data/app/models/pageflow/image_file.rb +22 -4
- data/app/models/pageflow/invitation_form.rb +10 -4
- data/app/models/pageflow/managed_user_query.rb +44 -0
- data/app/models/pageflow/membership.rb +1 -1
- data/app/models/pageflow/overview_button.rb +3 -4
- data/app/models/pageflow/page.rb +3 -7
- data/app/models/pageflow/potential_memberships.rb +112 -0
- data/app/models/pageflow/published_entry.rb +2 -1
- data/app/models/pageflow/revision.rb +13 -4
- data/app/models/pageflow/storyline.rb +3 -4
- data/app/models/pageflow/text_track_file.rb +1 -1
- data/app/models/pageflow/theming.rb +15 -10
- data/app/models/pageflow/url_template.rb +8 -2
- data/app/models/pageflow/user_name_query.rb +30 -0
- data/app/models/pageflow/video_file.rb +5 -1
- data/app/models/pageflow/widget.rb +3 -1
- data/app/models/pageflow/zencoder_attachment.rb +16 -5
- data/app/policies/pageflow/account_policy.rb +31 -61
- data/app/policies/pageflow/application_policy.rb +6 -0
- data/app/policies/pageflow/entry_policy.rb +11 -3
- data/app/policies/pageflow/membership_policy.rb +1 -2
- data/app/policies/pageflow/user_policy.rb +20 -1
- data/app/views/admin/accounts/_form.html.erb +4 -4
- data/app/views/admin/accounts/_theming_defaults_inline_help.html.erb +5 -0
- data/app/views/admin/memberships/_form.html.erb +9 -14
- data/app/views/admin/memberships/_role_hint.html.arb +1 -1
- data/app/views/admin/users/invitation.html.erb +18 -9
- data/app/views/admin/users/me.html.erb +2 -2
- data/app/views/admin/users/quota_state.html.erb +1 -0
- data/app/views/components/pageflow/admin/add_membership_button.rb +81 -0
- data/app/views/components/pageflow/admin/members_tab.rb +6 -4
- data/app/views/components/pageflow/admin/revisions_tab.rb +16 -4
- data/app/views/components/pageflow/admin/user_accounts_tab.rb +8 -2
- data/app/views/components/pageflow/admin/user_entries_tab.rb +6 -2
- data/app/views/components/pageflow/admin/users_tab.rb +9 -5
- data/app/views/layouts/pageflow/application.html.erb +2 -1
- data/app/views/pageflow/admin/users/_quota_exhausted.html.erb +1 -0
- data/app/views/pageflow/admin/users/_quota_state.html.erb +7 -0
- data/app/views/pageflow/config/_editor_seeds.json.jbuilder +2 -0
- data/app/views/pageflow/editor/entries/_entry.json.jbuilder +1 -0
- data/app/views/pageflow/editor/entries/seed.json.erb +3 -1
- data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +1 -1
- data/app/views/pageflow/editor/themings/_theming.json.jbuilder +0 -7
- data/app/views/pageflow/editor/widgets/_widget.json.jbuilder +1 -1
- data/app/views/pageflow/entries/_entry.html.erb +5 -5
- data/app/views/pageflow/entries/edit.html.erb +1 -1
- data/app/views/pageflow/entries/show.html.erb +1 -1
- data/app/views/pageflow/entry_json_seed/_entry.json.jbuilder +1 -0
- data/app/views/pageflow/themes/_theme.json.jbuilder +13 -0
- data/config/initializers/admin_resource_tabs.rb +19 -6
- data/config/initializers/features.rb +1 -0
- data/config/locales/de.yml +26 -3
- data/config/locales/en.yml +26 -3
- data/db/migrate/20170201074328_add_configuration_to_widgets.rb +5 -0
- data/db/migrate/20170222124848_update_video_file_output_presences.rb +1 -1
- data/db/migrate/20170315130000_add_theme_name_to_revisions.rb +12 -0
- data/db/migrate/20170912165050_reset_copied_snapshot_type.rb +24 -0
- data/lib/generators/pageflow/routes/routes_generator.rb +11 -1
- data/lib/generators/pageflow/seeds/seeds_generator.rb +5 -0
- data/lib/generators/pageflow/seeds/templates/seeds.rb +5 -3
- data/lib/generators/pageflow/theme/templates/preview.png +0 -0
- data/lib/generators/pageflow/theme/templates/preview_thumbnail.png +0 -0
- data/lib/generators/pageflow/theme/theme_generator.rb +3 -0
- data/lib/pageflow/ability_mixin.rb +27 -6
- data/lib/pageflow/active_admin_can_can_fix.rb +34 -0
- data/lib/pageflow/configuration/permissions.rb +27 -0
- data/lib/pageflow/configuration.rb +28 -0
- data/lib/pageflow/engine.rb +25 -19
- data/lib/pageflow/images/palette.png +0 -0
- data/lib/pageflow/seeds.rb +1 -1
- data/lib/pageflow/theme.rb +8 -0
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow/widget_type.rb +13 -0
- data/lib/pageflow/zencoder_video_output_definition.rb +16 -16
- data/lib/tasks/pageflow_tasks.rake +14 -0
- data/spec/factories/entries.rb +4 -0
- data/spec/factories/revisions.rb +10 -0
- data/spec/factories/users.rb +6 -0
- data/spec/factories/video_files.rb +4 -0
- data/vendor/assets/javascripts/audio5.min.js +3 -0
- metadata +78 -15
- data/app/assets/javascripts/pageflow/editor/models/mixins/widget_subject.js +0 -37
- data/app/assets/javascripts/pageflow/editor/utils/reload_stylesheet.js +0 -9
- data/app/assets/stylesheets/pageflow/text_variants.scss +0 -24
- data/app/views/admin/accounts/_widgets_inline_help.html.erb +0 -5
- data/app/views/admin/memberships/_entity_account_input.html.erb +0 -5
- data/app/views/admin/memberships/_entity_entry_input.html.erb +0 -5
- data/app/views/admin/users/_quota_exhausted.html.erb +0 -1
- data/app/views/components/pageflow/admin/add_membership_button_if_needed.rb +0 -62
@@ -36,17 +36,23 @@ module Pageflow
|
|
36
36
|
initial_account && initial_account.users.find_by_email(user.email)
|
37
37
|
end
|
38
38
|
|
39
|
+
def initial_account
|
40
|
+
@initial_account ||=
|
41
|
+
if initial_account_id
|
42
|
+
available_accounts.find_by_id(initial_account_id)
|
43
|
+
else
|
44
|
+
available_accounts.first
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
39
48
|
private
|
40
49
|
|
41
50
|
def existing_user
|
42
51
|
@existing_user ||=
|
52
|
+
Pageflow.config.allow_multiaccount_users &&
|
43
53
|
User.find_by_email(user.email)
|
44
54
|
end
|
45
55
|
|
46
|
-
def initial_account
|
47
|
-
@initial_account ||= available_accounts.find_by_id(initial_account_id)
|
48
|
-
end
|
49
|
-
|
50
56
|
def initial_account_id
|
51
57
|
@attributes.fetch(:membership, {})[:entity_id]
|
52
58
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Pageflow
|
2
|
+
# @api private
|
3
|
+
class ManagedUserQuery < ApplicationQuery
|
4
|
+
class Scope < Scope
|
5
|
+
def initialize(current_user, scope)
|
6
|
+
@current_user = current_user
|
7
|
+
@scope = scope
|
8
|
+
end
|
9
|
+
|
10
|
+
def resolve
|
11
|
+
if current_user.admin?
|
12
|
+
scope.all
|
13
|
+
else
|
14
|
+
scope
|
15
|
+
.distinct
|
16
|
+
.joins(account_memberships)
|
17
|
+
.joins(account_manager_memberships_of_current_user)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :current_user, :scope
|
24
|
+
|
25
|
+
def account_memberships
|
26
|
+
<<-SQL
|
27
|
+
INNER JOIN pageflow_memberships account_memberships ON
|
28
|
+
account_memberships.user_id = users.id AND
|
29
|
+
account_memberships.entity_type = "Pageflow::Account"
|
30
|
+
SQL
|
31
|
+
end
|
32
|
+
|
33
|
+
def account_manager_memberships_of_current_user
|
34
|
+
sanitize_sql(<<-SQL, user_id: current_user.id)
|
35
|
+
INNER JOIN pageflow_memberships account_manager_memberships ON
|
36
|
+
account_manager_memberships.entity_type = account_memberships.entity_type AND
|
37
|
+
account_manager_memberships.entity_id = account_memberships.entity_id AND
|
38
|
+
account_manager_memberships.user_id = :user_id AND
|
39
|
+
account_manager_memberships.role = "manager"
|
40
|
+
SQL
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
module Pageflow
|
2
2
|
class OverviewButton
|
3
|
-
attr_reader :revision
|
3
|
+
attr_reader :revision
|
4
4
|
|
5
|
-
def initialize(revision
|
5
|
+
def initialize(revision)
|
6
6
|
@revision = revision
|
7
|
-
@theming = theming
|
8
7
|
end
|
9
8
|
|
10
9
|
def enabled?
|
11
10
|
revision.overview_button_enabled? &&
|
12
|
-
|
11
|
+
revision.theme.has_overview_button?
|
13
12
|
end
|
14
13
|
|
15
14
|
def enabled_value
|
data/app/models/pageflow/page.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module Pageflow
|
2
|
-
class Page <
|
2
|
+
class Page < ApplicationRecord
|
3
|
+
include SerializedConfiguration
|
4
|
+
|
3
5
|
belongs_to :chapter, :touch => true
|
4
6
|
|
5
7
|
attr_accessor :is_first
|
6
8
|
|
7
9
|
validates_inclusion_of :template, :in => ->(_) { Pageflow.config.page_types.names }
|
8
10
|
|
9
|
-
serialize :configuration, JSON
|
10
|
-
|
11
11
|
scope :displayed_in_navigation, -> { where(:display_in_navigation => true) }
|
12
12
|
|
13
13
|
before_save :ensure_perma_id
|
@@ -28,10 +28,6 @@ module Pageflow
|
|
28
28
|
Pageflow.config.page_types.find_by_name!(template)
|
29
29
|
end
|
30
30
|
|
31
|
-
def configuration
|
32
|
-
super || {}
|
33
|
-
end
|
34
|
-
|
35
31
|
def configuration=(value)
|
36
32
|
self.display_in_navigation = value['display_in_navigation']
|
37
33
|
super
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Pageflow
|
2
|
+
# @api private
|
3
|
+
class PotentialMemberships
|
4
|
+
def initialize(current_user)
|
5
|
+
@current_user = current_user
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.creatable_by(user)
|
9
|
+
new(user)
|
10
|
+
end
|
11
|
+
|
12
|
+
def accounts_for_user(user)
|
13
|
+
exclude_accounts_with_membership(user, managed_accounts)
|
14
|
+
end
|
15
|
+
|
16
|
+
def entries_for_user(user)
|
17
|
+
exclude_entries_with_membership(user, entries_managed_by_current_user_in_accounts_of(user))
|
18
|
+
end
|
19
|
+
|
20
|
+
def users_for_account(account)
|
21
|
+
exclude_users_with_membership(account, users_of_managed_accounts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def users_for_entry(entry)
|
25
|
+
return User.none unless manages_entry?(entry)
|
26
|
+
exclude_users_with_membership(entry, entry.account.users)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def managed_accounts
|
32
|
+
if @current_user.admin?
|
33
|
+
Account.all
|
34
|
+
else
|
35
|
+
AccountRoleQuery::Scope
|
36
|
+
.new(@current_user, Account)
|
37
|
+
.with_role_at_least(:manager)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def entries_managed_by_current_user_in_accounts_of(user)
|
42
|
+
EntryRoleQuery::Scope
|
43
|
+
.new(user, entries_managed_by_current_user, table_alias_prefix: 'member')
|
44
|
+
.with_account_role_at_least(:member)
|
45
|
+
end
|
46
|
+
|
47
|
+
def entries_managed_by_current_user
|
48
|
+
if @current_user.admin?
|
49
|
+
Entry.all
|
50
|
+
else
|
51
|
+
EntryRoleQuery::Scope
|
52
|
+
.new(@current_user, Entry, table_alias_prefix: 'manager')
|
53
|
+
.with_role_at_least(:manager)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def users_of_managed_accounts
|
58
|
+
ManagedUserQuery::Scope
|
59
|
+
.new(@current_user, User)
|
60
|
+
.resolve
|
61
|
+
end
|
62
|
+
|
63
|
+
def manages_entry?(entry)
|
64
|
+
@current_user.admin? ||
|
65
|
+
EntryRoleQuery.new(@current_user, entry).has_at_least_role?(:manager)
|
66
|
+
end
|
67
|
+
|
68
|
+
def exclude_accounts_with_membership(user, accounts)
|
69
|
+
accounts
|
70
|
+
.joins(existing_memberships_of(user, Account))
|
71
|
+
.where(existing_membership_is_missing)
|
72
|
+
end
|
73
|
+
|
74
|
+
def exclude_entries_with_membership(user, entries)
|
75
|
+
entries
|
76
|
+
.joins(existing_memberships_of(user, Entry))
|
77
|
+
.where(existing_membership_is_missing)
|
78
|
+
end
|
79
|
+
|
80
|
+
def exclude_users_with_membership(entity, users)
|
81
|
+
users
|
82
|
+
.joins(existing_memberships_on(entity))
|
83
|
+
.where(existing_membership_is_missing)
|
84
|
+
end
|
85
|
+
|
86
|
+
def existing_memberships_of(user, entity_model)
|
87
|
+
sanitize_sql_array(['LEFT OUTER JOIN pageflow_memberships existing_memberships ON ' \
|
88
|
+
'existing_memberships.user_id = :user_id AND ' \
|
89
|
+
"existing_memberships.entity_id = #{entity_model.table_name}.id AND " \
|
90
|
+
'existing_memberships.entity_type = :entity_type',
|
91
|
+
user_id: user.id,
|
92
|
+
entity_type: entity_model.name])
|
93
|
+
end
|
94
|
+
|
95
|
+
def existing_memberships_on(entity)
|
96
|
+
sanitize_sql_array(['LEFT OUTER JOIN pageflow_memberships existing_memberships ON ' \
|
97
|
+
'existing_memberships.user_id = users.id AND ' \
|
98
|
+
'existing_memberships.entity_id = :entity_id AND ' \
|
99
|
+
'existing_memberships.entity_type = :entity_type',
|
100
|
+
entity_id: entity.id,
|
101
|
+
entity_type: entity.class.name])
|
102
|
+
end
|
103
|
+
|
104
|
+
def existing_membership_is_missing
|
105
|
+
'existing_memberships.id IS NULL'
|
106
|
+
end
|
107
|
+
|
108
|
+
def sanitize_sql_array(array)
|
109
|
+
ActiveRecord::Base.send(:sanitize_sql_array, array)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -23,6 +23,7 @@ module Pageflow
|
|
23
23
|
:share_url, :share_image_id, :share_image_x, :share_image_y,
|
24
24
|
:locale,
|
25
25
|
:author, :publisher, :keywords,
|
26
|
+
:theme,
|
26
27
|
:password_protected?,
|
27
28
|
:to => :revision)
|
28
29
|
|
@@ -68,7 +69,7 @@ module Pageflow
|
|
68
69
|
end
|
69
70
|
|
70
71
|
def overview_button
|
71
|
-
OverviewButton.new(revision
|
72
|
+
OverviewButton.new(revision)
|
72
73
|
end
|
73
74
|
|
74
75
|
def resolve_widgets(options = {})
|
@@ -1,21 +1,24 @@
|
|
1
1
|
module Pageflow
|
2
|
-
class Revision <
|
2
|
+
class Revision < ApplicationRecord
|
3
3
|
PAGE_ORDER = [
|
4
4
|
'pageflow_storylines.position ASC',
|
5
5
|
'pageflow_chapters.position ASC',
|
6
6
|
'pageflow_pages.position ASC'
|
7
7
|
].join(',')
|
8
8
|
|
9
|
+
include ThemeReferencer
|
10
|
+
|
9
11
|
belongs_to :entry, touch: :edited_at
|
10
12
|
belongs_to :creator, :class_name => 'User'
|
11
13
|
belongs_to :restored_from, :class_name => 'Pageflow::Revision'
|
12
14
|
|
13
|
-
has_many :widgets, :
|
14
|
-
|
15
|
+
has_many :widgets, as: :subject, dependent: :destroy
|
16
|
+
|
17
|
+
has_many :storylines, -> { order('pageflow_storylines.position ASC') }, dependent: :destroy
|
15
18
|
has_many :chapters, -> { order('position ASC') }, through: :storylines
|
16
19
|
has_many :pages, -> { reorder(PAGE_ORDER) }, through: :storylines
|
17
20
|
|
18
|
-
has_many :file_usages
|
21
|
+
has_many :file_usages, dependent: :destroy
|
19
22
|
|
20
23
|
has_many :image_files, -> { extending WithFileUsageExtension },
|
21
24
|
:through => :file_usages, :source => :file, :source_type => 'Pageflow::ImageFile'
|
@@ -37,6 +40,8 @@ module Pageflow
|
|
37
40
|
|
38
41
|
scope :publications, -> { where('published_at IS NOT NULL') }
|
39
42
|
scope :publications_and_user_snapshots, -> { where('published_at IS NOT NULL OR snapshot_type = "user"') }
|
43
|
+
scope :user_snapshots, -> { where(snapshot_type: 'user') }
|
44
|
+
scope :auto_snapshots, -> { where(snapshot_type: 'auto') }
|
40
45
|
|
41
46
|
validates :entry, :presence => true
|
42
47
|
validates :creator, :presence => true, :if => :published?
|
@@ -148,5 +153,9 @@ module Pageflow
|
|
148
153
|
def published_at_blank?
|
149
154
|
published_at.blank?
|
150
155
|
end
|
156
|
+
|
157
|
+
def available_themes
|
158
|
+
Pageflow.config_for(entry).themes
|
159
|
+
end
|
151
160
|
end
|
152
161
|
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
module Pageflow
|
2
|
-
class Storyline <
|
2
|
+
class Storyline < ApplicationRecord
|
3
|
+
include SerializedConfiguration
|
3
4
|
include RevisionComponent
|
4
5
|
|
5
6
|
belongs_to :revision, touch: true
|
6
7
|
|
7
|
-
has_many :chapters, -> { order('pageflow_chapters.position ASC') }
|
8
|
+
has_many :chapters, -> { order('pageflow_chapters.position ASC') }, dependent: :destroy
|
8
9
|
has_many :pages, through: :chapters
|
9
10
|
|
10
11
|
delegate :entry, to: :revision
|
11
12
|
|
12
|
-
serialize :configuration, JSON
|
13
|
-
|
14
13
|
def copy_to(revision)
|
15
14
|
storyline = dup
|
16
15
|
revision.storylines << storyline
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module Pageflow
|
2
|
-
class Theming <
|
2
|
+
class Theming < ApplicationRecord
|
3
|
+
include ThemeReferencer
|
4
|
+
|
3
5
|
belongs_to :account
|
4
|
-
has_many :widgets, as: :subject
|
6
|
+
has_many :widgets, as: :subject, dependent: :destroy
|
5
7
|
|
6
8
|
has_many :entries
|
7
9
|
|
@@ -9,7 +11,6 @@ module Pageflow
|
|
9
11
|
scope :for_request, ->(request) { Pageflow.config.theming_request_scope.call(all, request) }
|
10
12
|
|
11
13
|
validates :account, :presence => true
|
12
|
-
validates_inclusion_of :theme_name, :in => ->(_) { Pageflow.config.themes.names }
|
13
14
|
|
14
15
|
def resolve_widgets(options = {})
|
15
16
|
widgets.resolve(Pageflow.config_for(account), options)
|
@@ -19,25 +20,29 @@ module Pageflow
|
|
19
20
|
cname.split('.').pop(2).join('.')
|
20
21
|
end
|
21
22
|
|
22
|
-
def theme
|
23
|
-
Pageflow.config.themes.get(theme_name)
|
24
|
-
end
|
25
|
-
|
26
23
|
def name
|
27
24
|
I18n.t('pageflow.admin.themings.name', :account_name => account.name, :theme_name => theme_name)
|
28
25
|
end
|
29
26
|
|
30
27
|
def copy_defaults_to(revision)
|
31
28
|
widgets.copy_all_to(revision)
|
32
|
-
|
29
|
+
copy_attributes_to(revision)
|
33
30
|
end
|
34
31
|
|
35
|
-
|
32
|
+
private
|
33
|
+
|
34
|
+
def copy_attributes_to(revision)
|
36
35
|
revision.update(
|
37
36
|
author: default_author.presence || Pageflow.config.default_author_meta_tag,
|
38
37
|
publisher: default_publisher.presence || Pageflow.config.default_publisher_meta_tag,
|
39
|
-
keywords: default_keywords.presence || Pageflow.config.default_keywords_meta_tag
|
38
|
+
keywords: default_keywords.presence || Pageflow.config.default_keywords_meta_tag,
|
39
|
+
theme_name: theme_name,
|
40
|
+
home_button_enabled: home_button_enabled_by_default
|
40
41
|
)
|
41
42
|
end
|
43
|
+
|
44
|
+
def available_themes
|
45
|
+
Pageflow.config_for(account).themes
|
46
|
+
end
|
42
47
|
end
|
43
48
|
end
|
@@ -1,13 +1,19 @@
|
|
1
1
|
module Pageflow
|
2
2
|
module UrlTemplate
|
3
|
-
|
3
|
+
extend self
|
4
4
|
|
5
5
|
def from_attachment(attachment, *style)
|
6
6
|
insert_id_partition_placeholder(attachment.url(*style))
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
9
11
|
def insert_id_partition_placeholder(url)
|
10
|
-
url
|
12
|
+
replace_last_group_of_digit_segments(url, with: '/:id_partition/')
|
13
|
+
end
|
14
|
+
|
15
|
+
def replace_last_group_of_digit_segments(str, with:)
|
16
|
+
str.reverse.sub(%r'/(\d{3}/)+', with.reverse).reverse
|
11
17
|
end
|
12
18
|
end
|
13
19
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Pageflow
|
2
|
+
# @api private
|
3
|
+
class UserNameQuery < ApplicationQuery
|
4
|
+
class Scope < Scope
|
5
|
+
def initialize(term, scope)
|
6
|
+
@term = term
|
7
|
+
@scope = scope
|
8
|
+
end
|
9
|
+
|
10
|
+
def resolve
|
11
|
+
scope.where(word_conditions(term))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :term, :scope
|
17
|
+
|
18
|
+
def word_conditions(term)
|
19
|
+
term.split(' ').map { |word|
|
20
|
+
word_condition(word)
|
21
|
+
}.join(' AND ')
|
22
|
+
end
|
23
|
+
|
24
|
+
def word_condition(word)
|
25
|
+
sanitize_sql('(users.first_name LIKE :word OR users.last_name LIKE :word)',
|
26
|
+
word: "%#{word}%")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Pageflow
|
2
|
-
class VideoFile <
|
2
|
+
class VideoFile < ApplicationRecord
|
3
3
|
include HostedFile
|
4
4
|
include EncodedFileStateMachine
|
5
5
|
include OutputSource
|
@@ -43,6 +43,10 @@ module Pageflow
|
|
43
43
|
"s3://#{File.join(attachment_on_s3.bucket_name, attachment_on_s3.path)}"
|
44
44
|
end
|
45
45
|
|
46
|
+
def encode_highdef?
|
47
|
+
entry.feature_state('highdef_video_encoding')
|
48
|
+
end
|
49
|
+
|
46
50
|
def mp4_4k
|
47
51
|
ZencoderAttachment.new(self, '4k.mp4')
|
48
52
|
end
|
@@ -1,12 +1,13 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
1
3
|
module Pageflow
|
2
4
|
class ZencoderAttachment
|
3
|
-
|
4
5
|
cattr_accessor :default_options
|
5
6
|
self.default_options = {
|
6
|
-
path:
|
7
|
-
url:
|
8
|
-
hls_url:
|
9
|
-
hls_origin_url:
|
7
|
+
path: '/:zencoder_asset_version/:host/:class/:id_partition/:filename',
|
8
|
+
url: ':zencoder_protocol//:zencoder_host_alias:zencoder_path',
|
9
|
+
hls_url: ':zencoder_protocol//:zencoder_hls_host_alias:zencoder_path',
|
10
|
+
hls_origin_url: ':zencoder_protocol//:zencoder_hls_origin_host_alias:zencoder_path'
|
10
11
|
}
|
11
12
|
|
12
13
|
attr_reader :file_name_pattern, :instance, :options, :styles
|
@@ -44,6 +45,16 @@ module Pageflow
|
|
44
45
|
url_options)
|
45
46
|
end
|
46
47
|
|
48
|
+
def url_relative_to(attachment)
|
49
|
+
dir_path = File.dirname(URI.parse(attachment.url).path)
|
50
|
+
|
51
|
+
unless URI.parse(url).path.start_with?(dir_path)
|
52
|
+
raise("Could not generate relative url for #{url} based on #{attachment.url}.")
|
53
|
+
end
|
54
|
+
|
55
|
+
url.split("#{dir_path}/", 2).last
|
56
|
+
end
|
57
|
+
|
47
58
|
private
|
48
59
|
|
49
60
|
def ensure_default_protocol(url, url_options)
|
@@ -1,18 +1,19 @@
|
|
1
1
|
module Pageflow
|
2
2
|
class AccountPolicy < ApplicationPolicy
|
3
3
|
class Scope < Scope
|
4
|
-
attr_reader :user, :scope
|
4
|
+
attr_reader :user, :scope, :query
|
5
5
|
|
6
6
|
def initialize(user, scope)
|
7
7
|
@user = user
|
8
8
|
@scope = scope
|
9
|
+
@query = AccountRoleQuery::Scope.new(user, scope)
|
9
10
|
end
|
10
11
|
|
11
12
|
def resolve
|
12
13
|
if user.admin?
|
13
14
|
scope.all
|
14
15
|
else
|
15
|
-
|
16
|
+
query.with_role_at_least(:member)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -20,7 +21,7 @@ module Pageflow
|
|
20
21
|
if user.admin?
|
21
22
|
scope.all
|
22
23
|
else
|
23
|
-
|
24
|
+
query.with_role_at_least(:publisher)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -40,53 +41,21 @@ module Pageflow
|
|
40
41
|
if user.admin?
|
41
42
|
scope.all
|
42
43
|
else
|
43
|
-
|
44
|
+
query.with_role_at_least(:manager)
|
44
45
|
end
|
45
46
|
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def memberships_for_account(user)
|
50
|
-
sanitize_sql_array(['LEFT OUTER JOIN pageflow_memberships ON ' \
|
51
|
-
'pageflow_memberships.user_id = :user_id AND ' \
|
52
|
-
'pageflow_memberships.entity_id = pageflow_accounts.id AND ' \
|
53
|
-
'pageflow_memberships.entity_type = "Pageflow::Account" AND ' \
|
54
|
-
'pageflow_memberships.role IN '\
|
55
|
-
'("member", "previewer", "editor", "publisher", "manager")',
|
56
|
-
user_id: user.id])
|
57
|
-
end
|
58
|
-
|
59
|
-
def publisher_memberships_for_account(user)
|
60
|
-
sanitize_sql_array(['LEFT OUTER JOIN pageflow_memberships ON ' \
|
61
|
-
'pageflow_memberships.user_id = :user_id AND ' \
|
62
|
-
'pageflow_memberships.entity_id = pageflow_accounts.id AND ' \
|
63
|
-
'pageflow_memberships.entity_type = "Pageflow::Account" AND ' \
|
64
|
-
'pageflow_memberships.role IN ("publisher", "manager")',
|
65
|
-
user_id: user.id])
|
66
|
-
end
|
67
|
-
|
68
|
-
def manager_memberships_for_account(user)
|
69
|
-
sanitize_sql_array(['LEFT OUTER JOIN pageflow_memberships ON ' \
|
70
|
-
'pageflow_memberships.user_id = :user_id AND ' \
|
71
|
-
'pageflow_memberships.entity_id = pageflow_accounts.id AND ' \
|
72
|
-
'pageflow_memberships.entity_type = "Pageflow::Account" AND ' \
|
73
|
-
'pageflow_memberships.role IN ("manager")',
|
74
|
-
user_id: user.id])
|
75
|
-
end
|
76
|
-
|
77
|
-
def membership_is_present
|
78
|
-
'pageflow_memberships.entity_id IS NOT NULL'
|
79
|
-
end
|
80
47
|
end
|
81
48
|
|
49
|
+
attr_reader :user, :query
|
50
|
+
|
82
51
|
def initialize(user, account)
|
83
52
|
@user = user
|
84
53
|
@account = account
|
54
|
+
@query = AccountRoleQuery.new(user, account)
|
85
55
|
end
|
86
56
|
|
87
57
|
def publish?
|
88
|
-
|
89
|
-
allows?(%w(publisher manager))
|
58
|
+
user.admin? || query.has_at_least_role?(:publisher)
|
90
59
|
end
|
91
60
|
|
92
61
|
def configure_folder_on?
|
@@ -97,49 +66,50 @@ module Pageflow
|
|
97
66
|
publish?
|
98
67
|
end
|
99
68
|
|
100
|
-
def manage?
|
101
|
-
@user.admin? ||
|
102
|
-
allows?(%w(manager))
|
103
|
-
end
|
104
|
-
|
105
69
|
def read?
|
106
|
-
|
70
|
+
user.admin? ||
|
71
|
+
(query.has_at_least_role?(:manager) &&
|
72
|
+
Pageflow.config.allow_multiaccount_users)
|
107
73
|
end
|
108
74
|
|
109
75
|
def update?
|
110
|
-
|
76
|
+
read?
|
77
|
+
end
|
78
|
+
|
79
|
+
def update_feature_configuration_on?
|
80
|
+
user.admin? ||
|
81
|
+
(!permissions_config.only_admins_may_update_features &&
|
82
|
+
read?)
|
111
83
|
end
|
112
84
|
|
113
85
|
def add_member_to?
|
114
|
-
|
86
|
+
Pageflow.config.allow_multiaccount_users &&
|
87
|
+
(user.admin? ||
|
88
|
+
query.has_at_least_role?(:manager))
|
115
89
|
end
|
116
90
|
|
117
91
|
def edit_role_on?
|
118
|
-
|
92
|
+
user.admin? || query.has_at_least_role?(:manager)
|
119
93
|
end
|
120
94
|
|
121
95
|
def destroy_membership_on?
|
122
|
-
|
96
|
+
add_member_to?
|
123
97
|
end
|
124
98
|
|
125
99
|
def admin?
|
126
|
-
|
100
|
+
user.admin?
|
127
101
|
end
|
128
102
|
|
129
103
|
def see_badge_belonging_to?
|
130
|
-
(@account.entries &
|
131
|
-
|
132
|
-
|
104
|
+
(@account.entries & user.entries).any? ||
|
105
|
+
query.has_at_least_role?(:previewer) ||
|
106
|
+
user.admin?
|
133
107
|
end
|
134
108
|
|
135
109
|
def index?
|
136
|
-
admin? ||
|
137
|
-
|
138
|
-
|
139
|
-
private
|
140
|
-
|
141
|
-
def allows?(roles)
|
142
|
-
@user.memberships.where(role: roles, entity: @account).any?
|
110
|
+
admin? ||
|
111
|
+
(Pageflow.config.allow_multiaccount_users &&
|
112
|
+
@user.memberships.on_accounts.as_manager.any?)
|
143
113
|
end
|
144
114
|
end
|
145
115
|
end
|