Browse Source

Add "Triple Select" extra field type - refs BT#13347

Angel Fernando Quiroz Campos 7 years ago
parent
commit
b0faac4925

+ 248 - 1
main/inc/lib/extra_field.lib.php

@@ -68,6 +68,7 @@ class ExtraField extends Model
     const FIELD_TYPE_GEOLOCALIZATION = 24;
     const FIELD_TYPE_GEOLOCALIZATION_COORDINATES = 25;
     const FIELD_TYPE_SELECT_WITH_TEXT_FIELD = 26;
+    const FIELD_TYPE_TRIPLE_SELECT = 27;
 
     public $type = 'user';
     public $pageName;
@@ -443,6 +444,7 @@ class ExtraField extends Model
             'GeolocalizationCoordinates'
         );
         $types[self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD] = get_lang('FieldTypeSelectWithTextField');
+        $types[self::FIELD_TYPE_TRIPLE_SELECT] = get_lang('FieldTypeTripleSelect');
 
         switch ($handler) {
             case 'course':
@@ -563,6 +565,7 @@ class ExtraField extends Model
                 }
 
                 if ($field_value) {
+                    $variable = $field['variable'];
                     $field_value = $field_value['value'];
                     switch ($field['field_type']) {
                         case self::FIELD_TYPE_TAG:
@@ -594,6 +597,13 @@ class ExtraField extends Model
                         case self::FIELD_TYPE_RADIO:
                             $extra_data['extra_'.$field['variable']]['extra_'.$field['variable']] = $field_value;
                             break;
+                        case self::FIELD_TYPE_TRIPLE_SELECT:
+                            list($level1, $level2, $level3) = explode(';', $field_value);
+
+                            $extra_data["extra_$variable"]["extra_$variable"] = $level1;
+                            $extra_data["extra_$variable"]["extra_{$variable}_second"] = $level2;
+                            $extra_data["extra_$variable"]["extra_{$variable}_third"] = $level3;
+                            break;
                         default:
                             $extra_data['extra_'.$field['variable']] = $field_value;
                             break;
@@ -693,6 +703,44 @@ class ExtraField extends Model
         return $options_parsed;
     }
 
+    /**
+     * @param $string
+     * @return array
+     */
+    public static function tripleSelectConvertStringToArray($string)
+    {
+        $options = [];
+
+        foreach (explode('|', $string) as $i => $item0) {
+            $level1 = explode('\\', $item0);
+
+            foreach ($level1 as $j => $item1) {
+                if (0 === $j) {
+                    $options[] = ['label' => $item1, 'options' => []];
+
+                    continue;
+                }
+
+
+                foreach (explode(':', $item1) as $k => $item2) {
+                    if (0 === $k) {
+                        $options[$i]['options'][] = ['label' => $item2, 'options' => []];
+
+                        continue;
+                    }
+
+                    $options[$i]['options'][$j - 1]['options'][] = explode(';', $item2);
+                }
+            }
+        }
+
+        array_walk_recursive($options, function (&$item) {
+            $item = trim($item);
+        });
+
+        return $options;
+    }
+
     /**
      * @param array $options
      *
@@ -714,6 +762,38 @@ class ExtraField extends Model
         return $options_parsed;
     }
 
+    /**
+     * @param array $options
+     * @param int $parentId
+     * @return array
+     */
+    private static function getOptionsFromTripleSelect(array $options, $parentId) {
+        return array_filter($options, function ($option) use ($parentId) {
+            return $option['option_value'] == $parentId;
+        });
+    }
+
+    /**
+     * @param array $options
+     * @return array
+     */
+    public static function tripleSelectConvertArrayToOrderedArray(array $options)
+    {
+        $level1 = self::getOptionsFromTripleSelect($options, 0);
+        $level2 = [];
+        $level3 = [];
+
+        foreach ($level1 as $item1) {
+            $level2 += self::getOptionsFromTripleSelect($options, $item1['id']);
+        }
+
+        foreach ($level2 as $item2) {
+            $level3 += self::getOptionsFromTripleSelect($options, $item2['id']);
+        }
+
+        return ['level1' => $level1, 'level2' => $level2, 'level3' => $level3];
+    }
+
     /**
      * @param array $options the result of the get_field_options_by_field() array
      *
@@ -770,6 +850,32 @@ class ExtraField extends Model
         return rtrim($string, '|');
     }
 
+    /**
+     * @param array $options
+     * @return string
+     */
+    public static function tripleSelectConvertArrayToString(array $options)
+    {
+        $string = '';
+        $parsedOptions = self::tripleSelectConvertArrayToOrderedArray($options);
+
+        foreach ($parsedOptions['level1'] as $item1) {
+            $string .= $item1['display_text'];
+            $level2 = self::getOptionsFromTripleSelect($parsedOptions['level2'], $item1['id']);
+
+            foreach ($level2 as $item2) {
+                $string .= '\\'.$item2['display_text'].':';
+                $level3 = self::getOptionsFromTripleSelect($parsedOptions['level3'], $item2['id']);
+
+                $string .= implode(';', array_column($level3, 'display_text'));
+            }
+
+            $string .= '|';
+        }
+
+        return trim($string, '\\|;');
+    }
+
     /**
      * @param array $params
      *
@@ -1026,6 +1132,138 @@ class ExtraField extends Model
         return $jqueryReadyContent;
     }
 
+    /**
+     * @param \FormValidator $form
+     * @param array $fieldDetails
+     * @param array $extraData
+     * @param boolean $freezeElement
+     * @return string
+     */
+    private function addTripleSelectElement(
+        FormValidator $form,
+        array $fieldDetails,
+        array $extraData,
+        $freezeElement
+    )
+    {
+        $variable = $fieldDetails['variable'];
+        $id = $fieldDetails['id'];
+        $slctFirstId = "first_extra$variable";
+        $slctSecondId = "second_extra$variable";
+        $slctThirdId = "thrid_extra$variable";
+        $langSelect = get_lang('Select');
+
+        $js = "
+            (function () {
+                var slctFirst = $('#$slctFirstId'),
+                    slctSecond = $('#$slctSecondId'),
+                    slctThrid = $('#$slctThirdId');
+                    
+                slctFirst.on('change', function () {
+                    slctSecond.empty().selectpicker('refresh');
+                    slctThrid.empty().selectpicker('refresh');
+    
+                    var level = $(this).val();
+    
+                    if (!level) {
+                        return;
+                    }
+    
+                    $.getJSON(_p.web_ajax + 'extra_field.ajax.php', {
+                        'a': 'get_second_select_options',
+                        'type': '$this->type',
+                        'field_id': $id,
+                        'option_value_id': level
+                    })
+                        .done(function (data) {
+                            slctSecond.append(
+                                $('<option>', {value: '', text: '$langSelect'})
+                            );
+
+                            $.each(data, function (index, value) {
+                                slctSecond.append(
+                                    $('<option>', {value: index, text: value})
+                                );
+                            });
+    
+                            slctSecond.selectpicker('refresh');
+                        });
+                });
+                slctSecond.on('change', function () {
+                    slctThrid.empty().selectpicker('refresh');
+    
+                    var level = $(this).val();
+                    
+                    if (!level) {
+                        return;
+                    }
+                    
+                    $.getJSON(_p.web_ajax + 'extra_field.ajax.php', {
+                        'a': 'get_second_select_options',
+                        'type': '$this->type',
+                        'field_id': $id,
+                        'option_value_id': level
+                    })
+                        .done(function (data) {
+                            slctThrid.append(
+                                $('<option>', {value: '', text: '$langSelect'})
+                            );
+
+                            $.each(data, function (index, value) {
+                                slctThrid.append(
+                                    $('<option>', {value: index, text: value})
+                                );
+                            });
+    
+                            slctThrid.selectpicker('refresh');
+                        });
+                });
+            })();
+        ";
+
+        $firstId = isset($extraData["extra_$variable"]["extra_$variable"])
+            ? $extraData["extra_$variable"]["extra_$variable"]
+            : '';
+        $secondId = isset($extraData["extra_$variable"]["extra_{$variable}_second"])
+            ? $extraData["extra_$variable"]["extra_{$variable}_second"]
+            : '';
+
+        $options = self::tripleSelectConvertArrayToOrderedArray($fieldDetails['options']);
+        $values1 = ['' => $langSelect];
+        $values2 = ['' => $langSelect];
+        $values3 = ['' => $langSelect];
+        $level1 = self::getOptionsFromTripleSelect($options['level1'], 0);
+        $level2 = self::getOptionsFromTripleSelect($options['level2'], $firstId);
+        $level3 = self::getOptionsFromTripleSelect($options['level3'], $secondId);
+
+        foreach ($level1 as $item1) {
+            $values1[$item1['id']] = $item1['display_text'];
+        }
+
+        foreach ($level2 as $item2) {
+            $values2[$item2['id']] = $item2['display_text'];
+        }
+
+        foreach ($level3 as $item3) {
+            $values3[$item3['id']] = $item3['display_text'];
+        }
+
+        $form
+            ->defaultRenderer()
+            ->setGroupElementTemplate('<p>{element}</p>', "extra_$variable");
+        $group = [];
+        $group[] = $form->createElement('select', "extra_$variable", null, $values1, ['id' => $slctFirstId]);
+        $group[] = $form->createElement('select', "extra_{$variable}_second", null, $values2, ['id' => $slctSecondId]);
+        $group[] = $form->createElement('select', "extra_{$variable}_third", null, $values3, ['id' => $slctThirdId]);
+        $form->addGroup($group, "extra_$variable", $fieldDetails['display_text']);
+
+        if ($freezeElement) {
+            $form->freeze('extra_'.$fieldDetails['variable']);
+        }
+
+        return $js;
+    }
+
     /**
      * Add an element that matches the given extra field to the given $form object
      * @param FormValidator $form
@@ -2146,6 +2384,14 @@ class ExtraField extends Model
                             $freezeElement
                         );
                         break;
+                    case self::FIELD_TYPE_TRIPLE_SELECT:
+                        $jquery_ready_content .= self::addTripleSelectElement(
+                            $form,
+                            $field_details,
+                            $extraData,
+                            $freezeElement
+                        );
+                        break;
                 }
             }
         }
@@ -2349,7 +2595,8 @@ class ExtraField extends Model
             self::FIELD_TYPE_SELECT,
             self::FIELD_TYPE_TAG,
             self::FIELD_TYPE_DOUBLE_SELECT,
-            self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD
+            self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD,
+            self::FIELD_TYPE_TRIPLE_SELECT
         );
 
         if ($action == 'edit') {

+ 79 - 1
main/inc/lib/extra_field_option.lib.php

@@ -180,7 +180,8 @@ class ExtraFieldOption extends Model
                 ExtraField::FIELD_TYPE_SELECT,
                 ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
                 ExtraField::FIELD_TYPE_DOUBLE_SELECT,
-                ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD
+                ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD,
+                ExtraField::FIELD_TYPE_TRIPLE_SELECT
             )
         );
 
@@ -255,6 +256,80 @@ class ExtraFieldOption extends Model
                     }
                 }
                 break;
+            case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
+                //Format: Option1\Option11:Option111;Option112\Option12:Option121|Option2\Option21:Option211
+                $options = ExtraField::tripleSelectConvertStringToArray($params['field_options']);
+
+                if (!$options) {
+                    break;
+                }
+
+                foreach ($options as $level1) {
+                    $level1Params = [
+                        'field_id' => $field_id,
+                        'option_value' => 0,
+                        'display_text' => $level1['label'],
+                        'option_order' => 0,
+                    ];
+                    $optionInfo = self::get_field_option_by_field_id_and_option_display_text(
+                        $field_id,
+                        $level1['label']
+                    );
+
+                    if (empty($optionInfo)) {
+                        $level1Id = parent::save($level1Params);
+                    } else {
+                        $level1Id = $optionInfo['id'];
+                        $level1Params['id'] = $level1Id;
+                        parent::update($level1Params);
+                    }
+
+                    foreach ($level1['options'] as $level2) {
+                        $level2Params = [
+                            'field_id' => $field_id,
+                            'option_value' => $level1Id,
+                            'display_text' => $level2['label'],
+                            'display_order' => 0
+                        ];
+                        $optionInfo = self::getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
+                            $field_id,
+                            $level2['label'],
+                            $level1Id
+                        );
+
+                        if (empty($optionInfo)) {
+                            $level2Id = parent::save($level2Params);
+                        } else {
+                            $level2Id = $optionInfo['id'];
+                            $level2Params['id'] = $level2Id;
+                            parent::update($level2Params);
+                        }
+
+                        foreach ($level2['options'] as $level3) {
+                            foreach ($level3 as $item) {
+                                $level3Params = [
+                                    'field_id' => $field_id,
+                                    'option_value' => $level2Id,
+                                    'display_text' => $item,
+                                    'display_order' => 0
+                                ];
+                                $optionInfo = self::getFieldOptionByFieldIdAndOptionDisplayTextAndOptionValue(
+                                    $field_id,
+                                    $item,
+                                    $level2Id
+                                );
+
+                                if (empty($optionInfo)) {
+                                    parent::save($level3Params);
+                                } else {
+                                    $level3Params['id'] = $optionInfo['id'];
+                                    parent::update($level3Params);
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
             default:
                 $list = explode(';', $params['field_options']);
 
@@ -556,6 +631,9 @@ class ExtraFieldOption extends Model
                 case ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
                     $html = ExtraField::extrafieldSelectWithTextConvertArrayToString($options);
                     break;
+                case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
+                    $html = ExtraField::tripleSelectConvertArrayToString($options);
+                    break;
                 default:
                     foreach ($options as $option) {
                         $elements[] = $option['option_value'];

+ 28 - 0
main/inc/lib/extra_field_value.lib.php

@@ -598,6 +598,19 @@ class ExtraFieldValue extends Model
                                     .$options[1];
                             }
                             break;
+                        case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
+                            $optionIds = explode(';', $result['value']);
+                            $optionValues = [];
+
+                            foreach ($optionIds as $optionId) {
+                                $objEfOption = new ExtraFieldOption('user');
+                                $optionInfo = $objEfOption->get($optionId);
+
+                                $optionValues[] = $optionInfo['display_text'];
+                            }
+
+                            $result['value'] = implode(' / ', $optionValues);
+                            break;
                     }
                 }
             }
@@ -710,6 +723,21 @@ class ExtraFieldValue extends Model
                         }
                     }
                 }
+                if ($result['field_type'] == ExtraField::FIELD_TYPE_TRIPLE_SELECT) {
+                    if (!empty($result['value'])) {
+                        $optionIds = explode(';', $result['value']);
+                        $optionValues = [];
+
+                        foreach ($optionIds as $optionId) {
+                            $objEfOption = new ExtraFieldOption('user');
+                            $optionInfo = $objEfOption->get($optionId);
+
+                            $optionValues[] = $optionInfo['display_text'];
+                        }
+
+                        $result['value'] = implode(' / ', $optionValues);
+                    }
+                }
             }
 
             return $result;

+ 8 - 0
main/inc/lib/tracking.lib.php

@@ -7071,6 +7071,14 @@ class TrackingCourseLog
                                 $row['value'] = "$value1: $value2";
                             }
                         }
+
+                        if ($result_extra_field['field_type'] == ExtraField::FIELD_TYPE_TRIPLE_SELECT) {
+                            list($level1, $level2, $level3) = explode(';', $row['value']);
+
+                            $row['value'] = $result_extra_field['options'][$level1]['display_text'].' / ';
+                            $row['value'] .= $result_extra_field['options'][$level2]['display_text'].' / ';
+                            $row['value'] .= $result_extra_field['options'][$level3]['display_text'];
+                        }
                     }
                     // get other value from extra field
                     $return[$row['user_id']][] = $row['value'];

+ 14 - 0
main/social/profile.php

@@ -430,6 +430,20 @@ if ($show_full_profile) {
                             .$optionInfo['display_text'].': '
                             .$parsedData[1].'</li>';
                         break;
+                    case ExtraField::FIELD_TYPE_TRIPLE_SELECT:
+                        $optionIds = explode(';', $data);
+                        $optionValues = array();
+
+                        foreach ($optionIds as $optionId) {
+                            $objEfOption = new ExtraFieldOption('user');
+                            $optionInfo = $objEfOption->get($optionId);
+
+                            $optionValues[] = $optionInfo['display_text'];
+                        }
+                        $extra_information_value .= '<li class="list-group-item">'
+                            .ucfirst($extraFieldInfo['display_text']).': '
+                            .implode(' ', $optionValues).'</li>';
+                        break;
                     default:
                         $extra_information_value .= '<li class="list-group-item">'.ucfirst($extraFieldInfo['display_text']).': '.$data.'</li>';
                         break;