Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1101530
products_event_handler.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, Aug 16, 10:46 PM
Size
47 KB
Mime Type
text/x-php
Expires
Mon, Aug 18, 10:46 PM (13 h, 58 m)
Engine
blob
Format
Raw Data
Handle
713417
Attached To
rMINC Modules.In-Commerce
products_event_handler.php
View Options
<?php
/**
* @version $Id: products_event_handler.php 16693 2021-08-31 09:24:39Z alex $
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software is protected by copyright law and international treaties.
* Unauthorized reproduction or unlicensed usage of the code of this program,
* or any portion of it may result in severe civil and criminal penalties,
* and will be prosecuted to the maximum extent possible under the law
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined
(
'FULL_PATH'
)
or
die
(
'restricted access!'
);
class
ProductsEventHandler
extends
kCatDBEventHandler
{
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected
function
mapPermissions
()
{
parent
::
mapPermissions
();
$permissions
=
Array
(
// front
'OnCancelAction'
=>
Array
(
'self'
=>
true
),
'OnRateProduct'
=>
Array
(
'self'
=>
true
),
'OnClearRecent'
=>
Array
(
'self'
=>
true
),
'OnRecommendProduct'
=>
Array
(
'self'
=>
true
),
'OnAddToCompare'
=>
Array
(
'self'
=>
true
),
'OnRemoveFromCompare'
=>
Array
(
'self'
=>
true
),
'OnCancelCompare'
=>
Array
(
'self'
=>
true
),
// admin
'OnQtyAdd'
=>
Array
(
'self'
=>
'add|edit'
),
'OnQtyRemove'
=>
Array
(
'self'
=>
'add|edit'
),
'OnQtyOrder'
=>
Array
(
'self'
=>
'add|edit'
),
'OnQtyReceiveOrder'
=>
Array
(
'self'
=>
'add|edit'
),
'OnQtyCancelOrder'
=>
Array
(
'self'
=>
'add|edit'
),
);
$this
->
permMapping
=
array_merge
(
$this
->
permMapping
,
$permissions
);
}
/**
* Define alternative event processing method names
*
* @return void
* @see kEventHandler::$eventMethods
* @access protected
*/
protected
function
mapEvents
()
{
parent
::
mapEvents
();
// ensure auto-adding of approve/decine and so on events
$product_events
=
Array
(
'OnQtyAdd'
=>
'InventoryAction'
,
'OnQtyRemove'
=>
'InventoryAction'
,
'OnQtyOrder'
=>
'InventoryAction'
,
'OnQtyReceiveOrder'
=>
'InventoryAction'
,
'OnQtyCancelOrder'
=>
'InventoryAction'
,
);
$this
->
eventMethods
=
array_merge
(
$this
->
eventMethods
,
$product_events
);
}
/**
* Sets default processing data for subscriptions
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnBeforeItemCreate
(
kEvent
$event
)
{
parent
::
OnBeforeItemCreate
(
$event
);
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$product_approve_events
=
Array
(
2
=>
'p:OnSubscriptionApprove'
,
4
=>
'p:OnDownloadableApprove'
,
5
=>
'p:OnPackageApprove'
);
$product_type
=
$object
->
GetDBField
(
'Type'
);
$type_found
=
in_array
(
$product_type
,
array_keys
(
$product_approve_events
));
if
(
$type_found
&&
!
$object
->
GetDBField
(
'ProcessingData'
)
)
{
$processing_data
=
Array
(
'ApproveEvent'
=>
$product_approve_events
[
$product_type
]);
$object
->
SetDBField
(
'ProcessingData'
,
serialize
(
$processing_data
));
}
}
/**
* Process product count manipulations
*
* @param kEvent $event
* @access private
*/
function
InventoryAction
(
$event
)
{
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$field_values
=
$this
->
getSubmittedFields
(
$event
);
$object
->
SetFieldsFromHash
(
$field_values
);
$event
->
setEventParam
(
'form_data'
,
$field_values
);
if
(
$object
->
GetDBField
(
'InventoryStatus'
)
==
2
)
{
// inventory by options (use first selected combination in grid)
$combinations
=
$this
->
Application
->
GetVar
(
'poc_grid'
);
$combination_id
=
key
(
$combinations
);
}
else
{
// inventory by product
$combination_id
=
0
;
}
// save id of selected option combination & preselect it in grid
$this
->
Application
->
SetVar
(
'combination_id'
,
$combination_id
);
$this
->
ScheduleInventoryAction
(
$event
->
Name
,
$object
->
GetId
(),
$object
->
GetDBField
(
'Qty'
),
$combination_id
);
$object
->
Validate
();
if
(
!
$object
->
GetErrorPseudo
(
'Qty'
)
){
// only update, when no error on that field
$this
->
modifyInventory
(
$event
->
Name
,
$object
,
$object
->
GetDBField
(
'Qty'
),
$combination_id
);
}
$object
->
SetDBField
(
'Qty'
,
null
);
$event
->
redirect
=
false
;
}
/**
* Perform inventory action on supplied object
*
* @param string $action event name which is actually called by user
* @param ProductsItem $product
* @param int $qty
* @param int $combination_id
*/
function
modifyInventory
(
$action
,
&
$product
,
$qty
,
$combination_id
)
{
if
(
$product
->
GetDBField
(
'InventoryStatus'
)
==
2
)
{
// save inventory changes to option combination instead of product
$object
=
$this
->
Application
->
recallObject
(
'poc.-item'
,
null
,
Array
(
'skip_autoload'
=>
true
));
$object
->
Load
(
$combination_id
);
}
elseif
(
$combination_id
>
0
)
{
// combination id present, but not inventory by combinations => skip
return
false
;
}
elseif
(
$product
->
GetDBField
(
'InventoryStatus'
)
==
1
)
{
// save inventory changes to product
$object
=&
$product
;
}
else
{
// product has inventory actions, but don't use inventory => skip
return
false
;
}
if
(!
$object
->
isLoaded
())
{
// product/combination in action doesn't exist in database by now
return
false
;
}
switch
(
$action
)
{
case
'OnQtyAdd'
:
$object
->
SetDBField
(
'QtyInStock'
,
$object
->
GetDBField
(
'QtyInStock'
)
+
$qty
);
break
;
case
'OnQtyRemove'
:
if
(
$object
->
GetDBField
(
'QtyInStock'
)
<
$qty
)
{
$qty
=
$object
->
GetDBField
(
'QtyInStock'
);
}
$object
->
SetDBField
(
'QtyInStock'
,
$object
->
GetDBField
(
'QtyInStock'
)
-
$qty
);
break
;
case
'OnQtyOrder'
:
$object
->
SetDBField
(
'QtyOnOrder'
,
$object
->
GetDBField
(
'QtyOnOrder'
)
+
$qty
);
break
;
case
'OnQtyReceiveOrder'
:
$object
->
SetDBField
(
'QtyOnOrder'
,
$object
->
GetDBField
(
'QtyOnOrder'
)
-
$qty
);
$object
->
SetDBField
(
'QtyInStock'
,
$object
->
GetDBField
(
'QtyInStock'
)
+
$qty
);
break
;
case
'OnQtyCancelOrder'
:
$object
->
SetDBField
(
'QtyOnOrder'
,
$object
->
GetDBField
(
'QtyOnOrder'
)
-
$qty
);
break
;
}
return
$object
->
Update
();
}
function
ScheduleInventoryAction
(
$action
,
$prod_id
,
$qty
,
$combination_id
=
0
)
{
$inv_actions
=
$this
->
Application
->
RecallVar
(
'inventory_actions'
);
if
(!
$inv_actions
)
{
$inv_actions
=
Array
();
}
else
{
$inv_actions
=
unserialize
(
$inv_actions
);
}
array_push
(
$inv_actions
,
Array
(
'action'
=>
$action
,
'product_id'
=>
$prod_id
,
'combination_id'
=>
$combination_id
,
'qty'
=>
$qty
));
$this
->
Application
->
StoreVar
(
'inventory_actions'
,
serialize
(
$inv_actions
));
}
function
RealInventoryAction
(
$action
,
$prod_id
,
$qty
,
$combination_id
)
{
$product
=
$this
->
Application
->
recallObject
(
'p.liveitem'
,
null
,
Array
(
'skip_autoload'
=>
true
));
$product
->
SwitchToLive
();
$product
->
Load
(
$prod_id
);
$this
->
modifyInventory
(
$action
,
$product
,
$qty
,
$combination_id
);
}
function
RunScheduledInventoryActions
(
$event
)
{
$inv_actions
=
$this
->
Application
->
GetVar
(
'inventory_actions'
);
if
(!
$inv_actions
)
{
return
;
}
$inv_actions
=
unserialize
(
$inv_actions
);
$products
=
array
();
foreach
(
$inv_actions
as
$an_action
)
{
$this
->
RealInventoryAction
(
$an_action
[
'action'
],
$an_action
[
'product_id'
],
$an_action
[
'qty'
],
$an_action
[
'combination_id'
]);
array_push
(
$products
,
$an_action
[
'product_id'
].
'_'
.
$an_action
[
'combination_id'
]);
}
$products
=
array_unique
(
$products
);
if
(
$products
)
{
$product_obj
=
$this
->
Application
->
recallObject
(
'p.liveitem'
,
null
,
Array
(
'skip_autoload'
=>
true
));
$product_obj
->
SwitchToLive
();
foreach
(
$products
as
$product_key
)
{
list
(
$prod_id
,
$combination_id
)
=
explode
(
'_'
,
$product_key
);
$product_obj
->
Load
(
$prod_id
);
$this
->
FullfillBackOrders
(
$product_obj
,
$combination_id
);
}
}
}
/**
* In case if products arrived into inventory and they are required by old (non processed) orders, then use them (products) in that orders
*
* @param ProductsItem $product
* @param int $combination_id
*/
function
FullfillBackOrders
(&
$product
,
$combination_id
)
{
if
(
!
$this
->
Application
->
ConfigValue
(
'Comm_Process_Backorders_Auto'
)
)
return
;
if
(
$combination_id
&&
(
$product
->
GetDBField
(
'InventoryStatus'
)
==
2
))
{
// if combination id present and inventory by combinations
$poc_idfield
=
$this
->
Application
->
getUnitOption
(
'poc'
,
'IDField'
);
$poc_tablename
=
$this
->
Application
->
getUnitOption
(
'poc'
,
'TableName'
);
$sql
=
'SELECT QtyInStock
FROM '
.
$poc_tablename
.
'
WHERE '
.
$poc_idfield
.
' = '
.
$combination_id
;
$stock_qty
=
$this
->
Conn
->
GetOne
(
$sql
);
}
else
{
// inventory by product
$stock_qty
=
$product
->
GetDBField
(
'QtyInStock'
);
}
$qty
=
(
int
)
$stock_qty
-
$product
->
GetDBField
(
'QtyInStockMin'
);
$prod_id
=
$product
->
GetID
();
if
(
$prod_id
<=
0
||
!
$prod_id
||
$qty
<=
0
)
return
;
//selecting up to $qty backorders with $prod_id where full qty is not reserved
$query
=
'SELECT '
.
TABLE_PREFIX
.
'Orders.OrderId
FROM '
.
TABLE_PREFIX
.
'OrderItems
LEFT JOIN '
.
TABLE_PREFIX
.
'Orders ON '
.
TABLE_PREFIX
.
'Orders.OrderId = '
.
TABLE_PREFIX
.
'OrderItems.OrderId
WHERE (ProductId = '
.
$prod_id
.
') AND (Quantity > QuantityReserved) AND (Status = '
.
ORDER_STATUS_BACKORDERS
.
')
GROUP BY '
.
TABLE_PREFIX
.
'Orders.OrderId
ORDER BY OrderDate ASC
LIMIT 0,'
.
$qty
;
//assuming 1 item per order - minimum possible
$orders
=
$this
->
Conn
->
GetCol
(
$query
);
if
(
!
$orders
)
{
return
;
}
/** @var OrdersItem $order */
$order
=
$this
->
Application
->
recallObject
(
'ord.-inv'
,
null
,
array
(
'skip_autoload'
=>
true
));
foreach
(
$orders
as
$ord_id
)
{
$order
->
Load
(
$ord_id
);
$this
->
Application
->
emailAdmin
(
'BACKORDER.FULLFILL'
);
// Reserve what's possible in any case.
$reserve_event
=
new
kEvent
(
'ord:OnReserveItems'
);
$this
->
Application
->
HandleEvent
(
$reserve_event
);
// In case the order is ready to process - process it.
if
(
$reserve_event
->
status
==
kEvent
::
erSUCCESS
)
{
$this
->
Application
->
HandleEvent
(
new
kEvent
(
'ord:OnOrderProcess'
));
}
}
}
/**
* Occurs before an item is deleted from live table when copying from temp
* (temp handler deleted all items from live and then copy over all items from temp)
* Id of item being deleted is passed as event' 'id' param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnBeforeDeleteFromLive
(
kEvent
$event
)
{
parent
::
OnBeforeDeleteFromLive
(
$event
);
/** @var kCatDBItem $product */
$product
=
$this
->
Application
->
recallObject
(
$event
->
Prefix
.
'.itemlive'
,
null
,
Array
(
'skip_autoload'
=>
true
));
$product
->
SwitchToLive
();
$id
=
$event
->
getEventParam
(
'id'
);
if
(
!
$product
->
Load
(
$id
)
)
{
// this will make sure New product will not be overwritten with empty data
return
;
}
/** @var kCatDBItem $temp */
$temp
=
$this
->
Application
->
recallObject
(
$event
->
Prefix
.
'.itemtemp'
,
null
,
Array
(
'skip_autoload'
=>
true
));
$temp
->
SwitchToTemp
();
$temp
->
Load
(
$id
);
$temp
->
SetDBFieldsFromHash
(
$product
->
GetFieldValues
(),
Array
(
'QtyInStock'
,
'QtyReserved'
,
'QtyBackOrdered'
,
'QtyOnOrder'
));
$temp
->
Update
();
}
/**
* Removes any information about current/selected ids
* from Application variables and Session
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
clearSelectedIDs
(
kEvent
$event
)
{
parent
::
clearSelectedIDs
(
$event
);
$this
->
Application
->
SetVar
(
'inventory_actions'
,
$this
->
Application
->
RecallVar
(
'inventory_actions'
));
$this
->
Application
->
RemoveVar
(
'inventory_actions'
);
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnSave
(
kEvent
$event
)
{
parent
::
OnSave
(
$event
);
if
(
$event
->
status
==
kEvent
::
erSUCCESS
)
{
$this
->
RunScheduledInventoryActions
(
$event
);
}
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnPreCreate
(
kEvent
$event
)
{
parent
::
onPreCreate
(
$event
);
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$object
->
SetDBField
(
'Type'
,
$this
->
Application
->
GetVar
(
$event
->
getPrefixSpecial
(
true
)
.
'_new_type'
));
}
/**
* Saves edited item in temp table and loads
* item with passed id in current template
* Used in Prev/Next buttons
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnPreSaveAndGo
(
kEvent
$event
)
{
$event
->
CallSubEvent
(
'OnPreSave'
);
$this
->
LoadItem
(
$event
);
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$from_type
=
$object
->
GetDBField
(
'Type'
);
if
(
$event
->
status
==
kEvent
::
erSUCCESS
)
{
$this
->
Application
->
SetVar
(
$event
->
getPrefixSpecial
()
.
'_id'
,
$this
->
Application
->
GetVar
(
$event
->
getPrefixSpecial
(
true
)
.
'_GoId'
));
$this
->
LoadItem
(
$event
);
$to_type
=
$object
->
GetDBField
(
'Type'
);
if
(
$from_type
!=
$to_type
)
{
$from_tabs
=
$this
->
GetTabs
(
$from_type
);
$from_tab_i
=
array_search
(
$this
->
Application
->
GetVar
(
't'
),
$from_tabs
);
$to_tabs
=
$this
->
GetTabs
(
$to_type
);
$to_tab
=
$this
->
Application
->
GetVar
(
't'
);
$found
=
false
;
while
(!
isset
(
$to_tabs
[
$from_tab_i
])
&&
$from_tab_i
<
count
(
$to_tabs
))
{
$from_tab_i
++;
}
if
(
!
isset
(
$to_tabs
[
$from_tab_i
])
)
{
$from_tab_i
=
0
;
}
$to_tab
=
$to_tabs
[
$from_tab_i
];
$event
->
redirect
=
$to_tab
;
}
}
}
function
GetTabs
(
$type
)
{
switch
(
$type
)
{
case
1
:
return
Array
(
0
=>
'in-commerce/products/products_edit'
,
1
=>
'in-commerce/products/products_inventory'
,
2
=>
'in-commerce/products/products_pricing'
,
3
=>
'in-commerce/products/products_categories'
,
4
=>
'in-commerce/products/products_images'
,
5
=>
'in-commerce/products/products_reviews'
,
6
=>
'in-commerce/products/products_custom'
,
);
case
2
:
return
Array
(
0
=>
'in-commerce/products/products_edit'
,
1
=>
'in-commerce/products/products_access'
,
/*2 => 'in-commerce/products/products_access_pricing',*/
3
=>
'in-commerce/products/products_categories'
,
4
=>
'in-commerce/products/products_images'
,
5
=>
'in-commerce/products/products_reviews'
,
6
=>
'in-commerce/products/products_custom'
,
);
case
3
:
return
Array
(
0
=>
'in-commerce/products/products_edit'
,
2
=>
'in-commerce/products/products_access_pricing'
,
3
=>
'in-commerce/products/products_categories'
,
4
=>
'in-commerce/products/products_images'
,
5
=>
'in-commerce/products/products_reviews'
,
6
=>
'in-commerce/products/products_custom'
,
);
case
4
:
return
Array
(
0
=>
'in-commerce/products/products_edit'
,
2
=>
'in-commerce/products/products_files'
,
3
=>
'in-commerce/products/products_categories'
,
4
=>
'in-commerce/products/products_images'
,
5
=>
'in-commerce/products/products_reviews'
,
6
=>
'in-commerce/products/products_custom'
,
);
}
}
/**
* Return type clauses for list bulding on front
*
* @param kEvent $event
* @return Array
*/
function
getTypeClauses
(
$event
)
{
$types
=
$event
->
getEventParam
(
'types'
);
$types
=
$types
?
explode
(
','
,
$types
)
:
Array
();
$except_types
=
$event
->
getEventParam
(
'except'
);
$except_types
=
$except_types
?
explode
(
','
,
$except_types
)
:
Array
();
/** @var kDBList $object */
$object
=
$event
->
getObject
();
$type_clauses
=
parent
::
getTypeClauses
(
$event
);
$type_clauses
[
'featured'
][
'include'
]
=
'%1$s.Featured = 1 AND '
.
TABLE_PREFIX
.
'CategoryItems.PrimaryCat = 1'
;
$type_clauses
[
'featured'
][
'except'
]
=
'%1$s.Featured != 1 AND '
.
TABLE_PREFIX
.
'CategoryItems.PrimaryCat = 1'
;
$type_clauses
[
'featured'
][
'having_filter'
]
=
false
;
$type_clauses
[
'onsale'
][
'include'
]
=
'%1$s.OnSale = 1 AND '
.
TABLE_PREFIX
.
'CategoryItems.PrimaryCat = 1'
;
$type_clauses
[
'onsale'
][
'except'
]
=
'%1$s.OnSale != 1 AND '
.
TABLE_PREFIX
.
'CategoryItems.PrimaryCat = 1'
;
$type_clauses
[
'onsale'
][
'having_filter'
]
=
false
;
// products from selected manufacturer: begin
$manufacturer
=
$event
->
getEventParam
(
'manufacturer'
);
if
(
!
$manufacturer
)
{
$manufacturer
=
$this
->
Application
->
GetVar
(
'manuf_id'
);
}
if
(
$manufacturer
)
{
$type_clauses
[
'manufacturer'
][
'include'
]
=
'%1$s.ManufacturerId = '
.
$manufacturer
.
' AND PrimaryCat = 1'
;
$type_clauses
[
'manufacturer'
][
'except'
]
=
'%1$s.ManufacturerId != '
.
$manufacturer
.
' AND PrimaryCat = 1'
;
$type_clauses
[
'manufacturer'
][
'having_filter'
]
=
false
;
}
// products from selected manufacturer: end
// recent products: begin
$recent
=
$this
->
Application
->
RecallVar
(
'recent_products'
);
if
(
$recent
)
{
$recent
=
unserialize
(
$recent
);
$type_clauses
[
'recent'
][
'include'
]
=
'%1$s.ProductId IN ('
.
implode
(
','
,
$recent
)
.
') AND PrimaryCat = 1'
;
$type_clauses
[
'recent'
][
'except'
]
=
'%1$s.ProductId NOT IN ('
.
implode
(
','
,
$recent
)
.
') AND PrimaryCat = 1'
;
}
else
{
$type_clauses
[
'recent'
][
'include'
]
=
'0'
;
$type_clauses
[
'recent'
][
'except'
]
=
'1'
;
}
$type_clauses
[
'recent'
][
'having_filter'
]
=
false
;
// recent products: end
// compare products: begin
if
(
in_array
(
'compare'
,
$types
)
||
in_array
(
'compare'
,
$except_types
)
)
{
$compare_products
=
$this
->
getCompareProducts
();
if
(
$compare_products
)
{
$compare_products
=
$this
->
Conn
->
qstrArray
(
$compare_products
);
$type_clauses
[
'compare'
][
'include'
]
=
'%1$s.ProductId IN ('
.
implode
(
','
,
$compare_products
)
.
') AND PrimaryCat = 1'
;
$type_clauses
[
'compare'
][
'except'
]
=
'%1$s.ProductId NOT IN ('
.
implode
(
','
,
$compare_products
)
.
') AND PrimaryCat = 1'
;
}
else
{
$type_clauses
[
'compare'
][
'include'
]
=
'0'
;
$type_clauses
[
'compare'
][
'except'
]
=
'1'
;
}
$type_clauses
[
'compare'
][
'having_filter'
]
=
false
;
if
(
$event
->
getEventParam
(
'per_page'
)
===
false
)
{
$event
->
setEventParam
(
'per_page'
,
$this
->
Application
->
ConfigValue
(
'MaxCompareProducts'
));
}
}
// compare products: end
// products already in shopping cart: begin
if
(
in_array
(
'in_cart'
,
$types
)
||
in_array
(
'in_cart'
,
$except_types
)
)
{
$order_id
=
$this
->
Application
->
RecallVar
(
'ord_id'
);
if
(
$order_id
)
{
$sql
=
'SELECT ProductId
FROM '
.
TABLE_PREFIX
.
'OrderItems
WHERE OrderId = '
.
$order_id
;
$in_cart
=
$this
->
Conn
->
GetCol
(
$sql
);
if
(
$in_cart
)
{
$type_clauses
[
'in_cart'
][
'include'
]
=
'%1$s.ProductId IN ('
.
implode
(
','
,
$in_cart
)
.
') AND PrimaryCat = 1'
;
$type_clauses
[
'in_cart'
][
'except'
]
=
'%1$s.ProductId NOT IN ('
.
implode
(
','
,
$in_cart
)
.
') AND PrimaryCat = 1'
;
}
else
{
$type_clauses
[
'in_cart'
][
'include'
]
=
'0'
;
$type_clauses
[
'in_cart'
][
'except'
]
=
'1'
;
}
}
else
{
$type_clauses
[
'in_cart'
][
'include'
]
=
'0'
;
$type_clauses
[
'in_cart'
][
'except'
]
=
'1'
;
}
$type_clauses
[
'in_cart'
][
'having_filter'
]
=
false
;
}
// products already in shopping cart: end
// my downloadable products: begin
if
(
in_array
(
'my_downloads'
,
$types
)
||
in_array
(
'my_downloads'
,
$except_types
)
)
{
$user_id
=
$this
->
Application
->
RecallVar
(
'user_id'
);
$sql
=
'SELECT ProductId
FROM '
.
TABLE_PREFIX
.
'UserFileAccess
WHERE PortalUserId = '
.
$user_id
;
$my_downloads
=
$user_id
>
0
?
$this
->
Conn
->
GetCol
(
$sql
)
:
false
;
if
(
$my_downloads
)
{
$type_clauses
[
'my_downloads'
][
'include'
]
=
'%1$s.ProductId IN ('
.
implode
(
','
,
$my_downloads
)
.
') AND PrimaryCat = 1'
;
$type_clauses
[
'my_downloads'
][
'except'
]
=
'%1$s.ProductId NOT IN ('
.
implode
(
','
,
$my_downloads
)
.
') AND PrimaryCat = 1'
;
}
else
{
$type_clauses
[
'my_downloads'
][
'include'
]
=
'0'
;
$type_clauses
[
'my_downloads'
][
'except'
]
=
'1'
;
}
$type_clauses
[
'my_downloads'
][
'having_filter'
]
=
false
;
}
// my downloadable products: end
// my favorite products: begin
if
(
in_array
(
'wish_list'
,
$types
)
||
in_array
(
'wish_list'
,
$except_types
)
)
{
$sql
=
'SELECT ResourceId
FROM '
.
$this
->
Application
->
getUnitOption
(
'fav'
,
'TableName'
)
.
'
WHERE PortalUserId = '
.
(
int
)
$this
->
Application
->
RecallVar
(
'user_id'
);
$wishlist_ids
=
$this
->
Conn
->
GetCol
(
$sql
);
if
(
$wishlist_ids
)
{
$type_clauses
[
'wish_list'
][
'include'
]
=
'%1$s.ResourceId IN ('
.
implode
(
','
,
$wishlist_ids
)
.
') AND PrimaryCat = 1'
;
$type_clauses
[
'wish_list'
][
'except'
]
=
'%1$s.ResourceId NOT IN ('
.
implode
(
','
,
$wishlist_ids
)
.
') AND PrimaryCat = 1'
;
}
else
{
$type_clauses
[
'wish_list'
][
'include'
]
=
'0'
;
$type_clauses
[
'wish_list'
][
'except'
]
=
'1'
;
}
$type_clauses
[
'wish_list'
][
'having_filter'
]
=
false
;
}
// my favorite products: end
// products from package: begin
if
(
in_array
(
'content'
,
$types
)
||
in_array
(
'content'
,
$except_types
)
)
{
$object
->
removeFilter
(
'category_filter'
);
$object
->
AddGroupByField
(
'%1$s.ProductId'
);
/** @var ProductsItem $object_product */
$object_product
=
$this
->
Application
->
recallObject
(
$event
->
Prefix
);
$content_ids_array
=
$object_product
->
GetPackageContentIds
();
if
(
sizeof
(
$content_ids_array
)
==
0
)
{
$content_ids_array
=
array
(
'-1'
);
}
if
(
sizeof
(
$content_ids_array
)
>
0
)
{
$type_clauses
[
'content'
][
'include'
]
=
'%1$s.ProductId IN ('
.
implode
(
','
,
$content_ids_array
)
.
')'
;
}
else
{
$type_clauses
[
'content'
][
'include'
]
=
'0'
;
}
$type_clauses
[
'related'
][
'having_filter'
]
=
false
;
}
// products from package: end
$object
->
addFilter
(
'not_virtual'
,
'%1$s.Virtual = 0'
);
if
(
!
$this
->
Application
->
isAdminUser
)
{
$object
->
addFilter
(
'expire_filter'
,
'%1$s.Expire IS NULL OR %1$s.Expire > '
.
adodb_mktime
());
}
return
$type_clauses
;
}
function
OnClearRecent
(
$event
)
{
$this
->
Application
->
RemoveVar
(
'recent_products'
);
}
/**
* Occurs, when user rates a product
*
* @param kEvent $event
*/
function
OnRateProduct
(
$event
)
{
$event
->
SetRedirectParam
(
'pass'
,
'all,p'
);
$event
->
redirect
=
$this
->
Application
->
GetVar
(
'success_template'
);
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$user_id
=
$this
->
Application
->
RecallVar
(
'user_id'
);
$sql
=
' SELECT * FROM '
.
TABLE_PREFIX
.
'SpamControl
WHERE ItemResourceId='
.
$object
->
GetDBField
(
'ResourceId'
)
.
'
AND IPaddress="'
.
$this
->
Application
->
getClientIp
()
.
'"
AND PortalUserId='
.
$user_id
.
'
AND DataType="Rating"'
;
$res
=
$this
->
Conn
->
GetRow
(
$sql
);
if
(
$res
&&
$res
[
'Expire'
]
<
adodb_mktime
()
)
{
$sql
=
' DELETE FROM '
.
TABLE_PREFIX
.
'SpamControl
WHERE ItemResourceId='
.
$object
->
GetDBField
(
'ResourceId'
)
.
'
AND IPaddress="'
.
$this
->
Application
->
getClientIp
()
.
'"
AND PortalUserId='
.
$user_id
.
'
AND DataType="Rating"'
;
$this
->
Conn
->
Query
(
$sql
);
unset
(
$res
);
}
$new_rating
=
$this
->
Application
->
GetVar
(
'rating'
);
if
(
$new_rating
!==
false
&&
!
$res
)
{
$rating
=
$object
->
GetDBField
(
'CachedRating'
);
$votes
=
$object
->
GetDBField
(
'CachedVotesQty'
);
$new_votes
=
$votes
+
1
;
$rating
=
((
$rating
*
$votes
)
+
$new_rating
)
/
$new_votes
;
$object
->
SetDBField
(
'CachedRating'
,
$rating
);
$object
->
SetDBField
(
'CachedVotesQty'
,
$new_votes
);
$object
->
Update
();
$expire
=
adodb_mktime
()
+
$this
->
Application
->
ConfigValue
(
'product_ReviewDelay_Value'
)
*
$this
->
Application
->
ConfigValue
(
'product_ReviewDelay_Interval'
);
$sql
=
' INSERT INTO '
.
TABLE_PREFIX
.
'SpamControl
(ItemResourceId, IPaddress, PortalUserId, DataType, Expire)
VALUES ('
.
$object
->
GetDBField
(
'ResourceId'
)
.
',
"'
.
$this
->
Application
->
getClientIp
()
.
'",
'
.
$user_id
.
',
"Rating",
'
.
$expire
.
')'
;
$this
->
Conn
->
Query
(
$sql
);
}
else
{
$event
->
status
==
kEvent
::
erFAIL
;
$event
->
redirect
=
false
;
$object
->
SetError
(
'CachedRating'
,
'too_frequent'
,
'lu_ferror_rate_duplicate'
);
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function
OnCancelAction
(
$event
)
{
$event
->
SetRedirectParam
(
'pass'
,
'all,p'
);
$event
->
redirect
=
$this
->
Application
->
GetVar
(
'cancel_template'
);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function
OnRecommendProduct
(
$event
)
{
// used for error reporting only -> rewrite code + theme (by Alex)
$object
=
$this
->
Application
->
recallObject
(
'u'
,
null
,
Array
(
'skip_autoload'
=>
true
));
// TODO: change theme too
/** @var kDBItem $object */
$friend_email
=
$this
->
Application
->
GetVar
(
'friend_email'
);
$friend_name
=
$this
->
Application
->
GetVar
(
'friend_name'
);
$my_email
=
$this
->
Application
->
GetVar
(
'your_email'
);
$my_name
=
$this
->
Application
->
GetVar
(
'your_name'
);
$my_message
=
$this
->
Application
->
GetVar
(
'your_message'
);
$send_params
=
array
();
$send_params
[
'to_email'
]=
$friend_email
;
$send_params
[
'to_name'
]=
$friend_name
;
$send_params
[
'from_email'
]=
$my_email
;
$send_params
[
'from_name'
]=
$my_name
;
$send_params
[
'message'
]=
$my_message
;
if
(
preg_match
(
'/'
.
REGEX_EMAIL_USER
.
'@'
.
REGEX_EMAIL_DOMAIN
.
'/'
,
$friend_email
)
)
{
$user_id
=
$this
->
Application
->
RecallVar
(
'user_id'
);
$email_sent
=
$this
->
Application
->
emailUser
(
'PRODUCT.SUGGEST'
,
$user_id
,
$send_params
);
$this
->
Application
->
emailAdmin
(
'PRODUCT.SUGGEST'
);
if
(
$email_sent
)
{
$event
->
setRedirectParams
(
Array
(
'opener'
=>
's'
,
'pass'
=>
'all'
));
$event
->
redirect
=
$this
->
Application
->
GetVar
(
'template_success'
);
}
else
{
// $event->setRedirectParams(Array('opener' => 's', 'pass' => 'all'));
// $event->redirect = $this->Application->GetVar('template_fail');
$object
->
SetError
(
'Email'
,
'send_error'
,
'lu_email_send_error'
);
$event
->
status
=
kEvent
::
erFAIL
;
}
}
else
{
$object
->
SetError
(
'Email'
,
'invalid_email'
,
'lu_InvalidEmail'
);
$event
->
status
=
kEvent
::
erFAIL
;
}
}
/**
* Creates/updates virtual product based on listing type data
*
* @param kEvent $event
*/
function
OnSaveVirtualProduct
(
$event
)
{
$object
=
$event
->
getObject
(
Array
(
'skip_autoload'
=>
true
)
);
$listing_type
=
$this
->
Application
->
recallObject
(
'lst'
,
null
,
Array
(
'skip_autoload'
=>
true
));
$listing_type
->
Load
(
$event
->
MasterEvent
->
getEventParam
(
'id'
));
$product_id
=
$listing_type
->
GetDBField
(
'VirtualProductId'
);
if
(
$product_id
)
{
$object
->
Load
(
$product_id
);
}
if
(!
$listing_type
->
GetDBField
(
'EnableBuying'
))
{
if
(
$product_id
)
{
// delete virtual product here
$temp_handler
=
$this
->
Application
->
recallObject
(
$event
->
getPrefixSpecial
().
'_TempHandler'
,
'kTempTablesHandler'
);
$temp_handler
->
DeleteItems
(
$event
->
Prefix
,
$event
->
Special
,
Array
(
$product_id
));
$listing_type
->
SetDBField
(
'VirtualProductId'
,
0
);
$listing_type
->
Update
();
}
return
true
;
}
$ml_formatter
=
$this
->
Application
->
recallObject
(
'kMultiLanguage'
);
$object
->
SetDBField
(
$ml_formatter
->
LangFieldName
(
'Name'
),
$listing_type
->
GetDBField
(
'ShopCartName'
)
);
$object
->
SetDBField
(
$ml_formatter
->
LangFieldName
(
'Description'
),
$listing_type
->
GetDBField
(
'Description'
));
$object
->
SetDBField
(
'SKU'
,
'ENHANCE_LINK_'
.
abs
(
crc32
(
$listing_type
->
GetDBField
(
'Name'
)
)
)
);
if
(
$product_id
)
{
$object
->
Update
();
}
else
{
$object
->
SetDBField
(
'Type'
,
2
);
$object
->
SetDBField
(
'Status'
,
1
);
$object
->
SetDBField
(
'HotItem'
,
0
);
$object
->
SetDBField
(
'PopItem'
,
0
);
$object
->
SetDBField
(
'NewItem'
,
0
);
$object
->
SetDBField
(
'Virtual'
,
1
);
// $processing_data = Array('ApproveEvent' => 'ls:EnhanceLinkAfterOrderApprove', 'ExpireEvent' => 'ls:ExpireLink');
$processing_data
=
Array
(
'ApproveEvent'
=>
'ls:EnhanceLinkAfterOrderApprove'
,
'DenyEvent'
=>
'ls:EnhanceLinkAfterOrderDeny'
,
'CompleteOrderEvent'
=>
'ls:EnhancedLinkOnCompleteOrder'
,
'ExpireEvent'
=>
'ls:ExpireLink'
,
'HasNewProcessing'
=>
1
);
$object
->
SetDBField
(
'ProcessingData'
,
serialize
(
$processing_data
));
$object
->
Create
();
$listing_type
->
SetDBField
(
'VirtualProductId'
,
$object
->
GetID
());
$listing_type
->
Update
();
}
$additiona_fields
=
Array
(
'AccessDuration'
=>
$listing_type
->
GetDBField
(
'Duration'
),
'AccessUnit'
=>
$listing_type
->
GetDBField
(
'DurationType'
),
);
$this
->
setPrimaryPrice
(
$object
->
GetID
(),
(
double
)
$listing_type
->
GetDBField
(
'Price'
),
$additiona_fields
);
}
/**
* [HOOK] Deletes virtual product when listing type is deleted
*
* @param kEvent $event
*/
function
OnDeleteListingType
(
$event
)
{
/** @var kDBItem $listing_type */
$listing_type
=
$event
->
MasterEvent
->
getObject
();
$product_id
=
$listing_type
->
GetDBField
(
'VirtualProductId'
);
if
(
$product_id
)
{
$temp_handler
=
$this
->
Application
->
recallObject
(
$event
->
getPrefixSpecial
()
.
'_TempHandler'
,
'kTempTablesHandler'
);
$temp_handler
->
DeleteItems
(
$event
->
Prefix
,
$event
->
Special
,
Array
(
$product_id
));
}
}
/**
* Extends user membership in group when his order is approved
*
* @param kEvent $event
*/
function
OnSubscriptionApprove
(
$event
)
{
$field_values
=
$event
->
getEventParam
(
'field_values'
);
$item_data
=
unserialize
(
$field_values
[
'ItemData'
]);
if
(
!
getArrayValue
(
$item_data
,
'PortalGroupId'
)
)
{
// is subscription product, but no group defined in it's properties
trigger_error
(
'Invalid product <b>'
.
$field_values
[
'ProductName'
].
'</b> (id: '
.
$field_values
[
'ProductId'
].
')'
,
E_USER_WARNING
);
return
false
;
}
$sql
=
'SELECT PortalUserId
FROM '
.
$this
->
Application
->
getUnitOption
(
'ord'
,
'TableName'
)
.
'
WHERE '
.
$this
->
Application
->
getUnitOption
(
'ord'
,
'IDField'
)
.
' = '
.
$field_values
[
'OrderId'
];
$user_id
=
$this
->
Conn
->
GetOne
(
$sql
);
$group_id
=
$item_data
[
'PortalGroupId'
];
$duration
=
$item_data
[
'Duration'
];
$sql
=
'SELECT *
FROM '
.
TABLE_PREFIX
.
'UserGroupRelations
WHERE PortalUserId = '
.
$user_id
;
$user_groups
=
$this
->
Conn
->
Query
(
$sql
,
'GroupId'
);
if
(
!
isset
(
$user_groups
[
$group_id
])
)
{
$expire
=
adodb_mktime
()
+
$duration
;
}
else
{
$expire
=
$user_groups
[
$group_id
][
'MembershipExpires'
];
$expire
=
$expire
<
adodb_mktime
()
?
adodb_mktime
()
+
$duration
:
$expire
+
$duration
;
}
/*// Customization healtheconomics.org
if ($item_data['DurationType'] == 2) {
$expire = $item_data['AccessExpiration'];
}
// Customization healtheconomics.org --*/
$fields_hash
=
Array
(
'PortalUserId'
=>
$user_id
,
'GroupId'
=>
$group_id
,
'MembershipExpires'
=>
$expire
,
);
$this
->
Conn
->
doInsert
(
$fields_hash
,
TABLE_PREFIX
.
'UserGroupRelations'
,
'REPLACE'
);
$sub_order
=
$this
->
Application
->
recallObject
(
'ord.-sub'
.
$event
->
getEventParam
(
'next_sub_number'
),
'ord'
);
$sub_order
->
SetDBField
(
'IsRecurringBilling'
,
getArrayValue
(
$item_data
,
'IsRecurringBilling'
)
?
1
:
0
);
$sub_order
->
SetDBField
(
'GroupId'
,
$group_id
);
$sub_order
->
SetDBField
(
'NextCharge_date'
,
$expire
);
$sub_order
->
SetDBField
(
'NextCharge_time'
,
$expire
);
}
function
OnDownloadableApprove
(
$event
)
{
$field_values
=
$event
->
getEventParam
(
'field_values'
);
$product_id
=
$field_values
[
'ProductId'
];
$sql
=
'SELECT PortalUserId FROM '
.
$this
->
Application
->
getUnitOption
(
'ord'
,
'TableName'
).
'
WHERE OrderId = '
.
$field_values
[
'OrderId'
];
$user_id
=
$this
->
Conn
->
GetOne
(
$sql
);
$sql
=
'INSERT INTO '
.
TABLE_PREFIX
.
'UserFileAccess VALUES("", '
.
$product_id
.
', '
.
$user_id
.
')'
;
$this
->
Conn
->
Query
(
$sql
);
}
protected
function
OnPackageApprove
(
kEvent
$event
)
{
$field_values
=
$event
->
getEventParam
(
'field_values'
);
$item_data
=
unserialize
(
$field_values
[
'ItemData'
]);
$package_content_ids
=
$item_data
[
'PackageContent'
];
/** @var ProductsItem $object_item */
$object_item
=
$this
->
Application
->
recallObject
(
'p.packageitem'
,
null
,
array
(
'skip_autoload'
=>
true
));
foreach
(
$package_content_ids
as
$package_item_id
)
{
$object_field_values
=
array
();
// query processing data from product and run approve event
$sql
=
'SELECT ProcessingData
FROM '
.
TABLE_PREFIX
.
'Products
WHERE ProductId = '
.
$package_item_id
;
$processing_data
=
$this
->
Conn
->
GetOne
(
$sql
);
if
(
$processing_data
)
{
$processing_data
=
unserialize
(
$processing_data
);
$approve_event
=
new
kEvent
(
$processing_data
[
'ApproveEvent'
]);
//$order_item_fields = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'OrderItems WHERE OrderItemId = '.$grouping_data[1]);
$object_item
->
Load
(
$package_item_id
);
$object_field_values
[
'OrderId'
]
=
$field_values
[
'OrderId'
];
$object_field_values
[
'ProductId'
]
=
$package_item_id
;
$object_field_values
[
'ItemData'
]
=
serialize
(
$item_data
[
'PackageItemsItemData'
][
$package_item_id
]);
$approve_event
->
setEventParam
(
'field_values'
,
$object_field_values
);
$this
->
Application
->
HandleEvent
(
$approve_event
);
}
}
}
/**
* Saves edited item into temp table
* If there is no id, new item is created in temp table
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnPreSave
(
kEvent
$event
)
{
$this
->
CheckRequiredOptions
(
$event
);
parent
::
OnPreSave
(
$event
);
}
/**
* Set new price to ProductsPricing
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnAfterItemCreate
(
kEvent
$event
)
{
parent
::
OnAfterItemCreate
(
$event
);
$this
->
_updateProductPrice
(
$event
);
}
/**
* Set new price to ProductsPricing
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnAfterItemUpdate
(
kEvent
$event
)
{
parent
::
OnAfterItemUpdate
(
$event
);
$this
->
_updateProductPrice
(
$event
);
}
/**
* Updates product's primary price based on Price virtual field value
*
* @param kEvent $event
*/
function
_updateProductPrice
(
$event
)
{
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$price
=
$object
->
GetDBField
(
'Price'
);
// always create primary pricing, to show on Pricing tab (in admin) for tangible products
$force_create
=
(
$object
->
GetDBField
(
'Type'
)
==
PRODUCT_TYPE_TANGIBLE
)
&&
is_null
(
$price
);
if
(
$force_create
||
(
$price
!=
$object
->
GetOriginalField
(
'Price'
)))
{
// new product OR price was changed in virtual field
$this
->
setPrimaryPrice
(
$object
->
GetID
(),
(
float
)
$price
);
}
}
function
CheckRequiredOptions
(
$event
)
{
$object
=
$event
->
getObject
();
if
(
$object
->
GetDBField
(
'ProductId'
)
==
''
)
return
;
// if product does not have ID - it's not yet created
$opt_object
=
$this
->
Application
->
recallObject
(
'po'
,
null
,
Array
(
'skip_autoload'
=>
true
)
);
$has_required
=
$this
->
Conn
->
GetOne
(
'SELECT COUNT(*) FROM '
.
$opt_object
->
TableName
.
' WHERE Required = 1 AND ProductId = '
.
$object
->
GetDBField
(
'ProductId'
));
//we need to imitate data sumbit, as parent' PreSave sets object values from $items_info
$items_info
=
$this
->
Application
->
GetVar
(
$event
->
getPrefixSpecial
(
true
)
);
$items_info
[
$object
->
GetDBField
(
'ProductId'
)][
'HasRequiredOptions'
]
=
$has_required
?
'1'
:
'0'
;
$this
->
Application
->
SetVar
(
$event
->
getPrefixSpecial
(
true
),
$items_info
);
$object
->
SetDBField
(
'HasRequiredOptions'
,
$has_required
?
1
:
0
);
}
/**
* Sets required price in primary price backed, if it's missing, then create it
*
* @param int $product_id
* @param double $price
* @param Array $additional_fields
* @return bool
*/
function
setPrimaryPrice
(
$product_id
,
$price
,
$additional_fields
=
Array
())
{
/** @var kDBItem $pr_object */
$pr_object
=
$this
->
Application
->
recallObject
(
'pr.-item'
,
null
,
Array
(
'skip_autoload'
=>
true
)
);
$pr_object
->
Load
(
Array
(
'ProductId'
=>
$product_id
,
'IsPrimary'
=>
1
)
);
$sql
=
'SELECT COUNT(*) FROM '
.
$pr_object
->
TableName
.
' WHERE ProductId = '
.
$product_id
;
$has_pricings
=
$this
->
Conn
->
GetOne
(
$sql
);
if
(
$additional_fields
)
{
$pr_object
->
SetDBFieldsFromHash
(
$additional_fields
);
}
if
(
(
$price
===
false
)
&&
$has_pricings
)
return
false
;
if
(
$pr_object
->
isLoaded
()
)
{
$pr_object
->
SetField
(
'Price'
,
$price
);
return
$pr_object
->
Update
();
}
else
{
$group_id
=
$this
->
Application
->
ConfigValue
(
'User_LoggedInGroup'
);
$field_values
=
Array
(
'ProductId'
=>
$product_id
,
'IsPrimary'
=>
1
,
'MinQty'
=>
1
,
'MaxQty'
=>
-
1
,
'GroupId'
=>
$group_id
);
$pr_object
->
SetDBFieldsFromHash
(
$field_values
);
$pr_object
->
SetField
(
'Price'
,
$price
);
return
$pr_object
->
Create
();
}
}
/**
* Occurs after deleting item, id of deleted item
* is stored as 'id' param of event
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnAfterItemDelete
(
kEvent
$event
)
{
parent
::
OnAfterItemDelete
(
$event
);
$product_id
=
$event
->
getEventParam
(
'id'
);
if
(
!
$product_id
)
{
return
;
}
$sql
=
'DELETE FROM '
.
TABLE_PREFIX
.
'UserFileAccess
WHERE ProductId = '
.
$product_id
;
$this
->
Conn
->
Query
(
$sql
);
}
/**
* Load price from temp table if product mode is temp table
*
* @param kEvent $event
*/
/**
* Load price from temp table if product mode is temp table
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnAfterItemLoad
(
kEvent
$event
)
{
parent
::
OnAfterItemLoad
(
$event
);
/** @var ProductsItem $object */
$object
=
$event
->
getObject
();
$a_pricing
=
$object
->
getPrimaryPricing
();
if
(
!
$a_pricing
)
{
// pricing doesn't exist for new products
$price
=
$cost
=
null
;
}
else
{
$price
=
(
float
)
$a_pricing
[
'Price'
];
$cost
=
(
float
)
$a_pricing
[
'Cost'
];
}
// set original fields to use them in OnAfterItemCreate/OnAfterItemUpdate later
$object
->
SetDBField
(
'Price'
,
$price
);
$object
->
SetOriginalField
(
'Price'
,
$price
);
$object
->
SetDBField
(
'Cost'
,
$cost
);
$object
->
SetOriginalField
(
'Cost'
,
$cost
);
}
/**
* Allows to add products to package besides all that parent method does
*
* @param kEvent $event
*/
function
OnProcessSelected
(
$event
)
{
$dst_field
=
$this
->
Application
->
RecallVar
(
'dst_field'
);
if
(
$dst_field
==
'PackageContent'
)
{
$this
->
OnAddToPackage
(
$event
);
}
elseif
(
$dst_field
==
'AssignedCoupon'
)
{
$coupon_id
=
$this
->
Application
->
GetVar
(
'selected_ids'
);
$object
=
$event
->
getObject
();
$object
->
SetDBField
(
'AssignedCoupon'
,
$coupon_id
);
$this
->
RemoveRequiredFields
(
$object
);
$object
->
Update
();
}
else
{
parent
::
OnProcessSelected
(
$event
);
}
$this
->
finalizePopup
(
$event
);
}
/**
* Called when some products are selected in products selector for this prefix
*
* @param kEvent $event
*/
function
OnAddToPackage
(
$event
)
{
$selected_ids
=
$this
->
Application
->
GetVar
(
'selected_ids'
);
// update current package content with selected products
/** @var ProductsItem $object */
$object
=
$event
->
getObject
();
$product_ids
=
$selected_ids
[
'p'
]
?
explode
(
','
,
$selected_ids
[
'p'
])
:
Array
();
if
(
$product_ids
)
{
$current_ids
=
$object
->
GetPackageContentIds
();
$current_ids
=
array_unique
(
array_merge
(
$current_ids
,
$product_ids
));
// remove package product from selected list
$this_product
=
array_search
(
$object
->
GetID
(),
$current_ids
);
if
(
$this_product
!==
false
)
{
unset
(
$current_ids
[
$this_product
]);
}
$dst_field
=
$this
->
Application
->
RecallVar
(
'dst_field'
);
$object
->
SetDBField
(
$dst_field
,
'|'
.
implode
(
'|'
,
$current_ids
).
'|'
);
$object
->
Update
();
$this
->
ProcessPackageItems
(
$event
);
}
$this
->
finalizePopup
(
$event
);
}
function
ProcessPackageItems
(
kEvent
$event
)
{
//$this->Application->SetVar('p_mode', 't');
/** @var ProductsItem $object */
$object
=
$event
->
getObject
();
$content_ids
=
$object
->
GetPackageContentIds
();
if
(
sizeof
(
$content_ids
)
>
0
)
{
$total_weight
=
$this
->
Conn
->
GetOne
(
'SELECT SUM(Weight) FROM '
.
TABLE_PREFIX
.
'Products WHERE ProductId IN ('
.
implode
(
', '
,
$content_ids
).
') AND Type=1'
);
if
(!
$total_weight
)
$total_weight
=
0
;
$this
->
Conn
->
Query
(
'UPDATE '
.
$object
->
TableName
.
' SET Weight='
.
$total_weight
.
' WHERE ProductId='
.
$object
->
GetID
());
}
/*
$this->Application->SetVar('p_mode', false);
$list = $this->Application->recallObject('p.content', 'p_List', array('types'=>'content'));
$this->Application->SetVar('p_mode', 't');
$list->Query();
$total_weight_a = 0;
$total_weight_b = 0;
$list->GoFirst();
while (!$list->EOL())
{
if ($list->GetDBField('Type')==1){
$total_weight_a += $list->GetField('Weight_a');
$total_weight_b += $list->GetField('Weight_b');
}
$list->GoNext();
}
$object->SetField('Weight_a', $total_weight_a);
$object->SetField('Weight_b', $total_weight_b);
*/
//$object->Update();
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function
OnSaveItems
(
$event
)
{
//$event->CallSubEvent('OnUpdate');
$event
->
redirect
=
false
;
//$event->setRedirectParams(Array ('opener' => 's', 'pass' => 'all,p'));
}
/**
* Removes product from package
*
* @param kEvent $event
*/
function
OnRemovePackageItem
(
$event
)
{
$this
->
Application
->
SetVar
(
'p_mode'
,
't'
);
$object
=
$event
->
getObject
();
$items_info
=
$this
->
Application
->
GetVar
(
'p_content'
);
if
(
$items_info
)
{
$product_ids
=
array_keys
(
$items_info
);
$current_ids
=
$object
->
GetPackageContentIds
();
$current_ids_flip
=
array_flip
(
$current_ids
);
foreach
(
$product_ids
as
$key
=>
$val
){
unset
(
$current_ids_flip
[
$val
]);
}
$current_ids
=
array_keys
(
$current_ids_flip
);
$current_ids_str
=
'|'
.
implode
(
'|'
,
array_unique
(
$current_ids
)).
'|'
;
$object
->
SetDBField
(
'PackageContent'
,
$current_ids_str
);
}
$object
->
Update
();
$this
->
ProcessPackageItems
(
$event
);
}
/**
* Occurs before deleting item, id of item being
* deleted is stored as 'id' event param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnBeforeItemDelete
(
kEvent
$event
)
{
parent
::
OnBeforeItemDelete
(
$event
);
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$sql
=
'SELECT COUNT(*)
FROM '
.
TABLE_PREFIX
.
'Products
WHERE PackageContent LIKE "%|'
.
$object
->
GetID
()
.
'%"'
;
$product_includes_in
=
$this
->
Conn
->
GetOne
(
$sql
);
if
(
$product_includes_in
>
0
)
{
$event
->
status
=
kEvent
::
erFAIL
;
}
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
* @access protected
*/
public
function
getCustomExportColumns
(
kEvent
$event
)
{
$columns
=
parent
::
getCustomExportColumns
(
$event
);
$new_columns
=
Array
(
'__VIRTUAL__Price'
=>
'Price'
,
'__VIRTUAL__Cost'
=>
'Cost'
,
);
return
array_merge
(
$columns
,
$new_columns
);
}
/**
* Sets non standart virtual fields (e.g. to other tables)
*
* @param kEvent $event
*/
function
setCustomExportColumns
(
$event
)
{
parent
::
setCustomExportColumns
(
$event
);
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$this
->
setPrimaryPrice
(
$object
->
GetID
(),
(
double
)
$object
->
GetDBField
(
'Price'
),
Array
(
'Cost'
=>
(
double
)
$object
->
GetDBField
(
'Cost'
)));
}
function
OnPreSaveAndOpenPopup
(
$event
)
{
/** @var kDBItem $object */
$object
=
$event
->
getObject
();
$this
->
RemoveRequiredFields
(
$object
);
$event
->
CallSubEvent
(
'OnPreSave'
);
$event
->
redirect
=
$this
->
Application
->
GetVar
(
't'
);
// pass ID too, in case if product is created by OnPreSave call to ensure proper editing
$event
->
SetRedirectParam
(
'pass'
,
'all'
);
$event
->
SetRedirectParam
(
$event
->
getPrefixSpecial
(
true
)
.
'_id'
,
$object
->
GetID
());
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
* @access public
*/
public
function
getPassedID
(
kEvent
$event
)
{
if
(
$this
->
Application
->
isAdminUser
)
{
$event
->
setEventParam
(
'raise_warnings'
,
0
);
}
$passed
=
parent
::
getPassedID
(
$event
);
if
(
$passed
)
{
return
$passed
;
}
if
(
$this
->
Application
->
isAdminUser
)
{
// we may get product id out of OrderItem, if it exists
/** @var OrdersItem $ord_item */
$ord_item
=
$this
->
Application
->
recallObject
(
'orditems'
,
null
,
Array
(
'raise_warnings'
=>
0
));
if
(
$ord_item
->
GetDBField
(
'ProductId'
)
)
{
$passed
=
$ord_item
->
GetDBField
(
'ProductId'
);
}
}
return
$passed
;
}
/**
* Occurs, when config was parsed, allows to change config data dynamically
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnAfterConfigRead
(
kEvent
$event
)
{
parent
::
OnAfterConfigRead
(
$event
);
if
(!
$this
->
Application
->
LoggedIn
())
{
return
;
}
$user_id
=
$this
->
Application
->
RecallVar
(
'user_id'
);
$sql
=
'SELECT PrimaryGroupId
FROM '
.
TABLE_PREFIX
.
'Users
WHERE PortalUserId = '
.
$user_id
;
$primary_group_id
=
$this
->
Conn
->
GetOne
(
$sql
);
if
(!
$primary_group_id
)
{
return
;
}
$sub_select
=
' SELECT pp.Price
FROM '
.
TABLE_PREFIX
.
'ProductsPricing AS pp
WHERE pp.ProductId = %1$s.ProductId AND GroupId = '
.
$primary_group_id
.
'
ORDER BY MinQty
LIMIT 0,1'
;
$calculated_fields
=
$this
->
Application
->
getUnitOption
(
$event
->
Prefix
,
'CalculatedFields'
);
$calculated_fields
[
''
][
'Price'
]
=
'IFNULL(('
.
$sub_select
.
'), '
.
$calculated_fields
[
''
][
'Price'
]
.
')'
;
$this
->
Application
->
setUnitOption
(
$event
->
Prefix
,
'CalculatedFields'
,
$calculated_fields
);
}
/**
* Starts product editing, remove any pending inventory actions
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnEdit
(
kEvent
$event
)
{
$this
->
Application
->
RemoveVar
(
'inventory_actions'
);
parent
::
OnEdit
(
$event
);
}
/**
* Adds "Shop Cart" tab on paid listing type editing tab
*
* @param kEvent $event
*/
function
OnModifyPaidListingConfig
(
$event
)
{
$edit_tab_presets
=
$this
->
Application
->
getUnitOption
(
$event
->
MasterEvent
->
Prefix
,
'EditTabPresets'
);
$edit_tab_presets
[
'Default'
][
'shopping_cart'
]
=
Array
(
'title'
=>
'la_tab_ShopCartEntry'
,
't'
=>
'in-commerce/paid_listings/paid_listing_type_shopcart'
,
'priority'
=>
2
);
$this
->
Application
->
setUnitOption
(
$event
->
MasterEvent
->
Prefix
,
'EditTabPresets'
,
$edit_tab_presets
);
}
/**
* [HOOK] Allows to add cloned subitem to given prefix
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnCloneSubItem
(
kEvent
$event
)
{
parent
::
OnCloneSubItem
(
$event
);
if
(
$event
->
MasterEvent
->
Prefix
==
'rev'
)
{
$clones
=
$this
->
Application
->
getUnitOption
(
$event
->
MasterEvent
->
Prefix
,
'Clones'
);
$subitem_prefix
=
$event
->
Prefix
.
'-'
.
$event
->
MasterEvent
->
Prefix
;
$clones
[
$subitem_prefix
][
'ConfigMapping'
]
=
Array
(
'PerPage'
=>
'Comm_Perpage_Reviews'
,
'ReviewDelayInterval'
=>
'product_ReviewDelay_Value'
,
'ReviewDelayValue'
=>
'product_ReviewDelay_Interval'
,
);
$this
->
Application
->
setUnitOption
(
$event
->
MasterEvent
->
Prefix
,
'Clones'
,
$clones
);
}
}
/**
* Adds product to comparison list
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnAddToCompare
(
kEvent
$event
)
{
$products
=
$this
->
getCompareProducts
();
$product_id
=
(
int
)
$this
->
Application
->
GetVar
(
$event
->
Prefix
.
'_id'
);
if
(
$product_id
)
{
$max_products
=
$this
->
Application
->
ConfigValue
(
'MaxCompareProducts'
);
if
(
count
(
$products
)
<
$max_products
)
{
$products
[]
=
$product_id
;
$this
->
Application
->
Session
->
SetCookie
(
'compare_products'
,
implode
(
'|'
,
array_unique
(
$products
)));
$event
->
SetRedirectParam
(
'result'
,
'added'
);
}
else
{
$event
->
SetRedirectParam
(
'result'
,
'error'
);
}
}
$event
->
SetRedirectParam
(
'pass'
,
'm,p'
);
}
/**
* Adds product to comparison list
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnRemoveFromCompare
(
kEvent
$event
)
{
$products
=
$this
->
getCompareProducts
();
$product_id
=
(
int
)
$this
->
Application
->
GetVar
(
$event
->
Prefix
.
'_id'
);
if
(
$product_id
&&
in_array
(
$product_id
,
$products
)
)
{
$products
=
array_diff
(
$products
,
Array
(
$product_id
));
$this
->
Application
->
Session
->
SetCookie
(
'compare_products'
,
implode
(
'|'
,
array_unique
(
$products
)));
$event
->
SetRedirectParam
(
'result'
,
'removed'
);
}
$event
->
SetRedirectParam
(
'pass'
,
'm,p'
);
}
/**
* Cancels product compare
*
* @param kEvent $event
* @return void
* @access protected
*/
protected
function
OnCancelCompare
(
kEvent
$event
)
{
$this
->
Application
->
Session
->
SetCookie
(
'compare_products'
,
''
,
-
1
);
$event
->
SetRedirectParam
(
'result'
,
'all_removed'
);
}
/**
* Returns products, that needs to be compared with each other
*
* @return Array
* @access protected
*/
protected
function
getCompareProducts
()
{
$products
=
$this
->
Application
->
GetVarDirect
(
'compare_products'
,
'Cookie'
);
$products
=
$products
?
explode
(
'|'
,
$products
)
:
Array
();
return
$products
;
}
}
Event Timeline
Log In to Comment