field_type, self::$field_types) ) return; $field->label = JText::_($field->label); $use_ingroup = 0; // Field grouped should not be recursively grouped if (!isset($field->formhidden_grp)) $field->formhidden_grp = $field->formhidden; if ($use_ingroup) $field->formhidden = 3; if ($use_ingroup && empty($field->ingroup)) return; $compact_edit = $field->parameters->get('compact_edit', 0); // initialize framework objects and other variables $document = JFactory::getDocument(); $cparams = JComponentHelper::getParams( 'com_flexicontent' ); $db = JFactory::getDBO(); $user = JFactory::getUser(); $app = JFactory::getApplication(); $isAdmin = $app->isAdmin(); $tooltip_class = 'hasTooltip'; $add_on_class = $cparams->get('bootstrap_ver', 2)==2 ? 'add-on' : 'input-group-addon'; $input_grp_class = $cparams->get('bootstrap_ver', 2)==2 ? 'input-append input-prepend' : 'input-group'; // **************** // Number of values // **************** $multiple = $use_ingroup || (int) $field->parameters->get( 'allow_multiple', 0 ) ; $max_values = $use_ingroup ? 0 : (int) $field->parameters->get( 'max_values', 0 ) ; $required = $field->parameters->get( 'required', 0 ) ; $required = $required ? ' required' : ''; $add_position = (int) $field->parameters->get( 'add_position', 3 ) ; // ************** // Value handling // ************** // Get fields belonging to this field group $grouped_fields = $this->getGroupFields($field); // Get values of fields making sure that also empty values are created too $max_count = 1; $this->getGroupFieldsValues($field, $item, $grouped_fields, $max_count); // Render Form HTML of the field foreach($grouped_fields as $field_id => $grouped_field) { $grouped_field->ingroup = 1; $grouped_field->item_id = $item->id; //FLEXIUtilities::call_FC_Field_Func($grouped_field->field_type, 'onDisplayField', array(&$grouped_field, &$item)); FlexicontentFields::getFieldFormDisplay($grouped_field, $item, $user); unset($grouped_field->ingroup); } $js = ""; $css = ""; if ($multiple) // handle multiple records { // Add the drag and drop sorting feature if (!$use_ingroup) $js .= " jQuery(document).ready(function(){ jQuery('#sortables_".$field->id."').sortable({ handle: '.fcfield-drag-handle', containment: 'parent', tolerance: 'pointer' }); }); "; $js .= " jQuery(document).ready(function(){" .($compact_edit==2 ? "jQuery('#sortables_".$field->id."').find('.toggle_group_down').data('fc_noeffect', 1).trigger('click');" : "") .($compact_edit==1 ? "jQuery('#sortables_".$field->id."').find('.toggle_group_up').data('fc_noeffect', 1).trigger('click');" : "") ."}); "; if ($max_values) JText::script("FLEXI_FIELD_MAX_ALLOWED_VALUES_REACHED", true); $js .= " var uniqueRowNum".$field->id." = ".$max_count."; // Unique row number incremented only var rowCount".$field->id." = ".$max_count."; // Counts existing rows to be able to limit a max number of values var maxValues".$field->id." = ".$max_values."; "; // Create function call for add/deleting Field values $addField_pattern = " var fieldval_box = groupval_box.find('.fcfieldval_container__GRP_FID_'); if (typeof addField_GRP_FID_ !== 'undefined') { fieldval_box.find('.invalid').removeClass('invalid').attr('aria-invalid', 'false'); var newSubLabel = fieldval_box.prev('label.sub_label'); var newLabelFor = 'custom_%s_'+uniqueRowNum".$field->id."; newSubLabel.attr('id', newLabelFor + '-lbl'); newSubLabel.attr('for', newLabelFor); newSubLabel.attr('data-for', newLabelFor); addField_GRP_FID_(null, groupval_box, groupval_box.find('.fcfieldval_container__GRP_FID_'), add_params); } else { // Clear displayed values of other value-set fieldval_box.find('.fc-non-editable-value').html('-'); } "; $delField_pattern = " if (typeof deleteField_GRP_FID_ !== 'undefined') { if (rowCount".$field->id." == 1) { // We need to update the current grouped label of the field if this was the last element being re-added var fieldval_box = groupval_box.find('.fcfieldval_container__GRP_FID_'); fieldval_box.find('.invalid').removeClass('invalid').attr('aria-invalid', 'false'); var newSubLabel = fieldval_box.prev('label.sub_label'); var newLabelFor = 'custom_%s_'+uniqueRowNum".$field->id."; newSubLabel.attr('for', newLabelFor); newSubLabel.attr('data-for', newLabelFor); } deleteField_GRP_FID_(null, groupval_box, groupval_box.find('.fcfieldval_container__GRP_FID_')); } "; $addField_funcs = $delField_funcs = ''; foreach($grouped_fields as $field_id => $grouped_field) { if ($grouped_field->formhidden == 4) continue; if ($isAdmin) { if ( $grouped_field->parameters->get('backend_hidden') || (isset($grouped_field->formhidden_grp) && in_array($grouped_field->formhidden_grp, array(2,3))) ) continue; } else { if ( $grouped_field->parameters->get('frontend_hidden') || (isset($grouped_field->formhidden_grp) && in_array($grouped_field->formhidden_grp, array(1,3))) ) continue; } $addField_funcs .= str_replace("_GRP_FID_", $grouped_field->id, sprintf($addField_pattern, $grouped_field->name) ); $delField_funcs .= str_replace("_GRP_FID_", $grouped_field->id, sprintf($delField_pattern, $grouped_field->name) ); } $js .= " function addField".$field->id."(el, groupval_box, fieldval_box, params) { var insert_before = (typeof params!== 'undefined' && typeof params.insert_before !== 'undefined') ? params.insert_before : 0; var remove_previous = (typeof params!== 'undefined' && typeof params.remove_previous !== 'undefined') ? params.remove_previous : 0; var scroll_visible = (typeof params!== 'undefined' && typeof params.scroll_visible !== 'undefined') ? params.scroll_visible : 1; var animate_visible = (typeof params!== 'undefined' && typeof params.animate_visible !== 'undefined') ? params.animate_visible : 1; if(!remove_previous && (rowCount".$field->id." >= maxValues".$field->id.") && (maxValues".$field->id." != 0)) { alert(Joomla.JText._('FLEXI_FIELD_MAX_ALLOWED_VALUES_REACHED') + maxValues".$field->id."); return 'cancel'; } // Find last container of fields and clone it to create a new container of fields var lastField = fieldval_box ? fieldval_box : jQuery(el).prev().find('ul.fcfield-sortables').children().last(); var newField = lastField.clone(); // Need to at least change FORM field names and HTML tag IDs before adding the container to the DOM var theSet = newField.find('input, select'); var nr = 0; theSet.each(function() { var elem = jQuery(this); elem.attr('name', '_duplicated_".$field->id."_'+uniqueRowNum".$field->id."+'_'+nr); elem.attr('id', '_duplicated_".$field->id."_'+uniqueRowNum".$field->id."+'_'+nr); nr++; }); "; // Add new field to DOM $js .= " lastField ? (insert_before ? newField.insertBefore( lastField ) : newField.insertAfter( lastField ) ) : newField.appendTo( jQuery('#sortables_".$field->id."') ) ; "; // Add new element to sortable objects (if field not in group) -- NOTE: remove_previous: 2 means remove element without do any cleanup actions if (!$use_ingroup) $js .= " //jQuery('#sortables_".$field->id."').sortable('refresh'); // Refresh was done appendTo ? // Add new values for each field var groupval_box = newField; var add_params = {remove_previous: 2, scroll_visible: 0, animate_visible: 0}; ".$addField_funcs." "; // Readd prettyCheckable and remove previous if so requested $js .=" if (remove_previous) lastField.remove(); "; // Show new field, increment counters $js .=" //newField.fadeOut({ duration: 400, easing: 'swing' }).fadeIn({ duration: 200, easing: 'swing' }); if (scroll_visible) fc_scrollIntoView(newField, 1); if (animate_visible) newField.css({opacity: 0.1}).animate({ opacity: 1 }, 800); // Enable tooltips on new element newField.find('.hasTooltip').tooltip({'html': true,'container': newField}); rowCount".$field->id."++; // incremented / decremented uniqueRowNum".$field->id."++; // incremented only } function deleteField".$field->id."(el) { // Disable clicks on remove button, so that it is not reclicked, while we do the field value hide effect (before DOM removal of field value) var btn = jQuery(el); if (btn && rowCount".$field->id." > 1) btn.css('pointer-events', 'none').off('click'); // Find field value container var row = btn.closest('li'); // Do cleanup by calling the deleteField of each individual field, these functions will re-add last element as empty if needed var groupval_box = jQuery(el).closest('li'); ".$delField_funcs." if(rowCount".$field->id." == 1) { uniqueRowNum".$field->id."++; // increment unique row id, since last group was re-added } // Also remove the group field values container if not last one if (rowCount".$field->id." > 1) { // Destroy the remove/add/etc buttons, so that they are not reclicked, while we do the field value hide effect (before DOM removal of field value) row.find('.fcfield-delvalue').remove(); row.find('.fcfield-expand-view').remove(); row.find('.fcfield-insertvalue').remove(); row.find('.fcfield-drag-handle').remove(); // Do hide effect then remove from DOM row.fadeOut(420, function(){ this.remove(); }); rowCount".$field->id."--; } } "; $css .= ''; $remove_button = ''; $move2 = ''; $add_here = ''; $add_here .= $add_position==2 || $add_position==3 ? ' ' : ''; $add_here .= $add_position==1 || $add_position==3 ? ' ' : ''; $togglers = !$compact_edit ? '' : ' '.JText::_( 'FLEXI_FIELD_GROUP_EDIT_DETAILS' ). ' '.JText::_( 'FLEXI_FIELD_GROUP_HIDE_DETAILS' ). ' '; } else { $remove_button = ''; $move2 = ''; $togglers = ''; $add_here = ''; $js .= ''; $css .= ''; } if ($js) $document->addScriptDeclaration($js); if ($css) $document->addStyleDeclaration($css); $close_btn = FLEXI_J30GE ? '×' : '×'; $alert_box = FLEXI_J30GE ? '
'.$close_btn.'%s
' : '
'.$close_btn.'%s
'; if ($compact_edit) { $compact_edit_excluded = $field->parameters->get('compact_edit_excluded', array()); if ( empty($compact_edit_excluded) ) $compact_edit_excluded = array(); if ( !is_array($compact_edit_excluded) ) $compact_edit_excluded = preg_split("/[\|,]/", $compact_edit_excluded); $compact_edit_excluded = array_flip($compact_edit_excluded); } $field->html = array(); for ($n = 0; $n < $max_count; $n++) { $field->html[$n] = ' '.($use_ingroup ? '' : '
'.$move2.' '.$remove_button.' '.$togglers.' '.(!$add_position ? '' : $add_here).'
'); // Append item-form display HTML of the every field in the group $i = 0; foreach($grouped_fields as $field_id => $grouped_field) { if ($grouped_field->formhidden == 4) continue; if ($isAdmin) { if ( $grouped_field->parameters->get('backend_hidden') || (isset($grouped_field->formhidden_grp) && in_array($grouped_field->formhidden_grp, array(2,3))) ) continue; } else { if ( $grouped_field->parameters->get('frontend_hidden') || (isset($grouped_field->formhidden_grp) && in_array($grouped_field->formhidden_grp, array(1,3))) ) continue; } $lbl_class = 'flexi label sub_label'; $lbl_title = ''; // field has tooltip $edithelp = $grouped_field->edithelp ? $grouped_field->edithelp : 1; if ( $grouped_field->description && ($edithelp==1 || $edithelp==2) ) { $lbl_class .= ($edithelp==2 ? ' fc_tooltip_icon ' : ' ') .$tooltip_class; $lbl_title = flexicontent_html::getToolTip(trim($field->label, ':'), $grouped_field->description, 0, 1); } $field->html[$n] .= '
'.($grouped_field->description && $edithelp==3 ? sprintf( $alert_box, '', 'info', 'fc-nobgimage', $grouped_field->description ) : '').' '.@ $grouped_field->html[$n].'
'; $i++; } if (!$multiple) break; // multiple values disabled, break out of the loop, not adding further values even if the exist } // Non value HTML $non_value_html = ''; foreach($grouped_fields as $field_id => $grouped_field) { if ($grouped_field->formhidden == 4) continue; if ($isAdmin) { if ( $grouped_field->parameters->get('backend_hidden') || (isset($grouped_field->formhidden_grp) && in_array($grouped_field->formhidden_grp, array(2,3))) ) continue; } else { if ( $grouped_field->parameters->get('frontend_hidden') || (isset($grouped_field->formhidden_grp) && in_array($grouped_field->formhidden_grp, array(1,3))) ) continue; } $non_value_html .= @$grouped_field->html[-1]; } // Implode form HTML as a list $list_classes = "fcfield-sortables"; $list_classes .= " fcfield-group"; if (count($field->html)) { $field->html = '
  • '. implode( '
  • ', $field->html ). '
  • '; $field->html = '
    '; } else { $field->html = ''; } if (!$add_position) $field->html .= ''.JText::_( 'FLEXI_ADD_VALUE' ).''; // Check max allowed version //$manifest_path = JPATH_ADMINISTRATOR .DS. 'components' .DS. 'com_flexicontent' .DS. 'manifest.xml'; //$com_xml = JApplicationHelper::parseXMLInstallFile( $manifest_path ); // Append non value html of fields $field->html = /*(version_compare( str_replace(' ', '.', $com_xml['version']), str_replace(' ', '.', self::$prior_to_version), '>=') ? ' Warning: installed version of Field: \''.$field->field_type.'\' was meant for FLEXIcontent versions prior to: v'.self::$prior_to_version.' It may or may not work properly in later versions ' : '').*/ ($field->parameters->get('compact_edit_global', 0) ? '
    '.JText::_( 'FLEXI_FIELD_GROUP_HIDE_VALUES' ).'
    ' : '').' '.$field->html. ($non_value_html ? '
    '.$non_value_html : ''); } // Method to create field's HTML display for frontend views function onDisplayFieldValue(&$field, $item, $values=null, $prop='display') { if ( !in_array($field->field_type, self::$field_types) ) return; // Use custom HTML display parameter $display_mode = (int) $field->parameters->get( 'display_mode', 0 ) ; // Prefix - Suffix - Separator parameters, replacing other field values if found $remove_space = $field->parameters->get( 'remove_space', 0 ) ; $pretext = FlexicontentFields::replaceFieldValue( $field, $item, $field->parameters->get( 'pretext', '' ), 'pretext' ); $posttext = FlexicontentFields::replaceFieldValue( $field, $item, $field->parameters->get( 'posttext', '' ), 'posttext' ); $separatorf = $field->parameters->get( 'separatorf', 1 ) ; $opentag = FlexicontentFields::replaceFieldValue( $field, $item, $field->parameters->get( 'opentag', '' ), 'opentag' ); $closetag = FlexicontentFields::replaceFieldValue( $field, $item, $field->parameters->get( 'closetag', '' ), 'closetag' ); // Microdata (classify the field group values for search engines) // we use itemtype and not itemprop as it is more appropriate for the a grouping field $fieldgroup_itemtype = $field->parameters->get('fieldgroup_itemtype'); // RGE itemprop="address" //
    // $fieldgroup_itemtype_code = $fieldgroup_itemtype ? 'itemscope itemtype="http://schema.org/'.$fieldgroup_itemtype.'"' : ''; $fieldgroup_itemtype_code = $fieldgroup_itemtype ? 'itemscope itemprop="address" itemtype="http://schema.org/'.$fieldgroup_itemtype.'"' : ''; if($pretext) { $pretext = $remove_space ? $pretext : $pretext . ' '; } if($posttext) { $posttext = $remove_space ? $posttext : ' ' . $posttext; } if (!$pretext && !$posttext && !$display_mode) { $pretext = '
    '; $posttext = '
    '; } if ($fieldgroup_itemtype_code) { $pretext = '
    '.$pretext; $posttext = $posttext.'
    '; } switch($separatorf) { case 0: $separatorf = ' '; break; case 1: $separatorf = '
    '; break; case 2: $separatorf = ' | '; break; case 3: $separatorf = ', '; break; case 4: $separatorf = $closetag . $opentag; break; case 5: $separatorf = ''; break; default: $separatorf = ' '; break; } // Get fields belonging to this field group $grouped_fields = $this->getGroupFields($field); // Get values of fields making sure that also empty values are created too $max_count = 0; $this->getGroupFieldsValues($field, $item, $grouped_fields, $max_count); // ********************************************** // Create a CUSTOMIZED display of the field group // ********************************************** if ( $display_mode ) { $custom_html = trim($field->parameters->get( 'custom_html', '' )) ; $field->{$prop} = $this->_createDisplayHTML($field, $item, $grouped_fields, $custom_html, $max_count, $pretext, $posttext); } // ********************************************* // Create the DEFAULT display of the field group // ********************************************* else { // Render HTML of fields in the group $method = 'display'; $view = JRequest::getVar('flexi_callview', JRequest::getVar('view', FLEXI_ITEMVIEW)); foreach($grouped_fields as $grouped_field) { // Render the display method for the given field $_values = $grouped_field->value; $grouped_field->ingroup = 1; // render as array //echo 'Rendering: '. $grouped_field->name . ', method: ' . $method . '
    '; //FLEXIUtilities::call_FC_Field_Func($grouped_field->field_type, 'onDisplayFieldValue', array(&$grouped_field, $item, $_values, $method)); unset($grouped_field->$method); // Unset display variable to make sure display HTML it is created, because we reuse the field FlexicontentFields::renderField($item, $grouped_field, $_values, $method, $view, $_skip_trigger_plgs = true); // We will trigger only once the final result unset($grouped_field->ingroup); } // Get labels to hide on empty values $hide_lbl_ifnoval = $this->getHideLabelsOnEmpty($field); // Render the list of groups $field->{$prop} = array(); for($n=0; $n < $max_count; $n++) { $default_html = array(); foreach($grouped_fields as $grouped_field) { // Skip (hide) label for field without value (is such behaviour was configured) if ( (!isset($grouped_field->{$prop}[$n]) || !strlen($grouped_field->{$prop}[$n])) && isset($hide_lbl_ifnoval[$grouped_field->id]) ) continue; // Add field's HTML (optionally including label) $_values = null; $default_html[] = '
    '.($grouped_field->parameters->get('display_label') ? ' '.$grouped_field->label.'' : ''). (isset($grouped_field->{$prop}[$n]) ? '
    '.$grouped_field->{$prop}[$n].'
    ' : '').'
    '; } if (count($default_html)) { $field->{$prop}[] = $pretext . implode('
    ', $default_html).'
    ' . $posttext; } } // Unset display of fields in case they need to be rendered again //foreach($grouped_fields as $grouped_field) unset($grouped_field->$prop); } if (count($field->{$prop})) { $field->{$prop} = implode($separatorf, $field->{$prop}); $field->{$prop} = $opentag . $field->{$prop} . $closetag; } else { $field->{$prop} = ''; } } // Helper method to create HTML display of an item list according to replacements private function _createDisplayHTML(&$field, &$item, &$grouped_fields, $custom_html, $max_count, $pretext, $posttext) { // ******************************** // Parse and identify custom fields // ******************************** //return array('"Custom HTML" display for fieldgroup field, is not implemented yet, please use default HTML'); if (!$custom_html) return "Empty custom HTML variable for group field: ". $field->label; $result = preg_match_all("/\{\{([a-zA-Z_0-9]+)(##)?([a-zA-Z_0-9]+)?\}\}/", $custom_html, $field_matches); $gf_reps = $result ? $field_matches[0] : array(); $gf_names = $result ? $field_matches[1] : array(); $gf_methods = $result ? $field_matches[3] : array(); //foreach ($gf_names as $i => $gf_name) // $parsed_fields[] = $gf_names[$i] . ($gf_methods[$i] ? "->". $gf_methods[$i] : ""); //echo "$custom_html :: Fields for Related Items List: ". implode(", ", $parsed_fields ? $parsed_fields : array() ) ."
    \n"; $_name_to_field = array(); foreach($grouped_fields as $i => $grouped_field) { $_name_to_field[$grouped_field->name] = & $grouped_fields[$i]; } //print_r(array_keys($_name_to_field)); echo "
    "; // *********************************************************************** // Parse and identify language strings and then make language replacements // *********************************************************************** $result = preg_match_all("/\%\%([^%]+)\%\%/", $custom_html, $translate_matches); $translate_strings = $result ? $translate_matches[1] : array('FLEXI_READ_MORE_ABOUT'); foreach ($translate_strings as $translate_string) $custom_html = str_replace('%%'.$translate_string.'%%', JText::_($translate_string), $custom_html); // ************************************************************** // Render HTML of grouped fields mentioned inside the custom HTML // ************************************************************** $_rendered_fields = array(); if ( count($gf_names) ) { $view = JRequest::getVar('flexi_callview', JRequest::getVar('view', FLEXI_ITEMVIEW));; $gf_props = array(); foreach($gf_names as $pos => $grp_field_name) { // Check that field exists and is assigned the fieldgroup field $grouped_field = $_name_to_field[$grp_field_name]; if ( ! isset($_name_to_field[$grp_field_name]) ) continue; $_rendered_fields[$pos] = $grouped_field; // Check if display method is 'label' aka nothing to render if ( $gf_methods[$pos] == 'label' ) continue; // Optional use custom display method $method = $gf_methods[$pos] ? $gf_methods[$pos] : 'display'; // SAME field with SAME method, may have been used more than ONCE, inside the custom HTML parameter // Check if field has been rendered already if ( isset($grouped_field->{$method}) && is_array($grouped_field->{$method}) ) continue; // Render the display method for the given field $_values = $grouped_field->value; $grouped_field->ingroup = 1; // render as array //echo 'Rendering: '. $grouped_field->name . ', method: ' . $method . '
    '; //FLEXIUtilities::call_FC_Field_Func($grouped_field->field_type, 'onDisplayFieldValue', array(&$grouped_field, $item, $_values, $method)); FlexicontentFields::renderField($item, $grouped_field, $_values, $method, $view, $_skip_trigger_plgs = true); // We will trigger only once the final result //print_r($grouped_field->$method); $grouped_field->_method = $method; // This is used to decide if field does not have value and hide label (if configured to hide on empty values) unset($grouped_field->ingroup); } } // ******************************************************************* // Render the value list of the fieldgroup, using custom HTML for each // value-set of the fieldgroup, and performing the field replacements // ******************************************************************* // Get labels to hide on empty values $hide_lbl_ifnoval = $this->getHideLabelsOnEmpty($field); $custom_display = array(); //echo "
    max_count: ".$max_count."
    "; for($n=0; $n < $max_count; $n++) { $rendered_html = $custom_html; foreach($_rendered_fields as $pos => $_rendered_field) { $method = $gf_methods[$pos] ? $gf_methods[$pos] : 'display'; //echo 'Replacing: '. $_rendered_field->name . ', method: ' . $method . ', index: ' .$n. '
    '; if ($method!='label') $_html = isset($_rendered_field->{$method}[$n]) ? $_rendered_field->{$method}[$n] : ''; else { $_method = isset($_rendered_field->_method) ? $_rendered_field->_method : 'display'; if ( (!isset($_rendered_field->{$_method}[$n]) || !strlen($_rendered_field->{$_method}[$n])) && isset($hide_lbl_ifnoval[$_rendered_field->id]) ) { $_html = ''; // Skip (hide) label for field without value (is such behaviour was configured) } else { $_html = $_rendered_field->label; } } $rendered_html = str_replace($gf_reps[$pos], $_html, $rendered_html); } $custom_display[$n] = $pretext . $rendered_html . $posttext; } // IMPORTANT FIELD IS REUSED, !! unset display methods since it maybe rendered again for different item foreach($_rendered_fields as $pos => $_rendered_field) { unset($_rendered_field->$method); } return $custom_display; } // ************************************************************** // METHODS HANDLING before & after saving / deleting field events // ************************************************************** // Method to handle field's values before they are saved into the DB function onBeforeSaveField( &$field, &$post, &$file, &$item ) { if ( !in_array($field->field_type, self::$field_types) ) return; // field_type is not changed text field can handle this field type //FLEXIUtilities::call_FC_Field_Func('text', 'onBeforeSaveField', array(&$field, &$post, &$file, &$item)); } // Method to take any actions/cleanups needed after field's values are saved into the DB function onAfterSaveField( &$field, &$post, &$file, &$item ) { if ( !in_array($field->field_type, self::$field_types) ) return; // field_type is not changed text field can handle this field type //FLEXIUtilities::call_FC_Field_Func('text', 'onAfterSaveField', array(&$field, &$post, &$file, &$item)); } // Method called just before the item is deleted to remove custom item data related to the field function onBeforeDeleteField(&$field, &$item) { if ( !in_array($field->field_type, self::$field_types) ) return; // field_type is not changed text field can handle this field type //FLEXIUtilities::call_FC_Field_Func('text', 'onBeforeDeleteField', array(&$field, &$item)); } // ********************** // VARIOUS HELPER METHODS // ********************** // Retrieves the fields that are part of the given 'fieldgroup' field function getGroupFields(&$field) { static $grouped_fields = array(); if (isset($grouped_fields[$field->id])) return $grouped_fields[$field->id]; $fieldids = $field->parameters->get('fields', array()); if ( empty($fieldids) ) { $fieldids = array(); } if ( !is_array($fieldids) ) { $fieldids = preg_split("/[\|,]/", $fieldids); } if ( empty($fieldids) ) { // No assigned fields return $grouped_fields[$field->id] = array(); } $db = JFactory::getDBO(); $query = 'SELECT f.* ' . ' FROM #__flexicontent_fields AS f ' . ' WHERE f.published = 1' . ' AND f.id IN ('.implode(',',$fieldids).')' . ' ORDER BY FIELD(f.id, '.implode(',',$fieldids).')' ; $db->setQuery($query); $grouped_fields[$field->id] = $db->loadObjectList('id'); $_grouped_fields = array(); foreach($grouped_fields[$field->id] as $field_id => $grouped_field) { // Create field parameters, if not already created, NOTE: for 'custom' fields loadFieldConfig() is optional if (empty($grouped_field->parameters)) { $grouped_field->parameters = new JRegistry($grouped_field->attribs); } // Check if field is not set to participate in a field group and skip it if ( !$grouped_field->parameters->get('use_ingroup') ) continue; $_grouped_fields[$field_id] = $grouped_field; } $grouped_fields[$field->id] = $_grouped_fields; return $grouped_fields[$field->id]; } // Retrieves and add values to the given field objects function getGroupFieldsValues(&$field, &$item, &$grouped_fields, &$max_count) { $do_compact = true; // **************** // Get field values // **************** $max_index = 0; foreach($grouped_fields as $field_id => $grouped_field) { // Item viewing if ( isset($item->fieldvalues[$field_id]) ) { $grouped_field->value = is_array($item->fieldvalues[$field_id]) ? $item->fieldvalues[$field_id] : array($item->fieldvalues[$field_id]); } // Item form else if ( isset($item->fields[$grouped_field->name]->value) ) { $grouped_field->value = $item->fields[$grouped_field->name]->value; } // Value not set else { $grouped_field->value = null; } // Update max value index $last_index = !is_array($grouped_field->value) || !count($grouped_field->value) ? 0 : max(array_keys($grouped_field->value)); $max_index = $last_index > $max_index ? $last_index : $max_index; } //echo "


    DB DATA
    "; foreach($grouped_fields as $field_id => $grouped_field) { echo "\n[".$grouped_field->id."] - ".$grouped_field->name; print_r($grouped_field->value); } echo "
    "; // *********************************************************************************** // (Compatibility) For groups that have fields with non-set values, add NULL values // This way the field will not skip the value and instead will create an empty display // *********************************************************************************** $null_count = array(); for ($n=0; $n <= $max_index; $n++) $null_count[$n] = 0; foreach($grouped_fields as $field_id => $grouped_field) { $vals = array(); for ($n=0; $n <= $max_index; $n++) { if ( isset($grouped_field->value[$n]) ) { $vals[$n] = $grouped_field->value[$n]; } else { $vals[$n] = null; ++$null_count[$n]; } } $grouped_field->value = $vals; } //echo "


    NULLED
    "; foreach($grouped_fields as $field_id => $grouped_field) { echo "\n[".$grouped_field->id."] - ".$grouped_field->name; print_r($grouped_field->value); } echo "
    "; //echo "
    "; print_r($null_count); echo "
    "; // ********************************* // Find groups that had empty values // ********************************* $grp_isempty = array(); for($n=0; $n <= $max_index; $n++) { if ( isset($null_count[$n]) && $null_count[$n]==count($grouped_fields) ) $grp_isempty[$n] = 1; } //print_r($grp_isempty); exit; // ************************************************************************* // Compact FIELD GROUP values by removing groups that are (ALL values) empty // ************************************************************************* // Make sure we have some empty fieldgroups, if this was requested (= that is the max_count that was passed to the function) $start_at = $max_count + count($grp_isempty) - ($max_index+1); if ($start_at < 0) $start_at = 0; if ($do_compact) foreach($grouped_fields as $field_id => $grouped_field) { $i = $start_at; for ($n = $start_at; $n <= $max_index; $n++) { //echo $n." - ".$i."
    "; // Move down to fill empty gaps, if current index is not in sync, meaning 1 empty group was encountered -before-, and also if current (value) group is non-empty if ( $n > $i && !isset($grp_isempty[$n]) ) { $grouped_field->value[$i] = $grouped_field->value[$n]; if ( isset($grouped_field->value[$n]) ) { if ( isset($item->fieldvalues[$field_id]) ) $item->fieldvalues[$field_id][$i] = $grouped_field->value[$n]; if ( isset($item->fields[$grouped_field->name]->value) ) $item->fields[$grouped_field->name]->value[$i] = $grouped_field->value[$n]; } } // Unset moved groups or group with ALL-empty values if ( $n > $i || isset($grp_isempty[$n]) ) { unset($grouped_field->value[$n]); if ( isset($item->fieldvalues[$field_id]) ) unset($item->fieldvalues[$field_id][$n]); if ( isset($item->fields[$grouped_field->name]->value) ) unset($item->fields[$grouped_field->name]->value[$n]); } // Increment adding position if group was not empty if ( !isset($grp_isempty[$n]) ) $i++; } } //echo "


    COMPACTED
    "; foreach($grouped_fields as $field_id => $grouped_field) { echo "\n[".$grouped_field->id."] - ".$grouped_field->name; print_r($grouped_field->value); } echo "
    "; $max_count = $max_index + 1; if ($do_compact) $max_count -= (count($grp_isempty) - $start_at); //echo $field->label.": max_count = $max_count
    "; } // Return the fields (ids) that will hide their labels if they have no value function getHideLabelsOnEmpty(&$field) { static $hide_lbl_ifnoval_arr = array(); if (isset($hide_lbl_ifnoval_arr[$field->id])) return $hide_lbl_ifnoval_arr[$field->id]; $hide_lbl_ifnoval = $field->parameters->get('hide_lbl_ifnoval', array()); if ( empty($hide_lbl_ifnoval) ) $hide_lbl_ifnoval = array(); if ( !is_array($hide_lbl_ifnoval) ) $hide_lbl_ifnoval = preg_split("/[\|,]/", $hide_lbl_ifnoval); $hide_lbl_ifnoval_arr[$field->id] = array_flip($hide_lbl_ifnoval); return $hide_lbl_ifnoval_arr[$field->id]; } }