/** * Function to translate a section object * @param array $rows * @param array $ids * @param string $reference_table * @param JFLanguage $language * @param string $refTablePrimaryKey * @param array $tableArray * @param string $querySQL * @param boolean $allowfallback */ public function translateListWithIDs(&$rows, $ids, $reference_table, $language, $refTablePrimaryKey = "id", &$tableArray, $querySQL, $allowfallback = true) { //print " translateListWithIDs for ids=$ids refTablePrimaryKey=$refTablePrimaryKey<br>" ; $config = JFactory::getConfig(); $debug = $config->get("dbprefix"); $registry = JFactory::getConfig(); $defaultLang = $registry->getValue("config.defaultlang"); $language = isset($language) && $language != '' ? $language : $defaultLang; $db = JFactory::getDBO(); // setup Joomfish pluginds $dispatcher = JDispatcher::getInstance(); JPluginHelper::importPlugin('joomfish'); if ($reference_table == "jf_content") { return; // I can't translate myself ;-) } $results = $dispatcher->trigger('onBeforeTranslation', array(&$rows, &$ids, $reference_table, $language, $refTablePrimaryKey, &$tableArray, $querySQL, $allowfallback)); // if onBeforeTranslation has cleaned out the list then just return at this point if (strlen($ids) == 0) { return; } // find reference table alias $reftableAlias = $reference_table; for ($i = 0; $i < $tableArray["fieldCount"]; $i++) { if (!array_key_exists($i, $tableArray["fieldTableAliasData"])) { continue; } if ($tableArray["fieldTableAliasData"][$i]["tableName"] == $reference_table && $tableArray["fieldTableAliasData"][$i]["fieldNameAlias"] == $refTablePrimaryKey) { $reftableAlias = $tableArray["fieldTableAliasData"][$i]["tableNameAlias"]; break; } } // NASTY KLUDGE TO DEAL WITH SQL CONSTRUCTION IN contact.php, weblinks.php where multiple tables to be translated all use "id" which gets dropped! etc. $currentRow = current($rows); // must not check on catid>0 since this would be uncategorised items if ($reference_table == 'categories' && count($rows) > 0 && isset($currentRow->catid)) { $reftableAlias = $tableArray["tableAliases"]["categories"]; } if ($reference_table == 'sections' && count($rows) > 0 && isset($currentRow->sectionid)) { $reftableAlias = $tableArray["tableAliases"]["sections"]; } //print " translateListWithIDs( ".count($rows). ", ids=$ids, reftab=$reference_table, $language, primkey = $refTablePrimaryKey )<br>"; if ($debug) { echo "<p><strong>JoomFish debug (new):</strong><br>" . "reference_table={$reference_table}<br>" . "{$refTablePrimaryKey} IN({$ids})<br>" . "language={$language}<br>" . (count($rows) > 0 ? "class=" . get_class(current($rows)) : "") . "</p>"; } static $languages; if (!isset($languages)) { $jfm = JoomFishManager::getInstance(); $languages = $jfm->getLanguagesIndexedByCode(); } // process fallback language $fallbacklanguage = false; $fallbackrows = array(); $idarray = explode(",", $ids); $fallbackids = array(); $allowfallback = false; if (isset($languages[$language]) && $languages[$language]->fallback_code != "") { $fallbacklanguage = $languages[$language]->fallback_code; if (!array_key_exists($fallbacklanguage, $languages)) { $allowfallback = false; } } if (!$fallbacklanguage) { $allowfallback = false; } if (isset($ids) && $reference_table != '') { $user = JFactory::getUser(); $published = $user->gid < 21 ? "\n\tAND jf_content.published=1" : ""; //$published = "\n AND jf_content.published=1"; $sql = "SELECT jf_content.reference_field, jf_content.value, jf_content.reference_id, jf_content.original_value " . "\nFROM #__jf_content AS jf_content" . "\nWHERE jf_content.language_id=" . $languages[$language]->lang_id . $published . "\n AND jf_content.reference_id IN({$ids})" . "\n AND jf_content.reference_table='{$reference_table}'"; $db->setQuery($sql); $translations = $db->loadObjectList('', false); if (count($translations) > 0) { $fieldmap = null; foreach (array_keys($rows) as $key) { $row_to_translate = $rows[$key]; $rowTranslationExists = false; //print_r ($row_to_translate); print"<br>"; if (isset($row_to_translate->{$refTablePrimaryKey})) { foreach ($translations as $row) { if ($row->reference_id != $row_to_translate->{$refTablePrimaryKey}) { continue; } // TODO - consider building array for refFields. Some queries may have multiple aliases e.g. SELECT a.*, a.field as fieldalias $refField = $row->reference_field; // adjust refField for aliases (make sure the field is from the same table!). // I could reduce the calculation by building an array of translation reference fields against their mapping number // but this refinement can wait! $fieldmatch = false; // This is used to confirm the field is from the correct table for ($i = 0; $i < $tableArray["fieldCount"]; $i++) { if (!array_key_exists($i, $tableArray["fieldTableAliasData"])) { continue; } // look for fields from the correct table with the correct name if ($tableArray["fieldTableAliasData"][$i]["tableName"] == $reference_table && $tableArray["fieldTableAliasData"][$i]["fieldName"] == $refField && $tableArray["fieldTableAliasData"][$i]["tableNameAlias"] == $reftableAlias) { $refField = $tableArray["fieldTableAliasData"][$i]["fieldNameAlias"]; $fieldmatch = true; break; } } $fieldIndex = $i; if ($fieldmatch && isset($row->reference_id) && $row->reference_id == $row_to_translate->{$refTablePrimaryKey} && $fieldIndex <= $tableArray["fieldCount"]) { if (is_subclass_of($row_to_translate, 'mosDBTable')) { $row_to_translate->set($row->reference_field, $row->value); } else { $row_to_translate->{$refField} = $row->value; } $rowTranslationExists = true; //print_r( $row_to_translate); } } if (!$rowTranslationExists) { if ($allowfallback && isset($rows[$key]->{$refTablePrimaryKey})) { $fallbackrows[$key] = $rows[$key]; $fallbackids[$key] = $rows[$key]->{$refTablePrimaryKey}; } else { $results = $dispatcher->trigger('onMissingTranslation', array(&$row_to_translate, $language, $reference_table, $tableArray, $querySQL)); //JoomFish::processMissingTranslation($row_to_translate, $language,$reference_table); } } } } } else { foreach (array_keys($rows) as $key) { if ($allowfallback && isset($rows[$key]->{$refTablePrimaryKey})) { $fallbackrows[$key] = $rows[$key]; $fallbackids[$key] = $rows[$key]->{$refTablePrimaryKey}; } else { $results = $dispatcher->trigger('onMissingTranslation', array(&$rows[$key], $language, $reference_table, $tableArray, $querySQL)); //JoomFish::processMissingTranslation($rows[$key], $language,$reference_table); } } } if ($allowfallback && count($fallbackrows) > 0) { $fallbackids = implode($fallbackids, ","); JoomFish::translateListWithIDs($fallbackrows, $fallbackids, $reference_table, $fallbacklanguage, $refTablePrimaryKey, $tableArray, $querySQL, false); } $dispatcher->trigger('onAfterTranslation', array(&$rows, $ids, $reference_table, $language, $refTablePrimaryKey, $tableArray, $querySQL, $allowfallback)); } }
/** * This function based on Joomfish own method, but the * JF one only returns the current item translated * instead of the full menu set * * @param $lang * @param $getOriginals * @param $currentLangMenuItems * @return unknown_type */ function shGetJFMenu($lang, $getOriginals = true, $currentLangMenuItems = false) { static $instance; if (!isset($instance)) { $instance = array(); if (!$currentLangMenuItems) { JError::raiseWarning('SOME_ERROR_CODE', "Error translating Menus - missing currentLangMenuItems"); return false; } $db =& JFactory::getDBO(); $sql = 'SELECT m.*, c.`option` as component' . ' FROM #__menu AS m' . ' LEFT JOIN #__components AS c ON m.componentid = c.id' . ' WHERE m.published = 1 ' . ' ORDER BY m.sublevel, m.parent, m.ordering'; $db->setQuery($sql); // get untranslated menus first // run through the translation code so that we get the correct reftablearray $registry =& JFactory::getConfig(); $defLang = $registry->getValue("config.defaultlang"); // done as array of one item so that joomla core menu code will work with it if (!($menu = $db->loadObjectList('id', true, $defLang))) { JError::raiseWarning('SOME_ERROR_CODE', "Error loading Menus: " . $db->getErrorMsg()); return false; } $instance["raw"] = array("rows" => $menu, "tableArray" => $db->_getRefTables(), "originals" => $currentLangMenuItems); shSetupMenuRoutes($instance["raw"]["rows"]); // This is really annoying in PHP5 - an array of stdclass objects is copied as an array of references // I tried doing this as a stdclass and cloning but it didn't seek to work. $instance["raw"] = serialize($instance["raw"]); $defLang = $registry->getValue("config.jflang"); $instance[$defLang] = unserialize($instance["raw"]); } if (!isset($instance[$lang])) { $instance[$lang] = unserialize($instance["raw"]); // Do not cache here since it can affect SEF components JLoader::import('helper', JPATH_ROOT . DS . 'modules' . DS . 'mod_jflanguageselection', 'jfmodule'); JoomFish::translateList($instance[$lang]["rows"], $lang, $instance[$lang]["tableArray"]); shSetupMenuRoutes($instance[$lang]["rows"]); } if ($getOriginals) { return $instance[$lang]["originals"]; } else { return $instance[$lang]["rows"]; } }
/** * Load a list of database objects * @param string The field name of a primary key * @return array If <var>key</var> is empty as sequential list of returned TRANSLATED records. * If <var>key</var> is not empty then the returned array is indexed by the value * the database key. Returns <var>null</var> if the query fails. */ function loadObjectList($key = '', $translate = true, $language = null) { global $_JOOMFISH_MANAGER; if (!$translate) { $this->_skipSetRefTables = true; $result = parent::loadObjectList($key); $this->_skipSetRefTables = false; return $result; } $result = parent::loadObjectList($key); if (isset($_JOOMFISH_MANAGER)) { $this->_setLanguage($language); } // TODO check the impact of this on frontend translation // It does stop Joomfish plugins from working on missing translations e.g. regional content so disable for now // Don't do it for now since translation caching is so effective /* $registry =& JFactory::getConfig(); $defaultLang = $registry->getValue("config.defaultlang"); if ($defaultLang == $language){ $translate = false; } */ if (isset($_JOOMFISH_MANAGER)) { $doTranslate = false; $tables = $this->_getRefTables(); if ($tables == null) { return $result; } // an unstranslatable query to return result as is // if we don't have "fieldTablePairs" then we can't translate if (!array_key_exists("fieldTablePairs", $tables)) { return $result; } foreach ($tables["fieldTablePairs"] as $i => $table) { if ($this->translatedContentAvailable($table)) { $doTranslate = true; break; } } if ($doTranslate) { $pfunc = $this->_profile(); if ($_JOOMFISH_MANAGER->getCfg("transcaching", 1)) { // cache the results // TODO call based on config //$cache = &JFactory::getCache('jfquery'); $cache = $_JOOMFISH_MANAGER->getCache($language); $this->orig_limit = $this->_limit; $this->orig_offset = $this->_offset; $result = $cache->get(array("JoomFish", 'translateListCached'), array($result, $language, $this->_getRefTables())); $this->orig_limit = 0; $this->orig_offset = 0; } else { $this->orig_limit = $this->_limit; $this->orig_offset = $this->_offset; JoomFish::translateList($result, $language, $this->_getRefTables()); $this->orig_limit = 0; $this->orig_offset = 0; } $pfunc = $this->_profile($pfunc); } } return $result; }
/** * Load a list of database objects * @param string The field name of a primary key * @return array If <var>key</var> is empty as sequential list of returned TRANSLATED records. * If <var>key</var> is not empty then the returned array is indexed by the value * the database key. Returns <var>null</var> if the query fails. */ function loadObjectList($key = '', $translate = true, $language = null) { global $mosConfig_lang, $_JOOMFISH_MANAGER; if ($language === null) { $jlang =& JFactory::getLanguage(); $language = $jlang->getTag(); } $result = $this->_db->loadObjectList($key); if ($translate && isset($_JOOMFISH_MANAGER)) { $doTranslate = false; $tables = $this->_getRefTables(); if ($tables == null) { return $result; } // an unstranslatable query to return result as is foreach ($tables["fieldTablePairs"] as $i => $table) { if ($this->translatedContentAvailable($table)) { $doTranslate = true; break; } } if ($doTranslate) { JoomFish::translateList($result, $this->_getTableName(), $language, $this->_getRefTables()); } } return $result; }
public function loadObjectList($key = '', $class = "stdClass", $translate = true, $language = null, $asObject = true, $onlytransFields = true) { $this->translate = $translate; if ($this->skipjf || $translate === false) { return parent::loadObjectList($key, $class); } $pfunc = $this->profile(); // we can't call the query twice! if (!($cur = $this->query())) { return null; } $fields = array(); if (!$this->doTranslate($fields)) { $array = array(); while ($row = mysqli_fetch_object($cur, $class)) { if ($key) { $array[$row->{$key}] = $row; } else { $array[] = $row; } } mysqli_free_result($cur); return $array; } $jfdata = array(); if ($key != "") { while ($row = mysqli_fetch_array($cur, MYSQLI_BOTH)) { $jfdata[$row[$key]] = $row; } } else { while ($row = mysqli_fetch_array($cur, MYSQLI_BOTH)) { $jfdata[] = $row; } } if (count($jfdata) == 0) { return $jfdata; } // Before joomfish manager is created since we can't translate so skip this anaylsis $jfManager = JoomFishManager::getInstance(); if (!$jfManager) { return $jfdata; } if (isset($jfManager)) { $this->setLanguage($language); } if ($jfManager->getCfg("transcaching", 1)) { $this->orig_limit = $this->get("limit"); $this->orig_offset = $this->get("offset"); // cache the results // special Joomfish database cache // $cache = $jfManager->getCache($language); // $jfdata = $cache->get(array("JoomFish", 'translateListArrayCached'), array($jfdata, $language, $fields)); $cache = JFactory::getCache('com_joomfish', 'callback'); $jfdata = $cache->get("JoomFish::translateListArrayCached", array(&$jfdata, $language, $fields, $onlytransFields)); $this->orig_limit = 0; $this->orig_offset = 0; } else { $this->orig_limit = $this->get("limit"); $this->orig_offset = $this->get("offset"); JoomFish::translateListArray($jfdata, $language, $fields, $onlytransFields); $this->orig_limit = 0; $this->orig_offset = 0; } mysqli_free_result($cur); if ($asObject) { $array = array(); foreach ($jfdata as $row) { $obj = new stdClass(); $fieldcount = 0; foreach ($fields as $field) { $fieldname = $field->name; $obj->{$fieldname} = $row[$fieldcount]; $fieldcount++; } if ($key) { $array[$obj->{$key}] = $obj; } else { $array[] = $obj; } } $pfunc = $this->profile($pfunc); return $array; } $pfunc = $this->profile($pfunc); return $jfdata; }
/** * Function to translate list of elements where the data is stord in Joomla native tables using language flag * @param array $rows * @param string $ids * @param string $reference_table * @param JFLanguage $language * @param string $refTablePrimaryKey * @param array $tableArray * @param string $querySQL * @param boolean $allowfallback */ public static function nativeTranslateListArrayWithIDs(&$rows, $ids, $reference_table, $tablealias, $language, $keycol, $idkey, &$fielddata, $querySQL, $allowfallback = true, $onlytransFields = true) { $registry = JFactory::getConfig(); $defaultLang = $registry->getValue("config.defaultlang"); $language = isset($language) && $language != '' ? $language : $defaultLang; $db = JFactory::getDBO(); // setup Joomfish pluginds $dispatcher = JDispatcher::getInstance(); JPluginHelper::importPlugin('joomfish'); $results = $dispatcher->trigger('onBeforeTranslation', array(&$rows, $ids, $reference_table, $tablealias, $language, $keycol, $idkey, &$fielddata, $querySQL, $allowfallback, $onlytransFields)); // if onBeforeTranslation has cleaned out the list then just return at this point if (strlen($ids) == 0) { return; } static $languages; if (!isset($languages)) { $jfm = JoomFishManager::getInstance(); $languages = $jfm->getLanguagesIndexedByCode(); } // process fallback language $fallbacklanguage = false; $fallbackrows = array(); $fallbackids = array(); if (isset($languages[$language]) && $languages[$language]->fallback_code != "") { $fallbacklanguage = $languages[$language]->fallback_code; if (!array_key_exists($fallbacklanguage, $languages)) { $allowfallback = false; } } if (!$fallbacklanguage) { $allowfallback = false; } if (isset($ids) && $reference_table != '') { $user = JFactory::getUser(); // NEW SYSTEM - check for published state of translation e.g. using mapping table! // Need to know the published column name!!! $jfm = JoomFishManager::getInstance(); $published = $jfm->getContentElement($reference_table)->getPublishedField(); $published = $user->authorise('core.publish', 'com_joomfish') ? "\n\tAND {$published}=1" : ""; $sql = "SELECT tab.*, tmap.reference_id, tmap.translation_id FROM #__{$reference_table} as tab" . "\n LEFT JOIN #__jf_translationmap AS tmap ON tmap.reference_table = " . $db->quote($reference_table) . " AND tmap.translation_id = tab.{$idkey} AND tmap.language= " . $db->quote($languages[$language]->code) . "\n WHERE tmap.reference_id IN({$ids})" . $published . "\n AND tmap.reference_id IS NOT NULL "; $db->setQuery($sql); $translations = $db->loadObjectList("reference_id", 'stdClass', false); if (count($translations) > 0) { $fieldmap = null; $rowsToUnset = array(); foreach (array_keys($rows) as $key) { // assign by reference since not an object $row_to_translate =& $rows[$key]; $rowTranslationExists = false; $refid = $row_to_translate[$keycol]; if (array_key_exists($refid, $translations)) { $rowTranslationExists = true; $translation = $translations[$refid]; // go on only it this is the matching row if ($translation->reference_id == $refid) { $row_to_translate['original_id'] = $refid; foreach ($fielddata[$tablealias]["fields"] as $fieldcount => $field) { $fieldname = $field->orgname; $transTest = $onlytransFields && !$db->testTranslateableFields($reference_table, array($field->orgname)) ? false : true; if (isset($translation->{$fieldname}) && $transTest) { $row_to_translate[$fieldcount] = $translation->{$fieldname}; } } $rowsToUnset[] = $translation->translation_id; // we cannot unset here as this foreach will set index again if unset element comes after current one! } } if (!$rowTranslationExists) { if ($allowfallback && isset($row_to_translate[$keycol])) { $fallbackrows[$key] =& $row_to_translate; $fallbackids[$key] = $row_to_translate[$keycol]; } else { //$results = $dispatcher->trigger('onMissingTranslation', array (&$row_to_translate, $language,$reference_table, $fielddata, $querySQL)); } } } // loop again and remove duplicates // @todo try to merge above loops foreach (array_keys($rows) as $key) { if (in_array($rows[$key][$keycol], $rowsToUnset)) { unset($rows[$key]); } } } else { foreach (array_keys($rows) as $key) { // assign by reference since not an object $row_to_translate =& $rows[$key]; if ($allowfallback && isset($row_to_translate[$keycol])) { $fallbackrows[$key] =& $row_to_translate; $fallbackids[$key] = $row_to_translate[$keycol]; } else { //$results = $dispatcher->trigger('onMissingTranslation', array (&$row_to_translate, $language,$reference_table, $fielddata, $querySQL)); } } } if ($allowfallback && count($fallbackrows) > 0) { $fallbackids = implode($fallbackids, ","); JoomFish::nativeTranslateListArrayWithIDs($fallbackrows, $fallbackids, $reference_table, $tablealias, $fallbacklanguage, $keycol, $idkey, $fielddata, $querySQL, false, $onlytransFields); } $dispatcher->trigger('onAfterTranslation', array(&$rows, $ids, $reference_table, $language, $keycol, $idkey, &$fielddata, $querySQL, $allowfallback, $onlytransFields)); } }