Coding standards
Security in ResourceSpace
Developer reference
Database
- Table: activity_log
- Table: annotation
- Table: annotation_node
- Table: collection
- Table: collection_keyword
- Table: collection_log
- Table: collection_resource
- Table: collection_savedsearch
- Table: comment
- Table: daily_stat
- Table: dash_tile
- Table: dynamic_tree_node
- Table: external_access_keys
- Table: filter
- Table: filter_rule
- Table: filter_rule_node
- Table: ip_lockout
- Table: job_queue
- Table: keyword
- Table: keyword_related
- Table: mail_log
- Table: message
- Table: node
- Table: node_keyword
- Table: plugins
- Table: preview_size
- Table: report
- Table: report_periodic_emails
- Table: report_periodic_emails_unsubscribe
- Table: request
- Table: research_request
- Table: resource
- Table: resource_alt_files
- Table: resource_custom_access
- Table: resource_dimensions
- Table: resource_keyword
- Table: resource_log
- Table: resource_node
- Table: resource_related
- Table: resource_type
- Table: resource_type_field
- Table: resource_type_field_resource_type
- Table: search_log
- Table: site_text
- Table: slideshow
- Table: sysvars
- Table: tab
- Table: user
- Table: user_collection
- Table: user_dash_tile
- Table: user_message
- Table: user_preferences
- Table: user_rating
- Table: user_report
- Table: user_userlist
- Table: usergroup
- Table: usergroup_collection
- Table: usergroup_dash_tile
Action functions
Admin functions
Ajax functions
Annotation functions
API functions
Collections functions
- get_user_collections()
- get_collection()
- get_collection_resources()
- get_collection_resources_with_data()
- add_resource_to_collection()
- remove_resource_from_collection()
- collection_writeable()
- collection_readable()
- set_user_collection()
- create_collection()
- delete_collection()
- refresh_collection_frame()
- search_public_collections()
- do_collections_search()
- add_collection()
- remove_collection()
- index_collection()
- save_collection()
- get_max_theme_levels()
- get_theme_headers()
- themes_comparator()
- collections_comparator()
- collections_comparator_desc()
- get_themes()
- get_smart_theme_headers()
- get_smart_themes_nodes()
- email_collection()
- generate_collection_access_key()
- get_saved_searches()
- add_saved_search()
- remove_saved_search()
- add_smart_collection()
- get_search_title()
- add_saved_search_items()
- allow_multi_edit()
- get_theme_image()
- swap_collection_order()
- update_collection_order()
- get_collection_resource_comment()
- save_collection_resource_comment()
- relate_to_collection()
- get_mycollection_name()
- get_collection_comments()
- send_collection_feedback()
- copy_collection()
- collection_is_research_request()
- add_to_collection_link()
- change_collection_link()
- get_collection_external_access()
- delete_collection_access_key()
- collection_log()
- get_collection_log()
- get_collection_videocount()
- collection_max_access()
- collection_min_access()
- collection_set_public()
- collection_set_private()
- collection_set_themes()
- remove_all_resources_from_collection()
- get_home_page_promoted_collections()
- is_collection_approved()
- edit_collection_external_access()
- show_hide_collection()
- get_session_collections()
- update_collection_user()
- compile_collection_actions()
- makeFilenameUnique()
- new_featured_collection_form()
- get_last_resource_edit()
- GetThemesFromRequest()
- collection_download_get_archive_file()
- collection_download_use_original_filenames_when_downloading()
- collection_download_process_text_file()
- collection_download_log_resource_ready()
- update_zip_progress_file()
- collection_download_process_data_only_types()
- collection_download_process_summary_notes()
- collection_download_process_csv_metadata_file()
- collection_download_process_command_to_file()
- collection_download_process_collection_download_name()
- collection_download_process_archive_command()
- collection_download_clean_temp_files()
- collection_cleanup_inaccessible_resources()
- relate_all_collection()
- update_collection_type()
- get_user_selection_collection()
- delete_old_collections()
- save_themename()
- get_featured_collection_resources()
- get_featured_collection_categ_sub_fcs()
- generate_featured_collection_image_urls()
- update_collection_parent()
- get_featured_collections()
- featured_collections_permissions_filter_sql()
- featured_collection_check_access_control()
- order_featured_collections_by_hasresources()
- get_featured_collection_categories()
- is_featured_collection_category()
- is_featured_collection_category_by_children()
- validate_collection_parent()
- get_featured_collection_category_branch_by_leaf()
- process_posted_featured_collection_categories()
- get_featured_collection_ref_by_name()
- allow_collection_share()
- allow_featured_collection_share()
- filter_featured_collections_by_root()
- get_featured_collections_by_resources()
- can_delete_featured_collection()
- order_featured_collections()
- strip_prefix_chars()
- allow_upload_to_collection()
- get_all_featured_collections()
- compute_featured_collections_acess_control()
- compute_featured_collections_access_control()
- cleanup_anonymous_collections()
- can_share_upload_link()
- can_edit_upload_share()
- create_upload_link()
- generate_share_key()
- upload_share_active()
- upload_share_setup()
- external_upload_notify()
- purge_expired_shares()
- can_delete_collection()
- move_featured_collection_branch_path_root()
- send_collection_to_admin()
- collection_add_resources()
- collection_remove_resources()
- get_default_user_collection()
- can_reorder_featured_collections()
- reorder_collections()
- update_smart_collection()
- check_upload_terms()
- unrelate_all_collection()
- reorder_all_featured_collections_with_parent()
- can_create_collections()
Comment functions
Config functions
- validate_field()
- render_select_option()
- render_bool_option()
- render_text_option()
- set_config_option()
- get_config_option()
- get_config_option_users()
- get_config_options()
- process_config_options()
- config_clean()
- config_html()
- config_add_html()
- config_text_input()
- config_add_text_input()
- config_file_input()
- config_colouroverride_input()
- config_add_file_input()
- config_single_select()
- config_add_single_select()
- config_boolean_select()
- config_add_boolean_select()
- config_checkbox_select()
- config_add_checkbox_select()
- config_add_colouroverride_input()
- config_add_single_ftype_select()
- config_single_ftype_select()
- config_generate_AutoSaveConfigOption_function()
- config_process_file_input()
- config_generate_html()
- config_merge_non_image_types()
- get_header_image()
- config_register_core_fieldvars()
- config_add_hidden_input()
- config_register_core_field_refs()
- checkValidExtension()
- override_rs_variables_by_eval()
- remove_config_option()
- update_resource_type_field_resource_types()
- get_resource_type_field_resource_types()
- create_resource_type()
- save_resource_type()
- rs_get_resource_type()
- save_resource_type_field()
- get_resource_type_field_columns()
- delete_config_option()
- set_maxNumberOfFiles()
- clear_restype_cache()
- is_valid_contact_sheet_preview_size()
- check_removed_ui_config()
CSV export functions
Dash functions
- create_dash_tile()
- update_dash_tile()
- delete_dash_tile()
- revoke_all_users_flag_cascade_delete()
- append_default_position()
- reorder_default_dash()
- update_default_dash_tile_order()
- get_tile()
- all_user_dash_tile_active()
- existing_tile()
- cleanup_dash_tiles()
- checkTileConfig()
- checkConfigCustomHomePanels()
- get_alluser_available_tiles()
- get_default_dash()
- deleteDefaultDashTile()
- updateDashTileOrder()
- get_managed_dash()
- add_usergroup_dash_tile()
- append_usergroup_position()
- reorder_usergroup_dash()
- update_usergroup_dash_tile_order()
- build_usergroup_dash()
- get_tile_user_groups()
- get_usergroup_available_tiles()
- get_usergroup_tile()
- add_user_dash_tile()
- get_user_tile()
- create_new_user_dash()
- update_user_dash_tile_order()
- delete_user_dash_tile()
- empty_user_dash()
- reorder_user_dash()
- append_user_position()
- get_user_available_tiles()
- get_user_dash()
- deleteDashTile()
- render_delete_dialog_JS()
- parse_dashtile_link()
- build_dash_tile_list()
- allow_tile_colour_change()
- render_dash_tile_colour_chooser()
- update_tile_preview_colour()
- get_tile_custom_style()
- delete_usergroup_dash_tile()
- allowPromotedResources()
- render_upgrade_available_tile()
- generate_dash_tile_toolbar()
- existing_dash_tile()
- dash_tile_featured_collection_get_resources()
- validate_tile_style()
- validate_build_url()
- tltype_srch_generate_js_for_background_and_count()
- get_dash_search_data()
- can_edit_tile()
Debug functions
Encryption functions
Facial recognition functions
File functions
- get_checksum()
- is_safe_basename()
- is_valid_rs_path()
- validate_temp_path()
- validate_resource_files()
- is_valid_upload_path()
- is_banned_extension()
- remove_empty_temp_directory()
- rrmdir()
- check_valid_file_extension()
- temp_local_download_remote_file()
- isPathWhitelisted()
- generateUserFilenameUID()
- safe_file_name()
General functions
- getval()
- getuid()
- escape_check()
- unescape()
- nicedate()
- redirect()
- trim_spaces()
- trim_array()
- tidylist()
- tidy_trim()
- average_length()
- get_stats_activity_types()
- get_stats_years()
- newlines()
- get_all_site_text()
- get_site_text()
- check_site_text_custom()
- save_site_text()
- string_similar()
- formatfilesize()
- filesize2bytes()
- get_mime_type()
- send_mail()
- send_mail_phpmailer()
- log_mail()
- rs_quoted_printable_encode()
- rs_quoted_printable_encode_subject()
- pager()
- send_statistics()
- remove_extension()
- verify_extension()
- get_allowed_extensions()
- get_allowed_extensions_by_type()
- getAbsolutePath()
- getFolderContents()
- mb_basename()
- strip_extension()
- is_process_lock()
- set_process_lock()
- clear_process_lock()
- filesize_unlimited()
- strip_leading_comma()
- convert()
- get_temp_dir()
- convert_path_to_url()
- escape_command_args()
- run_command()
- run_external()
- error_alert()
- xml_entities()
- get_xml_entity_at_index_0()
- sanitize_char()
- format_display_field()
- format_string_more_link()
- sortmulti()
- draw_performance_footer()
- sql_affected_rows()
- get_imagemagick_path()
- get_utility_path()
- get_executable_path()
- truncate_cache_arrays()
- txt2html()
- is_html()
- rs_setcookie()
- get_editable_states()
- validate_html()
- generateURL()
- tail()
- move_array_element()
- emptyiszero()
- array_column()
- get_slideshow_files_data()
- form_value_display()
- job_queue_add()
- job_queue_update()
- job_queue_delete()
- job_queue_get_jobs()
- job_queue_run_job()
- user_set_usergroup()
- generateSecureKey()
- IsModal()
- generateCSRFToken()
- isValidCSRFToken()
- generateFormToken()
- generateAjaxToken()
- enforcePostRequest()
- findDuplicates()
- is_resourcespace_upgrade_available()
- get_recent_users()
- check_script_last_ran()
- count_errors()
- search_array_by_keyvalue()
- bypass_permissions()
- set_sysvar()
- get_sysvar()
- hook()
- strip_tags_and_attributes()
- show_pagetime()
- get_debug_log_dir()
- debug()
- rcRmdir()
- daily_stat()
- pagename()
- text()
- get_section_list()
- resolve_user_agent()
- get_ip()
- ResolveKB()
- trim_filename()
- job_queue_get_job()
- job_queue_purge()
- get_inner_html_from_tag()
- array_flip_by_value_key()
- reshape_array_by_value_keys()
- permission_j()
- permission_negative_j()
- cleanup_files()
- is_int_loose()
- ip_matches()
- set_unique_filename()
- build_permission()
- validate_remote_code()
- get_system_status()
- allowed_type_mime()
- try_unlink()
- check_filestore_browseability()
- check_imagemagick_cli_version_found()
- check_numeric_cli_version_found()
- check_utility_cli_version_found_by_name()
- command_line_only()
- prefix_value()
- generate_csrf_js_object()
- strip_paragraph_tags()
- set_order_by_to_zero()
- try_getimagesize()
- execution_lockout_remove_resource_type_field_props()
- is_positive_int_loose()
- compute_dpi()
- compute_megapixel()
- is_jpeg_extension()
- get_total_approved_users()
- get_total_resources()
- getCertificateExpiry()
- validate_sort_value()
- js_call_CentralSpaceLoad()
- isValidCssColor()
- generateConsistentColour()
- hslToRgb()
Language functions
- ucfirstletter()
- lang_or_i18n_get_translated()
- i18n_get_translated()
- i18n_get_collection_name()
- i18n_get_indexable()
- i18n_get_translations()
- str_replace_formatted_placeholder()
- ucfirstletter_callback()
- normalize_keyword()
- remove_accents()
- seems_utf8()
- http_get_preferred_language()
- setLanguage()
- lang_load_site_text()
- i18n_get_all_translations()
- i18n_merge_translations()
- get_display_language()
Log functions
Login functions
Message functions
- system_notification()
- message_get()
- message_add()
- message_remove()
- message_seen()
- message_unseen()
- message_seen_all()
- message_purge()
- message_send_unread_emails()
- message_remove_related()
- message_user_remove()
- message_get_conversation()
- send_user_message()
- message_deleteselusrmsg()
- message_selectedseen()
- message_selectedunseen()
- message_getrefs()
- send_user_notification()
- get_user_message()
- send_integrity_failure_notices()
- build_specialsearch_list_urls()
Migration functions
Node functions
- set_node()
- delete_node()
- delete_nodes_for_resource_type_field()
- get_node()
- is_parent_node()
- get_tree_node_level()
- get_root_node_by_leaf()
- reorder_node()
- reorder_nodes()
- render_new_node_record()
- get_node_order_by()
- draw_tree_node_table()
- node_field_options_override()
- add_node_keyword()
- remove_node_keyword()
- remove_all_node_keyword_mappings()
- check_node_indexed()
- add_node_keyword_mappings()
- remove_node_keyword_mappings()
- add_resource_nodes()
- add_resource_nodes_multi()
- get_resource_nodes()
- delete_resource_nodes()
- delete_resource_nodes_multi()
- delete_all_resource_nodes()
- copy_resource_nodes()
- get_nodes_from_keywords()
- update_resource_node_hitcount()
- copy_resource_type_field_nodes()
- get_parent_nodes()
- get_nodes_count()
- extract_node_options()
- get_node_by_name()
- get_node_id()
- node_name_comparator()
- node_orderby_comparator()
- get_node_elements()
- get_node_tree()
- get_tree_strings()
- compute_node_branch_path()
- compute_nodes_by_parent()
- get_resource_nodes_batch()
- get_nodes_by_refs()
- process_node_search_syntax_to_names()
- delete_unused_non_fixed_list_nodes()
- remove_invalid_node_keyword_mappings()
- get_nodes_use_count()
- check_delete_nodes()
- remove_field_keywords()
- get_cattree_nodes_ordered()
- get_cattree_node_strings()
- cattree_node_creator()
- cattree_node_flatten()
- get_resources_nodes_by_rtf()
- get_node_strings()
- order_tree_nodes()
- add_sql_node_language()
- migrate_fixed_to_text()
- cleanup_invalid_nodes()
- get_all_parents_by_leaf()
- get_all_ancestors_for_node()
- delete_node_resources()
- remove_invalid_resource_node_mappings()
- update_node_active_state()
- toggle_active_state_for_nodes()
- toggle_category_tree_nodes_active_state()
- node_is_active()
- get_nodes()
PDF functions
Plugin functions
- activate_plugin()
- deactivate_plugin()
- purge_plugin_config()
- get_plugin_yaml()
- config_json_encode()
- config_encode()
- get_plugin_config()
- set_plugin_config()
- is_plugin_activated()
- handle_rsc_upload()
- display_rsc_upload()
- config_gen_setup_post()
- config_gen_setup_html()
- config_section_header()
- config_add_section_header()
- config_add_text_list_input()
- config_multi_select()
- config_add_multi_select()
- config_single_user_select()
- config_add_single_user_select()
- config_multi_user_select()
- config_add_multi_user_select()
- config_single_group_select()
- config_add_single_group_select()
- config_multi_group_select()
- config_add_multi_group_select()
- config_multi_ftype_select()
- config_add_multi_ftype_select()
- config_single_rtype_select()
- config_add_single_rtype_select()
- config_multi_rtype_select()
- config_add_multi_rtype_select()
- config_db_single_select()
- config_add_db_single_select()
- config_db_multi_select()
- config_add_db_multi_select()
- config_add_hidden()
- config_text_field()
- config_userselect_field()
- config_field_select()
- config_boolean_field()
- config_custom_select_multi()
- config_custom_select()
- get_plugin_css()
- plugin_activate_for_setup()
- include_plugin_config()
- register_plugin_language()
- get_plugin_path()
- register_plugin()
- config_multi_archive_select()
- config_add_multi_archive_select()
- plugin_encode_complex_configs()
- plugin_decode_complex_configs()
- get_active_plugins()
- register_group_access_plugins()
- RenderPlugin()
Render functions
- render_search_field()
- render_sort_order()
- render_dropdown_option()
- render_actions()
- render_user_group_multi_select()
- render_user_group_select()
- render_user_group_checkbox_select()
- render_text_question()
- render_split_text_question()
- render_dropdown_question()
- render_access_key_tr()
- is_field_displayed()
- display_multilingual_text_field()
- display_field()
- render_date_range_field()
- renderBreadcrumbs()
- renderCallToActionTile()
- renderSocialMediaShareLinksForUrl()
- renderLockButton()
- render_resource_image()
- calculate_image_display()
- render_share_options()
- render_field_selector_question()
- render_filter_bar_button()
- render_upload_here_button()
- render_trash()
- render_browse_bar()
- generate_browse_bar_item()
- render_help_link()
- render_question_div()
- render_custom_fields()
- render_selected_resources_counter()
- render_edit_selected_btn()
- render_clear_selected_btn()
- render_selected_collection_actions()
- render_user_collection_select()
- render_csrf_data_attributes()
- check_display_condition()
- has_browsebar()
- display_upload_options()
- display_field_data()
- render_resource_lock_link()
- EditNav()
- SaveAndClearButtons()
- UpdateResultOrder()
- display_size_option()
- show_upgrade_in_progress()
- render_audio_download_link()
- render_table()
- render_array_in_table_cells()
- render_new_featured_collection_cta()
- render_featured_collection_category_selector()
- render_featured_collections()
- render_featured_collection()
- DrawOption()
- render_featured_collections_category_permissions()
- render_top_page_error_style()
- render_workflow_state_question()
- render_share_password_question()
- pclick()
- pblur()
- render_question_form_helper()
- render_hidden_input()
- radio_get_layout()
- render_radio_buttons_question()
- render_message()
- render_antispam_question()
- render_fixed_text_question()
- render_fa_icon_selector()
- filterIcons()
- escape_quoted_data()
- display_related_resources()
- admin_resource_type_field_constraint()
- admin_resource_type_field_option()
- showHideResTypeSelector()
- render_resource_type_selector_question()
- add_download_column()
- escape()
- render_resource_view_image()
- is_another_tool_option_enabled()
- toggleMode()
- toggleAnnotationsOption()
- toggleImagePreviewZoomOption()
- render_resource_tools_size_download_options()
- render_fixedlist_as_pills()
- render_fixed_list_as_pills()
Reporting functions
- render_bar_graph()
- render_pie_graph()
- report_process_query_placeholders()
- report_has_thumbnail()
- report_has_date_by_id()
- report_has_date()
- get_translated_activity_type()
- unsubscribe_user_from_periodic_report()
- delete_periodic_report()
- send_periodic_report_emails()
- create_periodic_email()
- do_report()
- get_reports()
- get_report_name()
Request functions
- managed_collection_request()
- get_request()
- get_user_requests()
- save_request()
- get_requests()
- email_collection_request()
- email_resource_request()
- get_valid_custom_fields()
- gen_custom_fields_html_props()
- process_custom_fields_submission()
- can_use_owner_field()
- get_notification_users_by_owner_field()
- resource_request_visible()
Research functions
Slideshow functions
Theme permission functions
User functions
- validate_user()
- setup_user()
- get_users()
- get_users_with_permission()
- get_user_by_email()
- get_user_by_username()
- get_usergroups()
- get_usergroup()
- get_user()
- save_user()
- email_user_welcome()
- email_reset_link()
- auto_create_user_account()
- email_user_request()
- new_user()
- get_active_users()
- change_password()
- make_password()
- bulk_mail()
- get_user_log()
- resolve_userlist_groups()
- resolve_userlist_groups_smart()
- remove_groups_smart_from_userlist()
- check_password()
- resolve_users()
- check_access_key()
- check_access_key_collection()
- make_username()
- get_registration_selectable_usergroups()
- open_access_to_user()
- open_access_to_group()
- resolve_open_access()
- remove_access_to_user()
- user_email_exists()
- resolve_user_emails()
- create_password_reset_key()
- get_rs_session_id()
- get_notification_users()
- verify_antispam()
- check_share_password()
- get_users_from_permission_lookup()
- offset_user_local_timezone()
- checkPermission_anonymoususer()
- checkPermission_dashadmin()
- checkPermission_dashuser()
- checkPermission_dashmanage()
- checkPermission_dashcreate()
- checkperm()
- checkperm_user_edit()
- internal_share_access()
- save_usergroup()
- set_user_profile()
- delete_profile_image()
- get_profile_image()
- get_profile_text()
- get_languages_notify_users()
- get_upload_url()
- emulate_user()
- is_authenticated()
- get_approver_usergroups()
- get_usergroup_approvers()
- copy_usergroup_permissions()
- mark_email_as_invalid()
- check_email_invalid()
- get_users_by_permission()
- is_anonymous_user()
- get_users_by_preference()
- generate_temp_download_key()
- validate_temp_download_key()
- setup_command_line_user()
- user_limit_reached()
- can_set_admin_usergroup()
- update_user_access()
- checkPermission_manage_users()
- set_processing_message()
- checkperm_login_as_user()
Video functions
Database functions
- sql_truncate_text_val()
- db_end_transaction()
- db_rollback_transaction()
- sql_query()
- sql_value()
- sql_array()
- sql_insert_id()
- get_query_cache_location()
- clear_query_cache()
- check_db_structs()
- CheckDBStruct()
- sql_limit()
- sql_is_null_or_eq_val()
- sql_null_or_val()
- sql_query_prepared()
- ps_query()
- fetch_assoc_stmt()
- copy_value()
- ps_value()
- ps_array()
- ps_param_insert()
- ps_param_fill()
- columns_in()
- sql_limit_with_total_count()
- sql_reorder_records()
- ps_fill_param_array()
- db_chunk_id_list()
- errorhandler()
- db_use_multiple_connection_modes()
- db_set_connection_mode()
- db_get_connection_mode()
- db_clear_connection_mode()
- sql_connect()
- db_begin_transaction()
Metadata functions
Resource functions
- get_resource_path()
- get_resource_data()
- put_resource_data()
- create_resource()
- update_hitcount()
- save_resource_data()
- set_resource_defaults()
- save_resource_data_multi()
- append_field_value()
- remove_keyword_mappings()
- remove_keyword_from_resource()
- add_keyword_mappings()
- add_keyword_to_resource()
- remove_all_keyword_mappings_for_field()
- update_field()
- ()
- email_resource()
- delete_resource()
- get_resource_type_field()
- get_resource_field_data()
- get_resource_field_data_batch()
- get_resource_types()
- get_resource_top_keywords()
- clear_resource_data()
- get_max_resource_ref()
- get_resource_ref_range()
- copy_resource()
- resource_log()
- get_resource_log()
- get_resource_type_name()
- get_resource_custom_access()
- get_resource_custom_access_users_usergroups()
- save_resource_custom_access()
- get_custom_access()
- get_themes_by_resource()
- update_resource_type()
- relate_to_array()
- get_exiftool_fields()
- createTempFile()
- stripMetadata()
- write_metadata()
- delete_exif_tmpfile()
- update_resource()
- import_resource()
- get_alternative_files()
- add_alternative_file()
- delete_alternative_file()
- get_alternative_file()
- save_alternative_file()
- user_rating_save()
- process_notify_user_contributed_submitted()
- notify_user_contributed_submitted()
- notify_user_contributed_unsubmitted()
- get_field()
- get_field_options_with_stats()
- save_field_options()
- get_resources_matching_keyword()
- get_keyword_from_option()
- add_field_option()
- get_resource_access()
- get_custom_access_user()
- edit_resource_external_access()
- resource_download_allowed()
- get_edit_access()
- filter_match()
- log_diff()
- get_metadata_templates()
- get_resource_collections()
- download_summary()
- check_use_watermark()
- autocomplete_blank_fields()
- get_resource_files()
- reindex_resource()
- get_page_count()
- update_disk_usage()
- update_disk_usage_cron()
- get_total_disk_usage()
- overquota()
- notify_user_resources_approved()
- get_original_imagesize()
- generate_resource_access_key()
- get_resource_external_access()
- delete_resource_access_key()
- resource_type_config_override()
- update_archive_status()
- delete_resources_in_collection()
- update_related_resource()
- can_share_resource()
- delete_resource_custom_access_usergroups()
- truncate_join_field_value()
- get_video_snapshots()
- resource_file_readonly()
- delete_resource_custom_user_access()
- get_video_info()
- copyAllDataToResource()
- copyResourceDataValues()
- copy_locked_data()
- copy_locked_fields()
- copyRelatedResources()
- process_edit_form()
- update_timestamp()
- get_extension()
- get_last_resource_edit_array()
- get_default_archive_state()
- save_original_file_as_alternative()
- replace_resource_file()
- get_resource_all_image_sizes()
- sanitize_date_field_input()
- download_link_generate_key()
- download_link_check_key()
- filter_check()
- update_resource_keyword_hitcount()
- copy_hitcount_to_live()
- get_image_sizes()
- get_preview_quality()
- get_related_resources()
- get_field_options()
- get_data_by_field()
- get_resources_by_resource_data_value()
- get_all_image_sizes()
- image_size_restricted_access()
- get_fields()
- get_hidden_indexed_fields()
- get_category_tree_fields()
- get_OR_fields()
- get_nopreview_icon()
- get_indexed_resource_type_fields()
- get_resource_type_fields()
- notify_resource_change()
- add_verbatim_keywords()
- metadata_field_edit_access()
- get_download_filename()
- get_resource_type_from_extension()
- canSeePreviewTools()
- checkPreviewToolsOptionUniqueness()
- alt_is_ffmpeg_alternative()
- create_resource_type_field()
- metadata_field_view_access()
- get_workflow_states()
- delete_resource_type_field()
- tab_names()
- get_resource_table_joins()
- update_resource_lock()
- get_resource_lock_message()
- get_resource_data_batch()
- get_external_shares()
- get_video_duration()
- relate_all_resources()
- allow_in_browser()
- update_node_hitcount_from_search()
- update_resource_field_column()
- get_all_resource_types()
- data_joins_field_value_translate_and_csv()
- process_resource_data_joins_values()
- canSeeAnnotationsFields()
- apply_resource_default()
- skip_scr_size_preview()
- related_resource_pull()
- get_resource_preview()
- check_resources()
- get_resources_to_validate()
- get_nopreview_html()
Search functions
- copy_filter()
- save_related_keywords()
- get_simple_search_fields()
- get_fields_for_search_display()
- get_filters()
- get_filter()
- get_filter_rules()
- get_filter_rule()
- save_filter()
- save_filter_rule()
- delete_filter()
- delete_filter_rule()
- get_grouped_related_keywords()
- update_search_from_request()
- get_search_default_restypes()
- get_selectedtypes()
- render_advanced_search_buttons()
- get_collections_resource_count()
- get_search_params()
- is_not_wildcard_only()
- search_title_node_processing()
- setup_search_chunks()
- log_keyword_usage()
- set_search_order_by()
- get_upload_here_selected_nodes()
- suggest_refinement()
- get_advanced_search_fields()
- get_advanced_search_collection_fields()
- search_form_to_search_query()
- refine_searchstring()
- compile_search_actions()
- search_filter()
- search_special()
- resolve_nodes_from_string()
- rebuild_specific_field_search_from_node()
- search_get_previews()
- resolve_soundex()
- get_default_search_states()
- get_filter_sql()
- split_keywords()
- cleanse_string()
- resolve_keyword()
- add_partial_index()
- highlightkeywords()
- str_highlight()
- sorthighlights()
- get_suggested_keywords()
- get_related_keywords()
Map functions
Job functions
Tab functions
Test functions
save_resource_data()
Description
Save resource dataIMPORTANT: inactive nodes should be left alone (don't add/remove) except when processing fixed list field types that
only hold one value (dropdown, radio). Plugins should determine this based on their use cases when hooking.
Parameters
Column | Type | Default | Description |
---|---|---|---|
$ref | int | ||
$multi | bool | ||
$autosave_field | string|int | "" |
Return
true|array | List of errors if unsuccessful, true otherwise |
Location
include/resource_functions.php lines 628 to 1259
Definition
function save_resource_data($ref, $multi, $autosave_field = "")
{
debug_function_call("save_resource_data", func_get_args());
# Save all submitted data for resource $ref.
# Also re-index all keywords from indexable fields.
global $lang, $languages, $language, $FIXED_LIST_FIELD_TYPES,
$DATE_FIELD_TYPES, $reset_date_field, $reset_date_upload_template,
$edit_contributed_by, $new_checksums, $upload_review_mode, $blank_edit_template, $is_template, $NODE_FIELDS,
$userref, $userresourcedefaults;
hook("befsaveresourcedata", "", array($ref));
// Ability to avoid editing conflicts by checking checksums.
// NOTE: this should NOT apply to upload.
$check_edit_checksums = true;
// Save resource defaults (functionality available for upload only)
// Call it here so that if users have access to the field and want
// to override it, they can do so
if (0 > $ref) {
set_resource_defaults($ref);
$check_edit_checksums = false;
}
# Loop through the field data and save (if necessary)
$errors = array();
$fields = get_resource_field_data($ref, $multi, !hook("customgetresourceperms"));
$expiry_field_edited = false;
$resource_data = get_resource_data($ref);
if ($resource_data["lock_user"] > 0 && $resource_data["lock_user"] != $userref) {
$errors[] = get_resource_lock_message($resource_data["lock_user"]);
return $errors;
}
# Load the configuration for the selected resource type. Allows for alternative notification addresses, etc.
resource_type_config_override($resource_data["resource_type"]);
# Set up arrays of node ids to add/remove. We can't remove all nodes as user may not have access
$nodes_to_add = [];
$nodes_to_remove = [];
$oldnodenames = [];
$nodes_check_delete = [];
$resource_update_log_sql = [];
$ui_selected_node_values = [];
$all_current_field_nodes = [];
$new_node_values = [];
$updated_resources = [];
$node_not_active = fn(array $node): bool => !node_is_active($node);
// All the nodes passed for editing. Some of them were already a value
// of the fields while others have been added/removed
$user_set_values = getval('nodes', [], false, 'is_array');
// Initialise array to store new checksums that client needs after autosave, without which subsequent edits will fail
$new_checksums = array();
for ($n = 0; $n < count($fields); $n++) {
if (
!(
checkperm('F' . $fields[$n]['ref'])
|| (checkperm("F*") && !checkperm('F-' . $fields[$n]['ref']))
// If we hide on upload the field, there is no need to check values passed from the UI as there shouldn't be any
|| ((0 > $ref || $upload_review_mode) && $fields[$n]['hide_when_uploading'])
)
&& ('' == $autosave_field || $autosave_field == $fields[$n]['ref']
|| (is_array($autosave_field) && in_array($fields[$n]['ref'], $autosave_field))
)
) {
// Fixed list fields use node IDs directly
if (in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES)) {
debug("save_resource_data(): Checking nodes to add/ remove for field {$fields[$n]['ref']} - {$fields[$n]['title']}");
// Get currently selected nodes for this field
$current_field_nodes = get_resource_nodes($ref, $fields[$n]['ref']);
$all_current_field_nodes = array_merge($all_current_field_nodes, $current_field_nodes);
// Check if resource field data has been changed between form being loaded and submitted
$post_cs = getval("field_" . $fields[$n]['ref'] . "_checksum", "");
sort($current_field_nodes);
$current_cs = md5(implode(",", $current_field_nodes));
if ($check_edit_checksums && $post_cs != "" && $post_cs != $current_cs) {
$errors[$fields[$n]["ref"]] = i18n_get_translated($fields[$n]['title']) . ': ' . $lang["save-conflict-error"];
continue;
}
debug("save_resource_data(): Current nodes for resource " . $ref . ": " . implode(",", $current_field_nodes));
// Work out nodes submitted by user
if (
isset($user_set_values[$fields[$n]['ref']])
&& !is_array($user_set_values[$fields[$n]['ref']])
&& '' != $user_set_values[$fields[$n]['ref']]
&& is_numeric($user_set_values[$fields[$n]['ref']])
) {
$ui_selected_node_values[] = $user_set_values[$fields[$n]['ref']];
} elseif (
isset($user_set_values[$fields[$n]['ref']])
&& is_array($user_set_values[$fields[$n]['ref']])
) {
$ui_selected_node_values = $user_set_values[$fields[$n]['ref']];
}
// Check nodes are valid for this field
if (FIELD_TYPE_CATEGORY_TREE === $fields[$n]['type']) {
$all_tree_nodes_ordered = get_cattree_nodes_ordered($fields[$n]['ref'], null, true);
// remove the fake "root" node which get_cattree_nodes_ordered() is adding since we won't be using get_cattree_node_strings()
array_shift($all_tree_nodes_ordered);
$inactive_nodes = array_column(array_filter($all_tree_nodes_ordered, $node_not_active), 'ref');
$all_tree_nodes_ordered = array_values($all_tree_nodes_ordered);
$node_options = array_column($all_tree_nodes_ordered, 'name', 'ref');
$validnodes = array_keys($node_options);
} else {
$fieldnodes = get_nodes($fields[$n]['ref'], '', false);
$node_options = array_column($fieldnodes, 'name', 'ref');
$validnodes = array_column($fieldnodes, 'ref');
$inactive_nodes = array_column(array_filter($fieldnodes, $node_not_active), 'ref');
}
// $validnodes are already sorted by the order_by (default for get_nodes). This is needed for the data_joins fields later
$ui_selected_node_values = array_values(array_intersect($validnodes, $ui_selected_node_values));
debug("save_resource_data(): UI selected nodes for resource {$ref}: " . implode(',', $ui_selected_node_values));
// Set new value for logging
$new_node_values = array_merge($new_node_values, $ui_selected_node_values);
$added_nodes = array_diff($ui_selected_node_values, $current_field_nodes, $inactive_nodes);
debug("save_resource_data(): Adding nodes to resource " . $ref . ": " . implode(",", $added_nodes));
$nodes_to_add = array_merge($nodes_to_add, $added_nodes);
if (
// We must release an inactive node if the type can only hold one value...
in_array($fields[$n]['type'], [FIELD_TYPE_DROP_DOWN_LIST, FIELD_TYPE_RADIO_BUTTONS])
// ...but prevent direct removals (ie. no value)
&& $ui_selected_node_values !== []
) {
$removed_nodes = array_diff($current_field_nodes, $ui_selected_node_values);
$current_inactive_resource_field_nodes = [];
} else {
$removed_nodes = array_diff($current_field_nodes, $ui_selected_node_values, $inactive_nodes);
$current_inactive_resource_field_nodes = array_intersect($current_field_nodes, $inactive_nodes);
}
debug("save_resource_data(): Removed nodes from resource " . $ref . ": " . implode(",", $removed_nodes));
$nodes_to_remove = array_merge($nodes_to_remove, $removed_nodes);
if (count($added_nodes) > 0 || count($removed_nodes) > 0) {
$new_nodevals = array();
// Build new value
foreach ($ui_selected_node_values as $ui_selected_node_value) {
if (FIELD_TYPE_CATEGORY_TREE === $fields[$n]['type']) {
$new_nodevals[] = implode(
'/',
array_column(
compute_node_branch_path($all_tree_nodes_ordered, $ui_selected_node_value),
'name'
)
);
continue;
}
$new_nodevals[] = $node_options[$ui_selected_node_value];
}
# Is this is a 'joined' field?
$joins = get_resource_table_joins();
if (in_array($fields[$n]["ref"], $joins)) {
$new_nodes_val = implode($GLOBALS['field_column_string_separator'], $new_nodevals);
if ((1 == $fields[$n]['required'] && "" != $new_nodes_val) || 0 == $fields[$n]['required']) { # If joined field is required we shouldn't be able to clear it.
update_resource_field_column($ref, $fields[$n]["ref"], $new_nodes_val);
}
}
$val = implode(",", $new_nodevals);
$ui_selected_node_values = array_merge($ui_selected_node_values, $current_inactive_resource_field_nodes);
sort($ui_selected_node_values);
$new_checksums[$fields[$n]['ref']] = md5(implode(',', $ui_selected_node_values));
$updated_resources[$ref][$fields[$n]['ref']] = $new_nodevals; // To pass to hook
} else {
$val = "";
}
} // End of if in $FIXED_LIST_FIELD_TYPES
else {
if ($fields[$n]['type'] == FIELD_TYPE_DATE_RANGE) {
# date range type
# each value will be a node so we end up with a pair of nodes to represent the start and end dates
$daterangenodes = array();
$newval = "";
if (($date_edtf = getval("field_" . $fields[$n]["ref"] . "_edtf", "")) !== "") {
// We have been passed the range in EDTF format, check it is in the correct format
$rangeregex = "/^(\d{4})(-\d{2})?(-\d{2})?\/(\d{4})(-\d{2})?(-\d{2})?/";
if (!preg_match($rangeregex, $date_edtf, $matches)) {
$errors[$fields[$n]["ref"]] = $lang["information-regexp_fail"] . " : " . $date_edtf;
continue;
}
if (is_int_loose($fields[$n]["linked_data_field"])) {
// Update the linked field with the raw EDTF string submitted
update_field($ref, $fields[$n]["linked_data_field"], $date_edtf);
}
$rangedates = explode("/", $date_edtf);
$rangestart = str_pad($rangedates[0], 10, "-00");
$rangeendparts = explode("-", $rangedates[1]);
$rangeendyear = $rangeendparts[0];
$rangeendmonth = isset($rangeendparts[1]) ? $rangeendparts[1] : 12;
$rangeendday = isset($rangeendparts[2]) ? $rangeendparts[2] : cal_days_in_month(CAL_GREGORIAN, $rangeendmonth, $rangeendyear);
$rangeend = $rangeendyear . "-" . $rangeendmonth . "-" . $rangeendday;
$newval = $rangestart . DATE_RANGE_SEPARATOR . $rangeend;
$daterangenodes[] = set_node(null, $fields[$n]["ref"], $rangestart, null, null);
$daterangenodes[] = set_node(null, $fields[$n]["ref"], $rangeend, null, null);
} else {
// Range has been passed via normal inputs, construct the value from the date/time dropdowns
$date_parts = array("_start","_end");
foreach ($date_parts as $date_part) {
$val = getval("field_" . $fields[$n]["ref"] . $date_part . "-y", "");
if (intval($val) <= 0) {
$val = "";
} elseif (($field = getval("field_" . $fields[$n]["ref"] . $date_part . "-m", "")) != "") {
$val .= "-" . $field;
if (($field = getval("field_" . $fields[$n]["ref"] . $date_part . "-d", "")) != "") {
$val .= "-" . $field;
} else {
$val .= "-00";
}
} else {
$val .= "-00-00";
}
$newval .= ($newval != "" ? DATE_RANGE_SEPARATOR : "") . $val;
if ($val !== "") {
$daterangenodes[] = set_node(null, $fields[$n]["ref"], $val, null, null);
}
}
}
natsort($daterangenodes);
// Set new value for logging
$new_node_values = array_merge($new_node_values, $daterangenodes);
// Get currently selected nodes for this field
$current_field_nodes = get_resource_nodes($ref, $fields[$n]['ref'], false, SORT_ASC);
$all_current_field_nodes = array_merge($all_current_field_nodes, $current_field_nodes);
// Check if resource field data has been changed between form being loaded and submitted
$post_cs = getval("field_" . $fields[$n]['ref'] . "_checksum", "");
sort($current_field_nodes);
$current_cs = md5(implode(",", $current_field_nodes));
if ($check_edit_checksums && $post_cs != "" && $post_cs != $current_cs) {
$errors[$fields[$n]["ref"]] = i18n_get_translated($fields[$n]['title']) . ': ' . $lang["save-conflict-error"];
continue;
}
if ($daterangenodes !== $current_field_nodes) {
$added_nodes = array_diff($daterangenodes, $current_field_nodes);
debug("save_resource_data(): Adding nodes to resource " . $ref . ": " . implode(",", $added_nodes));
$nodes_to_add = array_merge($nodes_to_add, $added_nodes);
$removed_nodes = array_diff($current_field_nodes, $daterangenodes);
debug("save_resource_data(): Removed nodes from resource " . $ref . ": " . implode(",", $removed_nodes));
$nodes_to_remove = array_merge($nodes_to_remove, $removed_nodes);
$val = $newval;
# If this is a 'joined' field it still needs to be added to the resource column
$joins = get_resource_table_joins();
if (in_array($fields[$n]["ref"], $joins)) {
update_resource_field_column($ref, $fields[$n]["ref"], $newval);
}
sort($daterangenodes);
$new_checksums[$fields[$n]['ref']] = md5(implode(",", $daterangenodes));
$updated_resources[$ref][$fields[$n]['ref']][] = $newval; // To pass to hook
}
} elseif (in_array($fields[$n]['type'], $DATE_FIELD_TYPES)) {
# date type, construct the value from the date/time dropdowns to be used in DB
$val = sanitize_date_field_input($fields[$n]["ref"], false);
// A proper input:date field
if ($GLOBALS['use_native_input_for_date_field'] && $fields[$n]['type'] === FIELD_TYPE_DATE) {
$val = getval("field_{$fields[$n]['ref']}", '');
if ($val !== '' && !validateDatetime($val, 'Y-m-d')) {
$errors[$fields[$n]['ref']] = $lang['error_invalid_date'] . ' : ' . $val;
continue;
}
}
// Upload template: always reset to today's date, if configured and field is hidden
if (
0 > $ref
&& $reset_date_upload_template
&& $reset_date_field == $fields[$n]['ref']
&& $fields[$n]['hide_when_uploading']
) {
$val = date('Y-m-d H:i');
}
// Check if resource field data has been changed between form being loaded and submitted
$post_cs = getval("field_" . $fields[$n]['ref'] . "_checksum", "");
$current_cs = md5((string)$fields[$n]['value']);
if ($check_edit_checksums && $post_cs != "" && $post_cs != $current_cs) {
$errors[$fields[$n]["ref"]] = i18n_get_translated($fields[$n]['title']) . ': ' . $lang["save-conflict-error"];
continue;
}
$new_checksums[$fields[$n]['ref']] = md5($val);
$updated_resources[$ref][$fields[$n]['ref']][] = $val; // To pass to hook
} else {
# Set the value exactly as sent.
$val = getval("field_" . $fields[$n]["ref"], "");
$rawval = getval("field_" . $fields[$n]["ref"], "");
# Check if resource field data has been changed between form being loaded and submitted
# post_cs is the checksum of the data when it was loaded from the database
# current_cs is the checksum of the data on the database now
# if they are the same then there has been no intervening update and so its ok to update with our new value
# if our new data yields a different checksum, then we know the new value represents a change
# the new checksum for the new value of a field is stored in $new_checksums[$fields[$n]['ref']]
$post_cs = getval("field_" . $fields[$n]['ref'] . "_checksum", "");
$current_cs = md5(trim(preg_replace('/\s\s+/', ' ', (string) $fields[$n]['value'])));
if ($check_edit_checksums && $post_cs != "" && $post_cs != $current_cs) {
$errors[$fields[$n]["ref"]] = i18n_get_translated($fields[$n]['title']) . ': ' . $lang["save-conflict-error"];
continue;
}
$new_checksums[$fields[$n]['ref']] = md5(trim(preg_replace('/\s\s+/', ' ', $rawval)));
$updated_resources[$ref][$fields[$n]['ref']][] = $val; // To pass to hook
}
# Check for regular expression match
if (strlen(trim((string)$fields[$n]["regexp_filter"])) >= 1 && strlen((string) $val) > 0) {
global $regexp_slash_replace;
if (preg_match("#^" . str_replace($regexp_slash_replace, '\\', $fields[$n]["regexp_filter"]) . "$#", $val, $matches) <= 0) {
global $lang;
debug($lang["information-regexp_fail"] . ": -" . "reg exp: " . str_replace($regexp_slash_replace, '\\', $fields[$n]["regexp_filter"]) . ". Value passed: " . $val);
$errors[$fields[$n]["ref"]] = $lang["information-regexp_fail"] . " : " . $val;
continue;
}
}
$modified_val = hook("modifiedsavedfieldvalue", '', array($fields,$n,$val));
if (!empty($modified_val)) {
$val = $modified_val;
$new_checksums[$fields[$n]['ref']] = md5(trim(preg_replace('/\s\s+/', ' ', $val)));
}
$error = hook("additionalvalcheck", "all", array($fields, $fields[$n]));
if ($error) {
$errors[$fields[$n]["ref"]] = $error;
continue;
}
} // End of if not a fixed list field
// Determine whether a required field has a default for the user
$field_has_default_for_user = false;
if ($userresourcedefaults != '') {
foreach (explode(';', $userresourcedefaults) as $rule) {
$rule_detail = explode('=', trim($rule));
$field_shortname = $rule_detail[0];
$field_default_value = $rule_detail[1];
if ($field_shortname == $fields[$n]['name'] && $field_default_value != "") {
$field_has_default_for_user = true;
break;
}
}
}
// Populate empty field with the default if necessary
if ($field_has_default_for_user && strlen((string) $val) == 0) {
$val = $field_default_value;
$new_checksums[$fields[$n]['ref']] = md5(trim(preg_replace('/\s\s+/', ' ', $val)));
}
if (
$fields[$n]['required'] == 1
&& check_display_condition($n, $fields[$n], $fields, false, $ref)
&& (
// Required node field with no nodes submitted is a candidate for error
(in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES) && count($ui_selected_node_values) == 0)
// Required continuous field with no value is a candidate for error
|| (!in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES) && trim(strip_leading_comma($val)) == '')
)
&& (
// An existing resource node field with neither any nodes submitted nor a resource default
($ref > 0 && in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES) && count($ui_selected_node_values) == 0 && !$field_has_default_for_user)
// An existing resource continuous field with neither an input value nor a resource default
|| ($ref > 0 && !in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES) && strlen((string) $val) == 0 && !$field_has_default_for_user)
// A template node field with neither any nodes submitted nor a resource default
|| ($ref < 0 && in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES) && count($ui_selected_node_values) == 0 && !$field_has_default_for_user)
// A template continuous field with neither an input value nor a resource default
|| ($ref < 0 && !in_array($fields[$n]['type'], $FIXED_LIST_FIELD_TYPES) && strlen((string) $val) == 0 && !$field_has_default_for_user)
)
// Not a metadata template
&& !$is_template
) {
$field_visibility_status = getval("field_" . $fields[$n]['ref'] . "_displayed", "");
# Register an error only if the empty required field was actually displayed
if (is_field_displayed($fields[$n]) && $field_visibility_status == "block") {
$errors[$fields[$n]['ref']] = i18n_get_translated($fields[$n]['title']) . ": {$lang['requiredfield']}";
continue;
}
}
// If all good so far, then save the data
if (
in_array($fields[$n]['type'], NON_FIXED_LIST_SINGULAR_RESOURCE_VALUE_FIELD_TYPES)
&& str_replace("\r\n", "\n", trim((string) $fields[$n]['value'])) !== str_replace("\r\n", "\n", trim((string) $val))
) {
# This value is different from the value we have on record.
# Expiry field? Set that expiry date(s) have changed so the expiry notification flag will be reset later in this function.
if ($fields[$n]["type"] == FIELD_TYPE_EXPIRY_DATE) {
$expiry_field_edited = true;
}
$use_node = null;
if (trim((string) $fields[$n]["nodes"]) != "") {
// Remove any existing node IDs for this non-fixed list field (there should only be one) unless used by other resources.
$current_field_nodes = array_filter(explode(",", $fields[$n]["nodes"]), "is_int_loose");
$all_current_field_nodes = array_merge($all_current_field_nodes, $current_field_nodes);
foreach ($current_field_nodes as $current_field_node) {
$inuse = get_nodes_use_count([$current_field_node]);
$inusecount = $inuse[$current_field_node] ?? 0;
if ($current_field_node > 0 && $inusecount == 1) {
// Reuse same node
$use_node = $current_field_node;
} else {
// Remove node from resource and create new node
$nodes_to_remove[] = $current_field_node;
$nodes_check_delete[] = $current_field_node;
}
}
}
# Add new node unless empty string
if ($val == '') {
// Remove and delete node
$nodes_to_remove[] = $current_field_node;
$nodes_check_delete[] = $current_field_node;
} else {
// Update the existing node
$newnode = set_node($use_node, $fields[$n]["ref"], $val, null, null);
if ((int)$newnode != (int)$use_node) {
// Node already exists, remove current node and replace
$nodes_to_add[] = $newnode;
$nodes_to_remove[] = $use_node;
$nodes_check_delete[] = $use_node;
// Set new value for logging
$new_node_values[] = $newnode;
} else {
$new_node_values[] = $use_node;
}
// Add to array for logging
if (!is_null($use_node)) {
$oldnodenames[$use_node] = $fields[$n]['value'];
}
}
# If this is a 'joined' field we need to add it to the resource column
$joins = get_resource_table_joins();
if (in_array($fields[$n]["ref"], $joins)) {
update_resource_field_column($ref, $fields[$n]["ref"], $val);
}
}
# Add any onchange code if new checksum for field shows that it has changed
if (
isset($fields[$n]["onchange_macro"]) && $fields[$n]["onchange_macro"] !== ""
&& $post_cs !== ""
&& isset($new_checksums[$fields[$n]["ref"]])
&& $post_cs !== $new_checksums[$fields[$n]["ref"]]
) {
$macro_resource_id = $ref;
eval(eval_check_signed($fields[$n]["onchange_macro"]));
}
} # End of if "allowed to edit field conditions"
} # End of for $fields
// When editing a resource, prevent applying the change to the resource if there are any errors
if (count($errors) > 0 && $ref > 0) {
return $errors;
}
# Save related resource field if value for Related input field is autosaved, or if form has been submitted by user
if (($autosave_field == "" || $autosave_field == "Related") && isset($_POST["related"])) {
# save related resources field
$related = explode(",", getval("related", ""));
# Trim whitespace from each entry
foreach ($related as &$relatedentry) {
$relatedentry = trim($relatedentry);
}
# Make sure all submitted values are numeric
$to_relate = array_filter($related, "is_int_loose");
$currently_related = get_related_resources($ref);
$to_add = array_diff($to_relate, $currently_related);
$to_delete = array_diff($currently_related, $to_relate);
if (count($to_add) > 0) {
update_related_resource($ref, $to_add, true);
}
if (count($to_delete) > 0) {
update_related_resource($ref, $to_delete, false);
}
}
// Update resource_node table
db_begin_transaction("update_resource_node");
if (count($nodes_to_remove) > 0) {
delete_resource_nodes($ref, $nodes_to_remove, false);
}
if (count($nodes_to_add) > 0) {
add_resource_nodes($ref, $nodes_to_add, false, false);
}
log_node_changes($ref, $new_node_values, $all_current_field_nodes, "", $oldnodenames);
if (count($nodes_check_delete) > 0) {
// This has to be after call to log_node_changes() or nodes cannot be resolved
check_delete_nodes($nodes_check_delete);
}
db_end_transaction("update_resource_node");
// Autocomplete any blank fields without overwriting any existing metadata
$autocomplete_fields = autocomplete_blank_fields($ref, false, true);
foreach ($autocomplete_fields as $autocomplete_field_ref => $autocomplete_field_value) {
$new_checksums[$autocomplete_field_ref] = md5((string)$autocomplete_field_value);
}
// Initialise an array of updates for the resource table
$resource_update_sql = array();
$resource_update_params = array();
if ($edit_contributed_by) {
$created_by = $resource_data['created_by'];
$new_created_by = getval("created_by", 0, true);
if ((getval("created_by", 0, true) > 0) && $new_created_by != $created_by) {
# Also update created_by
$resource_update_sql[] = "created_by= ?";
$resource_update_params[] = "i";
$resource_update_params[] = $new_created_by;
$olduser = get_user($created_by);
$newuser = get_user($new_created_by);
$resource_update_log_sql[] = array(
"ref" => $ref,
"type" => LOG_CODE_CREATED_BY_CHANGED,
"field" => 0,
"notes" => "",
"from" => $created_by . " (" . ($olduser["fullname"] == "" ? $olduser["username"] : $olduser["fullname"]) . ")","to" => $new_created_by . " (" . ($newuser["fullname"] == "" ? $newuser["username"] : $newuser["fullname"]) . ")");
}
}
# Expiry field(s) edited? Reset the notification flag so that warnings are sent again when the date is reached.
if ($expiry_field_edited) {
$resource_update_sql[] = "expiry_notification_sent='0'";
}
if (!hook('forbidsavearchive', '', array($errors))) {
# Also update archive status and access level
$oldaccess = $resource_data['access'];
$access = getval("access", $oldaccess, true);
$oldarchive = $resource_data['archive'];
$setarchivestate = getval("status", $oldarchive, true);
if ($setarchivestate != $oldarchive && !checkperm("e" . $setarchivestate)) { // don't allow change if user has no permission to change archive state
$setarchivestate = $oldarchive;
}
// Only if changed
if (($autosave_field == "" || $autosave_field == "Status") && $setarchivestate != $oldarchive) {
// Check if resource status has already been changed between form being loaded and submitted
if (getval("status_checksum", "") != "" && getval("status_checksum", "") != $oldarchive) {
$errors["status"] = $lang["status"] . ': ' . $lang["save-conflict-error"];
} else {
// update archive status if different (doesn't matter whether it is a user template or a genuine resource)
if ($setarchivestate != $oldarchive) {
update_archive_status($ref, $setarchivestate, array($oldarchive));
}
$new_checksums["status"] = $setarchivestate;
}
}
if (($autosave_field == "" || $autosave_field == "Access") && $access != $oldaccess) {
// Check if resource access has already been changed between form being loaded and submitted
if (getval("access_checksum", "") != "" && getval("access_checksum", "") != $oldaccess) {
$errors["access"] = $lang["access"] . ': ' . $lang["save-conflict-error"];
} else {
$resource_update_sql[] = "access= ?";
$resource_update_params[] = "i";
$resource_update_params[] = $access;
if ($access != $oldaccess && 0 < $ref) {
$resource_update_log_sql[] = array(
'ref' => $ref,
'type' => 'a',
'field' => 0,
'notes' => '',
'from' => $oldaccess,
'to' => $access);
}
if ($oldaccess == 3 && $access != 3) {
# Moving out of the custom state. Delete any usergroup specific access.
# This can delete any 'manual' usergroup grants also as the user will have seen this as part of the custom access.
delete_resource_custom_access_usergroups($ref);
}
$new_checksums["access"] = $access;
}
}
}
if (count($resource_update_sql) > 0) {
$sql = "UPDATE resource SET " . implode(",", $resource_update_sql) . " WHERE ref=?";
$sqlparams = array_merge($resource_update_params, ["i",$ref]);
ps_query($sql, $sqlparams);
}
foreach ($resource_update_log_sql as $log_sql) {
resource_log($log_sql["ref"], $log_sql["type"], $log_sql["field"], $log_sql["notes"], $log_sql["from"], $log_sql["to"]);
}
# Save any custom permissions
if (getval("access", 0) == RESOURCE_ACCESS_CUSTOM_GROUP) {
save_resource_custom_access($ref);
}
// Plugins can do extra actions once all fields have been saved and return errors back if needed
$plg_errors = hook('aftersaveresourcedata', '', array($ref, $nodes_to_add, $nodes_to_remove, $autosave_field, $fields,$updated_resources));
if (is_array($plg_errors) && !empty($plg_errors)) {
$errors = array_merge($errors, $plg_errors);
}
if (count($errors) == 0) {
daily_stat("Resource edit", $ref);
return true;
}
return $errors;
}
This article was last updated 11th February 2025 20:35 Europe/London time based on the source file dated 10th February 2025 10:40 Europe/London time.