helper = $this->Application->recallObject('kMultiLanguageHelper'); } /** * Returns ML field equivalent to field name specifed * * @param string $field_name * @param bool $from_primary use primary/current language for name custruction * @return string */ function LangFieldName($field_name, $from_primary = false) { static $primary_language = null; if (preg_match('/^l[0-9]+_/', $field_name)) { return $field_name; } if (!isset($primary_language)) { $primary_language = $this->Application->GetDefaultLanguageId(); } $lang = $from_primary ? $primary_language : $this->Application->GetVar('m_lang'); if (!$lang || ($lang == 'default')) { $lang = $primary_language; } return 'l' . $lang . '_' . $field_name; } /** * The method is supposed to alter config options or cofigure object in some way based on its usage of formatters * The methods is called for every field with formatter defined when configuring item. * Could be used for adding additional VirtualFields to an object required by some special Formatter * * @param string $field_name * @param array $field_options * @param kDBBase $object */ function PrepareOptions($field_name, &$field_options, &$object) { if (getArrayValue($field_options, 'master_field') || getArrayValue($field_options, 'options_processed')) { return ; } $lang_field_name = $this->LangFieldName($field_name); //substitute title field $title_field = $this->Application->getUnitOption($object->Prefix, 'TitleField'); if ($title_field == $field_name) { $this->Application->setUnitOption($object->Prefix, 'TitleField', $lang_field_name); } $languages = $this->helper->getLanguages(); $primary_language_id = $this->Application->GetDefaultLanguageId(); $fields = $this->Application->getUnitOption($object->Prefix, 'Fields', Array ()); $virtual_fields = $this->Application->getUnitOption($object->Prefix, 'VirtualFields', Array ()); // substitute real field if (array_key_exists($field_name, $fields)) { $tmp_field_options = $fields[$field_name]; $tmp_field_options['master_field'] = $field_name; $tmp_field_options['error_field'] = $field_name; $field_required = array_key_exists('required', $tmp_field_options) && $tmp_field_options['required']; foreach ($languages as $language_id) { // make all non-primary language fields not required if ($language_id != $primary_language_id) { unset($tmp_field_options['required']); } elseif ($field_required) { $tmp_field_options['required'] = $field_required; } $translated_field = 'l' . $language_id . '_' . $field_name; $fields[$translated_field] = $tmp_field_options; $object->SetFieldOptions($translated_field, $tmp_field_options); } // makes original field non-required $object_fields = $object->getFields(); // use kDBBase::getFields, since there are no kDBList::setRequired unset($fields[$field_name]['required'], $object_fields[$field_name]['required']); $object->setFields($object_fields); // prevents real field with formatter set to be saved in db $virtual_fields[$field_name] = $object_fields[$field_name]; $object->SetFieldOptions($field_name, $object_fields[$field_name], true); } elseif (array_key_exists($field_name, $virtual_fields)) { // substitute virtual field $calculated_fields = $this->Application->getUnitOption($object->Prefix, 'CalculatedFields', Array ()); $calculated_field_special = array_key_exists($object->Special, $calculated_fields) ? $object->Special : (array_key_exists('', $calculated_fields) ? '' : false); /* @var $calculated_fields Array */ $tmp_field_options = $virtual_fields[$field_name]; $tmp_field_options['master_field'] = $field_name; $tmp_field_options['error_field'] = $field_name; $field_required = array_key_exists('required', $tmp_field_options) && $tmp_field_options['required']; foreach ($languages as $language_id) { // make all non-primary language fields not required if ($language_id != $primary_language_id) { unset($tmp_field_options['required']); } elseif ($field_required) { $tmp_field_options['required'] = $field_required; } $translated_field = 'l' . $language_id . '_' . $field_name; $virtual_fields[$translated_field] = $tmp_field_options; $object->SetFieldOptions($translated_field, $tmp_field_options, true); // substitute calculated fields associated with given virtual field foreach ($calculated_fields as $special => $special_fields) { if (!array_key_exists($field_name, $special_fields)) { continue; } $calculated_fields[$special][$translated_field] = str_replace('%2$s', $language_id, $special_fields[$field_name]); if ($special === $calculated_field_special) { $object->addCalculatedField($translated_field, $calculated_fields[$special][$translated_field]); } } // manually copy virtual field back to fields (see kDBBase::setVirtualFields about that) $fields[$translated_field] = $tmp_field_options; $object->SetFieldOptions($translated_field, $tmp_field_options); } // remove original calculated field foreach ($calculated_fields as $special => $special_fields) { unset($calculated_fields[$special][$field_name]); } $object_calculated_fields = $object->getCalculatedFields(); unset($object_calculated_fields[$field_name]); $object->setCalculatedFields($object_calculated_fields); // save back calculated fields $this->Application->setUnitOption($object->Prefix, 'CalculatedFields', $calculated_fields); // makes original field non-required $object_fields = $object->getFields(); // use kDBBase::getFields, since there are no kDBList::setRequired unset($fields[$field_name]['required'], $object_fields[$field_name]['required']); $object->setFields($object_fields); $virtual_field_options = $object->GetFieldOptions($field_name, true); unset($virtual_fields[$field_name]['required'], $virtual_field_options['required']); $object->SetFieldOptions($field_name, $virtual_field_options, true); } // substitute grid fields $grids = $this->Application->getUnitOption($object->Prefix, 'Grids', Array ()); /* @var $grids Array */ foreach ($grids as $name => $grid) { if ( getArrayValue($grid, 'Fields', $field_name) ) { // used by column picker to track column position $grids[$name]['Fields'][$field_name]['formatter_renamed'] = true; if (!array_key_exists('format', $grids[$name]['Fields'][$field_name])) { // prevent displaying value from primary language // instead of missing value in current language $grids[$name]['Fields'][$field_name]['format'] = 'no_default'; } if ( !isset($grid['Fields'][$field_name]['title']) ) { $grids[$name]['Fields'][$field_name]['title'] = 'column:la_fld_' . $field_name; } kUtil::array_rename_key($grids[$name]['Fields'], $field_name, $lang_field_name); } // update sort fields - used for sorting and filtering in SQLs foreach ($grid['Fields'] as $grid_fld_name => $fld_options) { if (isset($fld_options['sort_field']) && $fld_options['sort_field'] == $field_name) { $grids[$name]['Fields'][$grid_fld_name]['sort_field'] = $lang_field_name; } } } $this->Application->setUnitOption($object->Prefix, 'Grids', $grids); //TODO: substitute possible language-fields sortings after changing language if ( $object->isVirtualField($field_name) ) { $virtual_fields[$field_name]['options_processed'] = true; } else { $fields[$field_name]['options_processed'] = true; } $field_options['options_processed'] = true; $this->Application->setUnitOption($object->Prefix, 'Fields', $fields); $this->Application->setUnitOption($object->Prefix, 'VirtualFields', $virtual_fields); } /*function UpdateSubFields($field, $value, &$options, &$object) { } */ /** * Checks, that field value on primary language is set * * @param string $field * @param mixed $value * @param Array $options * @param kDBItem $object */ function UpdateMasterFields($field, $value, &$options, &$object) { $master_field = array_key_exists('master_field', $options) ? $options['master_field'] : false; if (!$master_field) { return ; } // moved here from Parse, because at Parse time not all of the fields may be set - this is extremly actual, when working with PopulateMlFields mode $lang = $this->Application->GetVar('m_lang'); $def_lang = $this->Application->GetDefaultLanguageId(); if ( !$this->Application->GetVar('allow_translation') && ($lang != $def_lang) && $object->isRequired($field) ) { $def_lang_field = 'l' . $def_lang . '_' . $master_field; if ( !$object->ValidateRequired($def_lang_field, $options) ) { $object->SetError($master_field, 'primary_lang_required'); if ( $object->isField($def_lang_field) ) { $object->SetError($def_lang_field, 'primary_lang_required'); } } } } /** * Formats value of a given field * * @param string $value * @param string $field_name * @param kDBItem|kDBList $object * @param string $format * @return string */ function Format($value, $field_name, &$object, $format=null) { $master_field = $object->GetFieldOption($field_name, 'master_field'); if (!$master_field) { // if THIS field is master it does NOT have reference to it's master_field $lang = $this->Application->GetVar('m_lang'); $value = $object->GetDBField('l'.$lang.'_'.$field_name); //getting value of current language $master_field = $field_name; // THIS is master_field } $options = $object->GetFieldOptions($field_name); $format = isset($format) ? $format : ( isset($options['format']) ? $options['format'] : null); // use strpos, becase 2 comma-separated formats could be specified if ($value == '' && strpos($format, 'no_default') === false) { // try to get default language value $def_lang_value = $object->GetDBField('l'.$this->Application->GetDefaultLanguageId().'_'.$master_field); if ($def_lang_value == '') { return NULL; } return $this->_replaceFCKLinks($def_lang_value, $options, $format); //return value from default language } return $this->_replaceFCKLinks($value, $options, $format); } /** * Performs required field check on primary language * * @param mixed $value * @param string $field_name * @param kDBItem $object * @return mixed * @access public */ public function Parse($value, $field_name, &$object) { if ($value == '') return NULL; return $value; } }