/** * Method to process string for URL safe value of the form data. * * @param array $field XML field which is being processed * @param string &$fieldValue Value of the field that needs to be processed * @param string &$allValues All values of the submitted form * @param object $translationTable Translation table object * * @return void */ public static function saveMenuPath($field, &$fieldValue, &$allValues, $translationTable) { // If there is no alias or path field, just return true. if (!array_key_exists('alias', $allValues) || !array_key_exists('path', $allValues)) { return; } $translationTableName = RTranslationTable::getTranslationsTableName($translationTable->table, ''); $originalTableName = $translationTable->table; // Get the aliases for the path from the node to the root node. $db = JFactory::getDbo(); $query = $db->getQuery(true)->select('COALESCE(translation.alias, original.alias) AS alias')->where('n.lft BETWEEN original.lft AND original.rgt')->order('original.lft'); $where = array(); $where[] = 'translation.rctranslations_language = ' . $db->q($allValues['rctranslations_language']); foreach ($translationTable->primaryKeys as $primaryKey) { if (!empty($allValues[$primaryKey])) { $where[] = 'translation.' . $db->qn($primaryKey) . ' = original.' . $db->qn($primaryKey); $query->where('n.' . $db->qn($primaryKey) . ' = ' . $db->q($allValues[$primaryKey])); } } $query->from($originalTableName . ' AS n, ' . $originalTableName . ' AS original LEFT JOIN ' . $translationTableName . ' AS translation ON ' . implode(' AND ', $where)); $db->setQuery($query); $segments = $db->loadColumn(); // Make sure to remove the root path if it exists in the list. if ($segments[0] == 'root') { array_shift($segments); } if (!empty($allValues['alias'])) { $segments[count($segments) - 1] = JFilterOutput::stringURLSafe($allValues['alias']); } // Build the path. $fieldValue = trim(implode('/', $segments), ' /\\'); }
/** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { $table = RedcoreHelpersTranslation::getTranslationTable(); $db = $this->getDbo(); $query = $db->getQuery(true); if (empty($table)) { $query->select('*')->from('#__extensions')->where('1=2'); return $query; } $query->select('o.*')->from($db->qn($table->table, 'o')); $columns = (array) $table->columns; foreach ($columns as $column) { $query->select($db->qn('t.' . $column, 't_' . $column)); } $query->select(array($db->qn('t.rctranslations_id'), $db->qn('t.rctranslations_language'), $db->qn('t.rctranslations_originals'), $db->qn('t.rctranslations_modified'), $db->qn('t.rctranslations_state'))); $leftJoinOn = array(); foreach ($table->primaryKeys as $primaryKey) { $leftJoinOn[] = 'o.' . $primaryKey . ' = t.' . $primaryKey; } if ($language = $this->getState('filter.language')) { $leftJoinOn[] = 't.rctranslations_language = ' . $db->q($language); } else { // We will return empty query $leftJoinOn[] = '1 = 2'; } $leftJoinOn = implode(' AND ', $leftJoinOn); $query->leftJoin($db->qn(RTranslationTable::getTranslationsTableName($table->table, ''), 't') . (!empty($leftJoinOn) ? ' ON ' . $leftJoinOn . '' : '')); // Filter search $search = $this->getState('filter.search_translations'); if (!empty($search)) { $search = $db->quote('%' . $db->escape($search, true) . '%'); $searchColumns = array(); foreach ($columns as $column) { $searchColumns[] = '(o.' . $column . ' LIKE ' . $search . ')'; $searchColumns[] = '(t.' . $column . ' LIKE ' . $search . ')'; } if (!empty($searchColumns)) { $query->where('(' . implode(' OR ', $searchColumns) . ')'); } } // Content Element filter $contentElement = RTranslationHelper::getContentElement($table->option, $table->xml); $filters = $contentElement->getTranslateFilter(); if (!empty($filters)) { foreach ($filters as $filter) { $query->where((string) $filter); } } // Ordering $orderList = $this->getState('list.ordering'); $directionList = $this->getState('list.direction'); $order = !empty($orderList) ? $orderList : 't.rctranslations_language'; $direction = !empty($directionList) ? $directionList : 'DESC'; $query->order($db->escape($order) . ' ' . $db->escape($direction)); return $query; }
/** * Constructor * * @param JDatabase &$db A database connector object * * @throws UnexpectedValueException */ public function __construct(&$db) { $this->_tableName = 'extension'; $this->_tbl_key = 'rctranslations_id'; $table = RedcoreHelpersTranslation::getTranslationTable(); $this->_tbl = RTranslationTable::getTranslationsTableName($table->table, ''); $this->_tableName = str_replace('#__', '', $this->_tbl); if (empty($this->_tbl) || empty($this->_tbl_key) && empty($this->_tbl_keys)) { throw new UnexpectedValueException(sprintf('Missing data to initialize %s table | id: %s', $this->_tbl, $this->_tbl_key)); } parent::__construct($db); // Initialise custom fields $this->loadCustomFields(); }
/** * Recursive method which go through every array and joins table if we have found the match * * @param array $parsedSql Parsed SQL in array format * @param array $translationTables List of translation tables * @param array &$foundTables Found replacement tables * @param array &$originalTables Found original tables used for creating unique alias * @param string $language Language tag you want to fetch translation from * @param string &$subQueryFound If sub query is found then we must parse end sql * * @return array Parsed query with added table joins if found */ public static function parseTableReplacements($parsedSql, $translationTables, &$foundTables, &$originalTables, $language, &$subQueryFound) { if (!empty($parsedSql) && is_array($parsedSql)) { // Replace all Tables and keys foreach ($parsedSql as $groupKey => $parsedGroup) { if (!empty($parsedGroup)) { $filteredGroup = array(); $filteredGroupEndPosition = array(); foreach ($parsedGroup as $tagKey => $tagValue) { $tableName = null; $newTagValue = null; if (!empty($tagValue['expr_type']) && $tagValue['expr_type'] == 'table' && !empty($tagValue['table'])) { $tableName = self::getNameIfIncluded($tagValue['table'], !empty($tagValue['alias']['name']) ? $tagValue['alias']['name'] : '', $translationTables, true, $groupKey); if (!empty($tableName)) { $newTagValue = $tagValue; $newTagValue['originalTableName'] = $tableName; $newTagValue['table'] = RTranslationTable::getTranslationsTableName($tableName, ''); $newTagValue['join_type'] = 'LEFT'; $newTagValue['ref_type'] = 'ON'; $alias = self::getUniqueAlias($tableName, $originalTables); if (!empty($newTagValue['alias']['name'])) { $alias = $newTagValue['alias']['name']; } $tagValue['alias'] = array('as' => true, 'name' => $alias, 'base_expr' => ''); $newTagValue['alias'] = array('as' => true, 'name' => self::getUniqueAlias($newTagValue['table'], $foundTables), 'originalName' => $alias, 'base_expr' => ''); $refClause = self::createParserJoinOperand($newTagValue['alias']['name'], '=', $newTagValue['alias']['originalName'], $translationTables[$tableName], $language); $newTagValue['ref_clause'] = $refClause; $foundTables[] = $newTagValue; $originalTables[$newTagValue['alias']['originalName']] = isset($originalTables[$newTagValue['alias']['originalName']]) ? $originalTables[$newTagValue['alias']['originalName']]++ : 1; } } elseif (!empty($tagValue['union_tree']) && is_array($tagValue['union_tree']) && in_array('UNION', $tagValue['union_tree'])) { $subQueryFound = true; $unionTree = array(); foreach ($tagValue['union_tree'] as $union) { $union = trim($union); if (!empty($union) && strtoupper($union) != 'UNION') { $parsedSubQuery = self::buildTranslationQuery(self::removeParenthesisFromStart($union)); $unionTree[] = !empty($parsedSubQuery) ? '(' . $parsedSubQuery . ')' : $union; } } $tagValue['base_expr'] = '(' . implode(' UNION ', $unionTree) . ')'; $tagValue['expr_type'] = 'const'; if (!empty($tagValue['sub_tree'])) { unset($tagValue['sub_tree']); } if (!empty($tagValue['join_type'])) { unset($tagValue['join_type']); } } elseif (!empty($tagValue['sub_tree'])) { if (!empty($tagValue['expr_type']) && $tagValue['expr_type'] == 'subquery') { $parsedSubQuery = self::buildTranslationQuery($tagValue['base_expr']); if (!empty($parsedSubQuery)) { $sqlParser = new RDatabaseSqlparserSqlparser($parsedSubQuery); $tagValue['sub_tree'] = $sqlParser->parsed; $tagValue['base_expr'] = $parsedSubQuery; $subQueryFound = true; } } elseif (!empty($tagValue['expr_type']) && in_array($tagValue['expr_type'], array('expression'))) { foreach ($tagValue['sub_tree'] as $subKey => $subTree) { // In case we have a Subquery directly under the expression we handle it separately if (!empty($subTree['expr_type']) && $subTree['expr_type'] == 'subquery') { // We need to remove brackets from the query or else the query will not be parsed properly $sqlBracketLess = self::removeParenthesisFromStart($subTree['base_expr']); $parsedSubQuery = self::buildTranslationQuery($sqlBracketLess); if (!empty($parsedSubQuery)) { $sqlParser = new RDatabaseSqlparserSqlparser($parsedSubQuery); $tagValue['sub_tree'][$subKey]['sub_tree'] = $sqlParser->parsed; $tagValue['sub_tree'][$subKey]['base_expr'] = '(' . $parsedSubQuery . ')'; $subQueryFound = true; } } elseif (!empty($tagValue['sub_tree'][$subKey]['sub_tree'])) { $tagValue['sub_tree'][$subKey]['sub_tree'] = self::parseTableReplacements($tagValue['sub_tree'][$subKey]['sub_tree'], $translationTables, $foundTables, $originalTables, $language, $subQueryFound); } } } else { $tagValue['sub_tree'] = self::parseTableReplacements($tagValue['sub_tree'], $translationTables, $foundTables, $originalTables, $language, $subQueryFound); } } if (!is_numeric($tagKey)) { $filteredGroup[$tagKey] = $tagValue; } else { $filteredGroup[] = $tagValue; } if (!empty($newTagValue)) { if (!empty($translationTables[$tableName]->tableJoinEndPosition)) { $filteredGroupEndPosition[] = $newTagValue; } else { $filteredGroup[] = $newTagValue; } } } foreach ($filteredGroupEndPosition as $table) { $filteredGroup[] = $table; } $parsedSql[$groupKey] = $filteredGroup; } } } return $parsedSql; }
/** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. */ public function save($data) { $translationTable = RedcoreHelpersTranslation::getTranslationTable(); $contentElement = RTranslationHelper::getContentElement($translationTable->option, $translationTable->xml); $translation = JFactory::getApplication()->input->get('translation', array(), 'array'); $original = JFactory::getApplication()->input->get('original', array(), 'array'); $id = !empty($data['rctranslations_id']) ? (int) $data['rctranslations_id'] : 0; $data = array_merge($data, $translation); $fieldsXml = $contentElement->getTranslateFields(); foreach ($fieldsXml as $field) { if ((string) $field['type'] == 'params' && (string) $field['translate'] == '1') { $fieldName = (string) $field['name']; $original[$fieldName] = $original['params_' . $fieldName]; $paramsChanged = false; if (!empty($data[$fieldName])) { $registry = new JRegistry(); $registry->loadString($original[$fieldName]); $originalParams = $registry->toArray(); foreach ($data[$fieldName] as $paramKey => $paramValue) { if (!isset($originalParams[$paramKey]) && $paramValue != '' || $originalParams[$paramKey] != $paramValue) { $paramsChanged = true; break; } } if ($paramsChanged) { $data[$fieldName] = json_encode($data[$fieldName]); } else { $data[$fieldName] = ''; } } } } $dispatcher = RFactory::getDispatcher(); /** @var RedcoreTableTranslation $table */ $table = $this->getTable(); if (empty($id)) { $db = $this->getDbo(); $query = $db->getQuery(true)->select('rctranslations_id')->from($db->qn(RTranslationTable::getTranslationsTableName($translationTable->table, '')))->where('rctranslations_language = ' . $db->q($data['rctranslations_language'])); foreach ($translationTable->primaryKeys as $primaryKey) { if (!empty($data[$primaryKey])) { $query->where($db->qn($primaryKey) . ' = ' . $db->q($data[$primaryKey])); } } $db->setQuery($query); $id = $db->loadResult(); } foreach ($translationTable->primaryKeys as $primaryKey) { $original[$primaryKey] = $data[$primaryKey]; } $isNew = true; // Load the row if saving an existing item. $table->load((int) $id); if ($table->rctranslations_modified) { $isNew = false; } $data['rctranslations_originals'] = RTranslationTable::createOriginalValueFromColumns($original, $translationTable->columns); // We run posthandler methods foreach ($fieldsXml as $field) { $postHandler = (string) $field['posthandler']; $fieldName = (string) $field['name']; if (!empty($postHandler) && (string) $field['translate'] == '1') { $postHandlerFunctions = explode(',', $postHandler); foreach ($postHandlerFunctions as $postHandlerFunction) { $postHandlerFunctionArray = explode('::', $postHandlerFunction); if (empty($postHandlerFunctionArray[1])) { $postHandlerFunctionArray[1] = $postHandlerFunctionArray[0]; $postHandlerFunctionArray[0] = 'RTranslationContentHelper'; $postHandlerFunction = 'RTranslationContentHelper::' . $postHandlerFunction; } if (method_exists($postHandlerFunctionArray[0], $postHandlerFunctionArray[1])) { call_user_func_array(array($postHandlerFunctionArray[0], $postHandlerFunctionArray[1]), array($field, &$data[$fieldName], &$data, $translationTable)); } } } } // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Prepare the row for saving $this->prepareTable($table); // Check the data. if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onContentBeforeSave event. $result = $dispatcher->trigger($this->event_before_save, array($this->option . '.' . $this->name, &$table, $isNew)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterSave event. $dispatcher->trigger($this->event_after_save, array($this->option . '.' . $this->name, &$table, $isNew)); $this->setState($this->getName() . '.id', $table->rctranslations_id); // Clear the cache $this->cleanCache(); return true; }
/** * Method to upload Content Element file. * * @return boolean True if successful, false otherwise. */ public function uploadContentElement() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $app = JFactory::getApplication(); $option = $app->input->getString('component'); $files = $app->input->files->get('redcoreContentElement', array(), 'array'); if (!empty($files)) { $uploadedFiles = RTranslationTable::uploadContentElement($option, $files); if (!empty($uploadedFiles)) { $app->enqueueMessage(JText::_('COM_REDCORE_CONFIG_TRANSLATIONS_UPLOAD_SUCCESS')); } } else { JFactory::getApplication()->enqueueMessage(JText::_('COM_REDCORE_CONFIG_TRANSLATIONS_UPLOAD_FILE_NOT_FOUND'), 'warning'); } $this->redirectAfterAction(); }
/** * Uninstall all Translation tables from database * * @return void */ protected function uninstallTranslations() { $class = get_called_class(); $extensionOption = strtolower(strstr($class, 'Installer', true)); $translationTables = RTranslationHelper::getInstalledTranslationTables(); if (!empty($translationTables)) { $db = JFactory::getDbo(); foreach ($translationTables as $translationTable => $translationTableParams) { if (method_exists('RTranslationTable', 'getTranslationsTableName') && ($class == 'Com_RedcoreInstallerScript' || $extensionOption == $translationTableParams->option)) { $newTable = RTranslationTable::getTranslationsTableName($translationTable, ''); try { RTranslationTable::removeExistingConstraintKeys($translationTable); $db->dropTable($newTable); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage(JText::sprintf('LIB_REDCORE_TRANSLATIONS_DELETE_ERROR', $e->getMessage()), 'error'); } } } } }
/** * Reset loaded tables * * @return void */ public static function resetLoadedTables() { self::$tablePrefix = ''; self::loadTables(); }
/** * Get status of the Content Element * * @return String Content Element Status */ public function getStatus() { $return = ''; if (empty($this->table)) { $return .= ' ' . JText::_('COM_REDCORE_CONFIG_TRANSLATIONS_CONTENT_ELEMENT_NOT_VALID_FILE'); } $fieldsTable = RTranslationTable::getTranslationsTableColumns($this->table); if (empty($fieldsTable)) { return JText::_('COM_REDCORE_CONFIG_TRANSLATIONS_CONTENT_ELEMENT_NOT_INSTALLED') . $return; } // Language is automatically added to the table if table exists $fieldsTable = RTranslationTable::removeFixedColumnsFromArray($fieldsTable); $fieldsXml = $this->getTranslateFields(); $fields = array(); foreach ($fieldsXml as $field) { $fields[(string) $field['name']] = (string) $field['name']; if ((string) $field['translate'] == '0') { unset($fieldsTable[(string) $field['name']]); unset($fields[(string) $field['name']]); continue; } foreach ($fieldsTable as $columnKey => $columnKeyValue) { $fields[$columnKey] = $columnKey; if ((string) $field['name'] == $columnKey) { unset($fieldsTable[$columnKey]); unset($fields[$columnKey]); } } } if (!empty($fields)) { $return .= ' ' . JText::_('COM_REDCORE_CONFIG_TRANSLATIONS_CONTENT_ELEMENT_FIELDS_MISSING') . implode(', ', $fields); } return JText::_('COM_REDCORE_CONFIG_TRANSLATIONS_CONTENT_ELEMENT_INSTALLED') . $return; }