diff --git a/eox_core/pipeline.py b/eox_core/pipeline.py index be5bfbd7a..2a7a47098 100644 --- a/eox_core/pipeline.py +++ b/eox_core/pipeline.py @@ -4,8 +4,12 @@ import logging from crum import get_current_request +from django.conf import settings +from django.core.exceptions import ImproperlyConfigured from django.db.models.signals import post_save +from openedx_filters import PipelineStep +from eox_core.edxapp_wrapper.configuration_helpers import get_configuration_helper from eox_core.edxapp_wrapper.users import ( generate_password, get_user_attribute, @@ -219,3 +223,76 @@ def ensure_user_has_signup_source(user=None, *args, **kwargs): "Created new singup source for user during the third party pipeline.", **locals() ) + + +class AddCustomOptionsOnAccountSettings(PipelineStep): + """ Pipeline used to add custom option fields in account settings. + + Example usage: + + Add the following configurations to your configuration file: + "OPEN_EDX_FILTERS_CONFIG": { + "org.openedx.learning.student.settings.render.started.v1": { + "fail_silently": false, + "pipeline": [ + "eox_core.pipeline.AddCustomOptionsOnAccountSettings" + ] + } + } + """ + + def run_filter(self, context): # pylint: disable=arguments-differ + """ Run the pipeline filter. """ + extended_profile_fields = context.get("extended_profile_fields", []) + + custom_options, field_labels_map = self._get_custom_context(extended_profile_fields) + + conf_helper = get_configuration_helper() + + extended_profile_field_options = conf_helper.get_value('EXTRA_FIELD_OPTIONS', custom_options) + extended_profile_field_option_tuples = {} + for field in extended_profile_field_options.keys(): + field_options = extended_profile_field_options[field] + extended_profile_field_option_tuples[field] = [(option.lower(), option) for option in field_options] + + for field in custom_options: + field_dict = { + "field_name": field, + "field_label": field_labels_map.get(field, field), + } + + field_options = extended_profile_field_option_tuples.get(field) + if field_options: + field_dict["field_type"] = "ListField" + field_dict["field_options"] = field_options + else: + field_dict["field_type"] = "TextField" + + field_index = next((index for (index, d) in enumerate(extended_profile_fields) if d["field_name"] == field_dict["field_name"]), None) + if field_index is not None: + context["extended_profile_fields"][field_index] = field_dict + return context + + def _get_custom_context(self, extended_profile_fields): + """ Get custom context for the field. """ + field_labels = {} + field_options = {} + custom_fields = getattr(settings, "EDNX_CUSTOM_REGISTRATION_FIELDS", []) + + for field in custom_fields: + field_name = field.get("name") + + if not field_name: # Required to identify the field. + msg = "Custom fields must have a `name` defined in their configuration." + raise ImproperlyConfigured(msg) + + field_label = field.get("label") + if not any(extended_field['field_name'] == field_name for extended_field in extended_profile_fields) and field_label: + field_labels[field_name] = (field_label) + + options = field.get("options") + + if options: + field_options[field_name] = options + + return field_options, field_labels diff --git a/requirements/base.in b/requirements/base.in index 2a5086485..228ab60a5 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -14,3 +14,4 @@ edx-opaque-keys[django]==2.3.0 openedx-events==0.13.0 django click +openedx-filters==1.2.0 diff --git a/requirements/base.txt b/requirements/base.txt index b45f787f7..70efce839 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -69,6 +69,7 @@ django==3.2.16 # event-tracking # jsonfield # openedx-events + # openedx-filters django-crum==0.7.9 # via # edx-django-utils @@ -182,6 +183,8 @@ oauthlib==3.2.2 # via django-oauth-toolkit openedx-events==0.13.0 # via -r requirements/base.in +openedx-filters==1.2.0 + # via -r requirements/base.in packaging==23.0 # via drf-yasg pbr==5.11.1 diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index bd3f4f113..968163d01 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -10,7 +10,6 @@ click==8.1.3 # via # -c requirements/constraints.txt # pip-tools -packaging==23.0 # via build pip-tools==6.12.1 # via -r requirements/pip-tools.in diff --git a/requirements/test.txt b/requirements/test.txt index dd4295090..f276abff3 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -279,6 +279,8 @@ oauthlib==3.2.2 # django-oauth-toolkit openedx-events==0.13.0 # via -r requirements/base.txt +openedx-filters==1.2.0 + # via -r requirements/base.txt packaging==23.0 # via # -r requirements/base.txt