Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F772222
cat_dbitem.php
No One
Temporary
Actions
Download 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 1, 5:54 AM
Size
17 KB
Mime Type
text/x-php
Expires
Mon, Feb 3, 5:54 AM (3 h, 50 m)
Engine
blob
Format
Raw Data
Handle
555753
Attached To
rINP In-Portal
cat_dbitem.php
View Options
<?php
/**
* @version $Id: cat_dbitem.php 14439 2011-07-08 10:04:42Z 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
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
)
{
$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
()
{
if
(
$this
->
GetDBField
(
'CategoryId'
)
<=
0
)
{
// set primary category in item object
$this
->
SetDBField
(
'CategoryId'
,
$this
->
Application
->
GetVar
(
'm_cat_id'
));
}
$this
->
assignToCategory
(
$this
->
GetDBField
(
'CategoryId'
),
true
);
}
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
?
(
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
?
(
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
);
}
}
Event Timeline
Log In to Comment