Page MenuHomeIn-Portal Phabricator

categories_item.php
No OneTemporary

File Metadata

Created
Fri, Oct 10, 12:23 AM

categories_item.php

<?php
/**
* @version $Id: categories_item.php 16513 2017-01-20 14:10:53Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CategoriesItem extends kDBItem
{
/**
* Builds parent path for this category
*
* @return Array
* @access public
*/
public function buildParentBasedFields()
{
static $parent_cache = Array (
0 => 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->Application->getUnitOption($this->Prefix, 'TableName') . '
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->Application->getUnitOption($this->Prefix, 'TitleField');
$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->Application->getUnitOption($this->Prefix, 'TitleField');
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);
}
}

Event Timeline