/** * Method to read a parameter from the arguments of a form that contains a list of key=value pairs on separate lines. * Each value is checked for references to the user's data (either {user_id}, {username}, {email} or {profile_*}) * and if found these substitutions are replaced. * @param string $listData Form argument data, with each key value pair on a separate line. * @return array Associative array. */ function get_options_array_with_user_data($listData) { global $user; $r = array(); if ($listData != '') { $params = helper_base::explode_lines($listData); foreach ($params as $param) { if (!empty($param)) { $tokens = explode('=', $param, 2); if (count($tokens) == 2) { $tokens[1] = apply_user_replacements($tokens[1]); } else { throw new Exception('Some of the preset or default parameters defined for this page are not of the form param=value.'); } $r[$tokens[0]] = $tokens[1]; } } } return $r; }
/** * Get the location control as a select dropdown. * Default control ordering is by name. * reportProvidesOrderBy option should be set to true if the control is populated by a report that * provides its own Order By statement, if the reportProvidesOrderBy option is not set in this situation, then the report * will have two Order By statements and will fail. */ protected static function get_control_locationselect($auth, $args, $tabAlias, $options) { if (isset($options['extraParams'])) { foreach ($options['extraParams'] as $key => &$value) { $value = apply_user_replacements($value); } $options['extraParams'] = array_merge($auth['read'], $options['extraParams']); } else { $options['extraParams'] = array_merge($auth['read']); } if (empty($options['reportProvidesOrderBy']) || $options['reportProvidesOrderBy'] == 0) { $options['extraParams']['orderby'] = 'name'; } $location_list_args = array_merge(array('label' => lang::get('LANG_Location_Label'), 'view' => 'detail'), $options); return data_entry_helper::location_select($location_list_args); }
protected static function get_control_standardparams($auth, $args, $tabalias, $options) { self::$applyUserPrefs = false; $options = array_merge(array('allowSave' => true, 'sharing' => empty($args['sharing']) ? 'reporting' : $args['sharing']), $options); if ($args['redirect_on_success']) { $options['redirect_on_success'] = url($args['redirect_on_success']); } // any preset params on the report page should be loaded as initial settings for the filter. if (!empty($args['param_presets'])) { $params = data_entry_helper::explode_lines_key_value_pairs($args['param_presets']); foreach ($params as $key => $val) { $options["filter-{$key}"] = $val; } } foreach ($options as $key => &$value) { $value = apply_user_replacements($value); } if ($options['allowSave'] && !function_exists('iform_ajaxproxy_url')) { return 'The AJAX Proxy module must be enabled to support saving filters. Set @allowSave=false to disable this in the [standard params] control.'; } if (!function_exists('hostsite_get_user_field') || !hostsite_get_user_field('indicia_user_id')) { return 'The standard params module requires Easy Login.'; } $r = report_filter_panel($auth['read'], $options, $args['website_id'], $hiddenStuff); return $r . $hiddenStuff; }
protected static function get_tab_content($auth, $args, $tab, $tabContent, $tabalias, &$attributes, &$hasControls) { // cols array used if we find | splitters $cols = array(); $defAttrOptions = array('extraParams' => $auth['read']); if (isset($args['attribute_termlist_language_filter']) && $args['attribute_termlist_language_filter']) { $defAttrOptions['language'] = iform_lang_iso_639_2($args['language']); } //create array of attribute field names to test against later $attribNames = array(); foreach ($attributes as $key => $attrib) { $attribNames[$key] = $attrib['id']; } $html = ''; // Now output the content of the tab. Use a for loop, not each, so we can treat several rows as one object for ($i = 0; $i < count($tabContent); $i++) { $component = trim($tabContent[$i]); if (preg_match('/\\A\\?[^�]*\\?\\z/', $component) === 1) { // Component surrounded by ? so represents a help text $helpText = substr($component, 1, -1); $html .= '<div class="page-notice ui-state-highlight ui-corner-all">' . lang::get($helpText) . "</div>"; } elseif (preg_match('/\\A\\[[^�]*\\]\\z/', $component) === 1) { // Component surrounded by [] so represents a control or control block // Anything following the component that starts with @ is an option to pass to the control $options = array(); while ($i < count($tabContent) - 1 && substr($tabContent[$i + 1], 0, 1) == '@' || trim($tabContent[$i]) === '') { $i++; // ignore empty lines if (trim($tabContent[$i]) !== '') { $option = explode('=', substr($tabContent[$i], 1), 2); if (!isset($option[1]) || $option[1] === 'false') { $options[$option[0]] = FALSE; } else { $options[$option[0]] = json_decode($option[1], TRUE); // if not json then need to use option value as it is if ($options[$option[0]] == '') { $options[$option[0]] = $option[1]; } } // urlParam is special as it loads the control's default value from $_GET if ($option[0] === 'urlParam' && isset($_GET[$option[1]])) { $options['default'] = $_GET[$option[1]]; } } } // if @permission specified as an option, then check that the user has access to this control if (!empty($options['permission']) && !user_access($options['permission'])) { continue; } $parts = explode('.', str_replace(array('[', ']'), '', $component)); $method = 'get_control_' . preg_replace('/[^a-zA-Z0-9]/', '', strtolower($component)); if (!empty($args['high_volume']) && $args['high_volume']) { // enable control level report caching when in high_volume mode $options['caching'] = empty($options['caching']) ? true : $options['caching']; $options['cachetimeout'] = empty($options['cachetimeout']) ? HIGH_VOLUME_CONTROL_CACHE_TIMEOUT : $options['cachetimeout']; } // allow user settings to override the control - see iform_user_ui_options.module if (isset(data_entry_helper::$data['structureControlOverrides']) && !empty(data_entry_helper::$data['structureControlOverrides'][$component])) { $options = array_merge($options, data_entry_helper::$data['structureControlOverrides'][$component]); } if (count($parts) === 1 && method_exists(self::$called_class, $method)) { //outputs a control for which a specific output function has been written. $html .= call_user_func(array(self::$called_class, $method), $auth, $args, $tabalias, $options); $hasControls = true; } elseif (count($parts) === 2) { require_once dirname($_SERVER['SCRIPT_FILENAME']) . '/' . data_entry_helper::relative_client_helper_path() . '/prebuilt_forms/extensions/' . $parts[0] . '.php'; if (method_exists('extension_' . $parts[0], $parts[1])) { //outputs a control for which a specific extension function has been written. $path = call_user_func(array(self::$called_class, 'getReloadPath')); //pass the classname of the form through to the extension control method to allow access to calling class functions and variables $args["calling_class"] = 'iform_' . self::$node->iform; $html .= call_user_func(array('extension_' . $parts[0], $parts[1]), $auth, $args, $tabalias, $options, $path, $attributes); $hasControls = true; // auto-add JavaScript for the extension if (file_exists(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.js')) { drupal_add_js(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.js', array('preprocess' => FALSE)); } if (file_exists(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.css')) { drupal_add_css(iform_client_helpers_path() . 'prebuilt_forms/extensions/' . $parts[0] . '.css', array('preprocess' => FALSE)); } } else { $html .= lang::get("The {$component} extension cannot be found."); } } elseif (($attribKey = array_search(substr($component, 1, -1), $attribNames)) !== false || preg_match('/^\\[[a-zA-Z]+:(?P<ctrlId>[0-9]+)\\]/', $component, $matches)) { // control is a smpAttr or other attr control. if (empty($options['extraParams'])) { $options['extraParams'] = array_merge($defAttrOptions['extraParams']); } else { $options['extraParams'] = array_merge($defAttrOptions['extraParams'], (array) $options['extraParams']); } //merge extraParams first so we don't loose authentication $options = array_merge($defAttrOptions, $options); foreach ($options as $key => &$value) { $value = apply_user_replacements($value); } if ($attribKey !== false) { // a smpAttr control $html .= data_entry_helper::outputAttribute($attributes[$attribKey], $options); $attributes[$attribKey]['handled'] = true; } else { // if the control name of form name:id, then we will call get_control_name passing the id as a parameter $method = 'get_control_' . preg_replace('/[^a-zA-Z]/', '', strtolower($component)); if (method_exists(self::$called_class, $method)) { $options['ctrlId'] = $matches['ctrlId']; $html .= call_user_func(array(self::$called_class, $method), $auth, $args, $tabalias, $options); } else { $html .= "Unsupported control {$component}<br/>"; } } $hasControls = true; } elseif ($component === '[*]') { // this outputs any custom attributes that remain for this tab. The custom attributes can be configured in the // settings text using something like @smpAttr:4|label=My label. The next bit of code parses these out into an // array used when building the html. // Alternatively, a setting like @option=value is applied to all the attributes. $attrSpecificOptions = array(); foreach ($options as $option => $value) { // split the id of the option into the control name and option name. $optionId = explode('|', $option); if (count($optionId) > 1) { // Found an option like @smpAttr:4|label=My label if (!isset($attrSpecificOptions[$optionId[0]])) { $attrSpecificOptions[$optionId[0]] = array(); } $attrSpecificOptions[$optionId[0]][$optionId[1]] = apply_user_replacements($value); } else { // Found an option like @option=value $defAttrOptions = array_merge($defAttrOptions, array($option => $value)); } } $attrHtml = get_attribute_html($attributes, $args, $defAttrOptions, $tab, $attrSpecificOptions); if (!empty($attrHtml)) { $hasControls = true; } $html .= $attrHtml; } else { $html .= "The form structure includes a control called {$component} which is not recognised.<br/>"; //ensure $hasControls is true so that the error message is shown $hasControls = true; } } elseif ($component === '|') { // column splitter. So, store the col html and start on the next column. $cols[] = $html; $html = ''; } else { // output anything else as is. This allow us to add html to the form structure. $html .= $component; } } if (count($cols) > 0) { $cols[] = $html; // a splitter in the structure so put the stuff so far in a 50% width left float div, and the stuff that follows in a 50% width right float div. global $indicia_templates; $html = str_replace(array('{col-1}', '{col-2}'), $cols, $indicia_templates['two-col-50']); if (count($cols) > 2) { unset($cols[1]); unset($cols[0]); $html .= '<div class="follow_on_block" style="clear:both;">' . implode('', $cols) . '</div>'; } else { $html .= '<div class="follow_on_block" style="clear:both;"></div>'; } // needed so any tab div is stretched around them } return $html; }
/** * Returns the species checklist input control. * @param array $auth Read authorisation tokens * @param array $args Form configuration * @param array $extraParams Extra parameters array, pre-configured with filters for taxa and name types. * @param array $options additional options for the control, e.g. those configured in the form structure. * @return HTML for the species_checklist control. * Again, this is an altered copy of the one found in dynamic_sample_occurrence with support for preloading a species grid with sample images from second level samples * and then loading it with occurrence images attached to occurrences which are attached to third level samples. * May contain coded that is not needed and can be removed if possible */ protected static function get_control_species_checklist($auth, $args, $extraParams, $options) { global $user; // Build the configuration options if (isset($options['view'])) { $extraParams['view'] = $options['view']; } // There may be options in the form occAttr:n|param => value targetted at specific attributes $occAttrOptions = array(); $optionToUnset = array(); foreach ($options as $option => $value) { // split the id of the option into the attribute name and option name. $optionParts = explode('|', $option); if ($optionParts[0] != $option) { // an occurrence attribute option was found $attrName = $optionParts[0]; $optName = $optionParts[1]; // split the attribute name into the type and id (type will always be occAttr) $attrParts = explode(':', $attrName); $attrId = $attrParts[1]; if (!isset($occAttrOptions[$attrId])) { $occAttrOptions[$attrId] = array(); } $occAttrOptions[$attrId][$optName] = apply_user_replacements($value); $optionToUnset[] = $option; } } // tidy up options array foreach ($optionToUnset as $value) { unset($options[$value]); } // make sure that if extraParams is specified as a config option, it does not replace the essential stuff if (isset($options['extraParams'])) { $options['extraParams'] = array_merge($extraParams, $options['extraParams']); } $species_ctrl_opts = array_merge(array('occAttrOptions' => $occAttrOptions, 'listId' => $args['list_id'], 'label' => lang::get('occurrence:taxa_taxon_list_id'), 'columns' => 1, 'extraParams' => $extraParams, 'survey_id' => $args['survey_id'], 'occurrenceComment' => $args['occurrence_comment'], 'occurrenceSensitivity' => isset($args['occurrence_sensitivity']) ? $args['occurrence_sensitivity'] : false, 'occurrenceImages' => $args['occurrence_images'], 'PHPtaxonLabel' => true, 'language' => iform_lang_iso_639_2(hostsite_get_user_field('language')), 'cacheLookup' => $args['cache_lookup'], 'speciesNameFilterMode' => self::getSpeciesNameFilterMode($args), 'userControlsTaxonFilter' => isset($args['user_controls_taxon_filter']) ? $args['user_controls_taxon_filter'] : false, 'subSpeciesColumn' => $args['sub_species_column'], 'copyDataFromPreviousRow' => !empty($args['copy_species_row_data_to_new_rows']) && $args['copy_species_row_data_to_new_rows'], 'previousRowColumnsToInclude' => empty($args['previous_row_columns_to_include']) ? '' : $args['previous_row_columns_to_include'], 'editTaxaNames' => !empty($args['edit_taxa_names']) && $args['edit_taxa_names'], 'includeSpeciesGridLinkPage' => !empty($args['include_species_grid_link_page']) && $args['include_species_grid_link_page'], 'speciesGridPageLinkUrl' => $args['species_grid_page_link_url'], 'speciesGridPageLinkParameter' => $args['species_grid_page_link_parameter'], 'speciesGridPageLinkTooltip' => $args['species_grid_page_link_tooltip']), $options); if ($groups = hostsite_get_user_field('taxon_groups')) { $species_ctrl_opts['usersPreferredGroups'] = unserialize($groups); } if ($args['extra_list_id']) { $species_ctrl_opts['lookupListId'] = $args['extra_list_id']; } //We only do the work to setup the filter if the user has specified a filter in the box if (!empty($args['taxon_filter_field']) && !empty($args['taxon_filter'])) { $species_ctrl_opts['taxonFilterField'] = $args['taxon_filter_field']; $filterLines = helper_base::explode_lines($args['taxon_filter']); $species_ctrl_opts['taxonFilter'] = $filterLines; } if (isset($args['col_widths']) && $args['col_widths']) { $species_ctrl_opts['colWidths'] = explode(',', $args['col_widths']); } call_user_func(array(self::$called_class, 'build_grid_taxon_label_function'), $args, $options); if (self::$mode == self::MODE_CLONE) { $species_ctrl_opts['useLoadedExistingRecords'] = true; } return self::species_checklist($species_ctrl_opts); }
/** * Get a location select control pair, first the user must select a square then a plot associated with a square. * Only squares that are associated with the user and also have plots are displayed * When a plot is selected, then a mini report about the plot is displayed. * * $options Options array with the following possibilities:<ul> * <li><b>coreSquareLocationTypeId</b><br/> * The location type id of a core square</li> * <li><b>additionalSquareLocationTypeId</b><br/> * The location type id of an additional square</li> * <li><b>viceCountyLocationAttributeId</b><br/> * The attribute ID that holds the vice counties associated with a square</li> * <li><b>noViceCountyFoundMessage</b><br/> * A square's vice country makes up part of its name, however if it doesn't have a vice county then display this replacement text instead</li> * <li><b>userSquareAttrId</b><br/> * The ID of the person attribute that holds the user squares.</li> * <li><b>orientationAttributeId</b><br/> * The location attribute id that holds a plot's Orientation</li> * <li><b>aspectAttributeId</b><br/> * The location attribute id that holds a plot's Aspect</li> * <li><b>slopeAttributeId</b><br/> * The location attribute id that holds a plot's Slope</li> * <li><b>ashAttributeId</b><br/> * The location attribute id that holds a plot's % Ash Coverage</li> * <li><b>privatePlotAttrId</b><br/> * Optional attribute for the location attribute id which holds whether a plot is private. If supplied then when a private plot is selected * as the location then all occurrences are set to have a sensitivity_precision=10000</li> * <li><b>rowInclusionCheckModeHasData</b><br/> * Optional. Supply this as true if the species grid is in rowInclusionCheck=hasData mode and you are using the privatePlotAttrId option. * <li><b>noPlotMessageInAlert</b><br/> * Optional. Override the default message that is displayed if a user has not plots to select. This message is displayed in an alert box as well. * </ul> */ public static function splash_location_select($auth, $args, $tabAlias, $options) { if (empty($options['coreSquareLocationTypeId'])) { drupal_set_message('Please fill in the @coreSquareLocationTypeId option for the splash_location_select control'); return ''; } if (empty($options['additionalSquareLocationTypeId'])) { drupal_set_message('Please fill in the @additionalSquareLocationTypeId option for the splash_location_select control'); return ''; } if (empty($options['viceCountyLocationAttributeId'])) { drupal_set_message('Please fill in the @viceCountyLocationAttributeId option for the splash_location_select control'); return ''; } if (empty($options['noViceCountyFoundMessage'])) { drupal_set_message('Please fill in the @noViceCountyFoundMessage option for the splash_location_select control'); return ''; } if (empty($options['userSquareAttrId'])) { drupal_set_message('Please fill in the @userSquareAttrId option for the splash_location_select control'); return ''; } $coreSquareLocationTypeId = $options['coreSquareLocationTypeId']; $additionalSquareLocationTypeId = $options['additionalSquareLocationTypeId']; $currentUserId = hostsite_get_user_field('indicia_user_id'); $viceCountyLocationAttributeId = $options['viceCountyLocationAttributeId']; $noViceCountyFoundMessage = $options['noViceCountyFoundMessage']; $userSquareAttrId = $options['userSquareAttrId']; $extraParamForSquarePlotReports = array('core_square_location_type_id' => $coreSquareLocationTypeId, 'additional_square_location_type_id' => $additionalSquareLocationTypeId, 'current_user_id' => $currentUserId, 'vice_county_location_attribute_id' => $viceCountyLocationAttributeId, 'no_vice_county_found_message' => $noViceCountyFoundMessage, 'user_square_attr_id' => $userSquareAttrId); $reportOptions = array('dataSource' => 'reports_for_prebuilt_forms/Splash/get_my_squares_that_have_plots', 'readAuth' => $auth['read'], 'mode' => 'report', 'extraParams' => $extraParamForSquarePlotReports); //In PSS/NPMS we don't show the Vice County in the label. if (!empty($reportOptions['extraParams']) && !empty($options['pssMode']) && $options['pssMode'] === true) { $reportOptions['extraParams'] = array_merge($reportOptions['extraParams'], ['pss_mode' => true]); data_entry_helper::$javascript .= "\$('#imp-sref').attr('readonly','readonly');"; } $rawData = data_entry_helper::get_report_data($reportOptions); if (empty($rawData)) { //If the user doesn't have any plots, then hide the map and disable the Spatial Ref field so they can't continue if (!empty($options['noPlotMessageInAlert'])) { data_entry_helper::$javascript .= "alert('" . $options['noPlotMessageInAlert'] . "');"; } else { drupal_set_message('Note: You have not been allocated any squares to input data for, or the squares you have been allocated do not have plots.'); } drupal_set_message('You cannot enter data without having a plot to select.'); data_entry_helper::$javascript .= "\$('#map').hide();"; data_entry_helper::$javascript .= "\$('#imp-sref').attr('disabled','disabled');"; if (!empty($options['noPlotMessageInAlert'])) { return '<b>' . $options['noPlotMessageInAlert'] . '</b></br>'; } else { return '<b>You have not been allocated any Squares that contain plots</b></br>'; } } else { //Convert the raw data in the report into array format suitable for the Select drop-down to user (an array of ID=>Name pairs) foreach ($rawData as $rawRow) { $squaresData[$rawRow['id']] = $rawRow['name']; } //Need a report to collect the square to default the Location Select to in edit mode, as this is not stored against the sample directly. if (!empty($_GET['sample_id'])) { $squareData = data_entry_helper::get_report_data(array('dataSource' => 'reports_for_prebuilt_forms/Splash/get_square_for_sample', 'readAuth' => $auth['read'], 'extraParams' => array('sample_id' => $_GET['sample_id']))); $defaultSquareSelection = $squareData[0]['id']; } else { $defaultSquareSelection = ''; } $r = data_entry_helper::select(array('id' => 'squares-select-list', 'blankText' => '<Please select>', 'fieldname' => 'squares-select-list', 'label' => lang::get('Select a Square'), 'helpText' => lang::get('Select a square to input data for before selecting a plot.'), 'lookupValues' => $squaresData, 'default' => $defaultSquareSelection)); //This code is same as standard lookup control if (isset($options['extraParams'])) { foreach ($options['extraParams'] as $key => &$value) { $value = apply_user_replacements($value); } $options['extraParams'] = array_merge($auth['read'], $options['extraParams']); } else { $options['extraParams'] = array_merge($auth['read']); } if (empty($options['reportProvidesOrderBy']) || $options['reportProvidesOrderBy'] == 0) { $options['extraParams']['orderby'] = 'name'; } //Setup the Plot drop-down which uses the Suqare selection the user makes. $options['parentControlId'] = 'squares-select-list'; $options['filterField'] = 'square_id'; $options['reportProvidesOrderBy'] = true; $options['searchUpdatesSref'] = true; $options['label'] = 'Plot'; $options['report'] = 'reports_for_prebuilt_forms/Splash/get_plots_for_square_id'; if (!empty($options['plotNumberAttrId'])) { $options['extraParams']['plot_number_attr_id'] = $options['plotNumberAttrId']; } //Create the drop-down for the plot $location_list_args = array_merge(array('label' => lang::get('LANG_Location_Label'), 'view' => 'detail'), $options); $r .= data_entry_helper::location_select($location_list_args); //Create the mini report, not currently required on PSS site if (empty($options['pssMode'])) { $r .= self::plot_report_panel($auth, $options); } //If an attribute holding whether plots are private is supplied, then we want to return //whether the selected plot is private and set the occurrence sensitivity_precision appropriately if (!empty($options['privatePlotAttrId'])) { $extraParamForSquarePlotReports = array_merge($extraParamForSquarePlotReports, array('private_plot_attr_id' => $options['privatePlotAttrId'], 'only_return_private_plots' => true)); //When the page initially loads, collect all the private plots that can be selected by the user, rather than //load whether the plot is private when each selection is made. $myPlotsAndSquares = data_entry_helper::get_report_data(array('dataSource' => 'reports_for_prebuilt_forms/Splash/get_my_squares_and_plots', 'readAuth' => $auth['read'], 'extraParams' => $extraParamForSquarePlotReports)); $privatePlots = array(); foreach ($myPlotsAndSquares as $locationDataItem) { $privatePlots[] = $locationDataItem['id']; } //Need option to tell the system if the species grid has rowInclusionCheck=hasData, and we are setting the occurrences //sensitivity_precision for occurrences when a plot is private. //This is because the way the system detects if an occurrence is present is different. if (!empty($options['rowInclusionCheckModeHasData']) && $options['rowInclusionCheckModeHasData'] == true) { $rowInclusionCheckModeHasData = 'true'; } else { $rowInclusionCheckModeHasData = 'false'; } if (!empty($_GET['sample_id'])) { $editMode = 'true'; } else { $editMode = 'false'; } data_entry_helper::$javascript .= ' private_plots_set_precision(' . json_encode($privatePlots) . ',' . $rowInclusionCheckModeHasData . ',' . $editMode . '); '; } return $r; } }
protected static function get_control_sampleattributes($auth, $args, $tabAlias, $options) { $r = ''; $tab = isset($options['tab']) ? $options['tab'] : null; $attrArgs = array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id']); if (self::$loadedSampleId) { // if we have a single occurrence Id to load, use it to get attribute values $attrArgs['id'] = self::$loadedSampleId; } if (isset($args['sample_method_id']) && !empty($args['sample_method_id'])) { $attrArgs['sample_method_id'] = $args['sample_method_id']; } if (!empty($options['attributeIds'])) { $attrArgs['extraParams']['query'] = json_encode(array('in' => array('id' => $options['attributeIds']))); } $smpAttrs = data_entry_helper::getAttributes($attrArgs, false); $ctrlOptions = array('extraParams' => $auth['read']); $attrSpecificOptions = array(); self::parseForAttrSpecificOptions($options, $ctrlOptions, $attrSpecificOptions); foreach ($attrSpecificOptions as $attr => $opts) { if (isset($attrSpecificOptions[$attr]['default'])) { $attrSpecificOptions[$attr]['default'] = apply_user_replacements($attrSpecificOptions[$attr]['default']); } } foreach ($smpAttrs as &$attribute) { if (in_array($attribute['id'], data_entry_helper::$handled_attributes)) { $attribute['handled'] = 1; } // Hide controls that have already been handled. if (($tab === null || strcasecmp($tab, $attribute['inner_structure_block']) == 0) && !isset($attribute['handled'])) { $options = $ctrlOptions + get_attr_validation($attribute, $args); // when getting the options, only use the first 2 parts of the fieldname as any further imply an existing record ID so would differ. $fieldNameParts = explode(':', $attribute['fieldname']); if (preg_match('/[a-z][a-z][a-z]Attr/', $fieldNameParts[count($fieldNameParts) - 2])) { $optionFieldName = $fieldNameParts[count($fieldNameParts) - 2] . ':' . $fieldNameParts[count($fieldNameParts) - 1]; } elseif (preg_match('/[a-za-za-z]Attr/', $fieldNameParts[count($fieldNameParts) - 3])) { $optionFieldName = $fieldNameParts[count($fieldNameParts) - 3] . ':' . $fieldNameParts[count($fieldNameParts) - 2]; } else { throw new exception('Option fieldname not found'); } $dummy = null; if (isset($attrSpecificOptions[$optionFieldName])) { $options = array_merge($options, $attrSpecificOptions[$optionFieldName]); } $r .= data_entry_helper::outputAttribute($attribute, $options); $attribute['handled'] = true; } } return $r; }