browsercms 3.4.2 → 3.5.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
File without changes
|
data/doc/release_notes.md
CHANGED
@@ -1,3 +1,62 @@
|
|
1
|
+
v3.5.0
|
2
|
+
======
|
3
|
+
|
4
|
+
This release includes a number of new features, including:
|
5
|
+
|
6
|
+
* Improved Attachments
|
7
|
+
* Mobile Friendly templates
|
8
|
+
* Rail 3.2 compatibility
|
9
|
+
* Improved Heroku support
|
10
|
+
|
11
|
+
See the upgrade instructions here for existing projects: https://github.com/browsermedia/browsercms/wiki/Upgrading-to-3.5.x-from-3.4.x
|
12
|
+
|
13
|
+
Improved Attachments
|
14
|
+
--------------------
|
15
|
+
|
16
|
+
Attachments have been completely reworked to use Paperclip (https://github.com/thoughtbot/paperclip).
|
17
|
+
|
18
|
+
* Each block can now have multiple attachments using different styles.
|
19
|
+
* Attachments can be defined as one to one (has_attachment :image) or be stored as a collection (has_many_attachments :photos).
|
20
|
+
* Upgrade migrations are provide to migrate file and data for older projects to the new attachment structure.
|
21
|
+
* New generators have been provided to create content blocks with the new attachment styles.
|
22
|
+
|
23
|
+
See this Attachments API guide for more details: https://github.com/browsermedia/browsercms/wiki/Attachments-API
|
24
|
+
|
25
|
+
Mobile
|
26
|
+
------
|
27
|
+
|
28
|
+
The CMS can now be configured to serve mobile optimized content, using a mobile subdomain and smart redirecting based on User Agents.
|
29
|
+
|
30
|
+
* Mobile Templates: Each template can have a 'mobile' version, which will be used when users request a mobile version of that page.
|
31
|
+
* Fallback Templates: Any page which lacks a mobile ready template will use the 'full' desktop template when displayed as mobile.
|
32
|
+
* Mobile Subdomain: Any requests to the mobile subdomain automatically serve mobile pages. m. is the assumed subdomain.
|
33
|
+
* Agent Redirection: Users on mobile devices can be automatically redirected to the mobile subdomain. (Handled via Apache User Agent detection.)
|
34
|
+
* Mobile Site Opt Out: Users on mobile device can opt to be redirected to the desktop site if they want. (Handled via a cookie)
|
35
|
+
* Mobile caching: The mobile and full sites have their own separate page cache, mean both can be served quickly by Apache.
|
36
|
+
* View as Mobile: Editors can preview the mobile templates while editing pages in the admin, if a page has a mobile template. Once in 'mobile' mode, all pages should be viewed as mobile until they disable it.
|
37
|
+
|
38
|
+
These features are originally from the bcms_mobile module, which has been inlined into the CMS core. See the [Mobile Setup Guide](https://github.com/browsermedia/browsercms/wiki/Setting-up-mobile-sites) for more information.
|
39
|
+
|
40
|
+
Improved Heroku Support
|
41
|
+
-----------------------
|
42
|
+
|
43
|
+
To better support deploying BrowserCMS to Heroku, we have put together a new guide: https://github.com/browsermedia/browsercms/wiki/Deploying-to-Heroku which covers what steps are required, as well as some considerations. For example, using Heroku requires storing files on an external service, so we refactored the core CMS and worked on a new Amazon S3 module (bcms_aws_s3) that will integrate with it.
|
44
|
+
|
45
|
+
As a side note, the CMS should work with Postgresql as well, based on our testing with Heroku (which uses Postgres by default).
|
46
|
+
|
47
|
+
Notable Fixes
|
48
|
+
-------------
|
49
|
+
|
50
|
+
* [#493] Add Mobile capability
|
51
|
+
* [#494] Speed up Cucumber Scenarios
|
52
|
+
* [#492] Upgrade to be Rails 3.2.x compatible
|
53
|
+
* [#509] Pagination works for custom blocks now
|
54
|
+
* [#508] Remove fancy file upload (probably unused and wasn't working anyway)
|
55
|
+
* [#519] Better support for Amazon/AWS S3
|
56
|
+
* [#521] Remove SITE_DOMAIN constant in favor of more conventional rails configuration methods
|
57
|
+
|
58
|
+
See the [detailed changelog](https://github.com/browsermedia/browsercms/compare/v3.4.0...v3.5.0.rc1) for more info.
|
59
|
+
|
1
60
|
v3.4.2
|
2
61
|
======
|
3
62
|
|
@@ -8,6 +67,13 @@ Maintenance Release
|
|
8
67
|
* [#470] Fix issue where loading throws errors on some OS's (Ubuntu)
|
9
68
|
|
10
69
|
|
70
|
+
v3.4.1
|
71
|
+
======
|
72
|
+
|
73
|
+
Maintenance Release
|
74
|
+
|
75
|
+
* [#490] Fix issue where Javascript errors occured when in Page edit mode
|
76
|
+
|
11
77
|
v3.4.0
|
12
78
|
======
|
13
79
|
|
@@ -63,6 +129,14 @@ Other Notable Fixes
|
|
63
129
|
|
64
130
|
See the [detailed changelog](https://github.com/browsermedia/browsercms/compare/v3.3.3...v3.4.0) for a complete list of changes, as well as the [Closed Tickets for 3.4.0](https://github.com/browsermedia/browsercms/issues?milestone=1&state=closed) for a complete list of closed items.
|
65
131
|
|
132
|
+
v3.3.4
|
133
|
+
======
|
134
|
+
|
135
|
+
Maintenance release
|
136
|
+
|
137
|
+
* [#503] - Searching and sort content blocks works
|
138
|
+
* [#472] - Sorting content blocks works
|
139
|
+
|
66
140
|
v3.3.3
|
67
141
|
======
|
68
142
|
|
data/lib/browsercms.rb
CHANGED
@@ -15,6 +15,9 @@ require 'cms/domain_support'
|
|
15
15
|
require 'cms/authoring'
|
16
16
|
require 'cms/date_picker'
|
17
17
|
require 'cms/content_rendering_support'
|
18
|
+
require 'cms/mobile_aware'
|
19
|
+
require 'cms/attachments/configuration'
|
20
|
+
require 'cms/default_accessible'
|
18
21
|
|
19
22
|
# This shouldn't be necessary, except for the need to get into the loadpath for testing.
|
20
23
|
require 'command_line'
|
@@ -11,13 +11,20 @@ module Cms
|
|
11
11
|
# Adds Content Block behavior to this class
|
12
12
|
#
|
13
13
|
# @param [Hash] options
|
14
|
+
# @option options [Boolean] :allow_attachments (true) Determines whether this content block can be marked as having attachments.
|
14
15
|
def acts_as_content_block(options={})
|
15
16
|
defaults = {
|
16
|
-
|
17
|
+
# Set default values here.
|
18
|
+
:allow_attachments => true
|
17
19
|
}
|
18
20
|
options = defaults.merge(options)
|
19
21
|
|
20
|
-
|
22
|
+
if options[:belongs_to_attachment].present?
|
23
|
+
raise ArgumentError.new ":belongs_to_attachment option is no longer supported. Please use :has_attachments option"
|
24
|
+
end
|
25
|
+
|
26
|
+
include Cms::DefaultAccessible
|
27
|
+
allow_attachments if options[:allow_attachments]
|
21
28
|
is_archivable(options[:archiveable].is_a?(Hash) ? options[:archiveable] : {}) unless options[:archiveable] == false
|
22
29
|
is_connectable(options[:connectable].is_a?(Hash) ? options[:connectable] : {}) unless options[:connectable] == false
|
23
30
|
flush_cache_on_change(options[:flush_cache_on_change].is_a?(Hash) ? options[:flush_cache_on_change] : {}) unless options[:flush_cache_on_change] == false
|
@@ -30,6 +37,7 @@ module Cms
|
|
30
37
|
is_versioned(options[:versioned].is_a?(Hash) ? options[:versioned] : {}) unless options[:versioned] == false
|
31
38
|
|
32
39
|
include InstanceMethods
|
40
|
+
extend Cms::Behaviors::Naming
|
33
41
|
end
|
34
42
|
|
35
43
|
module InstanceMethods
|
data/lib/cms/addressable.rb
CHANGED
@@ -4,6 +4,10 @@
|
|
4
4
|
module Cms
|
5
5
|
module Addressable
|
6
6
|
|
7
|
+
def self.included(model_class)
|
8
|
+
model_class.attr_accessible :parent
|
9
|
+
end
|
10
|
+
|
7
11
|
# Returns a list of all Addressable objects that are ancestors to this record.
|
8
12
|
# @param [Hash] options
|
9
13
|
# @option [Symbol] :include_self If this object should be included in the Array
|
@@ -57,6 +61,10 @@ module Cms
|
|
57
61
|
# These exist for backwards compatibility to avoid having to change tests.
|
58
62
|
# I want to get rid of these in favor of parent and parent_id
|
59
63
|
module DeprecatedPageAccessors
|
64
|
+
|
65
|
+
def self.included(model_class)
|
66
|
+
model_class.attr_accessible :section_id, :section
|
67
|
+
end
|
60
68
|
include LeafNode
|
61
69
|
include NodeAccessors
|
62
70
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Cms
|
2
|
+
module Attachments
|
3
|
+
|
4
|
+
# Can be added to Controllers to handle serving files.
|
5
|
+
module Serving
|
6
|
+
|
7
|
+
# Send the file if:
|
8
|
+
# 1. It exists:
|
9
|
+
# 2. The user has permissions to see it.
|
10
|
+
#
|
11
|
+
# The strategy used to send the file can be configured based on the config.cms.attachments.storage parameter.
|
12
|
+
# Default is:
|
13
|
+
# storage = :filesystem -> Cms::Attachments::FilesystemStrategy
|
14
|
+
def send_attachment(attachment)
|
15
|
+
if attachment
|
16
|
+
raise Cms::Errors::AccessDenied unless current_user.able_to_view?(attachment)
|
17
|
+
strategy_class = send_attachments_with
|
18
|
+
strategy_class.send_attachment(attachment, self)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def send_attachments_with
|
23
|
+
Cms::Attachments::Serving.send_attachments_with
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [#send_attachments] The strategy that will be used to serve files.
|
27
|
+
def self.send_attachments_with
|
28
|
+
storage = Rails.configuration.cms.attachments.storage
|
29
|
+
"Cms::Attachments::#{storage.to_s.classify}Strategy".constantize
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
class FilesystemStrategy
|
35
|
+
|
36
|
+
def self.attachments_storage_location
|
37
|
+
Rails.configuration.cms.attachments.storage_directory
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.send_attachment(attachment, controller)
|
41
|
+
style = controller.params[:style]
|
42
|
+
style = "original" unless style
|
43
|
+
path_to_file = attachment.path(style)
|
44
|
+
if File.exists?(path_to_file)
|
45
|
+
Rails.logger.debug "Sending file #{path_to_file}"
|
46
|
+
controller.send_file(path_to_file,
|
47
|
+
:filename => attachment.file_name,
|
48
|
+
:type => attachment.file_type,
|
49
|
+
:disposition => "inline"
|
50
|
+
)
|
51
|
+
else
|
52
|
+
msg = "Couldn't find file #{path_to_file}'"
|
53
|
+
Rails.logger.error msg
|
54
|
+
raise ActiveRecord::RecordNotFound.new(msg)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'paperclip'
|
2
|
+
require 'cms/attachments/attachment_serving'
|
3
|
+
|
4
|
+
module Cms
|
5
|
+
# Cms::Attachments::Configuration exposes an interface to setup paperclip for BrowserCMS.
|
6
|
+
#
|
7
|
+
# Provides defaults that are suitable for the CMS and that probably make sense for most installations.
|
8
|
+
#
|
9
|
+
#This module also declares Paperclip interpolations that are used
|
10
|
+
#to construct the default url and path.
|
11
|
+
#
|
12
|
+
# For example, the default path:
|
13
|
+
#
|
14
|
+
# ":attachments_root/:id_partition/:style/:fingerprint"
|
15
|
+
#
|
16
|
+
# expands to something like:
|
17
|
+
#
|
18
|
+
# #{Rails.root}/tmp/uploads/2011/1/30/thumb/thcu098rc87dgd
|
19
|
+
#
|
20
|
+
# but can be changed by using paperclip interpolations, either
|
21
|
+
# the ones already defined by Paperlip itself, the Cms::Assets
|
22
|
+
# module, or user defined.
|
23
|
+
module Attachments
|
24
|
+
mattr_accessor :configuration
|
25
|
+
|
26
|
+
def self.configure
|
27
|
+
configuration = self.configuration
|
28
|
+
yield configuration if block_given?
|
29
|
+
@@configuration = configuration
|
30
|
+
Attachment.configure_paperclip
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.configuration
|
34
|
+
@@configuration || Configuration.new
|
35
|
+
end
|
36
|
+
|
37
|
+
# Allows each Attachment to have a customized configuration, even though there is a single Attachment class.
|
38
|
+
# Designed to allow 'typical' Paperclip configuration to be specified per attachment.
|
39
|
+
class Configuration
|
40
|
+
attr_accessor :url, :path, :styles, :processors, :default_url, :default_style, :storage, :whiny
|
41
|
+
attr_accessor :s3_credentials, :bucket
|
42
|
+
attr_accessor :file_permissions
|
43
|
+
|
44
|
+
attr_reader :use_timestamp
|
45
|
+
|
46
|
+
# Set default configurations for Attachments.
|
47
|
+
def initialize
|
48
|
+
self.url = ":attachment_file_path"
|
49
|
+
self.path = ":attachments_root/:id_partition/:style/:fingerprint"
|
50
|
+
self.styles = {}
|
51
|
+
self.processors = [:thumbnail]
|
52
|
+
self.default_url = "/:attachment/:style/missing.png"
|
53
|
+
self.default_style = :original
|
54
|
+
self.storage = :filesystem
|
55
|
+
self.whiny = false
|
56
|
+
|
57
|
+
@use_timestamp = false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# This is the typical url for attachments
|
63
|
+
# Some attachments will have a custom path (data_file_path) specified by users
|
64
|
+
# while others will just be 'defaults'. This dynamically returns path at runtime based
|
65
|
+
# on the instance of the specific instance.
|
66
|
+
Paperclip.interpolates :attachment_file_path do |asset, style|
|
67
|
+
path = asset.instance.data_file_path
|
68
|
+
unless path
|
69
|
+
path = "/attachments/#{asset.instance.id}/#{asset.instance.data_file_name}"
|
70
|
+
end
|
71
|
+
if style && style != :original
|
72
|
+
"#{path}?style=#{style}"
|
73
|
+
else
|
74
|
+
path
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
Paperclip.interpolates :attachments_root do |_, _|
|
79
|
+
strategy = Cms::Attachments::Serving.send_attachments_with
|
80
|
+
strategy.attachments_storage_location
|
81
|
+
end
|
82
|
+
|
83
|
+
Paperclip.interpolates :full_filename do |asset, _|
|
84
|
+
"#{asset.instance.content_block_class}_#{asset.instance.data_file_name}"
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -1,207 +1,376 @@
|
|
1
1
|
module Cms
|
2
|
+
# @todo Comments need to be cleaned up to get rid of 'uses_paperclip'
|
2
3
|
module Behaviors
|
4
|
+
# Allows one or more files to be attached to content blocks.
|
5
|
+
#
|
6
|
+
# class Book
|
7
|
+
# acts_as_content_block
|
8
|
+
# uses_paperclip
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# It would probably be nice to do something like:
|
12
|
+
#
|
13
|
+
# class Book
|
14
|
+
# acts_as_content_block :uses_paperclip => true
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# has_attached_asset and has_many_attached_assets are very similar.
|
18
|
+
# They both define a couple of methods in the content block:
|
19
|
+
#
|
20
|
+
# class Book
|
21
|
+
# uses_paperclip
|
22
|
+
#
|
23
|
+
# has_attached_asset :cover
|
24
|
+
# has_many_attached_assets :drafts
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# book = Book.new
|
28
|
+
# book.cover = nil #is basically calling: book.assets.named(:cover).first
|
29
|
+
# book.drafts = [] #is calling book.assets.named(:drafts)
|
30
|
+
#
|
31
|
+
# Book#cover and Book#drafts both return Asset objects as opposed to what
|
32
|
+
# happens with stand alone Paperclip:
|
33
|
+
#
|
34
|
+
# class Book
|
35
|
+
# has_attached_file :invoice #straight Paperclip
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Book.new.invoice # returns an instance of Paperclip::Attachment
|
39
|
+
#
|
40
|
+
# However, Asset instances respond to most of the same methods
|
41
|
+
# Paperclip::Attachments do (at least the most usefull ones and the ones
|
42
|
+
# that make sense for this implementation). Please see asset.rb for more on
|
43
|
+
# this.
|
44
|
+
#
|
45
|
+
# At the moment, calling has_attached_asset does not enforce that only
|
46
|
+
# one asset is created, it only defines a method that returns the first one
|
47
|
+
# ActiveRecord finds. It would be possible to do if that makes sense.
|
48
|
+
#
|
49
|
+
# In terms of validations, I'm aiming to expose the same 3 class methods
|
50
|
+
# Paperclip exposes, apart from those needed by BCMS itself (like enforcing
|
51
|
+
# unique attachment paths) but this is not ready yet:
|
52
|
+
#
|
53
|
+
# validates_asset_size
|
54
|
+
# validates_asset_presence
|
55
|
+
# validates_asset_content_type
|
56
|
+
#
|
3
57
|
module Attaching
|
4
|
-
SANITIZATION_REGEXES = [[/\s/, '_'], [/[&+()]/, '-'], [/[=?!'"{}\[\]#<>%]/, '']]
|
5
|
-
#' this tic cleans up emacs ruby mode
|
6
58
|
|
7
|
-
def self.included(
|
8
|
-
|
59
|
+
def self.included(base)
|
60
|
+
base.extend MacroMethods
|
9
61
|
end
|
10
62
|
|
11
63
|
module MacroMethods
|
12
|
-
def belongs_to_attachment?
|
13
|
-
!!@belongs_to_attachment
|
14
|
-
end
|
15
64
|
|
16
|
-
|
17
|
-
|
65
|
+
# Adds additional behavior to a model which allows it to have attachments.
|
66
|
+
# Typically, clients will not need to call this directly. Enabling attachments is normally done via:
|
67
|
+
#
|
68
|
+
# acts_as_content_block :allow_attachments => false
|
69
|
+
#
|
70
|
+
## By default, blocks can have attachments.
|
71
|
+
def allow_attachments
|
72
|
+
extend ClassMethods
|
73
|
+
extend Validations
|
18
74
|
include InstanceMethods
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
75
|
+
|
76
|
+
# Allows a block to be associated with a list of uploaded attachments (done via AJAX)
|
77
|
+
attr_accessor :attachment_id_list
|
78
|
+
|
79
|
+
Cms::Attachment.definitions[self.name] = {}
|
80
|
+
has_many :attachments, :as => :attachable, :dependent => :destroy, :class_name => 'Cms::Attachment', :autosave => false
|
81
|
+
|
82
|
+
accepts_nested_attributes_for :attachments,
|
83
|
+
:allow_destroy => true,
|
84
|
+
# New attachments must have an uploaded file
|
85
|
+
:reject_if => lambda { |a| a[:data].blank? && a[:id].blank? }
|
86
|
+
attr_accessible :attachments_attributes, :attachment_id_list
|
87
|
+
|
88
|
+
validates_associated :attachments
|
89
|
+
before_validation :initialize_attachments, :check_for_updated_attachments
|
90
|
+
after_validation :filter_generic_attachment_errors
|
91
|
+
|
92
|
+
before_create :associate_new_attachments
|
93
|
+
before_save :ensure_status_matches_attachable
|
94
|
+
|
95
|
+
after_save :save_associated_attachments
|
96
|
+
|
35
97
|
end
|
36
98
|
end
|
37
|
-
module InstanceMethods
|
38
99
|
|
39
|
-
|
40
|
-
|
100
|
+
#NOTE: Assets should be validated when created individually.
|
101
|
+
module Validations
|
102
|
+
def validates_attachment_size(name, options = {})
|
103
|
+
|
104
|
+
min = options[:greater_than] || (options[:in] && options[:in].first) || 0
|
105
|
+
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
|
106
|
+
range = (min..max)
|
107
|
+
message = options[:message] || "#{name.to_s.capitalize} file size must be between :min and :max bytes."
|
108
|
+
message = message.gsub(/:min/, min.to_s).gsub(/:max/, max.to_s)
|
109
|
+
|
110
|
+
#options[:unless] = Proc.new {|r| r.a.asset_name != name.to_s}
|
111
|
+
|
112
|
+
validate(options) do |record|
|
113
|
+
record.attachments.each do |attachment|
|
114
|
+
next unless attachment.attachment_name == name.to_s
|
115
|
+
record.errors.add_to_base(message) unless range.include?(attachment.data_file_size)
|
116
|
+
end
|
117
|
+
end
|
41
118
|
end
|
42
119
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
120
|
+
def validates_attachment_presence(name, options = {})
|
121
|
+
message = options[:message] || "Must provide at least one #{name}"
|
122
|
+
validate(options) do |record|
|
123
|
+
record.errors.add(:attachment, message) unless record.attachments.any? { |a| a.attachment_name == name.to_s }
|
47
124
|
end
|
48
125
|
end
|
49
126
|
|
50
|
-
def
|
51
|
-
|
127
|
+
def validates_attachment_content_type(name, options = {})
|
128
|
+
validation_options = options.dup
|
129
|
+
allowed_types = [validation_options[:content_type]].flatten
|
130
|
+
validate(validation_options) do |record|
|
131
|
+
attachments.each do |a|
|
132
|
+
if !allowed_types.any? { |t| t === a.data_content_type } && !(a.data_content_type.nil? || a.data_content_type.blank?)
|
133
|
+
record.add_to_base(options[:message] || "is not one of #{allowed_types.join(', ')}")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
52
138
|
end
|
53
139
|
|
54
|
-
|
55
|
-
|
140
|
+
# Define at :set_attachment_path if you would like to override the way file_path is set
|
141
|
+
def handle_setting_attachment_path
|
142
|
+
if self.respond_to? :set_attachment_path
|
143
|
+
set_attachment_path
|
144
|
+
else
|
145
|
+
use_default_attachment_path
|
146
|
+
end
|
56
147
|
end
|
148
|
+
end
|
149
|
+
|
150
|
+
module ClassMethods
|
151
|
+
|
152
|
+
|
153
|
+
# Defines an single attachement with a given name.
|
154
|
+
#
|
155
|
+
# @param [Symbol] name The name of the attachment
|
156
|
+
# @param [Hash] options Accepts most Paperclip options for Paperclip::ClassMethods.has_attached_file
|
157
|
+
# @see http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods:has_attached_file
|
158
|
+
def has_attachment(name, options = {})
|
159
|
+
options[:type] = :single
|
160
|
+
options[:index] = Cms::Attachment.definitions[self.name].size
|
161
|
+
Cms::Attachment.definitions[self.name][name] = options
|
57
162
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
163
|
+
define_method name do
|
164
|
+
attachment_named(name)
|
165
|
+
end
|
166
|
+
define_method "#{name}?" do
|
167
|
+
(attachment_named(name) != nil)
|
63
168
|
end
|
64
169
|
end
|
65
170
|
|
66
|
-
|
67
|
-
|
171
|
+
# Allows multiple attachments under a specific name.
|
172
|
+
#
|
173
|
+
# @param [Symbol] name The name of the attachments.
|
174
|
+
# @param [Hash] options Accepts most Paperclip options for Paperclip::ClassMethods.has_attached_file
|
175
|
+
# @see http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods:has_attached_file
|
176
|
+
def has_many_attachments(name, options = {})
|
177
|
+
options[:type] = :multiple
|
178
|
+
Cms::Attachment.definitions[self.name][name] = options
|
179
|
+
|
180
|
+
define_method name do
|
181
|
+
attachments.named name
|
182
|
+
end
|
183
|
+
|
184
|
+
define_method "#{name}?" do
|
185
|
+
!attachments.named(name).empty?
|
186
|
+
end
|
68
187
|
end
|
69
188
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
189
|
+
# Find all attachments as of the given version for the specified block. Excludes attachments that were
|
190
|
+
# deleted as of a version.
|
191
|
+
#
|
192
|
+
# @param [Integer] version_number
|
193
|
+
# @param [Attaching] attachable The object with attachments
|
194
|
+
# @return [Array<Cms::Attachment>]
|
195
|
+
def attachments_as_of_version(version_number, attachable)
|
196
|
+
found_versions = Cms::Attachment::Version.where(:attachable_id => attachable.id).
|
197
|
+
where(:attachable_type => attachable.attachable_type).
|
198
|
+
where(:attachable_version => version_number).
|
199
|
+
order(:version).all
|
200
|
+
found_attachments = []
|
201
|
+
|
202
|
+
found_versions.each do |av|
|
203
|
+
record = av.build_object_from_version
|
204
|
+
found_attachments << record
|
74
205
|
end
|
206
|
+
found_attachments.delete_if { |value| value.deleted? }
|
207
|
+
found_attachments
|
75
208
|
end
|
76
209
|
|
77
|
-
|
78
|
-
|
210
|
+
# Return all definitions for a given class.
|
211
|
+
def definitions_for(name)
|
212
|
+
Cms::Attachment.definitions[self.name][name]
|
79
213
|
end
|
214
|
+
end
|
80
215
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
216
|
+
module InstanceMethods
|
217
|
+
|
218
|
+
# This ensures that if a change is made to an attachment, that this model is also marked as changed.
|
219
|
+
# Otherwise, if the change isn't detected, this record won't save a new version (since updates are rejected if no changes were made)
|
220
|
+
def check_for_updated_attachments
|
221
|
+
attachments.each do |a|
|
222
|
+
if a.changed?
|
223
|
+
changed_attributes['attachments'] = "Uploaded new files"
|
224
|
+
end
|
86
225
|
end
|
87
226
|
end
|
88
227
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
return false
|
95
|
-
end
|
96
|
-
unless attachment_section_id.blank?
|
97
|
-
errors.add(:attachment_file, "You must upload a file")
|
98
|
-
return false
|
99
|
-
end
|
100
|
-
else
|
101
|
-
build_attachment if attachment.nil?
|
102
|
-
attachment.temp_file = attachment_file
|
103
|
-
handle_setting_attachment_path
|
104
|
-
if attachment.file_path.blank?
|
105
|
-
errors.add(:attachment_file_path, "File Name is required for attachment")
|
106
|
-
return false
|
107
|
-
end
|
108
|
-
handle_setting_attachment_section
|
109
|
-
unless attachment.section
|
110
|
-
errors.add(:attachment_file, "Section is required for attachment")
|
111
|
-
return false
|
112
|
-
end
|
228
|
+
# Returns a list of all attachments this content type has defined.
|
229
|
+
# @return [Array<String>] Names
|
230
|
+
def attachment_names
|
231
|
+
Cms::Attachment.definitions[self.class.name].keys
|
232
|
+
end
|
113
233
|
|
114
|
-
|
234
|
+
def after_publish
|
235
|
+
attachments.each &:publish
|
115
236
|
end
|
116
237
|
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
else
|
122
|
-
use_default_attachment_path
|
123
|
-
end
|
238
|
+
# Locates the attachment with a given name
|
239
|
+
# @param [Symbol] name The name of the attachment
|
240
|
+
def attachment_named(name)
|
241
|
+
attachments.select { |item| item.attachment_name.to_sym == name }.first
|
124
242
|
end
|
125
243
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
@attachment_section_id = nil
|
130
|
-
@attachment_section = nil
|
244
|
+
def unassigned_attachments
|
245
|
+
return [] if attachment_id_list.blank?
|
246
|
+
Cms::Attachment.find attachment_id_list.split(',').map(&:to_i)
|
131
247
|
end
|
132
248
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
249
|
+
def all_attachments
|
250
|
+
attachments << unassigned_attachments
|
251
|
+
end
|
252
|
+
|
253
|
+
def attachable_type
|
254
|
+
self.class.name
|
140
255
|
end
|
141
256
|
|
142
|
-
#
|
143
|
-
|
144
|
-
|
145
|
-
|
257
|
+
# Versioning Callback - This will result in a new version of attachments being created every time the attachable is updated.
|
258
|
+
# Allows a complete version history to be reconstructed.
|
259
|
+
# @param [Versionable] new_version
|
260
|
+
def after_build_new_version(new_version)
|
261
|
+
attachments.each do |a|
|
262
|
+
a.attachable_version = new_version.version
|
146
263
|
end
|
147
264
|
end
|
148
265
|
|
149
|
-
|
150
|
-
|
151
|
-
|
266
|
+
# Version Callback - Reconstruct this object exactly as it was as of a particularly version
|
267
|
+
# Called after the object is 'reset' to the specific version in question.
|
268
|
+
def after_as_of_version()
|
269
|
+
@attachments_as_of = self.class.attachments_as_of_version(version, self)
|
270
|
+
|
271
|
+
|
272
|
+
# Override #attachments to return the original attachments for the current version.
|
273
|
+
metaclass = class << self;
|
274
|
+
self;
|
275
|
+
end
|
276
|
+
metaclass.send :define_method, :attachments do
|
277
|
+
@attachments_as_of
|
152
278
|
end
|
153
279
|
end
|
154
280
|
|
155
|
-
|
156
|
-
|
157
|
-
|
281
|
+
# Callback - Ensure attachments get reverted whenver a block does.
|
282
|
+
def after_revert(version)
|
283
|
+
version_number = version.version
|
284
|
+
attachments.each do |a|
|
285
|
+
a.revert_to(version_number, {:attachable_version => self.version+1})
|
158
286
|
end
|
159
287
|
end
|
160
288
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
logger.warn "Attachment was saved = #{saved_attach}"
|
289
|
+
# Ensures that attachments exist for form, since it uses attachments.each to iterate over them.
|
290
|
+
# Design Qualm: I don't like that this method has to exist, since its basically obscuring the fact that
|
291
|
+
# individual attachments don't exist when an object is created.
|
292
|
+
def ensure_attachment_exists
|
293
|
+
attachment_names.each do |n|
|
294
|
+
unless attachment_named(n.to_sym)
|
295
|
+
# Can't use attachments.build because sometimes its an array
|
296
|
+
attachments << Attachment.new(:attachment_name => n, :attachable => self)
|
170
297
|
end
|
171
|
-
self.attachment_version = attachment.draft.version
|
172
298
|
end
|
173
299
|
end
|
174
300
|
|
175
|
-
|
176
|
-
|
301
|
+
# @return [Array<Cms::Attachment>]
|
302
|
+
def multiple_attachments
|
303
|
+
attachments.select { |a| a.cardinality == Attachment::MULTIPLE }
|
177
304
|
end
|
178
305
|
|
179
|
-
|
180
|
-
|
181
|
-
|
306
|
+
private
|
307
|
+
|
308
|
+
# Saves associated attachments if they were updated. (Used in place of :autosave=>true, since the CMS Versioning API seems to break that)
|
309
|
+
#
|
310
|
+
# ActiveRecord Callback
|
311
|
+
def save_associated_attachments
|
312
|
+
attachments.each do |a|
|
313
|
+
a.save if a.changed?
|
314
|
+
end
|
182
315
|
end
|
183
316
|
|
184
|
-
|
185
|
-
|
186
|
-
|
317
|
+
|
318
|
+
# Filter - Ensures that the status of all attachments matches the this block
|
319
|
+
def ensure_status_matches_attachable
|
320
|
+
if self.class.archivable?
|
321
|
+
attachments.each do |a|
|
322
|
+
a.archived = self.archived
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
if self.class.publishable?
|
327
|
+
attachments.each do |a|
|
328
|
+
a.publish_on_save = self.publish_on_save
|
329
|
+
end
|
187
330
|
end
|
188
331
|
end
|
189
332
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
333
|
+
# Handles assigning attachments that were created via use of
|
334
|
+
# the cms_asset manager.
|
335
|
+
#
|
336
|
+
# Since Attachments are created via AJAX, we need to go back and associate those with this Attaching object.
|
337
|
+
def associate_new_attachments
|
338
|
+
unless attachment_id_list.blank?
|
339
|
+
ids = attachment_id_list.split(',').map(&:to_i)
|
340
|
+
ids.each do |i|
|
341
|
+
begin
|
342
|
+
attachment = Cms::Attachment.find(i)
|
343
|
+
rescue ActiveRecord::RecordNotFound
|
344
|
+
end
|
345
|
+
|
346
|
+
# Previously saved attachments shouldn't have an attachable_version or attachable_id yet.
|
347
|
+
if attachment
|
348
|
+
attachment.attachable_version = self.version
|
349
|
+
attachments << attachment
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|
195
353
|
end
|
196
354
|
end
|
197
355
|
|
198
|
-
#
|
199
|
-
|
200
|
-
|
201
|
-
# Seems like a hack, is there a better way?
|
202
|
-
self.updated_at = Time.now
|
356
|
+
# We don't want errors like: Attachments is invalid showing up, since they are duplicates
|
357
|
+
def filter_generic_attachment_errors
|
358
|
+
filter_errors_named([:attachments])
|
203
359
|
end
|
204
360
|
|
361
|
+
def initialize_attachments
|
362
|
+
attachments.each { |a| a.attachable_class = self.class.name }
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
private
|
367
|
+
def filter_errors_named(filter_list)
|
368
|
+
filtered_errors = self.errors.reject { |err| filter_list.include?(err.first) }
|
369
|
+
|
370
|
+
# reset the errors collection and repopulate it with the filtered errors.
|
371
|
+
self.errors.clear
|
372
|
+
filtered_errors.each { |err| self.errors.add(*err) }
|
373
|
+
end
|
205
374
|
end
|
206
375
|
end
|
207
376
|
end
|