browsercms 3.4.2 → 3.5.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +1 -0
- data/app/assets/images/cms/file-uploading.gif +0 -0
- data/app/assets/javascripts/cms/application.js +1 -0
- data/app/assets/javascripts/cms/attachment_manager.js.erb +87 -0
- data/app/assets/javascripts/cms/core_library.js.erb +38 -25
- data/app/assets/stylesheets/cms/application.css.erb +1 -0
- data/app/assets/stylesheets/cms/attachment_manager.css.scss +28 -0
- data/app/controllers/cms/application_controller.rb +1 -1
- data/app/controllers/cms/attachments_controller.rb +45 -10
- data/app/controllers/cms/cache_controller.rb +1 -1
- data/app/controllers/cms/content_block_controller.rb +134 -122
- data/app/controllers/cms/content_controller.rb +143 -155
- data/app/controllers/cms/dashboard_controller.rb +11 -9
- data/app/controllers/cms/error_handling.rb +19 -7
- data/app/controllers/cms/file_blocks_controller.rb +2 -2
- data/app/controllers/cms/home_controller.rb +3 -0
- data/app/controllers/cms/section_nodes_controller.rb +52 -44
- data/app/controllers/cms/sections_controller.rb +4 -2
- data/app/controllers/cms/toolbar_controller.rb +14 -10
- data/app/helpers/cms/application_helper.rb +23 -19
- data/app/helpers/cms/form_builder.rb +65 -18
- data/app/helpers/cms/mobile_helper.rb +19 -0
- data/app/helpers/cms/path_helper.rb +30 -4
- data/app/helpers/cms/rendering_helper.rb +9 -1
- data/app/models/cms/abstract_file_block.rb +6 -6
- data/app/models/cms/attachment.rb +196 -107
- data/app/models/cms/category.rb +3 -0
- data/app/models/cms/category_type.rb +2 -0
- data/app/models/cms/connector.rb +3 -0
- data/app/models/cms/content_type.rb +3 -0
- data/app/models/cms/content_type_group.rb +2 -0
- data/app/models/cms/dynamic_view.rb +4 -0
- data/app/models/cms/email_message.rb +2 -0
- data/app/models/cms/file_block.rb +9 -2
- data/app/models/cms/group.rb +5 -2
- data/app/models/cms/group_permission.rb +2 -0
- data/app/models/cms/group_section.rb +3 -0
- data/app/models/cms/group_type.rb +2 -0
- data/app/models/cms/group_type_permission.rb +2 -0
- data/app/models/cms/html_block.rb +3 -2
- data/app/models/cms/image_block.rb +13 -2
- data/app/models/cms/page.rb +14 -3
- data/app/models/cms/page_route.rb +4 -0
- data/app/models/cms/page_route_condition.rb +1 -0
- data/app/models/cms/page_route_option.rb +2 -0
- data/app/models/cms/page_route_requirement.rb +1 -0
- data/app/models/cms/permission.rb +3 -0
- data/app/models/cms/portlet.rb +2 -2
- data/app/models/cms/redirect.rb +2 -0
- data/app/models/cms/section.rb +15 -1
- data/app/models/cms/section_node.rb +1 -0
- data/app/models/cms/site.rb +3 -0
- data/app/models/cms/tag.rb +2 -0
- data/app/models/cms/tagging.rb +3 -0
- data/app/models/cms/task.rb +5 -1
- data/app/models/cms/user.rb +1 -1
- data/app/models/cms/user_group_membership.rb +3 -0
- data/app/views/cms/attachments/_attachment.html.erb +14 -0
- data/app/views/cms/attachments/_attachment_table.html.erb +17 -0
- data/app/views/cms/attachments/_attachment_wrapper.html.erb +4 -0
- data/app/views/cms/blocks/index.html.erb +2 -3
- data/app/views/cms/blocks/show.html.erb +1 -1
- data/app/views/cms/dynamic_views/index.html.erb +1 -1
- data/app/views/cms/email_messages/index.html.erb +1 -1
- data/app/views/cms/file_blocks/_form.html.erb +1 -27
- data/app/views/cms/file_blocks/_section_selector.html.erb +13 -0
- data/app/views/cms/file_blocks/render.html.erb +3 -3
- data/app/views/cms/form_builder/_cms_attachment_manager.html.erb +26 -0
- data/app/views/cms/form_builder/_cms_file_field.html.erb +27 -35
- data/app/views/cms/groups/index.html.erb +1 -1
- data/app/views/cms/image_blocks/_form.html.erb +1 -27
- data/app/views/cms/image_blocks/render.html.erb +4 -1
- data/app/views/cms/page_routes/index.html.erb +3 -0
- data/app/views/cms/shared/error.xml.erb +8 -0
- data/app/views/cms/tags/render.html.erb +1 -1
- data/app/views/cms/toolbar/_mobile_toggle.html.erb +33 -0
- data/app/views/cms/users/index.html.erb +1 -1
- data/app/views/layouts/_page_toolbar.html.erb +2 -1
- data/bin/bcms +21 -26
- data/config/routes.rb +3 -2
- data/db/browsercms.seeds.rb +2 -1
- data/db/migrate/20111130221145_browsercms340.rb +5 -4
- data/db/migrate/20120329144406_browsercms350.rb +32 -0
- data/{test/dummy/db → db}/schema.rb +97 -128
- data/{performance_tuning_notes.md → doc/performance_tuning_notes.md} +0 -0
- data/doc/release_notes.md +74 -0
- data/lib/browsercms.rb +3 -0
- data/lib/cms/acts/content_block.rb +10 -2
- data/lib/cms/addressable.rb +8 -0
- data/lib/cms/attachments/attachment_serving.rb +59 -0
- data/lib/cms/attachments/configuration.rb +88 -0
- data/lib/cms/behaviors/attaching.rb +305 -136
- data/lib/cms/behaviors/connecting.rb +3 -4
- data/lib/cms/behaviors/dynamic_attributes.rb +121 -118
- data/lib/cms/behaviors/flush_cache_on_change.rb +1 -3
- data/lib/cms/behaviors/naming.rb +16 -0
- data/lib/cms/behaviors/pagination.rb +4 -1
- data/lib/cms/behaviors/publishing.rb +9 -3
- data/lib/cms/behaviors/searching.rb +3 -8
- data/lib/cms/behaviors/soft_deleting.rb +1 -0
- data/lib/cms/behaviors/taggable.rb +2 -0
- data/lib/cms/behaviors/versioning.rb +73 -120
- data/lib/cms/caching.rb +53 -11
- data/lib/cms/commands/actions.rb +19 -2
- data/lib/cms/configuration.rb +44 -0
- data/lib/cms/content_rendering_support.rb +9 -6
- data/lib/cms/default_accessible.rb +13 -0
- data/lib/cms/domain_support.rb +22 -0
- data/lib/cms/engine.rb +40 -19
- data/lib/cms/engine_helper.rb +54 -0
- data/lib/cms/extensions/active_record/connection_adapters/abstract/schema_statements.rb +14 -2
- data/lib/cms/mobile_aware.rb +67 -0
- data/lib/cms/route_extensions.rb +3 -0
- data/lib/cms/upgrades/v3_5_0.rb +155 -0
- data/lib/cms/version.rb +6 -1
- data/lib/generators/cms/content_block/content_block_generator.rb +14 -9
- data/lib/generators/cms/content_block/templates/_form.html.erb +17 -6
- data/lib/generators/cms/content_block/templates/render.html.erb +12 -5
- data/lib/generators/cms/template/template_generator.rb +11 -2
- data/lib/tasks/cms.rake +23 -0
- data/lib/templates/active_record/model/model.rb +6 -0
- metadata +127 -517
- data/.gitignore +0 -24
- data/.rvmrc +0 -2
- data/Gemfile +0 -29
- data/Gemfile.lock +0 -196
- data/Rakefile +0 -97
- data/app/assets/images/browsercms/.gitkeep +0 -0
- data/app/controllers/browsercms/application_controller.rb +0 -4
- data/browsercms.gemspec +0 -35
- data/config/cucumber.yml +0 -8
- data/config/database.jdbcmysql.yml +0 -30
- data/config/database.mysql.yml +0 -27
- data/config/database.postgres.yml +0 -25
- data/config/database.sqlite3.yml +0 -11
- data/config/environment.rb +0 -6
- data/config/initializers/query_reviewer_patch.rb +0 -12
- data/config/initializers/rack_1_2_1_patch.rb +0 -12
- data/config/locales/en.yml +0 -5
- data/features/acts_as_content_page.feature +0 -62
- data/features/add_content_to_pages.feature +0 -45
- data/features/caching.feature +0 -13
- data/features/ckeditor.feature +0 -11
- data/features/commands/confirm_aruba_works.feature +0 -24
- data/features/commands/generate_module.feature +0 -54
- data/features/commands/install_browsercms.feature +0 -21
- data/features/commands/new_demo_project.feature +0 -30
- data/features/commands/new_projects.feature +0 -50
- data/features/commands/upgrade_modules_to_3_4_0_from_3_1_x.feature +0 -19
- data/features/commands/upgrade_project_to_3_4_0_from_3_3_x.feature +0 -52
- data/features/commands/upgrading_modules.feature +0 -67
- data/features/content_blocks/manage_custom_blocks.feature +0 -67
- data/features/content_blocks/manage_html_blocks.feature +0 -48
- data/features/content_blocks/manage_image_blocks.feature +0 -41
- data/features/content_files.feature +0 -37
- data/features/content_pages.feature +0 -21
- data/features/generators/content_blocks_for_modules.feature +0 -58
- data/features/generators/content_blocks_for_projects.feature +0 -109
- data/features/install_content.feature +0 -25
- data/features/jquery-testplan.txt +0 -12
- data/features/manage_groups.feature +0 -33
- data/features/manage_page_routes.feature +0 -72
- data/features/manage_redirects.feature +0 -20
- data/features/manage_sections.feature +0 -12
- data/features/manage_tasks.feature +0 -25
- data/features/manage_users.feature +0 -38
- data/features/page_templates.feature +0 -49
- data/features/portlets/email_friend_portlet.feature +0 -29
- data/features/portlets/portlets.feature +0 -100
- data/features/portlets/tag_cloud_portlet.feature +0 -28
- data/features/sitemap/create_pages.feature +0 -15
- data/features/sitemap/manage_links.feature +0 -29
- data/features/sitemap/sitemap.feature +0 -18
- data/features/step_definitions/acts_as_content_page_steps.rb.rb +0 -3
- data/features/step_definitions/ckeditor_steps.rb +0 -13
- data/features/step_definitions/command_line_steps.rb +0 -212
- data/features/step_definitions/content_pages_steps.rb +0 -170
- data/features/step_definitions/data_steps.rb +0 -48
- data/features/step_definitions/edit_page_templates_steps.rb +0 -21
- data/features/step_definitions/html_blocks_steps.rb +0 -9
- data/features/step_definitions/install_content_steps.rb +0 -4
- data/features/step_definitions/manage_content_blocks_steps.rb +0 -26
- data/features/step_definitions/manage_image_blocks_steps.rb +0 -31
- data/features/step_definitions/manage_sections_steps.rb +0 -18
- data/features/step_definitions/manage_user_steps.rb +0 -22
- data/features/step_definitions/more_custom_block_steps.rb +0 -34
- data/features/step_definitions/page_route_steps.rb +0 -65
- data/features/step_definitions/page_template_steps.rb +0 -5
- data/features/step_definitions/permissions_steps.rb +0 -13
- data/features/step_definitions/portlets_steps.rb +0 -64
- data/features/step_definitions/redirect_steps.rb +0 -12
- data/features/step_definitions/sitemap_steps.rb +0 -18
- data/features/step_definitions/tag_cloud_steps.rb +0 -11
- data/features/step_definitions/task_steps.rb +0 -4
- data/features/step_definitions/taxonomy_steps.rb +0 -16
- data/features/step_definitions/upgrade_module_steps.rb +0 -76
- data/features/step_definitions/web_steps.rb +0 -211
- data/features/support/async_support.rb +0 -17
- data/features/support/command_line_helpers.rb +0 -63
- data/features/support/debug_formatter.rb +0 -7
- data/features/support/debugging.rb +0 -28
- data/features/support/env.rb +0 -73
- data/features/support/git_api.rb +0 -9
- data/features/support/open_on_first_failure.rb +0 -25
- data/features/support/paths.rb +0 -32
- data/features/support/rails_api.rb +0 -8
- data/features/support/selectors.rb +0 -39
- data/features/support/transforms.rb +0 -7
- data/features/taxonomy/add_content_with_category.feature +0 -30
- data/features/taxonomy/manage_categories.feature +0 -20
- data/features/taxonomy/manage_category_types.feature +0 -16
- data/lib/cms/init.rb +0 -105
- data/lib/tasks/data.rake +0 -43
- data/lib/tasks/db.rake +0 -82
- data/public/styled_file_field/index.html +0 -72
- data/script/cucumber +0 -10
- data/script/rails +0 -6
- data/test/console_helper.rb +0 -5
- data/test/custom_assertions.rb +0 -84
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/assets/javascripts/application.js +0 -9
- data/test/dummy/app/assets/javascripts/content_page.js +0 -2
- data/test/dummy/app/assets/stylesheets/application.css +0 -7
- data/test/dummy/app/assets/stylesheets/content_page.css +0 -4
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/controllers/cms/products_controller.rb +0 -2
- data/test/dummy/app/controllers/cms/sample_blocks_controller.rb +0 -3
- data/test/dummy/app/controllers/content_page_controller.rb +0 -13
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/helpers/content_page_helper.rb +0 -2
- data/test/dummy/app/mailers/.gitkeep +0 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/models/cms/sample_block.rb +0 -22
- data/test/dummy/app/models/product.rb +0 -5
- data/test/dummy/app/views/cms/products/_form.html.erb +0 -7
- data/test/dummy/app/views/cms/products/render.html.erb +0 -3
- data/test/dummy/app/views/content_page/custom_page.html.erb +0 -3
- data/test/dummy/app/views/content_page/index.html.erb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/app/views/layouts/templates/default.html.erb +0 -17
- data/test/dummy/app/views/layouts/templates/subpage.html.erb +0 -16
- data/test/dummy/app/views/test_route/index.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -45
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -27
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -32
- data/test/dummy/config/environments/production.rb +0 -60
- data/test/dummy/config/environments/test.rb +0 -46
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/browsercms.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -10
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/quiet_sprocket_assets.rb +0 -13
- data/test/dummy/config/initializers/secret_token.rb +0 -7
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -23
- data/test/dummy/db/migrate/20111228141250_create_products.rb +0 -16
- data/test/dummy/db/seeds.rb +0 -1
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -26
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +0 -6
- data/test/dummy/test/functional/content_page_controller_test.rb +0 -9
- data/test/dummy/test/unit/helpers/content_page_helper_test.rb +0 -4
- data/test/factories.rb +0 -235
- data/test/fixtures/multipart/foo.jpg +0 -0
- data/test/fixtures/multipart/sample_upload.txt +0 -1
- data/test/fixtures/multipart/second_upload.txt +0 -1
- data/test/fixtures/multipart/test.jpg +0 -0
- data/test/fixtures/multipart/version1.txt +0 -1
- data/test/fixtures/multipart/version2.txt +0 -1
- data/test/functional/cms/cache_controller_test.rb +0 -16
- data/test/functional/cms/categories_controller_test.rb +0 -28
- data/test/functional/cms/connectors_controller_test.rb +0 -64
- data/test/functional/cms/content_block_controller_test.rb +0 -127
- data/test/functional/cms/content_controller_test.rb +0 -351
- data/test/functional/cms/dashboard_controller_test.rb +0 -20
- data/test/functional/cms/file_blocks_controller_test.rb +0 -55
- data/test/functional/cms/home_controller_test.rb +0 -160
- data/test/functional/cms/html_blocks_controller_test.rb +0 -159
- data/test/functional/cms/image_blocks_controller_test.rb +0 -78
- data/test/functional/cms/links_controller_test.rb +0 -92
- data/test/functional/cms/log/test.log +0 -0
- data/test/functional/cms/pages_controller_test.rb +0 -233
- data/test/functional/cms/portlets_controller_test.rb +0 -57
- data/test/functional/cms/sections_controller_test.rb +0 -234
- data/test/functional/cms/sessions_controller_test.rb +0 -80
- data/test/functional/cms/tasks_controller_test.rb +0 -64
- data/test/functional/cms/toolbar_controller_test.rb +0 -76
- data/test/functional/cms/users_controller_test.rb +0 -218
- data/test/integration/cms/password_management_test.rb +0 -66
- data/test/integration/sitemap_performance_test.rb +0 -26
- data/test/mock_file.rb +0 -33
- data/test/performance/browsing_test.rb +0 -9
- data/test/support/engine_controller_hacks.rb +0 -34
- data/test/support/factory_helpers.rb +0 -57
- data/test/support/rails_3_1_routes_hack.rb +0 -70
- data/test/test_helper.rb +0 -199
- data/test/test_logging.rb +0 -67
- data/test/unit/active_record_callbacks.rb +0 -50
- data/test/unit/behaviors/attaching_test.rb +0 -370
- data/test/unit/behaviors/cms_user_test.rb +0 -67
- data/test/unit/behaviors/connectable_test.rb +0 -32
- data/test/unit/behaviors/connecting_test.rb +0 -56
- data/test/unit/behaviors/dynamic_attributes_test.rb +0 -74
- data/test/unit/behaviors/namespacing_test.rb +0 -76
- data/test/unit/behaviors/publishable_test.rb +0 -83
- data/test/unit/behaviors/rendering_test.rb +0 -68
- data/test/unit/behaviors/searching_test.rb +0 -102
- data/test/unit/behaviors/taggable_test.rb +0 -110
- data/test/unit/behaviors/userstamping_test.rb +0 -27
- data/test/unit/behaviors/versioning_test.rb +0 -102
- data/test/unit/extensions/active_record/base_test.rb +0 -25
- data/test/unit/extensions/hash_test.rb +0 -26
- data/test/unit/extensions/integer_test.rb +0 -10
- data/test/unit/extensions/string_test.rb +0 -14
- data/test/unit/factories_test.rb +0 -50
- data/test/unit/generators/install_generator_test.rb +0 -15
- data/test/unit/helpers/application_helper_test.rb +0 -104
- data/test/unit/helpers/date_picker_test.rb +0 -17
- data/test/unit/helpers/menu_helper_test.rb +0 -240
- data/test/unit/helpers/page_helper_test.rb +0 -69
- data/test/unit/helpers/path_helper_test.rb +0 -38
- data/test/unit/helpers/rendering_helper_test.rb +0 -8
- data/test/unit/lib/acts_as_content_page_test.rb +0 -72
- data/test/unit/lib/cms/authentication/controller_test.rb +0 -20
- data/test/unit/lib/cms/engine_helper_test.rb +0 -119
- data/test/unit/lib/cms/sitemap_test.rb +0 -210
- data/test/unit/lib/cms_domain_support_test.rb +0 -44
- data/test/unit/lib/command_line_test.rb +0 -70
- data/test/unit/lib/content_block_test.rb +0 -304
- data/test/unit/lib/content_rendering_support_test.rb +0 -40
- data/test/unit/lib/generators_test.rb +0 -40
- data/test/unit/lib/routes_test.rb +0 -98
- data/test/unit/mock_file_test.rb +0 -19
- data/test/unit/models/attachment_test.rb +0 -160
- data/test/unit/models/category_test.rb +0 -40
- data/test/unit/models/category_type_test.rb +0 -8
- data/test/unit/models/connector_test.rb +0 -152
- data/test/unit/models/content_type_group_test.rb +0 -26
- data/test/unit/models/content_type_test.rb +0 -177
- data/test/unit/models/dynamic_views_test.rb +0 -36
- data/test/unit/models/email_page_portlet_test.rb +0 -20
- data/test/unit/models/file_block_test.rb +0 -246
- data/test/unit/models/group_test.rb +0 -29
- data/test/unit/models/html_block_test.rb +0 -121
- data/test/unit/models/image_block_test.rb +0 -35
- data/test/unit/models/link_test.rb +0 -52
- data/test/unit/models/namespaces_test.rb +0 -57
- data/test/unit/models/page_partial_test.rb +0 -37
- data/test/unit/models/page_route_test.rb +0 -113
- data/test/unit/models/page_template_test.rb +0 -50
- data/test/unit/models/page_test.rb +0 -879
- data/test/unit/models/permission_test.rb +0 -10
- data/test/unit/models/portlet_test.rb +0 -99
- data/test/unit/models/sections_test.rb +0 -278
- data/test/unit/models/site_test.rb +0 -50
- data/test/unit/models/task_test.rb +0 -150
- data/test/unit/models/user_test.rb +0 -358
- data/test/unit/schema_statements_test.rb +0 -137
- data/todo_list.markdown +0 -50
|
@@ -67,7 +67,9 @@ class Cms::SectionsController < Cms::BaseController
|
|
|
67
67
|
@move_to = Section.root.first
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
|
-
|
|
70
|
+
|
|
71
|
+
# Generates XML for Browsing files/pages/etc.
|
|
72
|
+
# @todo This MIGHT best live in the FCKeditor module, since it's XML format is highly coupled to that module's needs.
|
|
71
73
|
def file_browser
|
|
72
74
|
@section = Cms::Section.find_by_name_path(params[:CurrentFolder])
|
|
73
75
|
if request.post? && params[:NewFile]
|
|
@@ -112,7 +114,7 @@ class Cms::SectionsController < Cms::BaseController
|
|
|
112
114
|
else
|
|
113
115
|
@section.pages
|
|
114
116
|
end
|
|
115
|
-
render 'cms/sections/file_browser
|
|
117
|
+
render 'cms/sections/file_browser', :layout => false, :format=>:xml
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
def public_groups
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
module Cms
|
|
2
|
-
class ToolbarController < Cms::BaseController
|
|
2
|
+
class ToolbarController < Cms::BaseController
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
layout "cms/toolbar"
|
|
5
|
+
|
|
6
|
+
helper MobileHelper
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
if params[:page_toolbar] != "0"
|
|
10
|
+
@mode = params[:mode]
|
|
11
|
+
@page_toolbar_enabled = true
|
|
12
|
+
end
|
|
13
|
+
@page_version = params[:page_version]
|
|
14
|
+
@page = Page.find(params[:page_id]).as_of_version(params[:page_version]) if params[:page_id]
|
|
8
15
|
end
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
end
|
|
16
|
+
|
|
17
|
+
end
|
|
14
18
|
end
|
|
@@ -9,9 +9,9 @@ module Cms
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def searchable_sections(selected = nil)
|
|
12
|
-
root
|
|
12
|
+
root = Section.root.first
|
|
13
13
|
options = [['All sections', 'all'], [root.name, root.id]]
|
|
14
|
-
root.master_section_list.each { |s|
|
|
14
|
+
root.master_section_list.each { |s| options << [s.full_path, s.id] }
|
|
15
15
|
options_for_select(options, selected.to_i)
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -24,7 +24,7 @@ module Cms
|
|
|
24
24
|
text = select_tag(:version,
|
|
25
25
|
options_for_select(page.versions.all(:order => "version desc").map { |r|
|
|
26
26
|
["v#{r.version}: #{r.version_comment} by #{r.updated_by.login} at #{time_on_date(r.updated_at)}", r.version]
|
|
27
|
-
},
|
|
27
|
+
}, page.version),
|
|
28
28
|
:onchange => 'this.form.submit(); return false')
|
|
29
29
|
text << javascript_tag("$('version').selectedIndex = 0") if page.live?
|
|
30
30
|
text
|
|
@@ -54,7 +54,7 @@ module Cms
|
|
|
54
54
|
#
|
|
55
55
|
# @param [String] selector The CSS selector for the checkboxes that should be mass checked/unchecked.
|
|
56
56
|
def check_uncheck_tag(selector)
|
|
57
|
-
check_id
|
|
57
|
+
check_id = to_id(selector, "check")
|
|
58
58
|
uncheck_id = to_id(selector, "uncheck")
|
|
59
59
|
content_for :html_head do
|
|
60
60
|
html = <<HTML
|
|
@@ -71,7 +71,7 @@ HTML
|
|
|
71
71
|
javascript_tag html
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
"#{link_to "Check All", '#', :id=>check_id}, #{link_to "Uncheck All", '#', :id=>uncheck_id}".html_safe
|
|
74
|
+
"#{link_to "Check All", '#', :id => check_id}, #{link_to "Uncheck All", '#', :id => uncheck_id}".html_safe
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# @deprecated Use check_uncheck_tag instead. Retained for backwards compatibility w/ CMS implementations.
|
|
@@ -87,7 +87,7 @@ jQuery(function($) {
|
|
|
87
87
|
HTML
|
|
88
88
|
javascript_tag html
|
|
89
89
|
end
|
|
90
|
-
link_to name, '#', :id=>id
|
|
90
|
+
link_to name, '#', :id => id
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
# @deprecated Use check_uncheck_tag instead. Retained for backwards compatibility w/ CMS implementations.
|
|
@@ -103,7 +103,7 @@ jQuery(function($) {
|
|
|
103
103
|
HTML
|
|
104
104
|
javascript_tag html
|
|
105
105
|
end
|
|
106
|
-
link_to name, '#', :id=>id
|
|
106
|
+
link_to name, '#', :id => id
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def span_tag(content)
|
|
@@ -117,7 +117,7 @@ HTML
|
|
|
117
117
|
<div class="lt_button_content">
|
|
118
118
|
<span>#{ content }</span>
|
|
119
119
|
</div>
|
|
120
|
-
#{image_tag "cms/lt_button_r.gif", :style=>"margin-right: 10px;"}
|
|
120
|
+
#{image_tag "cms/lt_button_r.gif", :style => "margin-right: 10px;"}
|
|
121
121
|
</div>
|
|
122
122
|
LBW
|
|
123
123
|
button.html_safe
|
|
@@ -138,22 +138,26 @@ LBW
|
|
|
138
138
|
# Fetches a list of categories for a cms_drop_down. Will prompt users to create Categories/Categories types if the proper ones don't exist.
|
|
139
139
|
def categories_for(category_type_name, order="name")
|
|
140
140
|
cat_type = CategoryType.named(category_type_name).first
|
|
141
|
-
categories = cat_type ? cat_type.category_list(order) : [Category.new(:name=>"-- You must first create a 'Category Type' named '#{category_type_name}'")]
|
|
142
|
-
categories.empty? ? [Category.new(:name=>"-- You must first create a Category with a Category Type of '#{category_type_name}'.")]: categories
|
|
141
|
+
categories = cat_type ? cat_type.category_list(order) : [Category.new(:name => "-- You must first create a 'Category Type' named '#{category_type_name}'")]
|
|
142
|
+
categories.empty? ? [Category.new(:name => "-- You must first create a Category with a Category Type of '#{category_type_name}'.")] : categories
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
# Generates the HTML to render a paging control, if there is more than one page to be shown.
|
|
146
|
+
#
|
|
147
|
+
# @param [Array] collection List of content to be shown
|
|
148
|
+
# @param [Cms::ContentType] content_type The content type of the collection (used to generate links to Previous/Next)
|
|
149
|
+
# @param [Hash] options
|
|
150
|
+
def render_pagination(collection, content_type, options={})
|
|
146
151
|
if collection.blank?
|
|
147
152
|
content_tag(:div, "No Content", :class => "pagination")
|
|
148
153
|
else
|
|
149
|
-
collection_path = "#{collection_name}_path"
|
|
150
154
|
render :partial => "cms/shared/pagination", :locals => {
|
|
151
|
-
:collection
|
|
152
|
-
:first_page_path
|
|
153
|
-
:previous_page_path =>
|
|
154
|
-
:current_page_path
|
|
155
|
-
:next_page_path
|
|
156
|
-
:last_page_path
|
|
155
|
+
:collection => collection,
|
|
156
|
+
:first_page_path => cms_connectable_path(content_type, {:page => 1}.merge(options)),
|
|
157
|
+
:previous_page_path => cms_connectable_path(content_type, {:page => collection.previous_page ? collection.previous_page : 1}.merge(options)),
|
|
158
|
+
:current_page_path => cms_connectable_path(content_type, options),
|
|
159
|
+
:next_page_path => cms_connectable_path(content_type, {:page => collection.next_page ? collection.next_page : collection.current_page}.merge(options)),
|
|
160
|
+
:last_page_path => cms_connectable_path(content_type, {:page => collection.total_pages}.merge(options))
|
|
157
161
|
}
|
|
158
162
|
end
|
|
159
163
|
end
|
|
@@ -222,7 +226,7 @@ LBW
|
|
|
222
226
|
#
|
|
223
227
|
# @param [Path] The path or URL to link_to. Takes same types at url_for or link_to.
|
|
224
228
|
def add_button(path, options={})
|
|
225
|
-
classes
|
|
229
|
+
classes = "button"
|
|
226
230
|
span_options = {:class => classes}
|
|
227
231
|
link_to span_tag(" Add ".html_safe), path, span_options
|
|
228
232
|
end
|
|
@@ -12,21 +12,21 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
12
12
|
# * :width - The width for the select (defaults to 455px).
|
|
13
13
|
#
|
|
14
14
|
def drop_down(method, choices, options = {}, html_options = {})
|
|
15
|
-
select_class
|
|
16
|
-
h_opts
|
|
15
|
+
select_class = "#{@object_name}_#{method}"
|
|
16
|
+
h_opts = add_tabindex!(@default_options.merge(html_options))
|
|
17
17
|
h_opts[:class] = select_class
|
|
18
18
|
|
|
19
|
-
opts
|
|
19
|
+
opts = objectify_options(options)
|
|
20
20
|
set_default_value!(method, options)
|
|
21
21
|
cms_options = options.extract_only!(:default_value, :width)
|
|
22
22
|
render_cms_form_partial :fancy_drop_down,
|
|
23
23
|
:object_name => @object_name, :method => method,
|
|
24
|
-
:choices
|
|
24
|
+
:choices => choices, :options => opts,
|
|
25
25
|
:cms_options => cms_options, :html_options => h_opts
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def date_picker(method, options={})
|
|
29
|
-
text_field(method, {:size => 10, :class => "date_picker", :value=>Cms::DatePicker.format_for_ui(@object.send(method))}.merge(options))
|
|
29
|
+
text_field(method, {:size => 10, :class => "date_picker", :value => Cms::DatePicker.format_for_ui(@object.send(method))}.merge(options))
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def tag_list(options={})
|
|
@@ -51,13 +51,49 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
51
51
|
class_eval src, __FILE__, __LINE__
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# Returns a label for a given field
|
|
55
|
+
# @param [Symbol] field Name of the field
|
|
56
|
+
# @param [String] label_value If nil, will use default logic for Rails::FormBuilder#label
|
|
57
|
+
def cms_label(field, label_value)
|
|
58
|
+
if label_value
|
|
59
|
+
label field, label_value
|
|
60
|
+
else
|
|
61
|
+
label field
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Returns a file upload input tag for a given block, along with label and instructions.
|
|
66
|
+
#
|
|
67
|
+
# @param [Symbol] method The name of the model this form upload is associated with
|
|
68
|
+
# @param [Hash] options
|
|
69
|
+
# @option options [String] :label (Data)
|
|
70
|
+
# @option options [String] :instructions (blank) Helpful tips for the person entering the field, appears blank if nothing is specified.
|
|
71
|
+
# @option options [Boolean] :edit_path (false) If true, render a text field to allow users to edit path for this file.
|
|
72
|
+
# @option options [Boolean] :edit_section (false) If true, render a select box which allows users to choose which section this attachment should be placed in.
|
|
73
|
+
def cms_file_field(method, options={})
|
|
74
|
+
@object.ensure_attachment_exists if @object.respond_to?(:ensure_attachment_exists)
|
|
75
|
+
render_form_field("file_field", method, options)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Renders a multiple file uploader for attachments. Allows users to add as many attachments to this model as needed.
|
|
79
|
+
def cms_attachment_manager
|
|
80
|
+
defs = Cms::Attachment.definitions_for(object.class.name, :multiple)
|
|
81
|
+
names = defs.keys.sort
|
|
82
|
+
return if names.empty?
|
|
83
|
+
|
|
84
|
+
names.unshift "Select a type to upload a file" if names.size > 1
|
|
85
|
+
render_cms_form_partial :attachment_manager, :asset_definitions => defs, :asset_types => names
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @params html_options
|
|
89
|
+
# @options html_option [:class] - This will be overridden, so don't bother to set it
|
|
54
90
|
def cms_drop_down(method, choices, options={}, html_options={})
|
|
55
91
|
add_tabindex!(html_options)
|
|
56
92
|
set_default_value!(method, options)
|
|
57
93
|
cms_options = options.extract_only!(:label, :instructions, :default_value)
|
|
58
94
|
render_cms_form_partial :drop_down,
|
|
59
95
|
:object_name => @object_name, :method => method,
|
|
60
|
-
:choices
|
|
96
|
+
:choices => choices, :options => options,
|
|
61
97
|
:cms_options => cms_options, :html_options => html_options
|
|
62
98
|
end
|
|
63
99
|
|
|
@@ -86,20 +122,20 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
86
122
|
set_default_value!(method, options)
|
|
87
123
|
cms_options = options.extract_only!(:label, :instructions, :default_value)
|
|
88
124
|
render_cms_form_partial :text_editor,
|
|
89
|
-
:id
|
|
125
|
+
:id => (options[:id] || "#{@object_name}_#{method}"),
|
|
90
126
|
:editor_enabled => (cookies["editorEnabled"].blank? ? true : (cookies["editorEnabled"] == 'true' || cookies["editorEnabled"] == ['true'])),
|
|
91
|
-
:object_name
|
|
92
|
-
:options
|
|
127
|
+
:object_name => @object_name, :method => method,
|
|
128
|
+
:options => options, :cms_options => cms_options
|
|
93
129
|
end
|
|
94
130
|
|
|
95
131
|
# Renders instructions for a given field below the field itself. Instructions can be used to provide helpful
|
|
96
132
|
# guidance to content editors including formatting help or just explaining what a field is for.
|
|
97
133
|
#
|
|
98
|
-
#
|
|
134
|
+
# If instructions are blank/nil, then nothing will be shown.
|
|
99
135
|
#
|
|
100
|
-
#
|
|
136
|
+
# @param [String] instructions (blank) The help text to show
|
|
101
137
|
def cms_instructions(instructions)
|
|
102
|
-
render_cms_form_partial :instructions, :instructions=>instructions
|
|
138
|
+
render_cms_form_partial :instructions, :instructions => instructions
|
|
103
139
|
end
|
|
104
140
|
|
|
105
141
|
# Renders a label and checkbox suitable for allow editors to update a boolean field.
|
|
@@ -115,7 +151,7 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
115
151
|
add_tabindex!(options)
|
|
116
152
|
set_default_value!(method, options)
|
|
117
153
|
cms_options = options.extract_only!(:label, :instructions, :default_value)
|
|
118
|
-
render_cms_form_partial "check_box", :method=>method, :options => options, :cms_options => cms_options
|
|
154
|
+
render_cms_form_partial "check_box", :method => method, :options => options, :cms_options => cms_options
|
|
119
155
|
end
|
|
120
156
|
|
|
121
157
|
#
|
|
@@ -139,10 +175,10 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
139
175
|
set_default_value!(method, options)
|
|
140
176
|
options[:default_handler] = "erb" unless options[:default_handler]
|
|
141
177
|
|
|
142
|
-
cms_options
|
|
178
|
+
cms_options = options.extract_only!(:label, :instructions)
|
|
143
179
|
dropdown_options = options.extract_only!(:default_handler)
|
|
144
180
|
add_tabindex!(options)
|
|
145
|
-
render_cms_form_partial :template_editor, :method=>method, :dropdown_options=>dropdown_options, :options => options, :cms_options=>cms_options
|
|
181
|
+
render_cms_form_partial :template_editor, :method => method, :dropdown_options => dropdown_options, :options => options, :cms_options => cms_options
|
|
146
182
|
end
|
|
147
183
|
end
|
|
148
184
|
|
|
@@ -156,11 +192,23 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
156
192
|
errors_list << @template.content_tag(:p, "There were problems with the following fields:")
|
|
157
193
|
errors_list << @template.content_tag(:ul, object.errors.full_messages.map { |message| @template.content_tag(:li, message).html_safe }.join("\n").html_safe).html_safe
|
|
158
194
|
|
|
159
|
-
@template.content_tag(:div, errors_list.html_safe, :class => "errorExplanation", :id=>"errorExplanation")
|
|
195
|
+
@template.content_tag(:div, errors_list.html_safe, :class => "errorExplanation", :id => "errorExplanation")
|
|
160
196
|
end
|
|
161
197
|
|
|
162
198
|
private
|
|
163
199
|
|
|
200
|
+
def render_form_field(form_control_name, method, options)
|
|
201
|
+
add_tabindex!(options)
|
|
202
|
+
set_default_value!(method, options)
|
|
203
|
+
cms_options = options.extract!(:label, :instructions, :default_value)
|
|
204
|
+
render_cms_form_partial form_control_name.to_sym,
|
|
205
|
+
:model_object => @object,
|
|
206
|
+
:object_name => @object_name,
|
|
207
|
+
:method => method,
|
|
208
|
+
:options => options,
|
|
209
|
+
:cms_options => cms_options
|
|
210
|
+
end
|
|
211
|
+
|
|
164
212
|
def set_default_value!(method, options={})
|
|
165
213
|
if options.has_key?(:default_value) && @object.send(method).blank?
|
|
166
214
|
@object.send("#{method}=", options[:default_value])
|
|
@@ -182,8 +230,7 @@ class Cms::FormBuilder < ActionView::Helpers::FormBuilder
|
|
|
182
230
|
end
|
|
183
231
|
|
|
184
232
|
def render_cms_form_partial(field_type_name, locals)
|
|
185
|
-
@template.render :partial => "cms/form_builder/cms_#{field_type_name}",
|
|
186
|
-
:locals => {:f => self}.merge(locals)
|
|
233
|
+
@template.render :partial => "cms/form_builder/cms_#{field_type_name}", :locals => {:f => self}.merge(locals)
|
|
187
234
|
end
|
|
188
235
|
|
|
189
236
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Cms
|
|
2
|
+
module MobileHelper
|
|
3
|
+
|
|
4
|
+
def full_site_url
|
|
5
|
+
main_app.url_for(:host => Rails.configuration.cms.site_domain, :prefer_full_site => true)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def mobile_site_url
|
|
9
|
+
main_app.url_for(:host => Rails.configuration.cms.site_domain, :prefer_mobile_site => true)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Determines if the mobile template exists for a given page.
|
|
13
|
+
# Used by view to show/hide the mobile toggle.
|
|
14
|
+
def mobile_template_exists?(page)
|
|
15
|
+
controller.template_exists?(page.layout_name, "layouts/mobile")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -5,6 +5,30 @@ module Cms
|
|
|
5
5
|
# From app, should be cms.xyz_path
|
|
6
6
|
module PathHelper
|
|
7
7
|
|
|
8
|
+
# Returns the relative path to the given attachment.
|
|
9
|
+
# Content editors will see exact specific version path, while other users will see the 'public' url for the path.
|
|
10
|
+
def attachment_path_for(attachment)
|
|
11
|
+
return "" unless attachment
|
|
12
|
+
if current_user.able_to?(:edit_content)
|
|
13
|
+
attachment.attachment_version_path
|
|
14
|
+
else
|
|
15
|
+
attachment.url
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns a path to sort a table of Content Blocks by a given parameter. Retains other relevant parameters (like search criteria).
|
|
20
|
+
#
|
|
21
|
+
# @param [Cms::ContentType] content_type
|
|
22
|
+
# @param [String] column_to_sort The name of the column to sort on.
|
|
23
|
+
def cms_sortable_column_path(content_type, column_to_sort)
|
|
24
|
+
filtered_params = params.clone
|
|
25
|
+
filtered_params.delete(:action)
|
|
26
|
+
filtered_params.delete(:controller)
|
|
27
|
+
filtered_params.merge!(:order => determine_order(filtered_params[:order], column_to_sort))
|
|
28
|
+
cms_connectable_path(content_type.model_class, filtered_params)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @deprecated Use cms_connectable_path instead.
|
|
8
32
|
def cms_index_path_for(resource, options={})
|
|
9
33
|
polymorphic_path(build_path_for(resource), options)
|
|
10
34
|
end
|
|
@@ -23,6 +47,10 @@ module Cms
|
|
|
23
47
|
send("new_#{resource_collection_name(resource).underscore.gsub('/', '_')}_url", options)
|
|
24
48
|
end
|
|
25
49
|
|
|
50
|
+
# @param [Class, String] connectable The model class (i.e. HtmlBlock) or plural collection name (html_blocks) to link to
|
|
51
|
+
# @param [Hash] options Passed to polymorphic_path
|
|
52
|
+
#
|
|
53
|
+
# @return [String] path suitable to give to link_to
|
|
26
54
|
def cms_connectable_path(connectable, options={})
|
|
27
55
|
if Portlet === connectable
|
|
28
56
|
cms.portlet_path(connectable)
|
|
@@ -74,11 +102,9 @@ module Cms
|
|
|
74
102
|
|
|
75
103
|
private
|
|
76
104
|
|
|
105
|
+
|
|
77
106
|
def build_path_for(model_or_class_or_content_type)
|
|
78
|
-
|
|
79
|
-
path << engine_for(model_or_class_or_content_type)
|
|
80
|
-
path.concat path_elements_for(model_or_class_or_content_type)
|
|
81
|
-
path
|
|
107
|
+
Cms::EngineAwarePathBuilder.new(model_or_class_or_content_type).build(self)
|
|
82
108
|
end
|
|
83
109
|
|
|
84
110
|
# Returns the name of the collection that this resource belongs to
|
|
@@ -4,8 +4,16 @@
|
|
|
4
4
|
#
|
|
5
5
|
module Cms
|
|
6
6
|
module RenderingHelper
|
|
7
|
+
|
|
8
|
+
# Renders a table of attachments for a given content block.
|
|
9
|
+
# This is intended as a basic view of the content, and probably won't be suitable for blocks that need to be added directly to pages.
|
|
10
|
+
#
|
|
11
|
+
def attachment_viewer(content)
|
|
12
|
+
render :partial => 'cms/attachments/attachment_table', :locals => { :block => content, :can_delete => false }
|
|
13
|
+
end
|
|
14
|
+
|
|
7
15
|
def render_connector_and_connectable(connector, connectable)
|
|
8
|
-
logger.
|
|
16
|
+
logger.debug "Rendering #{connectable} "
|
|
9
17
|
if logged_in? && @mode == "edit" && current_user.able_to_edit?(connector.page)
|
|
10
18
|
render(:partial => 'cms/pages/edit_connector', :locals => { :connector => connector, :connectable => connectable})
|
|
11
19
|
else
|
|
@@ -2,23 +2,23 @@ module Cms
|
|
|
2
2
|
class AbstractFileBlock < ActiveRecord::Base
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
self.table_name = Namespacing.prefix("file_blocks")
|
|
6
6
|
|
|
7
7
|
validates_presence_of :name
|
|
8
8
|
|
|
9
9
|
scope :by_section, lambda { |section| {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
:include => {:attachment => :section_node},
|
|
11
|
+
:conditions => ["#{SectionNode.table_name}.ancestry = ?", section.node.ancestry_path]}
|
|
12
|
+
}
|
|
13
13
|
|
|
14
14
|
# Return the parent section for this block.
|
|
15
15
|
# @return [Cms::Section]
|
|
16
16
|
def parent
|
|
17
|
-
|
|
17
|
+
file.parent
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def path
|
|
21
|
-
|
|
21
|
+
file.url
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def self.publishable?
|
|
@@ -1,150 +1,149 @@
|
|
|
1
|
-
require 'digest/sha1'
|
|
2
|
-
require 'fileutils'
|
|
3
|
-
|
|
4
1
|
module Cms
|
|
5
2
|
class Attachment < ActiveRecord::Base
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
UNKNOWN_MIME_TYPE = 'application/octet-stream'
|
|
4
|
+
MULTIPLE = 'multiple'
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
is_publishable
|
|
13
|
-
uses_soft_delete
|
|
14
|
-
is_userstamped
|
|
15
|
-
is_versioned
|
|
6
|
+
SANITIZATION_REGEXES = [[/\s/, '_'], [/[&+()]/, '-'], [/[=?!'"{}\[\]#<>%]/, '']]
|
|
7
|
+
#' this tic cleans up emacs ruby mode
|
|
16
8
|
|
|
17
|
-
|
|
18
|
-
attr_accessor :uploaded_file
|
|
9
|
+
self.table_name = :cms_attachments
|
|
19
10
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
cattr_accessor :definitions, :instance_writer => false
|
|
12
|
+
@@definitions = {}.with_indifferent_access
|
|
13
|
+
cattr_reader :configuration
|
|
14
|
+
attr_accessor :attachable_class
|
|
15
|
+
attr_accessible :attachable_class
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
before_validation :extract_file_extension_from_file_name
|
|
28
|
-
before_validation :extract_file_type_from_temp_file
|
|
29
|
-
before_validation :extract_file_size_from_temp_file
|
|
30
|
-
before_validation :set_file_location
|
|
17
|
+
before_validation :set_cardinality
|
|
18
|
+
before_save :set_section, :sanitized_file_path_and_name
|
|
19
|
+
before_create :setup_attachment
|
|
31
20
|
|
|
32
|
-
|
|
33
|
-
after_save :clear_ivars
|
|
21
|
+
belongs_to :attachable, :polymorphic => true
|
|
34
22
|
|
|
23
|
+
include DefaultAccessible
|
|
24
|
+
attr_accessible :data, :attachable, :attachment_name
|
|
35
25
|
|
|
36
|
-
|
|
26
|
+
validates :attachment_name, :attachable_type, :presence => true
|
|
37
27
|
|
|
38
28
|
include Cms::Addressable
|
|
39
29
|
include Cms::Addressable::DeprecatedPageAccessors
|
|
40
30
|
has_one :section_node, :as => :node, :class_name => 'Cms::SectionNode'
|
|
41
31
|
alias :node :section_node
|
|
42
32
|
|
|
43
|
-
|
|
33
|
+
is_archivable; is_publishable; uses_soft_delete; is_userstamped; is_versioned
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
#TODO change this to a simple method
|
|
36
|
+
#def named(mid)
|
|
37
|
+
# find_all_by_name mid
|
|
38
|
+
# end
|
|
39
|
+
# ...or even get rid of it
|
|
40
|
+
scope :named, lambda { |name|
|
|
41
|
+
{:conditions => {:attachment_name => name.to_s}}
|
|
42
|
+
}
|
|
48
43
|
|
|
49
|
-
|
|
44
|
+
scope :multiple, :conditions => {:cardinality => MULTIPLE}
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
end
|
|
46
|
+
FILE_BLOCKS = "Cms::AbstractFileBlock"
|
|
47
|
+
validates_presence_of :data_file_path, :if => Proc.new { |a| a.attachable_type == FILE_BLOCKS }
|
|
48
|
+
validates_uniqueness_of :data_file_path, :message =>"must be unique. (Another file, image or page is already using '%{value}').", :if => Proc.new { |a| a.attachable_type == FILE_BLOCKS }
|
|
55
49
|
|
|
56
|
-
|
|
50
|
+
class << self
|
|
57
51
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
unless file_path.blank?
|
|
64
|
-
self.file_path = "/#{file_path}" unless file_path =~ /^\//
|
|
52
|
+
# Makes file paths more URL friendly
|
|
53
|
+
def sanitize_file_path(file_path)
|
|
54
|
+
SANITIZATION_REGEXES.inject(file_path.to_s) do |s, (regex, replace)|
|
|
55
|
+
s.gsub(regex, replace)
|
|
56
|
+
end
|
|
65
57
|
end
|
|
66
|
-
end
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
self.file_extension = file_name.split('.').last.to_s.downcase
|
|
59
|
+
def definitions_for(klass, type)
|
|
60
|
+
definitions[klass].inject({}) { |d, (k, v)| d[k.capitalize] = v if v["type"] == type; d }
|
|
71
61
|
end
|
|
72
|
-
end
|
|
73
62
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
def configuration
|
|
64
|
+
@@configuration ||= Cms::Attachments.configuration
|
|
65
|
+
end
|
|
77
66
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
# Returns a Proc that can be used to dynamically determine styles based on the Cms::Attachment class
|
|
68
|
+
#
|
|
69
|
+
# Paperclip can handle a :styles parameter which responds to :call(Paperclip::Attachment)
|
|
70
|
+
def dynamically_return_styles
|
|
71
|
+
lambda do |paperclip_attachment|
|
|
72
|
+
cms_attachment = paperclip_attachment.instance
|
|
73
|
+
|
|
74
|
+
# Look up the style for the given block
|
|
75
|
+
if cms_attachment.has_assigned_content_type?
|
|
76
|
+
configuration_value(cms_attachment.content_block_class, cms_attachment.attachment_name, :styles)
|
|
77
|
+
else # New attachments that aren't associated with an Attaching type yet have no styles
|
|
78
|
+
{}
|
|
79
|
+
end
|
|
81
80
|
end
|
|
82
81
|
end
|
|
83
|
-
end
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
self.file_size = temp_file.size
|
|
83
|
+
def find_live_by_file_path(path)
|
|
84
|
+
Attachment.published.not_archived.find_by_data_file_path path
|
|
88
85
|
end
|
|
89
|
-
end
|
|
90
86
|
|
|
91
|
-
# The file will be stored on disk at
|
|
92
|
-
# Attachment.storage_location/year/month/day/sha1
|
|
93
|
-
# The sha1 is a 40 character hash based on the original_filename
|
|
94
|
-
# of the file uploaded and the current time
|
|
95
|
-
def set_file_location
|
|
96
|
-
unless temp_file.blank?
|
|
97
|
-
sha1 = Digest::SHA1.hexdigest("#{temp_file.original_filename}#{Time.now.to_f}")
|
|
98
|
-
self.file_location = "#{Time.now.strftime("%Y/%m/%d")}/#{sha1}"
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
87
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
88
|
+
def configure_paperclip
|
|
89
|
+
# @todo This might be better done using subclasses of Attachment for each document instance.
|
|
90
|
+
# We could use single table inheritance to avoid needing to do meta configurations.
|
|
91
|
+
has_attached_file :data,
|
|
92
|
+
:url => configuration.url,
|
|
93
|
+
:path => configuration.path,
|
|
94
|
+
:styles => dynamically_return_styles,
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
96
|
+
# Needed for versioning so that we keep all previous files.
|
|
97
|
+
:preserve_files => true,
|
|
98
|
+
|
|
99
|
+
#TODO: enable custom processors
|
|
100
|
+
:processors => configuration.processors,
|
|
101
|
+
:default_url => configuration.default_url,
|
|
102
|
+
:default_style => configuration.default_style,
|
|
103
|
+
:use_timestamp => configuration.use_timestamp,
|
|
104
|
+
:whiny => configuration.whiny,
|
|
105
|
+
:storage => rail_config(:storage),
|
|
106
|
+
:s3_credentials => rail_config(:s3_credentials),
|
|
107
|
+
:bucket => rail_config(:s3_bucket)
|
|
113
108
|
|
|
114
|
-
if Cms.attachment_file_permission
|
|
115
|
-
FileUtils.chmod Cms.attachment_file_permission, full_file_location
|
|
116
|
-
end
|
|
117
109
|
end
|
|
118
|
-
end
|
|
119
110
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
end
|
|
111
|
+
# Looks up a value from Rails config
|
|
112
|
+
def rail_config(key)
|
|
113
|
+
Rails.configuration.cms.attachments[key]
|
|
114
|
+
end
|
|
125
115
|
|
|
126
|
-
|
|
116
|
+
# Looks up the configuration value given:
|
|
117
|
+
# @param [Class] block_class The class of a block which has an attachment.
|
|
118
|
+
# @param [String] name_of_attachment The name of the attachment association (i.e. if was 'has_attachment :photos' then pass 'photo')
|
|
119
|
+
# @param [Symbol] key The key for the value to be fetched (i.e. :styles)
|
|
120
|
+
#
|
|
121
|
+
def configuration_value(block_class, name_of_attachment, key)
|
|
122
|
+
class_definitions = definitions[block_class]
|
|
123
|
+
if class_definitions == nil
|
|
124
|
+
raise "Couldn't find any definitions for '#{block_class}'."
|
|
125
|
+
end
|
|
126
|
+
attachment_definition = class_definitions[name_of_attachment]
|
|
127
|
+
if attachment_definition == nil
|
|
128
|
+
raise "Verify that '#{block_class}' defines an attachment named ':#{name_of_attachment}'."
|
|
129
|
+
end
|
|
130
|
+
attachment_definition[key] || configuration.send(key)
|
|
131
|
+
end
|
|
127
132
|
|
|
128
|
-
def self.storage_location
|
|
129
|
-
@storage_location ||= File.join(Rails.root, "/tmp/uploads")
|
|
130
133
|
end
|
|
131
134
|
|
|
132
|
-
def self.storage_location=(storage_location)
|
|
133
|
-
@storage_location = storage_location
|
|
134
|
-
end
|
|
135
135
|
|
|
136
|
-
def
|
|
137
|
-
|
|
136
|
+
def section=(section)
|
|
137
|
+
dirty! if self.section != section
|
|
138
|
+
super(section)
|
|
138
139
|
end
|
|
139
140
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def file_name
|
|
143
|
-
file_path ? file_path.split('/').last : nil
|
|
141
|
+
def config_value_for(key)
|
|
142
|
+
self.class.configuration_value(content_block_class, attachment_name, key)
|
|
144
143
|
end
|
|
145
144
|
|
|
146
|
-
def
|
|
147
|
-
|
|
145
|
+
def content_block_class
|
|
146
|
+
attachable_class || attachable.try(:class).try(:name) || attachable_type
|
|
148
147
|
end
|
|
149
148
|
|
|
150
149
|
def icon
|
|
@@ -160,25 +159,115 @@ module Cms
|
|
|
160
159
|
:xml => %w[xml],
|
|
161
160
|
:zip => %w[zip rar tar gz tgz]
|
|
162
161
|
}.each do |icon, extensions|
|
|
163
|
-
return icon if extensions.include?(
|
|
162
|
+
return icon if extensions.include?(data_file_extension)
|
|
164
163
|
end
|
|
165
164
|
:file
|
|
166
165
|
end
|
|
167
166
|
|
|
167
|
+
# For authorized users, return the path to get the specific version of the file associated with this attachment.
|
|
168
|
+
# Guests should always get 'data_file_path' which is the public version of the asset.
|
|
169
|
+
def attachment_version_path
|
|
170
|
+
"/cms/attachments/#{id}?version=#{version}"
|
|
171
|
+
end
|
|
172
|
+
|
|
168
173
|
def public?
|
|
169
174
|
section ? section.public? : false
|
|
170
175
|
end
|
|
171
176
|
|
|
172
|
-
def
|
|
173
|
-
|
|
177
|
+
def is_image?
|
|
178
|
+
%w[jpg gif png jpeg].include?(data_file_extension)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Returns a Paperclip generated relative path to the file (with thumbnail sizing)
|
|
182
|
+
def url(style_name = configuration.default_style)
|
|
183
|
+
data.url(style_name)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Returns the absolute file location of the underlying asset
|
|
187
|
+
def path(style_name = configuration.default_style)
|
|
188
|
+
data.path(style_name)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def original_filename
|
|
192
|
+
data_file_name
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
alias :file_name :original_filename
|
|
196
|
+
|
|
197
|
+
def size
|
|
198
|
+
data_file_size
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def content_type
|
|
202
|
+
data_content_type
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
alias :file_type :content_type
|
|
206
|
+
|
|
207
|
+
# Returns the definitions for this particular attachment type.
|
|
208
|
+
# @return [Hash] Empty Hash if no definition have been defined for this attachment.
|
|
209
|
+
def config
|
|
210
|
+
content_defs = definitions[content_block_class] ? definitions[content_block_class] : {}
|
|
211
|
+
content_defs[attachment_name] ? content_defs[attachment_name] : {}
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Determines if this Attachment has access to configuration information yet. Until it is assigned to an Attaching object,
|
|
215
|
+
# it will lack style information.
|
|
216
|
+
def has_assigned_content_type?()
|
|
217
|
+
attachable_type && attachment_name
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
protected
|
|
221
|
+
|
|
222
|
+
private
|
|
223
|
+
|
|
224
|
+
def data_file_extension
|
|
225
|
+
data_file_name.split('.').last.downcase if data_file_name && data_file_name['.']
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Filter - Ensure that paths are going to URL friendly (and won't need encoding for special characters.')
|
|
229
|
+
def sanitized_file_path_and_name
|
|
230
|
+
if data_file_path
|
|
231
|
+
self.data_file_path = self.class.sanitize_file_path(data_file_path)
|
|
232
|
+
if !data_file_path.empty? && !data_file_path.starts_with?("/")
|
|
233
|
+
self.data_file_path = "/#{data_file_path}"
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
if data_file_name
|
|
238
|
+
self.data_file_name = self.class.sanitize_file_path(data_file_name)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def set_section
|
|
243
|
+
unless parent
|
|
244
|
+
self.parent = Section.root.first
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def setup_attachment
|
|
249
|
+
data.instance_variable_set :@url, config_value_for(:url)
|
|
250
|
+
data.instance_variable_set :@path, config_value_for(:path)
|
|
251
|
+
data.instance_variable_set :@styles, config_value_for(:styles)
|
|
252
|
+
data.instance_variable_set :@normalized_styles, nil
|
|
253
|
+
data.send :post_process_styles
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Attachments should always be configured with a cardinality
|
|
257
|
+
def set_cardinality
|
|
258
|
+
unless cardinality
|
|
259
|
+
self.cardinality = config[:type].to_s
|
|
260
|
+
end
|
|
261
|
+
|
|
174
262
|
end
|
|
175
263
|
|
|
176
264
|
# Forces this record to be changed, even if nothing has changed
|
|
177
265
|
# This is necessary if just the section.id has changed, for example
|
|
266
|
+
# test if this is necessary now that the attributes are in the
|
|
267
|
+
# model itself.
|
|
178
268
|
def dirty!
|
|
179
269
|
# Seems like a hack, is there a better way?
|
|
180
270
|
self.updated_at = Time.now
|
|
181
271
|
end
|
|
182
|
-
|
|
183
272
|
end
|
|
184
|
-
end
|
|
273
|
+
end
|