Array ('ParentPath' => '|', 'NamedParentPath' => '', 'CachedTemplate' => ''), ); /** @var kMultiLanguageHelper $ml_helper */ $ml_helper = $this->Application->recallObject('kMultiLanguageHelper'); $languages = $ml_helper->getLanguages(); $parent_id = $this->GetDBField('ParentId'); if ( !isset($parent_cache[$parent_id]) ) { $select_fields = Array ('ParentPath', 'NamedParentPath', 'Template', 'CachedTemplate'); foreach ($languages as $language_id) { $select_fields[] = 'l' . $language_id . '_Name'; $select_fields[] = 'l' . $language_id . '_CachedNavbar'; } $sql = 'SELECT ' . implode(', ', $select_fields) . ' FROM ' . $this->getUnitConfig()->getTableName() . ' WHERE CategoryId = ' . $parent_id; $parent_cache[$parent_id] = $this->Conn->GetRow($sql); } $named_parent_path = trim($parent_cache[$parent_id]['NamedParentPath'] . '/' . $this->GetDBField('Filename'), '/'); $cached_template = $this->GetDBField('Template') == CATEGORY_TEMPLATE_INHERIT ? $parent_cache[$parent_id]['CachedTemplate'] : $this->GetDBField('Template'); // maybe also build CachedNavbar field here $ret = Array ( 'ParentPath' => $parent_cache[$parent_id]['ParentPath'] . $this->GetID() . '|', 'NamedParentPath' => $named_parent_path, 'NamedParentPathHash' => kUtil::crc32(mb_strtolower(preg_replace('/^Content\//i', '', $named_parent_path))), 'CachedTemplate' => $cached_template, 'CachedTemplateHash' => kUtil::crc32(mb_strtolower($cached_template)), ); $primary_language = $this->Application->GetDefaultLanguageId(); foreach ($languages as $language_id) { $language_prefix = 'l' . $language_id . '_'; $cached_navbar = $parent_cache[$parent_id][$language_prefix . 'CachedNavbar'] . '&|&'; $cached_navbar .= $this->GetDBField($language_prefix . 'Name') ? $this->GetDBField($language_prefix . 'Name') : $this->GetDBField('l' . $primary_language . '_Name'); $ret['l' . $language_id . '_CachedNavbar'] = $cached_navbar; } return $ret; } /** * replace not allowed symbols with "_" chars + remove duplicate "_" chars in result * * @param string $string * @return string * @access protected */ protected function stripDisallowed($string) { /** @var kFilenamesHelper $filenames_helper */ $filenames_helper = $this->Application->recallObject('FilenamesHelper'); $string = $filenames_helper->replaceSequences($string); return $this->checkAutoFilename($string); } public function checkFilename() { if ( $this->GetDBField('AutomaticFilename') ) { // filename will be generated from scratch, don't check anything here return; } elseif ( $this->GetDBField('Type') == PAGE_TYPE_TEMPLATE ) { // system page with AutomaticFilename checkbox unchecked -> compatibility with Proj-CMS <= 4.3.9 (when "/" were allowed in Filename) return; } $filename = $this->GetDBField('Filename'); $this->SetDBField('Filename', $this->stripDisallowed($filename)); } protected function checkAutoFilename($filename) { static $current_theme = null; if (!$filename) { return $filename; } if (!isset($current_theme)) { /** @var kThemesHelper $themes_helper */ $themes_helper = $this->Application->recallObject('ThemesHelper'); $current_theme = (int)$themes_helper->getCurrentThemeId(); } $escape_char = $this->Application->ConfigValue('FilenameSpecialCharReplacement'); $item_id = !$this->GetID() ? 0 : $this->GetID(); $item_theme = $this->GetDBField('ThemeId'); if (!$item_theme) { // user creates category manually, that's why ThemeId = 0 -> use current admin theme instead $item_theme = $current_theme; } $unique_clause = '(Filename = %s) AND (ThemeId = ' . $item_theme . ' OR ThemeId = 0) AND (ParentId = ' . $this->GetDBField('ParentId') . ')'; $sql_mask = ' SELECT ' . $this->IDField . ' FROM %s WHERE ' . sprintf($unique_clause, $this->Conn->qstr($filename)); // check temp table $sql_temp = sprintf($sql_mask, $this->TableName); $found_temp_ids = $this->Conn->GetCol($sql_temp); // check live table $sql_live = sprintf($sql_mask, $this->Application->GetLiveName($this->TableName)); $found_live_ids = $this->Conn->GetCol($sql_live); $found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) ); $has_page = preg_match('/(.*)_([\d]+)([a-z]*)$/', $filename, $rets); $duplicates_found = (count($found_item_ids) > 1) || ($found_item_ids && $found_item_ids[0] != $item_id); if ($duplicates_found || $has_page) {// other category has same filename as ours OR we have filename, that ends with _number $append = $duplicates_found ? $escape_char . 'a' : ''; if ($has_page) { $filename = $rets[1].'_'.$rets[2]; $append = $rets[3] ? $rets[3] : $escape_char . 'a'; } // check live & temp table $sql_temp = ' SELECT ' . $this->IDField . ' FROM ' . $this->TableName . ' WHERE ' . $unique_clause . ' AND (' . $this->IDField . ' != ' . $item_id . ')'; $sql_live = ' SELECT ' . $this->IDField . ' FROM ' . $this->Application->GetLiveName($this->TableName) . ' WHERE ' . $unique_clause . ' AND (' . $this->IDField . ' != ' . $item_id . ')'; while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 || $this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 ) { if (mb_substr($append, -1) == 'z') $append .= 'a'; $append = mb_substr($append, 0, mb_strlen($append) - 1) . chr( ord( mb_substr($append, -1) ) + 1 ); } return $filename . $append; } return $filename; } /** * Generate item's filename based on it's title field value * * @return void * @access public */ public function generateFilename() { if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) { return ; } /** @var kMultiLanguage $ml_formatter */ $ml_formatter = $this->Application->recallObject('kMultiLanguage'); $name = $this->stripDisallowed( $this->GetDBField($ml_formatter->LangFieldName('Name', true)) ); if ( $name != $this->GetDBField('Filename') ) { $this->SetDBField('Filename', $name); } } /** * Allows to detect if root category being edited * * @return int * @access public */ public function IsRoot() { return $this->Application->RecallVar('IsRootCategory_'.$this->Application->GetVar('m_wid')); } /** * Sets correct name to Home category while editing it * * @return bool * @access public */ public function IsNewItem() { if ( $this->IsRoot() && $this->Prefix == 'c' ) { $title_field = $this->getUnitConfig()->getTitleField(); $category_name = $this->Application->Phrase(($this->Application->isAdmin ? 'la_' : 'lu_') . 'rootcategory_name'); $this->SetDBField($title_field, $category_name); return false; } return parent::IsNewItem(); } /** * Sets new name for item in case if it is being copied in same table * * @param array $master Table data from TempHandler * @param int $foreign_key ForeignKey value to filter name check query by * @param string $title_field FieldName to alter, by default - TitleField of the prefix * @param string $format sprintf-style format of renaming pattern, by default Copy %1$s of %2$s which makes it Copy [Number] of Original Name * @access public */ public function NameCopy($master=null, $foreign_key=null, $title_field=null, $format='Copy %1$s of %2$s') { if (!isset($title_field)) { $title_field = $this->getUnitConfig()->getTitleField(); if (!$title_field || isset($this->CalculatedFields[$title_field]) ) return; } $new_name = $this->GetDBField($title_field); $cat_id = $this->Application->GetVar('m_cat_id'); $this->SetDBField('ParentId', $cat_id); $original_checked = false; do { if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) { $new_name = 'Copy '.($regs[1]+1).' of '.$regs[2]; } elseif ($original_checked) { $new_name = 'Copy of '.$new_name; } // if we are cloning in temp table this will look for names in temp table, // since object' TableName contains correct TableName (for temp also!) // if we are cloning live - look in live $query = ' SELECT ' . $title_field . ' FROM ' . $this->TableName . ' WHERE ParentId = ' . (int)$cat_id . ' AND ' . $title_field . ' = ' . $this->Conn->qstr($new_name); $foreign_key_field = getArrayValue($master, 'ForeignKey'); $foreign_key_field = is_array($foreign_key_field) ? $foreign_key_field[ $master['ParentPrefix'] ] : $foreign_key_field; if ($foreign_key_field && isset($foreign_key)) { $query .= ' AND '.$foreign_key_field.' = '.$foreign_key; } $res = $this->Conn->GetOne($query); /*// if not found in live table, check in temp table if applicable if ($res === false && $object->Special == 'temp') { $query = 'SELECT '.$name_field.' FROM '.$this->GetTempName($master['TableName']).' WHERE '.$name_field.' = '.$this->Conn->qstr($new_name); $res = $this->Conn->GetOne($query); }*/ $original_checked = true; } while ($res !== false); $this->SetDBField($title_field, $new_name); } }