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 ? '
'.$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] .= '
// $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];
}
}