2016-10-06 15:57:01 +00:00
< ? php
/**
* Project :
* Contenido Content Management System
*
* Description :
* Custom properties
*
* Requirements :
* @ con_php_req 5.0
*
*
* @ package Contenido Backend classes
* @ version 1.2
* @ author Timo A . Hummel
* @ copyright four for business AG < www . 4 fb . de >
* @ license http :// www . contenido . org / license / LIZENZ . txt
* @ link http :// www . 4 fb . de
* @ link http :// www . contenido . org
* @ since file available since contenido release <= 4.6
*
* { @ internal
* created 2003 - 12 - 21
* modified 2008 - 06 - 30 , Dominik Ziegler , add security fix
* modified 2009 - 09 - 27 , Dominik Ziegler , fixed wrong ( un ) escaping
* modified 2011 - 02 - 05 , Murat Purc , cleanup , formatting and documentation .
* modified 2011 - 03 - 14 , Murat Purc , adapted to new GenericDB , partly ported to PHP 5 , formatting
*
2019-07-03 11:58:28 +00:00
* $Id $ :
2016-10-06 15:57:01 +00:00
* }}
*
*/
if ( ! defined ( 'CON_FRAMEWORK' )) {
die ( 'Illegal call' );
}
/* Custom properties
* -----------------
*
* Custom properties are properties which can be assigned to virtually any element
* in Contenido and underlaying websites .
*
*
* Table structure
* ---------------
*
* Field Size Description
* ----- ---- -----------
* idproperty int ( 10 ) idproperty ( automatically handled by this class )
* itemtype varchar ( 32 ) Custom item type ( e . g . idcat , idart , idartlang , custom )
* itemid varchar ( 32 ) ID of the item
* type varchar ( 32 ) Property type
* name varchar ( 32 ) Property name
* value text Property value
* author varchar ( 32 ) Author ( md5 - hash of the username )
* created datetime Created date and time
* modified datetime Modified date and time
* modifiedby varchar ( 32 ) Modified by ( md5 - hash of the username )
*
*
* Example :
* --------
* A module needs to store custom properties for categories . Modifying the database
* would be a bad thing , since the changes might get lost during an upgrade or
* reinstall .
*
* If the custom property for a category would be the path to a category image ,
* we would fill a row as follows :
*
* itemtype : idcat
* itemid : < number of your category >
* type : category
* name : image
* value : images / category01 . gif
*
* idproperty , author , created , modified and modifiedby are automatically handled by
* the class .
*/
class PropertyCollection extends ItemCollection
{
public $client ;
/**
* Constructor Function
* @ param none
*/
public function __construct ()
{
global $cfg , $client ;
$this -> client = Contenido_Security :: toInteger ( $client );
parent :: __construct ( $cfg [ 'tab' ][ 'properties' ], 'idproperty' );
$this -> _setItemClass ( 'PropertyItem' );
}
/**
* Creates a new property item .
*
* Example :
*
* $properties -> create ( 'idcat' , 27 , 'visual' , 'image' , 'images/tool.gif' );
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
* @ param mixed $type Type of the data to store ( arbitary data )
* @ param mixed $name Entry name
* @ param mixed $value Value
* @ param bool $bInternally Optionally default false ( on internal call do not escape parameters again
* @ return PropertyItem
*/
public function create ( $itemtype , $itemid , $type , $name , $value , $bInternally = false )
{
global $cfg , $auth ;
2016-10-08 13:39:50 +00:00
$item = parent :: createNewItem ();
2016-10-06 15:57:01 +00:00
if ( ! $bInternally ) {
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
$value = Contenido_Security :: escapeDB ( $value , null );
$type = Contenido_Security :: escapeDB ( $type , null );
$name = Contenido_Security :: escapeDB ( $name , null );
}
$item -> set ( 'idclient' , $this -> client );
$item -> set ( 'itemtype' , $itemtype , false );
$item -> set ( 'itemid' , $itemid , false );
$item -> set ( 'type' , $type );
$item -> set ( 'name' , $name );
$item -> set ( 'value' , $value );
$item -> set ( 'created' , date ( 'Y-m-d H:i:s' ), false );
$item -> set ( 'author' , Contenido_Security :: escapeDB ( $auth -> auth [ 'uid' ], null ));
$item -> store ();
return ( $item );
}
/**
* Returns the value for a given item .
*
* Example :
*
* $file = $properties -> getValue ( 'idcat' , 27 , 'visual' , 'image' );
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
* @ param mixed $type Type of the data to store ( arbitary data )
* @ param mixed $name Entry name
* @ return mixed Value
*/
public function getValue ( $itemtype , $itemid , $type , $name , $default = false )
{
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
$type = Contenido_Security :: escapeDB ( $type , null );
$name = Contenido_Security :: escapeDB ( $name , null );
2018-07-22 18:03:30 +00:00
if ( $mValue = cPropertyCache :: getProp ( $itemtype , $itemid , $type , $name )) {
2018-07-22 18:16:48 +00:00
return $mValue ;
2016-10-06 15:57:01 +00:00
}
if ( isset ( $this -> client )) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' AND name = ' " . $name . " ' " );
} else {
$this -> select ( " itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' AND name = ' " . $name . " ' " );
}
if ( $item = $this -> next ()) {
cPropertyCache :: addProp ( $item );
return ( Contenido_Security :: unescapeDB ( $item -> get ( 'value' )));
}
2018-07-22 18:03:30 +00:00
//return $default;
2016-10-06 15:57:01 +00:00
}
/**
* Returns the value for a given item .
*
* Example :
*
* $file = $properties -> getValuesByType ( 'idcat' , 27 , 'visual' );
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
* @ param mixed $type Type of the data to store ( arbitary data )
* @ return array Value
**/
public function getValuesByType ( $itemtype , $itemid , $type )
{
$aResult = array ();
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
$type = Contenido_Security :: escapeDB ( $type , null );
if ( isset ( $this -> client )) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' " );
} else {
$this -> select ( " itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' " );
}
while ( $item = $this -> next ()) {
cPropertyCache :: addProp ( $item );
$aResult [ $item -> get ( 'name' )] = Contenido_Security :: unescapeDB ( $item -> get ( 'value' ));
}
return $aResult ;
}
/**
* Sets a property item . Handles creation and updating .
*
* Example :
*
* $properties -> setValue ( 'idcat' , 27 , 'visual' , 'image' , 'images/tool.gif' );
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
* @ param mixed $type Type of the data to store ( arbitary data )
* @ param mixed $name Entry name
* @ param mixed $value Value
* @ param int $idProp Id of database record ( if set , update on this basis ( possiblity to update name value and type ))
*/
public function setValue ( $itemtype , $itemid , $type , $name , $value , $idProp = 0 )
{
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
$type = Contenido_Security :: escapeDB ( $type , null );
$name = Contenido_Security :: escapeDB ( $name , null );
$value = Contenido_Security :: escapeDB ( $value , null );
$idProp = Contenido_Security :: toInteger ( $idProp );
if ( $idProp == 0 ) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' AND name = ' " . $name . " ' " );
} else {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND idproperty = ' " . $idProp . " ' " );
}
if ( $item = $this -> next ()) {
$item -> set ( 'value' , $value );
$item -> set ( 'name' , $name );
$item -> set ( 'type' , $type );
$item -> store ();
} else {
$this -> create ( $itemtype , $itemid , $type , $name , $value , true );
}
}
/**
* Delete a property item .
*
* Example :
*
* $properties -> deleteValue ( 'idcat' , 27 , 'visual' , 'image' );
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
* @ param mixed $type Type of the data to store ( arbitary data )
* @ param mixed $name Entry name
*/
public function deleteValue ( $itemtype , $itemid , $type , $name )
{
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
$type = Contenido_Security :: escapeDB ( $type , null );
$name = Contenido_Security :: escapeDB ( $name , null );
if ( isset ( $this -> client )) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' AND name = ' " . $name . " ' " );
} else {
$this -> select ( " itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' AND type = ' " . $type . " ' AND name = ' " . $name . " ' " );
}
if ( $item = $this -> next ()) {
$this -> delete ( $item -> get ( 'idproperty' ));
}
}
/**
* Checks if values for a given item are available .
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
* @ return array For each given item
*/
public function getProperties ( $itemtype , $itemid )
{
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
if ( isset ( $this -> client )) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' " );
} else {
$this -> select ( " itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' " );
}
$result [ $itemid ] = false ;
while ( $item = $this -> next ()) {
cPropertyCache :: addProp ( $item );
// enable accessing property values per number and field name
$result [ $item -> get ( 'itemid' )][ $item -> get ( 'idproperty' )] = array (
0 => $item -> get ( 'type' ), 'type' => $item -> get ( 'type' ),
1 => $item -> get ( 'name' ), 'name' => $item -> get ( 'name' ),
2 => $item -> get ( 'value' ), 'value' => $item -> get ( 'value' )
);
}
return $result ;
}
/**
* Returns all datasets selected by given field and value combination
*
* @ param mixed $field Field to search in
* @ param mixed $fieldValue Value to search for
* @ param Contenido_Auth $auth Narrow result down to user in auth objext
* @ return array For each given item
*/
public function getAllValues ( $field , $fieldValue , $auth = NULL )
{
$authString = '' ;
2019-07-03 19:14:30 +00:00
if ( ! is_null ( $auth )
&& is_countable ( $auth )
&& sizeof ( $auth ) > 0 ) {
2016-10-06 15:57:01 +00:00
$authString .= " AND author = ' " . $auth -> auth [ " uid " ] . " ' " ;
}
if ( isset ( $this -> client )) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND " . $field . " = ' " . $fieldValue . " ' " . $authString , '' , 'itemid' );
} else {
$this -> select ( $field . " = ' " . $fieldValue . " ' " . $authString );
}
$retValue = array ();
while ( $item = $this -> next ()) {
cPropertyCache :: addProp ( $item );
$dbLine = array (
'idproperty' => $item -> get ( 'idproperty' ),
'idclient' => $item -> get ( 'idclient' ),
'itemtype' => $item -> get ( 'itemtype' ),
'itemid' => $item -> get ( 'itemid' ),
'type' => $item -> get ( 'type' ),
'name' => $item -> get ( 'name' ),
'value' => $item -> get ( 'value' ),
'author' => $item -> get ( 'author' ),
'created' => $item -> get ( 'created' ),
'modified' => $item -> get ( 'modified' ),
'modifiedby' => $item -> get ( 'modifiedby' )
);
$retValue [] = $dbLine ;
}
return $retValue ;
}
/**
* Delete all properties which match itemtype and itemid
*
* @ param mixed $itemtype Type of the item ( example : idcat )
* @ param mixed $itemid ID of the item ( example : 31 )
*/
public function deleteProperties ( $itemtype , $itemid )
{
$itemtype = Contenido_Security :: escapeDB ( $itemtype , null );
$itemid = Contenido_Security :: escapeDB ( $itemid , null );
if ( isset ( $this -> client )) {
$this -> select ( " idclient = ' " . $this -> client . " ' AND itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' " );
} else {
$this -> select ( " itemtype = ' " . $itemtype . " ' AND itemid = ' " . $itemid . " ' " );
}
$deleteProperties = array ();
while ( $item = $this -> next ()) {
$deleteProperties [] = $item -> get ( 'idproperty' );
}
foreach ( $deleteProperties as $idproperty ) {
cPropertyCache :: deleteProp ( $idproperty );
$this -> delete ( $idproperty );
}
}
public function changeClient ( $idclient )
{
$this -> client = $idclient ;
}
}
class PropertyItem extends Item
{
/**
* maximumLength : Array which stores the maximum string length of each field
*/
public $maximumLength ;
/**
* Constructor Function
* @ param mixed $mId Specifies the ID of item to load
*/
public function __construct ( $mId = false )
{
global $cfg ;
parent :: __construct ( $cfg [ 'tab' ][ 'properties' ], 'idproperty' );
// Initialize maximum lengths for each column
$this -> maximumLength = array ();
$this -> maximumLength [ 'itemtype' ] = 64 ;
$this -> maximumLength [ 'itemid' ] = 255 ;
$this -> maximumLength [ 'type' ] = 96 ;
$this -> maximumLength [ 'name' ] = 96 ;
if ( $mId !== false ) {
$this -> loadByPrimaryKey ( $mId );
}
}
/**
* Stores changed PropertyItem
*/
public function store ()
{
global $auth ;
$this -> set ( 'modified' , date ( 'Y-m-d H:i:s' ), false );
$this -> set ( 'modifiedby' , $auth -> auth [ 'uid' ]);
parent :: store ();
}
/**
* Sets value of a field
*
* @ param string $field
* @ param string $value
* @ param bool $safe Flag to run filter on passed value
*/
2023-07-18 20:08:17 +00:00
public function setField ( $field , $value , $safe = true ) : bool
2016-10-06 15:57:01 +00:00
{
if ( array_key_exists ( $field , $this -> maximumLength )) {
if ( strlen ( $value ) > $this -> maximumLength [ $field ]) {
cWarning ( __FILE__ , __LINE__ , " Tried to set field $field to value $value , but the field is too small. Truncated. " );
}
}
2023-07-18 20:08:17 +00:00
return parent :: setField ( $field , $value , $safe );
2016-10-06 15:57:01 +00:00
}
}
class cPropertyCache {
2018-07-22 18:03:30 +00:00
/**
* Property cache array
* @ var array
*/
2016-10-06 15:57:01 +00:00
public static $_aEntries ;
2018-07-22 18:03:30 +00:00
/**
* add item to cache
*
* @ param object $oEntry
*/
2016-10-06 15:57:01 +00:00
public static function addProp ( $oEntry ) {
2018-07-22 18:03:30 +00:00
if ( ! is_array ( self :: $_aEntries )) {
self :: $_aEntries = array ();
}
2016-10-06 15:57:01 +00:00
$aData = $oEntry -> toArray ();
2018-07-22 18:03:30 +00:00
2016-10-06 15:57:01 +00:00
self :: $_aEntries [ $aData [ 'idproperty' ]] = $aData ;
}
2018-07-22 18:03:30 +00:00
/**
* Delete item from cache
*
* @ param int $iId id of prperty
*/
2016-10-06 15:57:01 +00:00
public static function deleteProp ( $iId ) {
if ( isset ( self :: $_aEntries [ $iId ]) && is_array ( self :: $_aEntries [ $iId ])) {
unset ( self :: $_aEntries [ $iId ]);
}
}
2018-07-22 18:03:30 +00:00
/**
* get property from cache
*
* @ param string $itemtype
* @ param int $itemid
* @ param string $type
* @ param string $name
* @ return string | boolean string of entry or false
*/
2016-10-06 15:57:01 +00:00
public static function getProp ( $itemtype , $itemid , $type , $name ) {
2018-07-22 18:03:30 +00:00
if ( ! is_array ( self :: $_aEntries ) || empty ( self :: $_aEntries )) {
return false ;
2016-10-06 15:57:01 +00:00
}
foreach ( self :: $_aEntries as $id => $entry ) {
if ( $entry [ 'itemtype' ] == $itemtype && $entry [ 'itemid' ] == $itemid && $entry [ 'type' ] == $type && $entry [ 'name' ] == $name ) {
2018-07-22 18:03:30 +00:00
return ( string ) $entry [ 'value' ];
2016-10-06 15:57:01 +00:00
}
}
2018-07-22 18:03:30 +00:00
return false ;
2016-10-06 15:57:01 +00:00
}
}
?>