Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F802138
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Feb 22, 5:12 AM
Size
37 KB
Mime Type
text/x-diff
Expires
Mon, Feb 24, 5:12 AM (1 h, 56 m)
Engine
blob
Format
Raw Data
Handle
573067
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.1.x/core/kernel/db/cat_dbitem.php
===================================================================
--- branches/5.1.x/core/kernel/db/cat_dbitem.php (revision 14393)
+++ branches/5.1.x/core/kernel/db/cat_dbitem.php (revision 14394)
@@ -1,605 +1,600 @@
<?php
/**
* @version $Id$
* @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 kCatDBItem extends kDBItem {
/**
* Category path, needed for import
*
* @var Array
*/
var $CategoryPath = Array();
/**
* Use automatic filename generation
*
* @var bool
*/
var $useFilenames = true;
/**
* Use pending editing abilities during item (delegated by permissions)
*
* @var bool
*/
var $usePendingEditing = false;
function Clear($new_id = null)
{
parent::Clear($new_id);
$this->CategoryPath = Array();
}
/**
* Set's prefix and special
*
* @param string $prefix
* @param string $special
* @access public
*/
function Init($prefix, $special, $event_params = null)
{
parent::Init($prefix, $special, $event_params);
$this->usePendingEditing = $this->Application->getUnitOption($this->Prefix, 'UsePendingEditing');
}
function Create($force_id = false, $system_create = false)
{
- // TODO: move to OnBeforeItemCreate method
- if ($this->useFilenames) {
- $this->checkFilename();
- $this->generateFilename();
- }
-
$ret = parent::Create($force_id, $system_create);
if ($ret) {
// TODO: move to OnAfterItemCreate method
$this->assignPrimaryCategory();
}
+
return $ret;
}
/**
* Assigns primary category for the item
*
* @access public
*/
function assignPrimaryCategory()
{
$primary_category = $this->GetDBField('CategoryId') > 0 ? $this->GetDBField('CategoryId') : $this->Application->GetVar('m_cat_id');
$this->assignToCategory($primary_category, true);
$this->SetDBField('CategoryId', $primary_category); // set primary category in item object
}
function Update($id=null, $system_update=false)
{
$this->VirtualFields['ResourceId'] = Array();
if ($this->GetChangedFields()) {
$now = adodb_mktime();
$this->SetDBField('Modified_date', $now);
$this->SetDBField('Modified_time', $now);
$this->SetDBField('ModifiedById', $this->Application->RecallVar('user_id'));
}
if ($this->useFilenames) {
$this->checkFilename();
$this->generateFilename();
}
$ret = parent::Update($id, $system_update);
if ($ret) {
- $filename = $this->useFilenames ? $this->GetDBField('Filename') : '';
+ $filename = $this->useFilenames ? (string)$this->GetDBField('Filename') : '';
$sql = 'UPDATE '.$this->CategoryItemsTable().'
SET Filename = '.$this->Conn->qstr($filename).'
WHERE ItemResourceId = '.$this->GetDBField('ResourceId');
$this->Conn->Query($sql);
}
unset($this->VirtualFields['ResourceId']);
return $ret;
}
/**
* Returns CategoryItems table based on current item mode (temp/live)
*
* @return string
*/
function CategoryItemsTable()
{
$table = TABLE_PREFIX.'CategoryItems';
if ($this->Application->IsTempTable($this->TableName)) {
$table = $this->Application->GetTempName($table, 'prefix:'.$this->Prefix);
}
return $table;
}
function checkFilename()
{
if( !$this->GetDBField('AutomaticFilename') )
{
$filename = $this->GetDBField('Filename');
$this->SetDBField('Filename', $this->stripDisallowed($filename) );
}
}
function Copy($cat_id=null)
{
if (!isset($cat_id)) $cat_id = $this->Application->GetVar('m_cat_id');
$this->NameCopy($cat_id);
return $this->Create($cat_id);
}
function NameCopy($master=null, $foreign_key=null)
{
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
if (!$title_field) return;
$new_name = $this->GetDBField($title_field);
$cat_id = (int)$this->Application->GetVar('m_cat_id');
$original_checked = false;
do {
if ( preg_match('/Copy ([0-9]*) *of (.*)/', $new_name, $regs) ) {
$new_name = 'Copy '.( (int)$regs[1] + 1 ).' of '.$regs[2];
}
elseif ($original_checked) {
$new_name = 'Copy of '.$new_name;
}
$query = 'SELECT '.$title_field.' FROM '.$this->TableName.'
LEFT JOIN '.TABLE_PREFIX.'CategoryItems ON
('.TABLE_PREFIX.'CategoryItems.ItemResourceId = '.$this->TableName.'.ResourceId)
WHERE ('.TABLE_PREFIX.'CategoryItems.CategoryId = '.$cat_id.') AND '.
$title_field.' = '.$this->Conn->qstr($new_name);
$res = $this->Conn->GetOne($query);
$original_checked = true;
} while ($res !== false);
$this->SetDBField($title_field, $new_name);
// this is needed, because Create will create items in its own CategoryId (if it's set),
// but we need to create it in target Paste category @see{kCatDBItem::Create} and its primary_category detection
$this->SetDBField('CategoryId', $cat_id);
}
/**
* Changes item primary category to given/current category
*
* @param int $category_id
*/
function MoveToCat($category_id = null)
{
// $this->NameCopy();
if (!isset($category_id)) {
$category_id = $this->Application->GetVar('m_cat_id');
}
$table_name = TABLE_PREFIX . 'CategoryItems';
if ($this->IsTempTable()) {
$table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix);
}
// check if the item already exists in destination category
$sql = 'SELECT PrimaryCat
FROM ' . $table_name . '
WHERE (CategoryId = ' . (int)$category_id . ') AND (ItemResourceId = ' . $this->GetDBField('ResourceId') . ')';
$is_primary = $this->Conn->GetOne($sql);
// if it's not found is_primary will be FALSE, if it's found but not primary it will be int 0
$exists = $is_primary !== false;
if ($exists) {
// if the item already exists in destination category
if ($is_primary) {
// do nothing when we paste to primary
return ;
}
// if it's not primary - delete it from destination category, as we will move it from current primary below
$sql = 'DELETE FROM ' . $table_name . '
WHERE (CategoryId = ' . (int)$category_id . ') AND (ItemResourceId = ' . $this->GetDBField('ResourceId') . ')';
$this->Conn->Query($sql);
}
// change category id in existing primary category record
$sql = 'UPDATE ' . $table_name . '
SET CategoryId = ' . (int)$category_id . '
WHERE (ItemResourceId = ' . $this->GetDBField('ResourceId') . ') AND (PrimaryCat = 1)';
$this->Conn->Query($sql);
$this->Update();
}
/**
* When item is deleted, then also delete it from all categories
*
* @param int $id
* @return bool
*/
function Delete($id = null)
{
if( isset($id) ) {
$this->setID($id);
}
$this->Load($this->GetID());
$ret = parent::Delete();
if ($ret) {
// TODO: move to OnAfterItemDelete method
$query = ' DELETE FROM ' . $this->CategoryItemsTable() . '
WHERE ItemResourceId = ' . $this->GetDBField('ResourceId');
$this->Conn->Query($query);
}
return $ret;
}
/**
* Deletes item from categories
*
* @param Array $delete_category_ids
* @author Alex
*/
function DeleteFromCategories($delete_category_ids)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField'); // because item was loaded before by ResourceId
$ci_table = $this->Application->getUnitOption($this->Prefix.'-ci', 'TableName');
$resource_id = $this->GetDBField('ResourceId');
$item_cats_sql = 'SELECT CategoryId FROM %s WHERE ItemResourceId = %s';
$delete_category_items_sql = 'DELETE FROM %s WHERE ItemResourceId = %s AND CategoryId IN (%s)';
$category_ids = $this->Conn->GetCol( sprintf($item_cats_sql, $ci_table, $resource_id) );
$cats_left = array_diff($category_ids, $delete_category_ids);
if(!$cats_left)
{
$sql = 'SELECT %s FROM %s WHERE ResourceId = %s';
$ids = $this->Conn->GetCol( sprintf($sql, $id_field, $this->TableName, $resource_id) );
$temp =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->DeleteItems($this->Prefix, $this->Special, $ids);
}
else
{
$this->Conn->Query( sprintf($delete_category_items_sql, $ci_table, $resource_id, implode(',', $delete_category_ids) ) );
$sql = 'SELECT CategoryId FROM %s WHERE PrimaryCat = 1 AND ItemResourceId = %s';
$primary_cat_id = $this->Conn->GetCol( sprintf($sql, $ci_table, $resource_id) );
if( count($primary_cat_id) == 0 )
{
$sql = 'UPDATE %s SET PrimaryCat = 1 WHERE (CategoryId = %s) AND (ItemResourceId = %s)';
$this->Conn->Query( sprintf($sql, $ci_table, reset($cats_left), $resource_id ) );
}
}
}
/**
* replace not allowed symbols with "_" chars + remove duplicate "_" chars in result
*
* @param string $string
* @return string
*/
function stripDisallowed($filename)
{
$filenames_helper =& $this->Application->recallObject('FilenamesHelper');
$table = $this->mode == 't' ? $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems', 'prefix:'.$this->Prefix) : TABLE_PREFIX.'CategoryItems';
return $filenames_helper->stripDisallowed($table, 'ItemResourceId', $this->GetDBField('ResourceId'), $filename);
}
/* commented out because it's called only from stripDisallowed body, which is moved to helper
function checkAutoFilename($filename)
{
$filenames_helper =& $this->Application->recallObject('FilenamesHelper');
return $filenames_helper->checkAutoFilename($this->TableName, $this->IDField, $this->GetID(), $filename);
}*/
/**
* Generate item's filename based on it's title field value
*
* @return string
*/
function generateFilename()
{
if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) return false;
$title_field = $this->Application->getUnitOption($this->Prefix, 'TitleField');
if (preg_match('/l([\d]+)_(.*)/', $title_field, $regs)) {
// if title field is multilingual, then use it's name from primary language
$title_field = 'l'.$this->Application->GetDefaultLanguageId().'_'.$regs[2];
}
$name = $this->stripDisallowed( $this->GetDBField($title_field) );
if ( $name != $this->GetDBField('Filename') ) $this->SetDBField('Filename', $name);
}
/**
* Check if value is set for required field
*
* @param string $field field name
* @param Array $params field options from config
* @return bool
* @access private
*/
function ValidateRequired($field, $params)
{
$res = true;
if (getArrayValue($params, 'required')) {
$res = ( (string) $this->FieldValues[$field] != '');
}
if (!$res) {
$this->SetError($field, 'required');
}
return $res;
}
/**
* Adds item to other category
*
* @param int $category_id
* @param bool $is_primary
*/
function assignToCategory($category_id, $is_primary = false)
{
$table = $this->CategoryItemsTable();
$key_clause = '(ItemResourceId = '.$this->GetDBField('ResourceId').')';
// get all cateories, where item is in
$sql = 'SELECT PrimaryCat, CategoryId FROM '.$table.' WHERE '.$key_clause;
$item_categories = $this->Conn->GetCol($sql, 'CategoryId');
if (!$item_categories) {
$item_categories = Array();
$primary_found = false;
}
// find primary category
foreach ($item_categories as $item_category_id => $primary_found) {
if ($primary_found) {
break;
}
}
if ($primary_found && ($item_category_id == $category_id) && !$is_primary) {
// want to make primary category as non-primary :(
return true;
}
else if (!$primary_found) {
$is_primary = true;
}
if ($is_primary && $item_categories) {
// reset primary mark from all other categories
$sql = 'UPDATE '.$table.' SET PrimaryCat = 0 WHERE '.$key_clause;
$this->Conn->Query($sql);
}
// UPDATE & INSERT instead of REPLACE because CategoryItems table has no primary key defined in database
if (isset($item_categories[$category_id])) {
$sql = 'UPDATE '.$table.' SET PrimaryCat = '.($is_primary ? 1 : 0).' WHERE '.$key_clause.' AND (CategoryId = '.$category_id.')';
$this->Conn->Query($sql);
}
else {
$fields_hash = Array(
'CategoryId' => $category_id,
'ItemResourceId' => $this->GetField('ResourceId'),
'PrimaryCat' => $is_primary ? 1 : 0,
'ItemPrefix' => $this->Prefix,
- 'Filename' => $this->useFilenames ? $this->GetDBField('Filename') : '', // because some prefixes does not use filenames,
+ 'Filename' => $this->useFilenames ? (string)$this->GetDBField('Filename') : '', // because some prefixes does not use filenames,
);
$this->Conn->doInsert($fields_hash, $table);
}
// to ensure filename update after adding to another category
// this is critical since there may be an item with same filename in newly added category!
$this->Update();
}
/**
* Removes item from category specified
*
* @param int $category_id
*/
function removeFromCategory($category_id)
{
$sql = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems WHERE (CategoryId = %s) AND (ItemResourceId = %s)';
$this->Conn->Query( sprintf($sql, $category_id, $this->GetDBField('ResourceId')) );
}
/**
* Returns list of columns, that could exist in imported file
*
* @return Array
*/
function getPossibleExportColumns()
{
static $columns = null;
if (!is_array($columns)) {
$columns = array_merge($this->Fields['AvailableColumns']['options'], $this->Fields['ExportColumns']['options']);
}
return $columns;
}
/**
* Returns item's primary image data
*
* @return Array
*/
function getPrimaryImageData()
{
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'Images
WHERE (ResourceId = '.$this->GetDBField('ResourceId').') AND (DefaultImg = 1)';
$image_data = $this->Conn->GetRow($sql);
if (!$image_data) {
// 2. no primary image, then get image with name "main"
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'Images
WHERE (ResourceId = '.$this->GetDBField('ResourceId').') AND (Name = "main")';
$image_data = $this->Conn->GetRow($sql);
}
return $image_data;
}
function ChangeStatus($new_status, $pending_editing = false)
{
$status_field = array_shift( $this->Application->getUnitOption($this->Prefix,'StatusField') );
if ($new_status != $this->GetDBField($status_field)) {
// status was changed
$this->sendEmailEvents($new_status, $pending_editing);
}
$this->SetDBField($status_field, $new_status);
return $this->Update();
}
function sendEmailEvents($new_status, $pending_editing = false)
{
$owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
$event_name = $this->Application->getUnitOption($this->Prefix, 'PermItemPrefix');
if ($pending_editing) {
$event_name .= '.MODIFY';
}
$event_name .= $new_status == STATUS_ACTIVE ? '.APPROVE' : '.DENY';
$this->Application->EmailEventUser($event_name, $this->GetDBField($owner_field));
}
/**
* Approves changes made to category item
*
* @return bool
*/
function ApproveChanges()
{
$original_id = $this->GetDBField('OrgId');
if (!($this->usePendingEditing && $original_id)) {
// non-pending copy of original link
return $this->ChangeStatus(STATUS_ACTIVE);
}
if ($this->raiseEvent('OnBeforeDeleteOriginal', null, Array('original_id' => $original_id))) {
// delete original item, because changes made in pending copy (this item) got to be approved in this method
$temp_handler =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp_handler->DeleteItems($this->Prefix, $this->Special, Array($original_id));
$this->SetDBField('OrgId', 0);
return $this->ChangeStatus(STATUS_ACTIVE, true);
}
return false;
}
/**
* Decline changes made to category item
*
* @return bool
*/
function DeclineChanges()
{
$original_id = $this->GetDBField('OrgId');
if (!($this->usePendingEditing && $original_id)) {
// non-pending copy of original link
return $this->ChangeStatus(STATUS_DISABLED);
}
// delete this item, because changes made in pending copy (this item) will be declined in this method
$temp_handler =& $this->Application->recallObject($this->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp_handler->DeleteItems($this->Prefix, $this->Special, Array($this->GetID()));
$this->sendEmailEvents(STATUS_DISABLED, true);
// original item is not changed here, because it is already enabled (thrus pending copy is visible to item's owner or admin with permission)
return true;
}
function RegisterHit()
{
$already_viewed = $this->Application->RecallVar($this->getPrefixSpecial().'_already_viewed');
$already_viewed = $already_viewed ? unserialize($already_viewed) : Array ();
$id = $this->GetID();
if (!in_array($id, $already_viewed)) {
$property_map = $this->Application->getUnitOption($this->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return ;
}
$hits_field = $property_map['ClickField'];
$new_hits = $this->GetDBField($hits_field) + 1;
$sql = 'SELECT MAX('.$hits_field.')
FROM '.$this->TableName.'
WHERE FLOOR('.$hits_field.') = '.$new_hits;
$max_hits = $this->Conn->GetOne($sql);
if ($max_hits) {
$new_hits = $max_hits + 0.000001;
}
$fields_hash = Array (
$hits_field => $new_hits,
);
$this->Conn->doUpdate($fields_hash, $this->TableName, $this->IDField.' = '.$id);
array_push($already_viewed, $id);
$this->Application->StoreVar($this->getPrefixSpecial().'_already_viewed', serialize($already_viewed));
}
}
/**
* Returns part of SQL WHERE clause identifing the record, ex. id = 25
*
* @access public
* @param string $method Child class may want to know who called GetKeyClause, Load(), Update(), Delete() send its names as method
* @param Array $keys_hash alternative, then item id, keys hash to load item by
* @return void
* @see kDBItem::Load()
* @see kDBItem::Update()
* @see kDBItem::Delete()
*/
function GetKeyClause($method = null, $keys_hash = null)
{
if ($method == 'load') {
// for item with many categories makes primary to load
$ci_table = TABLE_PREFIX . 'CategoryItems';
if ($this->IsTempTable()) {
$ci_table = $this->Application->GetTempName($ci_table, 'prefix:' . $this->Prefix);
}
$primary_category_clause = Array ('`' . $ci_table . '`.`PrimaryCat`' => 1);
if (!isset($keys_hash)) {
$keys_hash = Array ($this->IDField => $this->ID);
}
// merge primary category clause in any case to be sure, that
// CategoryId field will always contain primary category of item
$keys_hash = array_merge($keys_hash, $primary_category_clause);
}
return parent::GetKeyClause($method, $keys_hash);
}
}
\ No newline at end of file
Index: branches/5.1.x/core/units/categories/categories_item.php
===================================================================
--- branches/5.1.x/core/units/categories/categories_item.php (revision 14393)
+++ branches/5.1.x/core/units/categories/categories_item.php (revision 14394)
@@ -1,275 +1,276 @@
<?php
/**
* @version $Id$
* @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
{
function Create($force_id = false, $system_create = false)
{
+ // set parent category first, so filename generation could use it
+ $parent_category = $this->GetDBField('ParentId') > 0 ? $this->GetDBField('ParentId') : $this->Application->GetVar('m_cat_id');
+ $this->SetDBField('ParentId', $parent_category);
+
$this->checkFilename();
$this->generateFilename();
if ($this->Validate()) {
// TODO: such approach will not respect changes from CategoryEventHandler::OnBeforeItemCreate event
$this->SetDBField('ResourceId', $this->Application->NextResourceId());
}
// TODO: move to CategoryEventHandler::OnBeforeItemCreate
$is_admin = $this->Application->isAdminUser;
if ((!$this->IsTempTable() && !$is_admin) || ($is_admin && !$this->GetDBField('CreatedById'))) {
$this->SetDBField('CreatedById', $this->Application->RecallVar('user_id'));
}
- $parent_category = $this->GetDBField('ParentId') > 0 ? $this->GetDBField('ParentId') : $this->Application->GetVar('m_cat_id');
- $this->SetDBField('ParentId', $parent_category);
-
$ret = parent::Create($force_id, $system_create);
if ($ret) {
// TODO: move to CategoryEventHandler::OnAfterItemCreate method
$sql = 'UPDATE %s SET ParentPath = %s WHERE CategoryId = %s';
$parent_path = $this->buildParentPath();
$this->Conn->Query( sprintf($sql, $this->TableName, $this->Conn->qstr($parent_path), $this->GetID() ) );
$this->SetDBField('ParentPath', $parent_path);
}
return $ret;
}
function Update($id=null, $system_update = false)
{
$this->checkFilename();
$this->generateFilename();
return parent::Update($id, $system_update);
}
function buildParentPath()
{
$parent_id = $this->GetDBField('ParentId');
if ($parent_id == 0) {
$parent_path = '|';
}
else {
$cat_table = $this->Application->getUnitOption($this->Prefix, 'TableName');
$sql = 'SELECT ParentPath FROM '.$cat_table.' WHERE CategoryId = %s';
$parent_path = $this->Conn->GetOne( sprintf($sql, $parent_id) );
}
return $parent_path.$this->GetID().'|';
}
/**
* replace not allowed symbols with "_" chars + remove duplicate "_" chars in result
*
* @param string $string
* @return string
*/
function stripDisallowed($string)
{
$filenames_helper =& $this->Application->recallObject('FilenamesHelper');
/* @var $filenames_helper kFilenamesHelper */
$string = $filenames_helper->replaceSequences($string);
return $this->checkAutoFilename($string);
}
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));
}
function checkAutoFilename($filename)
{
static $current_theme = null;
if (!$filename) {
return $filename;
}
if (!isset($current_theme)) {
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$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)';
- $check_in_parent_cat_only = $item_id ? ' AND ParentId = ' . $this->GetDBField('ParentId') : '';
+ $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 = ' SELECT ' . $this->IDField . '
- FROM ' . $this->TableName . '
- WHERE ' . sprintf($unique_clause, $this->Conn->qstr($filename)) . $check_in_parent_cat_only;
+ $sql_temp = sprintf($sql_mask, $this->TableName);
$found_temp_ids = $this->Conn->GetCol($sql_temp);
// check live table
- $sql_live = ' SELECT ' . $this->IDField . '
- FROM ' . $this->Application->GetLiveName($this->TableName) . '
- WHERE ' . sprintf($unique_clause, $this->Conn->qstr($filename)) . $check_in_parent_cat_only;
+ $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 string
*/
function generateFilename()
{
if ( !$this->GetDBField('AutomaticFilename') && $this->GetDBField('Filename') ) return false;
$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
*
* @param Array $params
*/
function IsRoot()
{
return $this->Application->RecallVar('IsRootCategory_'.$this->Application->GetVar('m_wid'));
}
/**
* Sets correct name to Home category while editing it
*
* @return bool
*/
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 beeing copied
* in same table
*
* @param array $master Table data from TempHandler
* @param int $foreign_key ForeignKey value to filter name check query by
* @access private
*/
function NameCopy($master=null, $foreign_key=null)
{
$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);
}
}
\ No newline at end of file
Index: branches/5.1.x/core/units/helpers/filenames_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/filenames_helper.php (revision 14393)
+++ branches/5.1.x/core/units/helpers/filenames_helper.php (revision 14394)
@@ -1,158 +1,183 @@
<?php
/**
* @version $Id$
* @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 kFilenamesHelper extends kHelper {
/**
* Character, that should replace disallowed symbols in filename
*
* @var string
*/
var $_escapeChar = '_';
/**
* Sequences, that should be replaced with mathing sequences from _filenameReplaceTo property
*
* @var Array
*/
var $_filenameReplaceFrom = Array ();
/**
* Sequences, that will replace matching sequences from _filenameReplaceFrom property
*
* @var Array
*/
var $_filenameReplaceTo = Array ();
function kFilenamesHelper()
{
parent::kHelper();
$this->_escapeChar = $this->Application->ConfigValue('FilenameSpecialCharReplacement');
$language =& $this->Application->recallObject('lang.primary');
/* @var $language kDBItem */
$replacements = $language->GetDBField('FilenameReplacements');
if ($replacements) {
$replacements = explode("\r\n", $replacements);
foreach ($replacements as $replacement) {
list ($replace_from, $replace_to) = explode('=', $replacement);
$this->_filenameReplaceFrom[] = trim($replace_from);
$this->_filenameReplaceTo[] = trim($replace_to);
}
}
}
function replaceSequences($filename)
{
$not_allowed = Array (
' ', '\\', '/', ':', '*', '?', '"', '<', '>', '|', '`',
'~', '!', '@', '#', '$', '%', '^', '&', '(', ')', '~',
'+', '=', '-', '{', '}', ']', '[', "'", ';', '.', ',', "\r", "\n"
);
if ($this->_filenameReplaceFrom) {
// replace predefined sequences
$filename = str_replace($this->_filenameReplaceFrom, $this->_filenameReplaceTo, $filename);
}
$filename = str_replace($not_allowed, $this->_escapeChar, $filename);
$filename = preg_replace('/(' . $this->_escapeChar . '+)/', $this->_escapeChar, $filename);
return trim($filename, $this->_escapeChar); // remove trailing escape chars
}
/**
* replace not allowed symbols with "_" chars + remove duplicate "_" chars in result
*
* @param string $string
* @return string
*/
function stripDisallowed($table, $id_field, $item_id, $filename)
{
$filename = $this->replaceSequences($filename);
return $this->checkAutoFilename($table, $id_field, $item_id, $filename);
}
function checkAutoFilename($table, $id_field, $item_id, $filename)
{
- if(!$filename) return $filename;
+ if (!$filename) {
+ return $filename;
+ }
$item_id = !$item_id ? 0 : $item_id;
- if ($table == TABLE_PREFIX.'CategoryItems') {
- $item_categories_cur = $this->Conn->GetCol('SELECT CategoryId FROM '.$table.' WHERE ItemResourceId = '.$item_id);
- $item_categories_live = $this->Application->IsTempTable($table) ? $this->Conn->GetCol('SELECT CategoryId FROM '.$this->Application->GetLiveName($table).' WHERE ItemResourceId = '.$item_id) : array();
+ if ( $this->Application->GetLiveName($table) == TABLE_PREFIX.'CategoryItems' ) {
+ $sql_mask = ' SELECT CategoryId
+ FROM %1$s
+ WHERE ItemResourceId = %2$s';
+
+ $item_categories_cur = $this->Conn->GetCol( sprintf($sql_mask, $table, $item_id) );
+
+ if ( $this->Application->IsTempTable($table) ) {
+ $item_categories_live = $this->Conn->GetCol( sprintf($sql_mask, $this->Application->GetLiveName($table), $item_id) );
+ }
+ else {
+ $item_categories_live = Array ();
+ }
$item_categories = array_unique(array_merge($item_categories_cur, $item_categories_live));
+
if (!$item_categories) {
- $item_categories = array($this->Application->GetVar('m_cat_id')); // this may happen when creating new item
+ $item_categories = Array( $this->Application->GetVar('m_cat_id') ); // this may happen when creating new item
}
- $cat_filter = ' AND CategoryId IN ('.implode(',', $item_categories).')';
+
+ $cat_filter = ' AND CategoryId IN (' . implode(',', $item_categories) . ')';
}
else {
$cat_filter = '';
}
// check current table (temp or live)
- $sql_temp = 'SELECT '.$id_field.' FROM '.$table.' WHERE Filename = '.$this->Conn->qstr($filename).$cat_filter;
- $found_temp_ids = $this->Conn->GetCol($sql_temp);
+ $sql_mask = ' SELECT ' . $id_field . '
+ FROM %1$s
+ WHERE Filename = ' . $this->Conn->qstr($filename) . $cat_filter;
+ $found_temp_ids = $this->Conn->GetCol( sprintf($sql_mask, $table) );
// check live table if current is temp
if ( $this->Application->IsTempTable($table) ) {
- $sql_live = 'SELECT '.$id_field.' FROM '.$this->Application->GetLiveName($table).' WHERE Filename = '.$this->Conn->qstr($filename).$cat_filter;
- $found_live_ids = $this->Conn->GetCol($sql_live);
+ $found_live_ids = $this->Conn->GetCol( sprintf($sql_mask, $this->Application->GetLiveName($table)) );
}
else {
- $found_live_ids = array();
+ $found_live_ids = Array ();
}
$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 ? '_a' : '';
- if($has_page)
- {
+ if ($duplicates_found || $has_page) {// other category has same filename as ours OR we have filename, that ends with _number
+ $append = $duplicates_found ? $this->_escapeChar . 'a' : '';
+
+ if ($has_page) {
$filename = $rets[1].'_'.$rets[2];
- $append = $rets[3] ? $rets[3] : '_a';
+ $append = $rets[3] ? $rets[3] : $this->_escapeChar . 'a';
}
// check live & temp table
- $sql_cur = 'SELECT '.$id_field.' FROM '.$table.' WHERE (Filename = %s) AND ('.$id_field.' != '.$item_id.')'.$cat_filter;
- $sql_live = $this->Application->IsTempTable($table) ? 'SELECT '.$id_field.' FROM '.$this->Application->GetLiveName($table).' WHERE (Filename = %s) AND ('.$id_field.' != '.$item_id.')'.$cat_filter : false;
+ $sql_cur = 'SELECT ' . $id_field . '
+ FROM ' . $table . '
+ WHERE (Filename = %s) AND (' . $id_field . ' != ' . $item_id . ')' . $cat_filter;
+
+ if ( $this->Application->IsTempTable($table) ) {
+ $sql_live = ' SELECT ' . $id_field . '
+ FROM ' . $this->Application->GetLiveName($table) . '
+ WHERE (Filename = %s) AND (' . $id_field . ' != ' . $item_id . ')' . $cat_filter;
+ }
+ else {
+ $sql_live = false;
+ }
+
while ( $this->Conn->GetOne( sprintf($sql_cur, $this->Conn->qstr($filename.$append)) ) > 0 ||
( $sql_live
&&
( $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;
}
}
\ No newline at end of file
Event Timeline
Log In to Comment