zena 1.0.0.beta3 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +29 -0
- data/Rakefile +2 -0
- data/TODO_ZENA_1_0 +13 -23
- data/app/controllers/columns_controller.rb +1 -1
- data/app/controllers/comments_controller.rb +4 -3
- data/app/controllers/documents_controller.rb +8 -11
- data/app/controllers/nodes_controller.rb +39 -21
- data/app/controllers/users_controller.rb +8 -3
- data/app/controllers/versions_controller.rb +2 -2
- data/app/controllers/virtual_classes_controller.rb +17 -11
- data/app/helpers/documents_helper.rb +0 -3
- data/app/helpers/users_helper.rb +17 -0
- data/app/models/cache.rb +36 -31
- data/app/models/column.rb +48 -5
- data/app/models/comment.rb +14 -5
- data/app/models/data_entry.rb +2 -2
- data/app/models/document.rb +23 -33
- data/app/models/idx_nodes_datetime.rb +4 -0
- data/app/models/idx_nodes_float.rb +4 -0
- data/app/models/idx_project.rb +3 -0
- data/app/models/node.rb +372 -308
- data/app/models/page.rb +1 -31
- data/app/models/relation.rb +4 -4
- data/app/models/relation_proxy.rb +128 -17
- data/app/models/role.rb +27 -2
- data/app/models/site.rb +64 -56
- data/app/models/template.rb +11 -12
- data/app/models/text_document.rb +6 -7
- data/app/models/user.rb +95 -46
- data/app/models/version.rb +2 -2
- data/app/models/virtual_class.rb +418 -73
- data/app/views/columns/_form.html.erb +1 -1
- data/app/views/columns/_li.html.erb +1 -1
- data/app/views/comments/_form.rhtml +1 -1
- data/app/views/comments/_li.rhtml +1 -1
- data/app/views/comments/_li_simple.rhtml +1 -1
- data/app/views/groups/_form.rhtml +1 -1
- data/app/views/links/_li.rhtml +1 -1
- data/app/views/nodes/_groups.rhtml +1 -1
- data/app/views/nodes/_import_results.rhtml +1 -1
- data/app/views/nodes/_parent.rhtml +1 -1
- data/app/views/nodes/_results.rhtml +1 -1
- data/app/views/nodes/create.rjs +4 -2
- data/app/views/relations/_li.erb +2 -2
- data/app/views/templates/document_create_tabs/_file.rhtml +1 -1
- data/app/views/templates/document_create_tabs/_template.rhtml +2 -2
- data/app/views/templates/document_create_tabs/_text_document.rhtml +2 -2
- data/app/views/templates/edit_tabs/_help.rhtml +1 -1
- data/app/views/templates/edit_tabs/_title.rhtml +0 -3
- data/app/views/users/_form.rhtml +2 -6
- data/app/views/users/_li.rhtml +1 -3
- data/app/views/users/create.rjs +4 -4
- data/app/views/users/preferences.html.erb +1 -4
- data/app/views/versions/custom_tab.rhtml +5 -0
- data/app/views/virtual_classes/_form.erb +20 -10
- data/app/views/virtual_classes/_li.erb +21 -8
- data/app/views/zafu/default/Node-+search.zafu +1 -1
- data/app/views/zafu/default/Node.zafu +3 -3
- data/bricks/captcha/lib/bricks/captcha.rb +1 -1
- data/bricks/mongrel/zena/deploy.rb +14 -0
- data/bricks/{data2pdf → pdf}/.document +0 -0
- data/bricks/pdf/README +33 -0
- data/bricks/{data2pdf → pdf}/Rakefile +0 -0
- data/bricks/pdf/VERSION +1 -0
- data/bricks/pdf/lib/bricks/pdf.rb +110 -0
- data/bricks/pdf/lib/bricks/pdf/engine/prince.rb +38 -0
- data/bricks/pdf/lib/bricks/pdf/engine/xhtml2pdf.rb +9 -0
- data/bricks/pdf/lib/bricks/pdf/install.rb +121 -0
- data/bricks/pdf/test/engines/test_prince.rb +15 -0
- data/bricks/pdf/test/engines/test_xhtml2pdf.rb +15 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/application.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/contact.html +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/pisa-default.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/sheet1.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/sheet2.css +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/simple-html.html +0 -0
- data/bricks/{data2pdf → pdf}/test/fixtures/simple-text.txt +0 -0
- data/bricks/{data2pdf → pdf}/test/helper.rb +4 -5
- data/bricks/pdf/test/shoulda_macros/shoulda_pdf.rb +72 -0
- data/bricks/pdf/zena/init.rb +5 -0
- data/bricks/pdf/zena/tasks.rb +17 -0
- data/bricks/sphinx/lib/{use_sphinx.rb → bricks/sphinx.rb} +1 -1
- data/bricks/tags/zena/init.rb +2 -2
- data/bricks/tags/zena/test/zafu/tags.yml +4 -4
- data/bricks/zena/zena/migrate/01_base.rb +482 -0
- data/config/bricks.yml +22 -6
- data/config/gems.yml +8 -6
- data/db/20100628074512_zena0x_to1x.rb +6 -1
- data/db/fix/024_correct_vclass_kpath.rb +11 -0
- data/db/fix/025_move_tag_into_vclass.rb +13 -0
- data/db/{migrate → fix}/026_rename_templates.rb +0 -0
- data/db/{migrate → fix}/045_avoid_star_in_templates.rb +0 -0
- data/db/{migrate → fix}/046_fix_zazen_image_tag.rb +0 -0
- data/db/{migrate → fix}/047_change_default_link_id_to_zero.rb +1 -3
- data/db/{migrate → fix}/049_fix_publish_from_is_null.rb +0 -0
- data/db/{migrate → fix}/20090924141459_zafu_fix_sept09.rb +0 -0
- data/db/{migrate → fix}/20091013100351_rename_publish_group_to_drive_group.rb +1 -3
- data/db/{migrate → fix}/20091124161608_rebuild_fullpath.rb +0 -1
- data/db/{migrate → fix}/20100115134729_rebuild_fullpath_after_fix.rb +0 -0
- data/db/{migrate → fix}/20100526090140_renamed_contact_model_to_base_contact.rb +2 -4
- data/db/{migrate → fix/old_migrations}/001_create_base.rb +0 -1
- data/db/{migrate → fix/old_migrations}/002_add_time_zone_to_users.rb +0 -0
- data/db/{migrate → fix/old_migrations}/003_add_custom_base_flag.rb +0 -0
- data/db/{migrate → fix/old_migrations}/004_rename_template_skin.rb +0 -0
- data/db/{migrate → fix/old_migrations}/005_create_cached_pages.rb +0 -0
- data/db/{migrate → fix/old_migrations}/006_create_sites.rb +0 -0
- data/db/{migrate → fix/old_migrations}/007_replace_id_by_zip.rb +0 -0
- data/db/{migrate → fix/old_migrations}/008_user_status.rb +0 -0
- data/db/{migrate → fix/old_migrations}/009_fulltext.rb +0 -0
- data/db/fix/old_migrations/010_create_template_content.rb +17 -0
- data/db/{migrate → fix/old_migrations}/011_project_to_section.rb +0 -0
- data/db/{migrate → fix/old_migrations}/012_add_project_id.rb +0 -0
- data/db/{migrate → fix/old_migrations}/013_remove_defaults.rb +0 -0
- data/db/{migrate → fix/old_migrations}/014_add_sort_field.rb +0 -0
- data/db/{migrate → fix/old_migrations}/015_add_dyn_attributes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/016_remove_translations.rb +0 -0
- data/db/{migrate → fix/old_migrations}/017_rename_authorize.rb +0 -0
- data/db/{migrate → fix/old_migrations}/018_add_auth_option.rb +0 -0
- data/db/{migrate → fix/old_migrations}/019_remove_user_status.rb +0 -0
- data/db/{migrate → fix/old_migrations}/020_create_participation.rb +0 -0
- data/db/{migrate → fix/old_migrations}/021_create_relations.rb +0 -0
- data/db/{migrate → fix/old_migrations}/022_create_virtual_classes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/023_ip_on_anonymous_comment.rb +0 -0
- data/db/{migrate → fix/old_migrations}/027_add_country_to_contacts.rb +0 -0
- data/db/{migrate → fix/old_migrations}/028_change_size_of_conten_type_field.rb +0 -0
- data/db/{migrate → fix/old_migrations}/029_create_data_entries.rb +0 -0
- data/db/{migrate → fix/old_migrations}/030_redit_auto_publish_site_settings.rb +0 -0
- data/db/{migrate → fix/old_migrations}/031_create_iformats.rb +0 -0
- data/db/{migrate → fix/old_migrations}/032_caches_context_as_hash.rb +0 -0
- data/db/{migrate → fix/old_migrations}/033_documents_kpath_change.rb +0 -0
- data/db/{migrate → fix/old_migrations}/034_change_file_storage.rb +0 -0
- data/db/{migrate → fix/old_migrations}/035_add_status_to_link.rb +0 -0
- data/db/{migrate → fix/old_migrations}/036_add_flag_fields_on_nodes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/037_add_auto_create_discussion_to_v_class.rb +0 -0
- data/db/{migrate → fix/old_migrations}/038_create_site_attributes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/039_default_position.rb +0 -0
- data/db/{migrate → fix/old_migrations}/040_second_value_for_data_entry.rb +0 -0
- data/db/{migrate → fix/old_migrations}/041_add_attributes_to_v_class.rb +0 -0
- data/db/{migrate → fix/old_migrations}/042_fix_position_should_be_float.rb +0 -0
- data/db/{migrate → fix/old_migrations}/043_move_user_lang_into_participation.rb +0 -0
- data/db/{migrate → fix/old_migrations}/044_remove_monolingual_site_option.rb +0 -0
- data/db/{migrate → fix/old_migrations}/048_link_source_target_can_be_null.rb +0 -0
- data/db/{migrate → fix/old_migrations}/050_date_in_links.rb +0 -0
- data/db/{migrate → fix/old_migrations}/051_add_exif_tags_to_images.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090825201159_insert_zero_link.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090825201200_merge_bricks_migrations_with_std_migrations.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090927125912_allow_null_in_text_fields.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090928133440_no_more_private_nodes.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20090928143754_version_status_change.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091001084025_change_status_values_for_comments.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091009084057_add_vhash_in_node.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091014130833_fix_template_title.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091014183726_merge_participation_into_users.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091018200734_add_popup_info_to_image_format.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091026161708_add_persistence_token.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091101184952_add_session_table.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20091123175137_add_single_access_token.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100125062254_add_dynamo_to_version.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100201133242_remove_default_status_on_version.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100208194210_create_attachments.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100210112319_change_dynamo_to_property.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100320145726_transform_template_contents_into_index.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100328125634_change_skin_name_to_id.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100417061257_add_properties_to_sites.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100419163149_rename_name_to_node_name.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100422091606_change_v_class_table_into_roles.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100422094048_node_habtm_roles.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100422115935_create_columns.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100513181529_add_site_id_to_columns.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100519091711_add_index_definition_to_columns.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100519091940_create_idx_nodes_string.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100519232432_create_idx_nodes_ml_string.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100525113858_add_porperties_to_users.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100527130937_change_column_index_to_string.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100531135128_add_fulltext_builder_fields.rb +0 -0
- data/db/{migrate → fix/old_migrations}/20100915062903_add_api_group_id_to_site.rb +0 -0
- data/db/fix/old_migrations/20100923154807_remove_base_contact.rb +84 -0
- data/db/fix/old_migrations/20100926192223_remove_su_user.rb +8 -0
- data/db/fix/old_migrations/20100927141658_add_eval_attributes_to_v_class.rb +12 -0
- data/db/fix/old_migrations/20100928185257_add_obvious_idx.rb +52 -0
- data/db/fix/old_migrations/20100929143111_remove_node_name.rb +11 -0
- data/db/fix/old_migrations/20101006090454_store_properties_in_long_text.rb +9 -0
- data/db/fix/old_migrations/20101014185753_remove_user_prototype_id.rb +9 -0
- data/db/fix/old_migrations/20101101084318_create_scope_index.rb +35 -0
- data/db/fix/old_migrations/20101109074232_create_idx_nodes_tables.rb +65 -0
- data/db/fix/old_migrations/20101110184235_add_role_update_to_site.rb +9 -0
- data/db/fix/old_migrations/20101116103920_change_scope_index.rb +31 -0
- data/db/fix/old_migrations/20101123125822_add_integer_idx.rb +17 -0
- data/db/fix/old_migrations/20101130134522_add_index_field.rb +13 -0
- data/db/fix/old_migrations/20101213133816_add_group_to_relation.rb +9 -0
- data/db/init/base/help.fr.zml +1 -1
- data/db/init/base/skins/default.zml +0 -1
- data/db/init/base/skins/default/Node-+search.zafu +1 -1
- data/db/init/base/skins/default/Node-tree.zafu +3 -3
- data/db/init/base/skins/default/Node.zafu +3 -3
- data/lib/bricks/loader.rb +4 -1
- data/lib/bricks/requirements_validation.rb +11 -6
- data/lib/log_recorder/lib/log_recorder.rb +2 -2
- data/lib/tasks/zena.rake +25 -15
- data/lib/zena.rb +42 -9
- data/lib/zena/acts/enrollable.rb +81 -99
- data/lib/zena/acts/secure.rb +27 -23
- data/lib/zena/acts/secure_node.rb +10 -55
- data/lib/zena/acts/serializable.rb +9 -10
- data/lib/zena/app.rb +0 -2
- data/lib/zena/code_syntax.rb +1 -1
- data/lib/zena/controller/test_case.rb +0 -5
- data/lib/zena/core_ext/string.rb +48 -20
- data/lib/zena/db.rb +10 -442
- data/lib/zena/db_helper/abstract_db.rb +184 -0
- data/lib/zena/db_helper/mysql.rb +150 -0
- data/lib/zena/db_helper/postgresql.rb +79 -0
- data/lib/zena/db_helper/sqlite3.rb +135 -0
- data/lib/zena/deploy.rb +4 -1
- data/lib/zena/deploy/httpd.rhtml +3 -3
- data/lib/zena/deploy/vhost.rhtml +1 -1
- data/lib/zena/foxy_parser.rb +37 -18
- data/lib/zena/info.rb +3 -13
- data/lib/zena/migrator.rb +0 -1
- data/lib/zena/parser/zafu_rules.rb +9 -4
- data/lib/zena/parser/zazen_rules.rb +5 -5
- data/lib/zena/parser/zena_rules.rb +1 -1
- data/lib/zena/remote/interface.rb +1 -1
- data/lib/zena/site_worker.rb +3 -3
- data/lib/zena/test_controller.rb +10 -10
- data/lib/zena/use/action.rb +66 -6
- data/lib/zena/use/ajax.rb +39 -13
- data/lib/zena/use/ancestry.rb +210 -0
- data/lib/zena/use/authlogic.rb +30 -1
- data/lib/zena/use/calendar.rb +158 -0
- data/lib/zena/use/conditional.rb +3 -2
- data/lib/zena/use/context.rb +42 -12
- data/lib/zena/use/dates.rb +15 -14
- data/lib/zena/use/display.rb +54 -7
- data/lib/zena/use/error_rendering.rb +1 -0
- data/lib/zena/use/field_index.rb +20 -0
- data/lib/zena/use/fixtures.rb +12 -9
- data/lib/zena/use/forms.rb +230 -106
- data/lib/zena/use/fulltext.rb +28 -14
- data/lib/zena/use/html_tags.rb +1 -24
- data/lib/zena/use/i18n.rb +69 -14
- data/lib/zena/use/kpath.rb +60 -0
- data/lib/zena/use/ml_index.rb +6 -4
- data/lib/zena/use/node_context.rb +63 -0
- data/lib/zena/use/prop_eval.rb +90 -0
- data/lib/zena/use/query_builder.rb +159 -29
- data/lib/zena/use/query_comment.rb +1 -1
- data/lib/zena/use/query_node.rb +147 -56
- data/lib/zena/use/recursion.rb +2 -2
- data/lib/zena/use/relations.rb +31 -19
- data/lib/zena/use/rendering.rb +111 -121
- data/lib/zena/use/scope_index.rb +230 -0
- data/lib/zena/use/search.rb +7 -7
- data/lib/zena/use/urls.rb +87 -25
- data/lib/zena/use/version_hash.rb +113 -113
- data/lib/zena/use/workflow.rb +5 -1
- data/lib/zena/use/zafu_attributes.rb +11 -14
- data/lib/zena/use/zafu_eval.rb +1 -1
- data/lib/zena/use/zafu_safe_definitions.rb +91 -9
- data/lib/zena/use/zafu_templates.rb +146 -102
- data/lib/zena/use/zazen.rb +5 -4
- data/lib/zena/zafu_compiler.rb +1 -0
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +0 -1
- data/locale/fr/LC_MESSAGES/zena.mo +0 -0
- data/locale/fr/zena.mo +0 -0
- data/locale/fr/zena.po +4 -4
- data/misc/zena +35 -0
- data/misc/zena_init +41 -0
- data/public/images/ext/{basecontact.png → contact.png} +0 -0
- data/public/javascripts/zena.js +35 -7
- data/public/stylesheets/admin.css +5 -2
- data/public/stylesheets/default.css +2 -1
- data/public/stylesheets/popup.css +1 -1
- data/public/stylesheets/zena.css +2 -2
- data/test/custom_queries/complex.host.yml +12 -5
- data/test/fixtures/files/Node-test.zafu +3 -3
- data/test/fixtures/files/translations_fr.yml +4 -2
- data/test/functional/documents_controller_test.rb +31 -0
- data/test/functional/nodes_controller_commit_test.rb +1 -5
- data/test/functional/nodes_controller_test.rb +92 -12
- data/test/functional/user_sessions_controller_test.rb +2 -2
- data/test/functional/users_controller_test.rb +31 -29
- data/test/functional/versions_controller_test.rb +2 -2
- data/test/functional/virtual_classes_controller_test.rb +2 -2
- data/test/integration/multiple_hosts_test.rb +19 -8
- data/test/integration/navigation_test.rb +91 -12
- data/test/integration/query_node/basic.yml +40 -37
- data/test/integration/query_node/complex.yml +23 -18
- data/test/integration/query_node/dates.yml +3 -3
- data/test/integration/query_node/errors.yml +7 -1
- data/test/integration/query_node/filters.yml +41 -35
- data/test/integration/query_node/idx_fields.yml +11 -0
- data/test/integration/query_node/idx_key_value.yml +77 -0
- data/test/integration/query_node/idx_scope.yml +33 -0
- data/test/integration/query_node/relations.yml +13 -13
- data/test/integration/query_node_test.rb +6 -10
- data/test/integration/zafu_compiler/action.yml +19 -6
- data/test/integration/zafu_compiler/ajax.yml +111 -51
- data/test/integration/zafu_compiler/apphelper.yml +1 -1
- data/test/integration/zafu_compiler/asset.yml +1 -1
- data/test/integration/zafu_compiler/basic.yml +42 -52
- data/test/integration/zafu_compiler/calendar.yml +3 -3
- data/test/integration/zafu_compiler/complex.yml +16 -16
- data/test/integration/zafu_compiler/complex_ok.yml +2 -2
- data/test/integration/zafu_compiler/conditional.yml +42 -33
- data/test/integration/zafu_compiler/data.yml +3 -3
- data/test/integration/zafu_compiler/dates.yml +25 -10
- data/test/integration/zafu_compiler/display.yml +49 -12
- data/test/integration/zafu_compiler/errors.yml +26 -6
- data/test/integration/zafu_compiler/eval.yml +4 -4
- data/test/integration/zafu_compiler/forms.yml +89 -15
- data/test/integration/zafu_compiler/i18n.yml +23 -18
- data/test/integration/zafu_compiler/idx_scope.yml +7 -0
- data/test/integration/zafu_compiler/later.yml +10 -16
- data/test/integration/zafu_compiler/off/off.yml +2 -2
- data/test/integration/zafu_compiler/query.yml +207 -0
- data/test/integration/zafu_compiler/recursion.yml +2 -2
- data/test/integration/zafu_compiler/relations.yml +144 -168
- data/test/integration/zafu_compiler/roles.yml +86 -10
- data/test/integration/zafu_compiler/rubyless.yml +49 -6
- data/test/integration/zafu_compiler/safe_definitions.yml +35 -6
- data/test/integration/zafu_compiler/search.yml +1 -1
- data/test/integration/zafu_compiler/security.yml +37 -0
- data/test/integration/zafu_compiler/urls.yml +50 -40
- data/test/integration/zafu_compiler/user.yml +21 -6
- data/test/integration/zafu_compiler/version.yml +6 -6
- data/test/integration/zafu_compiler/zafu_attributes.yml +43 -34
- data/test/integration/zafu_compiler/zazen.yml +10 -10
- data/test/integration/zafu_compiler_test.rb +19 -13
- data/test/sites/complex/nodes.yml +0 -2
- data/test/sites/complex/roles.yml +9 -1
- data/test/sites/complex/sites.yml +0 -1
- data/test/sites/complex/users.yml +2 -5
- data/test/sites/ocean/nodes.yml +2 -5
- data/test/sites/ocean/roles.yml +8 -0
- data/test/sites/ocean/sites.yml +0 -1
- data/test/sites/ocean/users.yml +0 -13
- data/test/sites/zena/columns.yml +27 -5
- data/test/sites/zena/idx_projects.yml +5 -0
- data/test/sites/zena/nodes.yml +8 -32
- data/test/sites/zena/relations.yml +5 -0
- data/test/sites/zena/roles.yml +25 -3
- data/test/sites/zena/sites.yml +2 -2
- data/test/sites/zena/users.yml +1 -21
- data/test/sites/zena/versions.yml +35 -12
- data/test/test_helper.rb +7 -0
- data/test/unit/after_commit_test.rb +7 -7
- data/test/unit/cache_test.rb +32 -0
- data/test/unit/cached_page_test.rb +1 -1
- data/test/unit/column_test.rb +31 -7
- data/test/unit/comment_test.rb +2 -2
- data/test/unit/core_ext_test.rb +38 -7
- data/test/unit/document_test.rb +14 -42
- data/test/unit/node_test.rb +311 -324
- data/test/unit/note_test.rb +23 -31
- data/test/unit/page_test.rb +16 -58
- data/test/unit/project_test.rb +2 -2
- data/test/unit/relation_proxy_test.rb +148 -21
- data/test/unit/relation_test.rb +23 -3
- data/test/unit/remote_test.rb +15 -9
- data/test/unit/role_test.rb +9 -0
- data/test/unit/site_test.rb +49 -47
- data/test/unit/skin_test.rb +16 -0
- data/test/unit/template_test.rb +60 -69
- data/test/unit/text_document_test.rb +15 -14
- data/test/unit/user_test.rb +101 -41
- data/test/unit/version_test.rb +4 -4
- data/test/unit/virtual_class_test.rb +577 -36
- data/test/unit/workflow_test.rb +58 -21
- data/test/unit/zena/acts/enrollable_test.rb +36 -127
- data/test/unit/zena/acts/secure_test.rb +6 -22
- data/test/unit/zena/acts/serializable_test.rb +18 -0
- data/test/unit/zena/db_test.rb +14 -14
- data/test/unit/zena/parser/zafu.yml +5 -3
- data/test/unit/zena/use/ancestry_test.rb +198 -0
- data/test/unit/zena/use/calendar_test.rb +8 -8
- data/test/unit/zena/use/dates_test.rb +2 -0
- data/test/unit/zena/use/fulltext_test.rb +9 -1
- data/test/unit/zena/use/html_tags_test.rb +2 -16
- data/test/unit/zena/use/i18n_test.rb +2 -2
- data/test/unit/zena/use/kpath_test.rb +13 -0
- data/test/unit/zena/use/ml_index_test.rb +60 -12
- data/test/unit/zena/use/prop_eval_test.rb +170 -0
- data/test/unit/zena/use/query_node_test.rb +9 -2
- data/test/unit/zena/use/rendering_test.rb +98 -1
- data/test/unit/zena/use/scope_index_test.rb +464 -0
- data/test/unit/zena/use/urls_test.rb +23 -13
- data/test/unit/zena/use/version_hash_test.rb +2 -2
- data/test/unit/zena/use/zafu_template_test.rb +21 -8
- data/test/unit/zena/use/zazen_test.rb +47 -47
- data/zena.gemspec +177 -143
- metadata +222 -141
- data/app/models/base_contact.rb +0 -79
- data/app/models/book.rb +0 -242
- data/app/models/contact_content.rb +0 -70
- data/app/models/contact_version.rb +0 -40
- data/app/models/reference.rb +0 -18
- data/app/views/templates/edit_tabs/_basecontact.rhtml +0 -8
- data/bricks/data2pdf/README +0 -19
- data/bricks/data2pdf/VERSION +0 -1
- data/bricks/data2pdf/lib/data2pdf.rb +0 -60
- data/bricks/data2pdf/lib/engines/prince.rb +0 -39
- data/bricks/data2pdf/lib/engines/xhtml2pdf.rb +0 -41
- data/bricks/data2pdf/lib/install.rb +0 -111
- data/bricks/data2pdf/test/engines/test_prince.rb +0 -14
- data/bricks/data2pdf/test/engines/test_xhtml2pdf.rb +0 -14
- data/bricks/data2pdf/test/shoulda_macros/shoulda_data2pdf.rb +0 -91
- data/bricks/data2pdf/test/unit/test_rendering.rb +0 -37
- data/config/routes.rb +0 -3
- data/db/migrate/010_create_template_content.rb +0 -17
- data/db/migrate/024_correct_vclass_kpath.rb +0 -13
- data/db/migrate/025_move_tag_into_vclass.rb +0 -15
- data/lib/version_off.rb +0 -323
- data/lib/zena/use/node_name.rb +0 -94
- data/test/integration/query_node/properties.yml +0 -41
- data/test/unit/base_contact_test.rb +0 -242
- data/test/unit/node_name_test.rb +0 -137
data/app/models/page.rb
CHANGED
@@ -1,35 +1,5 @@
|
|
1
1
|
=begin rdoc
|
2
|
-
|
3
|
-
|
4
|
-
Section:: used to group pages together with a same 'section_id'
|
5
|
-
Tag:: used to create collections of items.
|
6
|
-
Document:: contains data from uploaded files.
|
7
|
-
Image:: subclass of Document, contains image data that can be resized/viewed in the browser.
|
8
|
-
TextDocument:: subclass of Document, used by documents that can be edited online (scripts, text).
|
9
|
-
Template:: subclass of TextDocument. Contains the zafu code to make the look and feel of the site.
|
10
|
-
Skin:: subclass of Template. Contains other templates.
|
2
|
+
The Page class is just used to group Section and Project in a common ancestor.
|
11
3
|
=end
|
12
4
|
class Page < Node
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def validate_node
|
17
|
-
super
|
18
|
-
|
19
|
-
# we are in a scope, we cannot just use the normal validates_...
|
20
|
-
# FIXME: remove 'with_exclusive_scope' once scopes are clarified and removed from 'secure'
|
21
|
-
test_same_name = nil
|
22
|
-
if node_name_changed? || parent_id_changed? || kpath_changed?
|
23
|
-
Node.send(:with_exclusive_scope) do
|
24
|
-
if new_record?
|
25
|
-
cond = ["node_name = ? AND parent_id = ? AND kpath LIKE 'NP%'", self[:node_name], self[:parent_id]]
|
26
|
-
else
|
27
|
-
cond = ["node_name = ? AND parent_id = ? AND kpath LIKE 'NP%' AND id != ? ", self[:node_name], self[:parent_id], self[:id]]
|
28
|
-
end
|
29
|
-
test_same_name = Node.find(:all, :conditions => cond)
|
30
|
-
end
|
31
|
-
errors.add("node_name", "has already been taken") unless test_same_name == []
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
5
|
end
|
data/app/models/relation.rb
CHANGED
@@ -31,25 +31,25 @@ class Relation < ActiveRecord::Base
|
|
31
31
|
end
|
32
32
|
|
33
33
|
if self[:source_role].blank?
|
34
|
-
if klass =
|
34
|
+
if klass = VirtualClass.find_by_kpath(source_kpath)
|
35
35
|
self.source_role = klass.to_s.underscore
|
36
36
|
else
|
37
37
|
klass = nil
|
38
38
|
end
|
39
39
|
else
|
40
|
-
klass =
|
40
|
+
klass = VirtualClass.find_by_kpath(source_kpath)
|
41
41
|
end
|
42
42
|
|
43
43
|
errors.add(:source_kpath, 'invalid (could not find class)') unless klass
|
44
44
|
|
45
45
|
if self[:target_role].blank?
|
46
|
-
if klass =
|
46
|
+
if klass = VirtualClass.find_by_kpath(target_kpath)
|
47
47
|
self.target_role = klass.to_s.underscore
|
48
48
|
else
|
49
49
|
klass = nil
|
50
50
|
end
|
51
51
|
else
|
52
|
-
klass =
|
52
|
+
klass = VirtualClass.find_by_kpath(target_kpath)
|
53
53
|
end
|
54
54
|
|
55
55
|
errors.add(:target_kpath, 'invalid (could not find class)') unless klass
|
@@ -1,5 +1,9 @@
|
|
1
1
|
class RelationProxy < Relation
|
2
|
-
|
2
|
+
include RubyLess
|
3
|
+
|
4
|
+
safe_method :name => {:class => String, :method => 'other_role'}
|
5
|
+
|
6
|
+
attr_accessor :side, :link_errors, :start, :other_link, :last_target, :add_links
|
3
7
|
LINK_ATTRIBUTES = Zena::Use::Relations::LINK_ATTRIBUTES
|
4
8
|
LINK_ATTRIBUTES_SQL = LINK_ATTRIBUTES.map {|sym| connection.quote_column_name(sym)}.join(',')
|
5
9
|
LINK_SELECT = "nodes.*,links.id AS link_id,#{LINK_ATTRIBUTES.map {|l| "links.#{l} AS l_#{l}"}.join(',')}"
|
@@ -33,7 +37,7 @@ class RelationProxy < Relation
|
|
33
37
|
def get_proxy(node, role)
|
34
38
|
# TODO: use find_by_role(role, node.kpath) when all tests are clear
|
35
39
|
rel = find_by_role(role)
|
36
|
-
if rel && (node.new_record? || node.
|
40
|
+
if rel && (node.new_record? || node.kpath =~ /\A#{rel.this_kpath}/)
|
37
41
|
rel.start = node
|
38
42
|
rel
|
39
43
|
else
|
@@ -82,11 +86,13 @@ class RelationProxy < Relation
|
|
82
86
|
end
|
83
87
|
|
84
88
|
def other_zips
|
89
|
+
return nil unless @start[:id]
|
85
90
|
return @other_zips if defined?(@other_zips)
|
86
91
|
@other_zips = @records ? @records.map { |r| r.zip} : Zena::Db.fetch_ids("SELECT zip FROM nodes INNER JOIN links ON nodes.id=links.#{other_side} AND links.relation_id = #{self[:id]} AND links.#{link_side} = #{@start[:id]} WHERE #{secure_scope('nodes')} GROUP BY nodes.zip", 'zip')
|
87
92
|
end
|
88
93
|
|
89
94
|
def records(opts = {})
|
95
|
+
return nil unless @start[:id]
|
90
96
|
return @records if defined?(@records)
|
91
97
|
options = {
|
92
98
|
:select => "nodes.*, #{LINK_SELECT}",
|
@@ -114,12 +120,30 @@ class RelationProxy < Relation
|
|
114
120
|
end
|
115
121
|
|
116
122
|
# Get class of other element (used by QueryNode to properly set resulting class).
|
117
|
-
def
|
118
|
-
|
123
|
+
def other_vclass
|
124
|
+
VirtualClass.find_by_kpath(@side == :source ? self[:target_kpath] : self[:source_kpath])
|
125
|
+
end
|
126
|
+
|
127
|
+
# set from query builder
|
128
|
+
def qb=(qb)
|
129
|
+
if qb.blank?
|
130
|
+
self.other_id = []
|
131
|
+
else
|
132
|
+
query = @start.class.build_query(:all, qb,
|
133
|
+
:node_name => '@start',
|
134
|
+
:main_class => @start.virtual_class,
|
135
|
+
:rubyless_helper => @start.virtual_class,
|
136
|
+
:default => {:order => 'id asc'}
|
137
|
+
)
|
138
|
+
self.other_id = secure(Node) {Node.find_by_sql(eval(query.to_s))} || []
|
139
|
+
end
|
140
|
+
rescue ::QueryBuilder::Error => err
|
141
|
+
attributes_to_update[:errors] = {'base' => err.message}
|
119
142
|
end
|
120
143
|
|
121
144
|
# set
|
122
145
|
def other_id=(v)
|
146
|
+
attributes_to_update[:errors] = {}
|
123
147
|
if !v.kind_of?(Array) && v.to_i < 0
|
124
148
|
# removing a link
|
125
149
|
# TODO: support Array
|
@@ -128,8 +152,62 @@ class RelationProxy < Relation
|
|
128
152
|
else
|
129
153
|
# ignore
|
130
154
|
end
|
155
|
+
elsif v.kind_of?(Array)
|
156
|
+
if v.first.kind_of?(Node)
|
157
|
+
node_by_id = attributes_to_update[:nodes] = {}
|
158
|
+
v.each do |r|
|
159
|
+
node_by_id[r.id.to_i] = r
|
160
|
+
end
|
161
|
+
attributes_to_update[:id] = v.map{|r| r.id.to_i}
|
162
|
+
else
|
163
|
+
attributes_to_update[:id] = v.map(&:to_i)
|
164
|
+
end
|
165
|
+
else
|
166
|
+
attributes_to_update[:id] = v.blank? ? nil : v.to_i
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# set
|
171
|
+
def other_zip=(zip_values)
|
172
|
+
# Translate ids and then set
|
173
|
+
errors = attributes_to_update[:errors] = {}
|
174
|
+
id_to_zip = attributes_to_update[:id_to_zip] = {}
|
175
|
+
|
176
|
+
if zip_values.kind_of?(Array)
|
177
|
+
attributes_to_update[:id] = []
|
178
|
+
zip_values.each do |zip|
|
179
|
+
if id = secure(Node) { Node.translate_pseudo_id(zip, :id, @start) }
|
180
|
+
# ok
|
181
|
+
id_to_zip[id] = zip
|
182
|
+
attributes_to_update[:id] << id
|
183
|
+
else
|
184
|
+
# error
|
185
|
+
errors[zip] = _('could not be found')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
elsif zip_values.blank?
|
189
|
+
# remove all
|
190
|
+
attributes_to_update[:id] = nil
|
131
191
|
else
|
132
|
-
|
192
|
+
if id = secure(Node) { Node.translate_pseudo_id(zip_values, :id, @start) }
|
193
|
+
if id < 0
|
194
|
+
# removing a link
|
195
|
+
# TODO: support Array
|
196
|
+
if link = other_links.select { |l| l[other_side] == -id }.first
|
197
|
+
remove_link(link)
|
198
|
+
else
|
199
|
+
# ignore
|
200
|
+
end
|
201
|
+
else
|
202
|
+
id_to_zip[id] = zip_values
|
203
|
+
attributes_to_update[:id] = id
|
204
|
+
end
|
205
|
+
else
|
206
|
+
# error
|
207
|
+
# do not try to add
|
208
|
+
attributes_to_update[:id] = :ignore
|
209
|
+
errors[zip_values] = _('could not be found')
|
210
|
+
end
|
133
211
|
end
|
134
212
|
end
|
135
213
|
|
@@ -137,6 +215,10 @@ class RelationProxy < Relation
|
|
137
215
|
self.other_id = v
|
138
216
|
end
|
139
217
|
|
218
|
+
def other_zips=(v)
|
219
|
+
self.other_zip = v
|
220
|
+
end
|
221
|
+
|
140
222
|
def remove_link(link)
|
141
223
|
@links_to_delete ||= []
|
142
224
|
@links_to_delete << link
|
@@ -167,7 +249,7 @@ class RelationProxy < Relation
|
|
167
249
|
def attributes_to_update_valid?
|
168
250
|
return true unless @attributes_to_update || @links_to_delete
|
169
251
|
|
170
|
-
@link_errors =
|
252
|
+
@link_errors = {}
|
171
253
|
@add_links = []
|
172
254
|
@del_links = []
|
173
255
|
@update_links = []
|
@@ -179,7 +261,7 @@ class RelationProxy < Relation
|
|
179
261
|
else
|
180
262
|
|
181
263
|
# check if we have an update/create
|
182
|
-
unless @attributes_to_update.has_key?(:id)
|
264
|
+
unless @attributes_to_update.has_key?(:id) # set during other_id=
|
183
265
|
# try to find current id/ids
|
184
266
|
if @other_link
|
185
267
|
@attributes_to_update[:id] = @other_link[other_side]
|
@@ -192,25 +274,28 @@ class RelationProxy < Relation
|
|
192
274
|
elsif @attributes_to_update.keys == [:id]
|
193
275
|
# ignore (set icon_id = nil when already == nil)
|
194
276
|
else
|
195
|
-
@link_errors
|
277
|
+
@link_errors['update'] = _('missing target')
|
196
278
|
end
|
197
279
|
else
|
198
280
|
# error: cannot set other attributes (status/comment) on multiple nodes
|
199
|
-
@link_errors
|
281
|
+
@link_errors['update'] = _('cannot update multiple targets')
|
200
282
|
end
|
201
283
|
end
|
202
284
|
|
203
285
|
if @attributes_to_update[:id].kind_of?(Array)
|
204
286
|
if unique?
|
205
|
-
|
287
|
+
# TODO: translate
|
288
|
+
@link_errors['arity'] = "Cannot set multiple targets on #{as_unique? ? 'one' : 'many'}-to-one relation '#{this_role}'."
|
206
289
|
elsif (@attributes_to_update.keys & LINK_ATTRIBUTES) != []
|
207
290
|
keys = @attributes_to_update.keys
|
208
291
|
keys.delete(:id)
|
209
|
-
|
292
|
+
# TODO: translate
|
293
|
+
@link_errors['arity'] = "Cannot set attributes #{keys.join(', ')} on multiple targets."
|
210
294
|
end
|
211
295
|
end
|
212
296
|
|
213
|
-
return false if @link_errors !=
|
297
|
+
return false if @link_errors != {}
|
298
|
+
@link_errors = @attributes_to_update[:errors] || {}
|
214
299
|
|
215
300
|
# 1. find what changed
|
216
301
|
if @attributes_to_update[:id].kind_of?(Array)
|
@@ -262,6 +347,8 @@ class RelationProxy < Relation
|
|
262
347
|
end
|
263
348
|
end
|
264
349
|
end
|
350
|
+
elsif @attributes_to_update[:id] == :ignore
|
351
|
+
# bad id set, just used for error reporting
|
265
352
|
else
|
266
353
|
# add
|
267
354
|
@add_links << @attributes_to_update
|
@@ -270,10 +357,14 @@ class RelationProxy < Relation
|
|
270
357
|
end
|
271
358
|
end
|
272
359
|
|
360
|
+
id_to_zip = attributes_to_update[:id_to_zip] || {}
|
361
|
+
|
273
362
|
# 2. can write in new target ? (and remove targets previous link)
|
274
363
|
@add_links.each do |hash|
|
275
364
|
# last_target is used by "linked_node" from Node to get hold of the last linked node
|
276
365
|
if @last_target = find_target(hash[:id])
|
366
|
+
# store remote node so that we can use in index rebuild (scope_index)
|
367
|
+
hash[:node] = @last_target
|
277
368
|
# make sure we can overwrite previous link if as_unique
|
278
369
|
if as_unique?
|
279
370
|
if previous_link = Link.find(:first, :conditions => ["relation_id = ? AND #{other_side} = ?", self[:id], @last_target[:id]])
|
@@ -281,19 +372,35 @@ class RelationProxy < Relation
|
|
281
372
|
end
|
282
373
|
end
|
283
374
|
else
|
284
|
-
|
375
|
+
if zip = id_to_zip[hash[:id]]
|
376
|
+
key = zip
|
377
|
+
elsif node = secure(Node) { Node.find_by_id(hash[:id]) }
|
378
|
+
key = node.zip
|
379
|
+
else
|
380
|
+
key = 'id'
|
381
|
+
end
|
382
|
+
|
383
|
+
@link_errors[key] = _('invalid target')
|
285
384
|
end
|
286
385
|
end
|
287
386
|
|
288
387
|
# 1. can remove old link ?
|
289
388
|
@del_links.each do |link|
|
290
389
|
unless find_node(link[other_side], unique?)
|
291
|
-
|
390
|
+
if zip = id_to_zip[link[other_side]]
|
391
|
+
key = zip
|
392
|
+
elsif node = secure(Node) { Node.find_by_id(hash[:id]) }
|
393
|
+
key = node.zip
|
394
|
+
else
|
395
|
+
key = 'id'
|
396
|
+
end
|
397
|
+
|
398
|
+
@link_errors[key] = _('cannot remove link')
|
292
399
|
end
|
293
400
|
end
|
294
401
|
|
295
402
|
@update_links.compact!
|
296
|
-
return @link_errors ==
|
403
|
+
return @link_errors == {}
|
297
404
|
end
|
298
405
|
|
299
406
|
# Return updated link if changed or nil when nothing changed
|
@@ -364,12 +471,16 @@ class RelationProxy < Relation
|
|
364
471
|
|
365
472
|
def find_target(obj_id)
|
366
473
|
if as_unique?
|
367
|
-
secure_drive(relation_class) { relation_class.find(:first, :conditions=>['id = ? AND kpath LIKE ?', obj_id, "#{other_kpath}%"]) }
|
474
|
+
cache[obj_id] ||= secure_drive(relation_class) { relation_class.find(:first, :conditions=>['id = ? AND kpath LIKE ?', obj_id, "#{other_kpath}%"]) }
|
368
475
|
else
|
369
|
-
secure_write(relation_class) { relation_class.find(:first, :conditions=>['id = ? AND kpath LIKE ?', obj_id, "#{other_kpath}%"]) }
|
476
|
+
cache[obj_id] ||= secure_write(relation_class) { relation_class.find(:first, :conditions=>['id = ? AND kpath LIKE ?', obj_id, "#{other_kpath}%"]) }
|
370
477
|
end
|
371
478
|
end
|
372
479
|
|
480
|
+
def cache
|
481
|
+
@cache ||= attributes_to_update[:nodes] || {}
|
482
|
+
end
|
483
|
+
|
373
484
|
def attributes_to_update
|
374
485
|
@attributes_to_update ||= {}
|
375
486
|
end
|
data/app/models/role.rb
CHANGED
@@ -1,22 +1,38 @@
|
|
1
1
|
require 'property/stored_role'
|
2
2
|
|
3
3
|
class Role < ActiveRecord::Base
|
4
|
+
# We define 'klass' in the Role used by the real classes so that property methods can be
|
5
|
+
# defined.
|
6
|
+
attr_accessor :klass
|
7
|
+
|
8
|
+
# Only store partial class name in 'type' field (not ::Role)
|
9
|
+
self.store_full_sti_class = false
|
10
|
+
|
4
11
|
include Property::StoredRole
|
5
12
|
has_many :stored_columns, :class_name => 'Column', :dependent => :destroy
|
6
13
|
has_and_belongs_to_many :nodes
|
7
14
|
|
8
15
|
before_validation :set_defaults
|
9
16
|
validate :check_can_save
|
17
|
+
attr_accessible :name, :superclass, :icon
|
18
|
+
|
19
|
+
after_save :expire_vclass_cache
|
20
|
+
after_destroy :expire_vclass_cache
|
10
21
|
|
11
22
|
include RubyLess
|
12
|
-
|
23
|
+
# Columns defined in the role.
|
24
|
+
safe_method :columns => {:class => ['Column'], :method => 'defined_safe_columns'}
|
25
|
+
|
13
26
|
safe_method :name => String
|
14
27
|
|
28
|
+
# We use property to store index information, default values and such
|
29
|
+
include Property
|
30
|
+
|
15
31
|
def superclass
|
16
32
|
if new_record?
|
17
33
|
Node
|
18
34
|
else
|
19
|
-
|
35
|
+
VirtualClass.find_by_kpath(kpath)
|
20
36
|
end
|
21
37
|
end
|
22
38
|
|
@@ -28,13 +44,22 @@ class Role < ActiveRecord::Base
|
|
28
44
|
end
|
29
45
|
end
|
30
46
|
|
47
|
+
# By default, all defined columns are safe (see )
|
48
|
+
def defined_safe_columns
|
49
|
+
@safe_column ||= defined_columns.values.sort {|a,b| a.name <=> b.name}
|
50
|
+
end
|
31
51
|
|
32
52
|
private
|
33
53
|
def set_defaults
|
54
|
+
self[:type] = self.class.to_s
|
34
55
|
self.site_id = visitor.site.id
|
35
56
|
end
|
36
57
|
|
37
58
|
def check_can_save
|
38
59
|
errors.add('base', 'You do not have the rights to change roles.') unless visitor.is_admin?
|
39
60
|
end
|
61
|
+
|
62
|
+
def expire_vclass_cache
|
63
|
+
VirtualClass.expire_cache!
|
64
|
+
end
|
40
65
|
end
|
data/app/models/site.rb
CHANGED
@@ -7,7 +7,6 @@ The #Site model holds configuration information for a site:
|
|
7
7
|
|
8
8
|
+host+:: Unique host name. (teti.ch, zenadmin.org, dev.example.org, ...)
|
9
9
|
+root_id+:: Site root node id. This is the only node in the site without a parent.
|
10
|
-
+su_id+:: Super User id. This user has extended priviledges on the site. It should only be used in case of emergency.
|
11
10
|
+anon_id+:: Anonymous user id. This user is the 'public' user of the site. Even if +authorize+ is set to true, this user is needed to configure the defaults for all newly created users.
|
12
11
|
+public_group_id+:: Id of the 'public' group. Every user of the site (with 'anonymous user') belongs to this group.
|
13
12
|
+site_group_id+:: Id of the 'site' group. Every user except anonymous are part of this group. This group can be seen as the 'logged in users' group.
|
@@ -69,24 +68,22 @@ class Site < ActiveRecord::Base
|
|
69
68
|
# =========== CREATE zip counter ==========================
|
70
69
|
connection.execute "INSERT INTO zips (site_id, zip) VALUES (#{site[:id]},0)"
|
71
70
|
|
72
|
-
# =========== CREATE
|
73
|
-
# create su user
|
74
|
-
su = User.new_no_defaults( :login => host, :password => su_password,
|
75
|
-
:first_name => "Super", :name => "User", :lang => site.default_lang, :status => User::Status[:su])
|
76
|
-
su.site = site
|
71
|
+
# =========== CREATE Admin User ===========================
|
77
72
|
|
78
|
-
|
73
|
+
# create admin user
|
74
|
+
admin_user = User.new_no_defaults( :login => 'admin', :password => su_password,
|
75
|
+
:lang => site.default_lang, :status => User::Status[:admin])
|
76
|
+
admin_user.site = site
|
77
|
+
|
78
|
+
Thread.current[:visitor] = admin_user
|
79
79
|
|
80
|
-
unless
|
80
|
+
unless admin_user.save
|
81
81
|
# rollback
|
82
82
|
Site.connection.execute "DELETE FROM #{Site.table_name} WHERE id = #{site.id}"
|
83
83
|
Site.connection.execute "DELETE FROM zips WHERE site_id = #{site.id}"
|
84
|
-
raise Exception.new("Could not create
|
84
|
+
raise Exception.new("Could not create admin user for site [#{host}] (site#{site[:id]})\n#{admin_user.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}")
|
85
85
|
end
|
86
86
|
|
87
|
-
site[:su_id] = su[:id]
|
88
|
-
|
89
|
-
|
90
87
|
# =========== CREATE PUBLIC, ADMIN, SITE GROUPS ===========
|
91
88
|
# create public group
|
92
89
|
pub = site.send(:secure,Group) { Group.create(:name => 'public') }
|
@@ -96,6 +93,9 @@ class Site < ActiveRecord::Base
|
|
96
93
|
admin = site.send(:secure,Group) { Group.create( :name => 'admin') }
|
97
94
|
raise Exception.new("Could not create admin group for site [#{host}] (site#{site[:id]})\n#{admin.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if admin.new_record?
|
98
95
|
|
96
|
+
# add admin to the 'admin group'
|
97
|
+
admin.users << admin_user
|
98
|
+
|
99
99
|
# create site group
|
100
100
|
sgroup = site.send(:secure,Group) { Group.create( :name => 'site') }
|
101
101
|
raise Exception.new("Could not create site group for site [#{host}] (site#{site[:id]})\n#{sgroup.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if sgroup.new_record?
|
@@ -104,39 +104,27 @@ class Site < ActiveRecord::Base
|
|
104
104
|
site.site_group_id = sgroup[:id]
|
105
105
|
site.groups << pub << sgroup << admin
|
106
106
|
|
107
|
-
#
|
107
|
+
# Reload group_ids in admin
|
108
|
+
admin_user.instance_variable_set(:@group_ids, nil)
|
109
|
+
|
110
|
+
# =========== CREATE Anonymous User =====================
|
108
111
|
# create anon user
|
109
|
-
# FIXME: make sure user_id = admin user
|
110
112
|
|
111
|
-
anon = site.send(:secure, User)
|
112
|
-
|
113
|
+
anon = site.send(:secure, User) do
|
114
|
+
User.new_no_defaults( :login => nil, :password => nil,
|
115
|
+
:lang => site.default_lang, :status => User::Status[:moderated])
|
116
|
+
end
|
113
117
|
|
114
118
|
anon.site = site
|
115
119
|
raise Exception.new("Could not create anonymous user for site [#{host}] (site#{site[:id]})\n#{anon.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") unless anon.save
|
116
120
|
site[:anon_id] = anon[:id]
|
117
121
|
|
118
|
-
# create admin user
|
119
|
-
admin_user = site.send(:secure,User) { User.new_no_defaults( :login => 'admin', :password => su_password,
|
120
|
-
:first_name => "Admin", :name => "User", :lang => site.default_lang, :status => User::Status[:admin]) }
|
121
|
-
admin_user.site = site
|
122
|
-
raise Exception.new("Could not create admin user for site [#{host}] (site#{site[:id]})\n#{admin_user.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") unless admin_user.save
|
123
|
-
class << admin_user
|
124
|
-
# until participation is created
|
125
|
-
def status; User::Status[:admin]; end
|
126
|
-
def lang; site.default_lang; end
|
127
|
-
end
|
128
|
-
# add admin to the 'admin group'
|
129
|
-
admin.users << admin_user
|
130
|
-
|
131
122
|
# =========== CREATE ROOT NODE ============================
|
132
|
-
# reload admin so all groups are set
|
133
|
-
|
134
|
-
#admin_user = site.send(:secure, User) { User.find(admin_user[:id]) }
|
135
123
|
|
136
|
-
|
137
|
-
|
124
|
+
root = site.send(:secure,Project) do
|
125
|
+
Project.create( :title => site.name, :rgroup_id => pub[:id], :wgroup_id => sgroup[:id], :dgroup_id => admin[:id], :title => site.name, :v_status => Zena::Status[:pub])
|
126
|
+
end
|
138
127
|
|
139
|
-
root = site.send(:secure,Project) { Project.create( :node_name => site.name, :rgroup_id => pub[:id], :wgroup_id => sgroup[:id], :dgroup_id => admin[:id], :title => site.name, :v_status => Zena::Status[:pub]) }
|
140
128
|
raise Exception.new("Could not create root node for site [#{host}] (site#{site[:id]})\n#{root.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if root.new_record?
|
141
129
|
|
142
130
|
Node.connection.execute "UPDATE nodes SET section_id = id, project_id = id WHERE id = '#{root[:id]}'"
|
@@ -150,16 +138,17 @@ class Site < ActiveRecord::Base
|
|
150
138
|
raise Exception.new("Could not save site definition for site [#{host}] (site#{site[:id]})\n#{site.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") unless site.save
|
151
139
|
|
152
140
|
# =========== CREATE CONTACT PAGES ==============
|
153
|
-
|
154
|
-
|
141
|
+
{admin_user => 'Admin User', anon => 'Anonymous User'}.each do |user, title|
|
142
|
+
# forces @node creation
|
143
|
+
user.node_attributes = {'title' => title, 'parent_id' => root[:id] }
|
144
|
+
user.send(:create_node)
|
155
145
|
user.save
|
156
146
|
end
|
157
147
|
|
158
148
|
# =========== LOAD INITIAL DATA (default skin) =============
|
159
149
|
|
160
|
-
nodes = site.send(:secure,Node) { Node.create_nodes_from_folder(:folder => File.join(Zena::ROOT, 'db', 'init', 'base'), :parent_id => root[:id], :defaults => { :v_status => Zena::Status[:pub], :rgroup_id => pub[:id], :wgroup_id => sgroup[:id], :dgroup_id => admin[:id] } ) }.values
|
161
|
-
|
162
|
-
# == set skin name to 'default' for all elements in the site == #
|
150
|
+
nodes = site.send(:secure, Node) { Node.create_nodes_from_folder(:folder => File.join(Zena::ROOT, 'db', 'init', 'base'), :parent_id => root[:id], :defaults => { :v_status => Zena::Status[:pub], :rgroup_id => pub[:id], :wgroup_id => sgroup[:id], :dgroup_id => admin[:id] } ) }.values
|
151
|
+
# == set skin id to 'default' for all elements in the site == #
|
163
152
|
skin = nodes.detect {|n| n.kind_of?(Skin) }
|
164
153
|
Node.connection.execute "UPDATE nodes SET skin_id = '#{skin.id}' WHERE site_id = '#{site[:id]}'"
|
165
154
|
|
@@ -184,6 +173,10 @@ class Site < ActiveRecord::Base
|
|
184
173
|
end
|
185
174
|
end
|
186
175
|
|
176
|
+
property.string 'usr_prototype_attributes'
|
177
|
+
|
178
|
+
Site.attributes_for_form[:text] << 'usr_prototype_attributes'
|
179
|
+
|
187
180
|
# Return path for static/cached content served by proxy: RAILS_ROOT/sites/_host_/public
|
188
181
|
# If you need to serve from another directory, we do not store the path into the sites table
|
189
182
|
# for security reasons. The easiest way around this limitation is to symlink the 'public' directory.
|
@@ -208,12 +201,6 @@ class Site < ActiveRecord::Base
|
|
208
201
|
@anon ||= User.find_by_id_and_site_id(self[:anon_id], self.id)
|
209
202
|
end
|
210
203
|
|
211
|
-
# Return the super user. This user has extended priviledges on the data (has access to private other's data).
|
212
|
-
# This is an emergency user.
|
213
|
-
def su
|
214
|
-
@su ||= User.find_by_id_and_site_id(self[:su_id], self.id)
|
215
|
-
end
|
216
|
-
|
217
204
|
# TODO: test
|
218
205
|
def root_node
|
219
206
|
secure(Node) { Node.find(self[:root_id]) }
|
@@ -221,17 +208,17 @@ class Site < ActiveRecord::Base
|
|
221
208
|
|
222
209
|
# Return the public group: the one in which every visitor belongs.
|
223
210
|
def public_group
|
224
|
-
@public_group ||= Group.find(self[:public_group_id])
|
211
|
+
@public_group ||= secure(Group) { Group.find(self[:public_group_id]) }
|
225
212
|
end
|
226
213
|
|
227
214
|
# Return the site group: the one in which every visitor except 'anonymous' belongs (= all logged in users).
|
228
215
|
def site_group
|
229
|
-
@site_group ||= Group.find(self[:site_group_id])
|
216
|
+
@site_group ||= secure(Group) { Group.find(self[:site_group_id]) }
|
230
217
|
end
|
231
218
|
|
232
219
|
# Return the API group: the one in which API visitors must be to use the API.
|
233
220
|
def api_group
|
234
|
-
@api_group ||= Group.find_by_id(self[:api_group_id])
|
221
|
+
@api_group ||= secure(Group) { Group.find_by_id(self[:api_group_id]) }
|
235
222
|
end
|
236
223
|
|
237
224
|
# Return true if the given user is an administrator for this site.
|
@@ -241,7 +228,7 @@ class Site < ActiveRecord::Base
|
|
241
228
|
|
242
229
|
# Return the ids of the administrators of the current site.
|
243
230
|
def admin_user_ids
|
244
|
-
# TODO: admin_user_ids could be cached in the 'site' record.
|
231
|
+
# TODO: PERFORMANCE admin_user_ids could be cached in the 'site' record.
|
245
232
|
@admin_user_ids ||= secure!(User) { User.find(:all, :conditions => "status >= #{User::Status[:admin]}") }.map {|r| r[:id]}
|
246
233
|
end
|
247
234
|
|
@@ -277,7 +264,7 @@ class Site < ActiveRecord::Base
|
|
277
264
|
|
278
265
|
# ids of the users that cannot be removed
|
279
266
|
def protected_user_ids
|
280
|
-
[anon_id,
|
267
|
+
[anon_id, visitor.id] # cannot remove self
|
281
268
|
end
|
282
269
|
|
283
270
|
# Return an array with the languages for the site.
|
@@ -304,6 +291,24 @@ class Site < ActiveRecord::Base
|
|
304
291
|
end
|
305
292
|
end
|
306
293
|
|
294
|
+
def iformats_updated!
|
295
|
+
Site.connection.execute "UPDATE sites SET formats_updated_at = (SELECT updated_at FROM iformats WHERE site_id = #{self[:id]} ORDER BY iformats.updated_at DESC LIMIT 1) WHERE id = #{self[:id]}"
|
296
|
+
if $iformats
|
297
|
+
$iformats[self[:id]] = @iformats = nil
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def virtual_classes
|
302
|
+
@iformats ||= begin
|
303
|
+
$iformats ||= {} # mem cache
|
304
|
+
site_formats = $iformats[self[:id]]
|
305
|
+
if !site_formats || self[:formats_updated_at] != site_formats[:updated_at]
|
306
|
+
site_formats = $iformats[self[:id]] = Iformat.formats_for_site(self[:id]) # reload
|
307
|
+
end
|
308
|
+
site_formats
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
307
312
|
def iformats_updated!
|
308
313
|
Site.connection.execute "UPDATE sites SET formats_updated_at = (SELECT updated_at FROM iformats WHERE site_id = #{self[:id]} ORDER BY iformats.updated_at DESC LIMIT 1) WHERE id = #{self[:id]}"
|
309
314
|
if $iformats
|
@@ -353,17 +358,20 @@ class Site < ActiveRecord::Base
|
|
353
358
|
true
|
354
359
|
end
|
355
360
|
|
356
|
-
#
|
357
|
-
|
361
|
+
# Recreates the fullpath ('/zip/zip/zip').
|
362
|
+
# TODO: find a way to use SiteWorker (need to remove get_nodes)
|
363
|
+
def rebuild_fullpath(parent_id = nil, parent_fullpath = "", parent_basepath = "", start=[])
|
364
|
+
raise Zena::InvalidRecord, "Infinit loop in 'ancestors' (#{start.inspect} --> #{parent_id})" if start.include?(parent_id)
|
365
|
+
start += [parent_id]
|
358
366
|
i = 0
|
359
367
|
batch_size = 100
|
360
368
|
children = []
|
361
369
|
while true
|
362
|
-
rec = Zena::Db.fetch_attributes(['id', 'fullpath', 'basepath', 'custom_base', '
|
370
|
+
rec = Zena::Db.fetch_attributes(['id', 'fullpath', 'basepath', 'custom_base', 'zip'], 'nodes', "parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"} AND site_id = #{self.id} ORDER BY id ASC LIMIT #{batch_size} OFFSET #{i * batch_size}")
|
363
371
|
break if rec.empty?
|
364
372
|
rec.each do |rec|
|
365
373
|
if parent_id
|
366
|
-
rec['fullpath'] = parent_fullpath == '' ? rec['
|
374
|
+
rec['fullpath'] = parent_fullpath == '' ? rec['zip'] : "#{parent_fullpath}/#{rec['zip']}"
|
367
375
|
else
|
368
376
|
# root node
|
369
377
|
rec['fullpath'] = ''
|
@@ -376,7 +384,7 @@ class Site < ActiveRecord::Base
|
|
376
384
|
end
|
377
385
|
|
378
386
|
id = rec.delete('id')
|
379
|
-
children << [id, rec['fullpath'], rec['basepath']]
|
387
|
+
children << [id, rec['fullpath'], rec['basepath'], start]
|
380
388
|
Zena::Db.execute "UPDATE nodes SET #{rec.map {|k,v| "#{Zena::Db.connection.quote_column_name(k)}=#{Zena::Db.quote(v)}"}.join(', ')} WHERE id = #{id}"
|
381
389
|
end
|
382
390
|
# 50 more
|