original_string: public static function export_customfields_data(approved_contextlist $contextlist, string $component, string $area,
                  string $itemidstest = 'IS NOT NULL', string $instanceidstest = 'IS NOT NULL', array $params = [],
                  array $subcontext = null) {
          global $DB;
  
          // This query is very similar to api::get_instances_fields_data() but also works for multiple itemids
          // and has a context filter.
          list($contextidstest, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED, 'cfctx');
          $sql = "SELECT d.*, f.type AS fieldtype, f.name as fieldname, f.shortname as fieldshortname, c.itemid
              FROM {customfield_category} c
              JOIN {customfield_field} f ON f.categoryid = c.id
              JOIN {customfield_data} d ON d.fieldid = f.id AND d.instanceid $instanceidstest AND d.contextid $contextidstest
              WHERE c.component = :cfcomponent AND c.area = :cfarea AND c.itemid $itemidstest
              ORDER BY c.itemid, c.sortorder, f.sortorder";
          $params = self::get_params($component, $area, $params) + $contextparams;
          $records = $DB->get_recordset_sql($sql, $params);
  
          if ($subcontext === null) {
              $subcontext = [get_string('customfielddata', 'core_customfield')];
          }
  
          /** @var handler $handler */
          $handler = null;
          $fields = null;
          foreach ($records as $record) {
              if (!$handler || $handler->get_itemid() != $record->itemid) {
                  $handler = handler::get_handler($component, $area, $record->itemid);
                  $fields = $handler->get_fields();
              }
              $field = (object)['type' => $record->fieldtype, 'shortname' => $record->fieldshortname, 'name' => $record->fieldname];
              unset($record->itemid, $record->fieldtype, $record->fieldshortname, $record->fieldname);
              try {
                  $field = array_key_exists($record->fieldid, $fields) ? $fields[$record->fieldid] : null;
                  $data = data_controller::create(0, $record, $field);
                  self::export_customfield_data($data, array_merge($subcontext, [$record->id]));
              } catch (Exception $e) {
                  // We store some data that we can not initialise controller for. We still need to export it.
                  self::export_customfield_data_unknown($record, $field, array_merge($subcontext, [$record->id]));
              }
          }
          $records->close();
      }
code: public static function export_customfields_data(approved_contextlist $contextlist, string $component, string $area,
                  string $itemidstest = 'IS NOT NULL', string $instanceidstest = 'IS NOT NULL', array $params = [],
                  array $subcontext = null) {
          global $DB;
  
          // This query is very similar to api::get_instances_fields_data() but also works for multiple itemids
          // and has a context filter.
          list($contextidstest, $contextparams) = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED, 'cfctx');
          $sql = "SELECT d.*, f.type AS fieldtype, f.name as fieldname, f.shortname as fieldshortname, c.itemid
              FROM {customfield_category} c
              JOIN {customfield_field} f ON f.categoryid = c.id
              JOIN {customfield_data} d ON d.fieldid = f.id AND d.instanceid $instanceidstest AND d.contextid $contextidstest
              WHERE c.component = :cfcomponent AND c.area = :cfarea AND c.itemid $itemidstest
              ORDER BY c.itemid, c.sortorder, f.sortorder";
          $params = self::get_params($component, $area, $params) + $contextparams;
          $records = $DB->get_recordset_sql($sql, $params);
  
          if ($subcontext === null) {
              $subcontext = [get_string('customfielddata', 'core_customfield')];
          }
  
          /** @var handler $handler */
          $handler = null;
          $fields = null;
          foreach ($records as $record) {
              if (!$handler || $handler->get_itemid() != $record->itemid) {
                  $handler = handler::get_handler($component, $area, $record->itemid);
                  $fields = $handler->get_fields();
              }
              $field = (object)['type' => $record->fieldtype, 'shortname' => $record->fieldshortname, 'name' => $record->fieldname];
              unset($record->itemid, $record->fieldtype, $record->fieldshortname, $record->fieldname);
              try {
                  $field = array_key_exists($record->fieldid, $fields) ? $fields[$record->fieldid] : null;
                  $data = data_controller::create(0, $record, $field);
                  self::export_customfield_data($data, array_merge($subcontext, [$record->id]));
              } catch (Exception $e) {
                  // We store some data that we can not initialise controller for. We still need to export it.
                  self::export_customfield_data_unknown($record, $field, array_merge($subcontext, [$record->id]));
              }
          }
          $records->close();
      }
code_tokens: public static function export_customfields_data ( approved_contextlist $ contextlist , string $ component , string $ area , string $ itemidstest = 'IS NOT NULL' , string $ instanceidstest = 'IS NOT NULL' , array $ params = [ ] , array $ subcontext = null ) { global $ DB ; // This query is very similar to api::get_instances_fields_data() but also works for multiple itemids // and has a context filter. list ( $ contextidstest , $ contextparams ) = $ DB -> get_in_or_equal ( $ contextlist -> get_contextids ( ) , SQL_PARAMS_NAMED , 'cfctx' ) ; $ sql = "SELECT d.*, f.type AS fieldtype, f.name as fieldname, f.shortname as fieldshortname, c.itemid
              FROM {customfield_category} c
              JOIN {customfield_field} f ON f.categoryid = c.id
              JOIN {customfield_data} d ON d.fieldid = f.id AND d.instanceid $instanceidstest AND d.contextid $contextidstest
              WHERE c.component = :cfcomponent AND c.area = :cfarea AND c.itemid $itemidstest
              ORDER BY c.itemid, c.sortorder, f.sortorder" ; $ params = self :: get_params ( $ component , $ area , $ params ) + $ contextparams ; $ records = $ DB -> get_recordset_sql ( $ sql , $ params ) ; if ( $ subcontext === null ) { $ subcontext = [ get_string ( 'customfielddata' , 'core_customfield' ) ] ; } /** @var handler $handler */ $ handler = null ; $ fields = null ; foreach ( $ records as $ record ) { if ( ! $ handler || $ handler -> get_itemid ( ) != $ record -> itemid ) { $ handler = handler :: get_handler ( $ component , $ area , $ record -> itemid ) ; $ fields = $ handler -> get_fields ( ) ; } $ field = ( object ) [ 'type' => $ record -> fieldtype , 'shortname' => $ record -> fieldshortname , 'name' => $ record -> fieldname ] ; unset ( $ record -> itemid , $ record -> fieldtype , $ record -> fieldshortname , $ record -> fieldname ) ; try { $ field = array_key_exists ( $ record -> fieldid , $ fields ) ? $ fields [ $ record -> fieldid ] : null ; $ data = data_controller :: create ( 0 , $ record , $ field ) ; self :: export_customfield_data ( $ data , array_merge ( $ subcontext , [ $ record -> id ] ) ) ; } catch ( Exception $ e ) { // We store some data that we can not initialise controller for. We still need to export it. self :: export_customfield_data_unknown ( $ record , $ field , array_merge ( $ subcontext , [ $ record -> id ] ) ) ; } } $ records -> close ( ) ; }
docstring: Exports customfields data
  
  To be used in implementations of core_user_data_provider::export_user_data
  Caller needs to transfer the $userid to the select subqueries for
  customfield_category->itemid and/or customfield_data->instanceid
  
  @param approved_contextlist $contextlist
  @param string $component
  @param string $area
  @param string $itemidstest subquery for selecting customfield_category->itemid
  @param string $instanceidstest subquery for selecting customfield_data->instanceid
  @param array $params array of named parameters for itemidstest and instanceidstest subqueries
  @param array $subcontext subcontext to use in context_writer::export_data, if null (default) the
  "Custom fields data" will be used;
  the data id will be appended to the subcontext array.
docstring_tokens: Exports customfields data