Page MenuHomeIn-Portal Phabricator

in-commerce
No OneTemporary

File Metadata

Created
Mon, Feb 3, 7:16 AM

in-commerce

Index: branches/RC/in-commerce/units/products/products_event_handler.php
===================================================================
--- branches/RC/in-commerce/units/products/products_event_handler.php (revision 11533)
+++ branches/RC/in-commerce/units/products/products_event_handler.php (revision 11534)
@@ -1,1204 +1,1216 @@
<?php
class ProductsEventHandler extends kCatDBEventHandler {
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
// front
'OnCancelAction' => Array('self' => true),
'OnRateProduct' => Array('self' => true),
'OnClearRecent' => Array('self' => true),
'OnRecommendProduct' => 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);
}
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
*/
function OnBeforeItemCreate(&$event)
{
$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)
{
$object =& $event->getObject();
$object->SetFieldsFromHash( $this->getSubmittedFields($event) );
if ($object->GetDBField('InventoryStatus') == 2) {
// inventory by options (use first selected combination in grid)
$combination_id = array_shift( array_keys( $this->Application->GetVar('poc_grid') ) );
}
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 (!isset($object->FieldErrors['Qty']['pseudo'])){
$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;
$order =& $this->Application->recallObject('ord.-inv', null, Array('skip_autoload' => true));
foreach ($orders as $ord_id) {
$order->Load($ord_id);
$email_event_admin =& $this->Application->EmailEventAdmin('BACKORDER.FULLFILL');
//reserve what's possible in any case
$this->Application->HandleEvent( $event, 'ord:OnReserveItems' );
if ($event->status == erSUCCESS) { //
//in case the order is ready to process - process it
$this->Application->HandleEvent( $event, 'ord:OnOrderProcess' );
}
}
}
function OnBeforeDeleteFromLive(&$event)
{
$id = $event->getEventParam('id');
$product =& $this->Application->recallObject($event->Prefix.'.itemlive', null, Array('skip_autoload' => true));
$product->SwitchToLive();
if (!$product->Load($id)) return ; // this will make sure New product will not be overwritten with empty data
$temp =& $this->Application->recallObject($event->Prefix.'.itemtemp', null, Array('skip_autoload' => true));
$temp->SwitchToTemp();
$temp->Load($id);
$temp->SetDBFieldsFromHash($product->FieldValues, Array('QtyInStock','QtyReserved','QtyBackOrdered','QtyOnOrder'));
$temp->Update();
}
function clearSelectedIDs(&$event)
{
parent::clearSelectedIDs($event);
$this->Application->SetVar('inventory_actions', $this->Application->RecallVar('inventory_actions'));
$this->Application->RemoveVar('inventory_actions');
}
function OnSave(&$event)
{
$res = parent::OnSave($event);
if ($event->status == erSUCCESS) {
$this->RunScheduledInventoryActions($event);
}
return $res;
}
function OnPreCreate(&$event)
{
parent::onPreCreate($event);
$object =& $event->GetObject();
$object->SetDBField('Type', $this->Application->GetVar( $event->getPrefixSpecial(true).'_new_type' ));
}
function OnPreSaveAndGo(&$event) {
$event->CallSubEvent('OnPreSave');
$this->LoadItem($event);
$object =& $event->getObject();
$from_type = $object->GetDBField('Type');
if ($event->status==erSUCCESS) {
$this->Application->SetVar($event->Prefix_Special.'_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');
$except_types=$event->getEventParam('except');
$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
// products already in shopping cart: begin
if (strpos($types, 'in_cart') !== false || strpos($except_types, 'in_cart') !== false) {
$order_id = $this->Application->RecallVar('ord_id');
if ($order_id) {
$in_cart = $this->Conn->GetCol('SELECT ProductId FROM '.TABLE_PREFIX.'OrderItems WHERE OrderId = '.$order_id);
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 (strpos($types, 'my_downloads') !== false || strpos($except_types, 'my_downloads') !== false)
{
$user_id = $this->Application->RecallVar('user_id');
$my_downloads = ($user_id > 0) ? $this->Conn->GetCol('SELECT ProductId FROM '.TABLE_PREFIX.'UserFileAccess WHERE PortalUserId = '.$user_id) : 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 (strpos($types, 'wish_list') !== false || strpos($except_types, 'wish_list') !== false) {
$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 (strpos($types, 'content') !== false) {
$object->removeFilter('category_filter');
$object->AddGroupByField('%1$s.ProductId');
$item_type = $this->Application->getUnitOption('p', 'ItemType');
$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->IsAdmin() ) {
$object->addFilter('expire_filter', '%1$s.Expire IS NULL OR %1$s.Expire > UNIX_TIMESTAMP()');
}
return $type_clauses;
}
function OnClearRecent(&$event)
{
$this->Application->RemoveVar('recent_products');
}
/**
* Occurs, when user rates a product
*
* @param kEvent $event
*/
function OnRateProduct(&$event)
{
$event->redirect_params = Array('pass' => 'all,p');
$event->redirect = $this->Application->GetVar('success_template');
$object =& $event->getObject();
$user_id = ($this->Application->RecallVar('user_id') == 0) ? -2 : $this->Application->RecallVar('user_id');
$sql = ' SELECT * FROM '.TABLE_PREFIX.'SpamControl
WHERE ItemResourceId='.$object->GetDBField('ResourceId').'
AND IPaddress="'.$_SERVER['REMOTE_ADDR'].'"
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="'.$_SERVER['REMOTE_ADDR'].'"
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').',
"'.$_SERVER['REMOTE_ADDR'].'",
'.$user_id.',
"Rating",
'.$expire.')';
$this->Conn->Query($sql);
}
else
{
$event->status == erFAIL;
$event->redirect=false;
$object->FieldErrors['CachedRating']['pseudo'] = 'too_frequent';
$object->ErrorMsgs['too_frequent'] = $this->Application->Phrase('lu_ferror_rate_duplicate');
}
}
function OnCancelAction(&$event)
{
$event->redirect_params = Array('pass' => 'all,p');
$event->redirect = $this->Application->GetVar('cancel_template');
}
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
$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 (eregi("^[a-z0-9]+([-_\.]?[a-z0-9])+@[a-z0-9]+([-_\.]?[a-z0-9])+\.[a-z]{2,4}", $friend_email))
{
$user_id = $this->Application->RecallVar('user_id');
$email_event = &$this->Application->EmailEventUser('PRODUCT.SUGGEST', $user_id, $send_params);
if ($email_event->status == erSUCCESS){
$event->redirect_params = array('opener' => 's', 'pass' => 'all');
$event->redirect = $this->Application->GetVar('template_success');
}
else {
// $event->redirect_params = array('opener' => 's', 'pass' => 'all');
// $event->redirect = $this->Application->GetVar('template_fail');
$object->ErrorMsgs['send_error'] = $this->Application->Phrase('lu_email_send_error');
$object->FieldErrors['Email']['pseudo'] = 'send_error';
$event->status = erFAIL;
}
}
else {
$object->ErrorMsgs['invalid_email'] = $this->Application->Phrase('lu_InvalidEmail');
$object->FieldErrors['Email']['pseudo'] = 'invalid_email';
$event->status = 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)
{
$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'].')');
return false;
}
$order_table = $this->Application->getUnitOption('ord', 'TableName');
$order_idfield = $this->Application->getUnitOption('ord', 'IDField');
$sql = 'SELECT PortalUserId FROM %s WHERE %s = %s';
$user_id = $this->Conn->GetOne( sprintf($sql, $order_table, $order_idfield, $field_values['OrderId']) );
$group_id = $item_data['PortalGroupId'];
$duration = $item_data['Duration'];
$sql = 'SELECT * FROM '.TABLE_PREFIX.'UserGroup WHERE PortalUserId = %s';
$user_groups = $this->Conn->Query( sprintf($sql, $user_id), 'GroupId' );
$sql = 'REPLACE INTO '.TABLE_PREFIX.'UserGroup (PortalUserId,GroupId,MembershipExpires,PrimaryGroup) VALUES (%s,%s,%s,%s)';
if( !isset($user_groups[$group_id]) )
{
$primary_group = count($user_groups) == 0 ? 1 : 0;
$expire = adodb_mktime() + $duration;
}
else {
$primary_group = $user_groups[$group_id]['PrimaryGroup'];
$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 --
*/
$this->Conn->Query( sprintf($sql, $user_id, $group_id, $expire, $primary_group) );
$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);
}
function OnPackageApprove(&$event){
$field_values = $event->getEventParam('field_values');
$item_data = unserialize($field_values['ItemData']);
$package_content_ids = $item_data['PackageContent'];
$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);
}
}
}
function OnPreSave(&$event)
{
$this->CheckRequiredOptions($event);
parent::OnPreSave($event);
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
foreach ($items_info as $id => $field_values) {
$primary_price = getArrayValue($field_values, 'Price');
$this->setPrimaryPrice($id, $primary_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())
{
$pr_object =& $this->Application->recallObject('pr.-item', null, Array('skip_autoload' => true) );
/* @var $pr_object kDBItem */
$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);
$ret = $pr_object->Create();
if ($pr_object->mode == 't') {
$pr_object->setTempID();
}
return $ret;
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function 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
*/
function OnAfterItemLoad(&$event)
{
parent::OnAfterItemLoad($event);
$object =& $event->getObject();
$a_pricing = $object->getPrimaryPricing();
$object->SetDBField('Price', floatval($a_pricing['Price']));
$object->SetDBField('Cost', floatval($a_pricing['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
$this->Application->SetVar($event->Prefix.'_mode', 't');
$object =& $event->getObject();
/* @var $object ProductsItem */
$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(&$event)
{
//$this->Application->SetVar('p_mode', 't');
$object =& $event->getObject();
/* @var $object ProductsItem */
$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->redirect_params = 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);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnBeforeItemDelete(&$event){
$object = &$event->getObject();
$product_includes_in = $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Products WHERE PackageContent LIKE "%|'.$object->GetID().'%"');
if ($product_includes_in > 0){
$event->status=erFAIL;
}
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
*/
function getCustomExportColumns(&$event)
{
$columns = parent::getCustomExportColumns($event);
$new_columns = Array(
'__VIRTUAL__Price' => 'Price',
'__VIRTUAL__Cost' => 'Cost',
);
return array_merge_recursive2($columns, $new_columns);
}
/**
* Sets non standart virtual fields (e.g. to other tables)
*
* @param kEvent $event
*/
function setCustomExportColumns(&$event)
{
parent::setCustomExportColumns($event);
$object =& $event->getObject();
$this->setPrimaryPrice($object->GetID(), (double)$object->GetDBField('Price'), Array('Cost' => (double)$object->GetDBField('Cost')) );
}
function OnPreSaveAndOpenPopup(&$event)
{
$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->redirect_params = Array(
'pass' => 'all',
$event->getPrefixSpecial(true).'_id' => $object->GetID(),
);
}
function getPassedId(&$event)
{
// $event->setEventParam('raise_warnings', 0);
$passed = parent::getPassedID($event);
if ($passed) return $passed;
if ($this->Application->IsAdmin()) {
// we may get product id out of OrderItem, if it exists
// if ($this->Application->GetVar('orditems_id')) {
$ord_item =& $this->Application->recallObject('orditems');
if ($ord_item->GetDBField('ProductId')) {
$passed = $ord_item->GetDBField('ProductId');
}
// }
}
return $passed;
}
function OnAfterConfigRead(&$event)
{
parent::OnAfterConfigRead($event);
$user_id = $this->Application->RecallVar('user_id');
if (!is_numeric($user_id)) {
return ;
}
$calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');
$sql = 'SELECT GroupId
FROM '.TABLE_PREFIX.'UserGroup
WHERE PrimaryGroup = 1 AND PortalUserId = '.$user_id;
$primary_group = $this->Conn->GetOne($sql);
if (!$primary_group) return;
$calculated_fields['']['Price'] = '
( IFNULL(
( SELECT pp.Price FROM '.TABLE_PREFIX.'ProductsPricing AS pp
WHERE pp.ProductId = %1$s.ProductId AND GroupId = '.$primary_group.' ORDER BY MinQty LIMIT 0,1
), pricing.Price
)
)';
$this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields);
}
/**
* Starts product editing, remove any pending inventory actions
*
* @param kEvent $event
*/
function OnEdit(&$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);
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/in-commerce/units/products/products_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.84.2.4
\ No newline at end of property
+1.84.2.5
\ No newline at end of property
Index: branches/RC/in-commerce/units/products/products_config.php
===================================================================
--- branches/RC/in-commerce/units/products/products_config.php (revision 11533)
+++ branches/RC/in-commerce/units/products/products_config.php (revision 11534)
@@ -1,540 +1,551 @@
<?php
$config = Array(
'Prefix' => 'p',
'ItemClass' => Array('class'=>'ProductsItem','file'=>'products_item.php', 'require_classes' => Array('kCatDBItem'), 'build_event'=>'OnItemBuild'),
'ListClass' => Array('class'=>'kCatDBList','file'=>'','build_event'=>'OnListBuild'),
'EventHandlerClass' => Array('class'=>'ProductsEventHandler','file'=>'products_event_handler.php', 'require_classes' => Array('kCatDBEventHandler'), 'build_event'=>'OnBuild'),
'TagProcessorClass' => Array('class'=>'ProductsTagProcessor','file'=>'products_tag_processor.php', 'require_classes' => Array('kCatDBTagProcessor'), 'build_event'=>'OnBuild'),
'AutoLoad' => true,
'QueryString' => Array(
1 => 'id',
2 => 'Page',
3 => 'Reviews_Page',
4 => 'event',
5 => 'mode',
),
'CatalogItem' => true,
'AdminTemplatePath' => 'products',
'AdminTemplatePrefix' => 'products_',
'SearchConfigPostfix' => 'products',
'ConfigPriority' => 0,
'Hooks' => Array (
// for subscription products: access group is saved before changing pricings
Array (
'Mode' => hAFTER,
'Conditional' => true,
'HookToPrefix' => 'pr',
'HookToSpecial' => '*',
'HookToEvent' => Array('OnNew', 'OnAfterItemLoad'),
'DoPrefix' => '',
'DoSpecial' => '*',
'DoEvent' => 'OnPreSave',
),
Array (
'Mode' => hAFTER,
'Conditional' => false,
'HookToPrefix' => 'lst',
'HookToSpecial' => '',
'HookToEvent' => Array( 'OnBeforeCopyToLive' ),
'DoPrefix' => '',
'DoSpecial' => '',
'DoEvent' => 'OnSaveVirtualProduct',
),
Array (
'Mode' => hAFTER,
'Conditional' => false,
'HookToPrefix' => 'lst',
'HookToSpecial' => '*',
'HookToEvent' => Array('OnAfterItemDelete'),
'DoPrefix' => '',
'DoSpecial' => '',
'DoEvent' => 'OnDeleteListingType',
),
Array (
+ 'Mode' => hAFTER,
+ 'Conditional' => false,
+ 'HookToPrefix' => 'lst',
+ 'HookToSpecial' => '*',
+ 'HookToEvent' => Array('OnAfterConfigRead'),
+ 'DoPrefix' => '',
+ 'DoSpecial' => '',
+ 'DoEvent' => 'OnModifyPaidListingConfig',
+ ),
+
+ Array (
'Mode' => hBEFORE,
'Conditional' => false,
'HookToPrefix' => 'file',
'HookToSpecial' => '',
'HookToEvent' => Array( 'OnNew', 'OnEdit' ),
'DoPrefix' => '',
'DoSpecial' => '',
'DoEvent' => 'OnPreSave',
),
Array (
'Mode' => hBEFORE,
'Conditional' => false,
'HookToPrefix' => '',
'HookToSpecial' => '*',
'HookToEvent' => Array('OnAfterConfigRead'),
'DoPrefix' => 'cdata',
'DoSpecial' => '*',
'DoEvent' => 'OnDefineCustomFields',
),
),
'IDField' => 'ProductId',
'StatusField' => Array('Status'), // field, that is affected by Approve/Decline events
'TitleField' => 'Name', // field, used in bluebar when editing existing item
'ItemType' => 11, // this is used when relation to product is added from in-portal and via-versa
'ViewMenuPhrase' => 'la_text_Products',
'CatalogTabIcon' => 'in-commerce:icon16_product.gif',
'ItemPropertyMappings' => Array(
'NewDays' => 'Product_NewDays', // number of days item to be NEW
'MinPopVotes' => 'Product_MinPopVotes', // minimum number of votes for an item to be POP
'MinPopRating' => 'Product_MinPopRating', // minimum rating for an item to be POP
'MaxHotNumber' => 'Product_MaxHotNumber', // maximum number of HOT (top seller) items
'HotLimit' => 'Product_HotLimit', // variable name in inp_Cache table
'ClickField' => 'Hits', // item click count is stored here (in item table)
),
'TitlePhrase' => 'la_text_Product',
'TitlePresets' => Array(
'default' => Array( 'new_status_labels' => Array('p'=>'!la_title_Adding_Product!'),
'edit_status_labels' => Array('p'=>'!la_title_Editing_Product!'),
'new_titlefield' => Array('p'=>'!la_title_NewProduct!'),
),
'product_list'=>Array( 'prefixes' => Array('c_List','p_List'),
'tag_params' => Array('c'=> Array('per_page'=>-1)),
'format' => "!la_title_Categories! (#c_recordcount#) - !la_title_Products! (#p_recordcount#)",
),
'products_edit'=>Array( 'prefixes' => Array('p'),
'new_titlefield' => Array('p'=>'!la_title_NewProduct!'),
'format' => "#p_status# '#p_titlefield#' - !la_title_General!",
),
'inventory' => Array('prefixes' => Array('p'), 'format' => "#p_status# - '#p_titlefield#' - !la_title_Product_Inventory!"),
'pricing' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Product_Pricing!"),
'access_pricing' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Product_AccessPricing!"),
'access' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Product_Access!"),
'files' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Product_Files!"),
'options'=> Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Product_Options!"),
'categories'=> Array('prefixes' => Array('p','p-ci_List'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Categories!"),
'relations' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Relations!"),
'content' => Array('prefixes' => Array('p','p.content_List'), 'tag_params' => Array('p.content' => Array('types'=>'content', 'live_table'=>true)), 'format' => "#p_status# '#p_titlefield#' - !la_title_Product_PackageContent!"),
'images' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Images!"),
'reviews' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Reviews!"),
'products_custom' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_Custom!"),
'images_edit' => Array( 'prefixes' => Array('p', 'img'),
'new_status_labels' => Array('img'=>'!la_title_Adding_Image!'),
'edit_status_labels' => Array('img'=>'!la_title_Editing_Image!'),
'new_titlefield' => Array('img'=>'!la_title_New_Image!'),
'format' => "#p_status# '#p_titlefield#' - #img_status# '#img_titlefield#'",
),
'pricing_edit' => Array( 'prefixes' => Array('p', 'pr'),
'new_status_labels' => Array('pr'=>"!la_title_Adding_PriceBracket! '!la_title_New_PriceBracket!'"),
'edit_status_labels' => Array('pr'=>'!la_title_Editing_PriceBracket!'),
'format' => "#p_status# '#p_titlefield#' - #pr_status#",
),
'options_edit' => Array( 'prefixes' => Array('p', 'po'),
'new_status_labels' => Array('po'=>"!la_title_Adding_Option!"),
'edit_status_labels' => Array('po'=>'!la_title_Editing_Option!'),
'new_titlefield' => Array('po'=>'!la_title_New_Option!'),
'format' => "#p_status# '#p_titlefield#' - #po_status# '#po_titlefield#'",
),
'options_combinations' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_ManagingOptionCombinations!"),
'shipping_options' => Array('prefixes' => Array('p'), 'format' => "#p_status# '#p_titlefield#' - !la_title_ManagingShippingOptions!"),
'file_edit' => Array( 'prefixes' => Array('p', 'file'),
'new_status_labels' => Array('file'=>"!la_title_Adding_File!"),
'edit_status_labels' => Array('file'=>'!la_title_Editing_File!'),
'new_titlefield' => Array('file'=>'!la_title_New_File!'),
'format' => "#p_status# '#p_titlefield#' - #file_status# '#file_titlefield#'",
),
'relations_edit' => Array( 'prefixes' => Array('p', 'rel'),
'new_status_labels' => Array('rel'=>"!la_title_Adding_Relationship! '!la_title_New_Relationship!'"),
'edit_status_labels' => Array('rel'=>'!la_title_Editing_Relationship!'),
'format' => "#p_status# '#p_titlefield#' - #rel_status#",
),
'reviews_edit' => Array( 'prefixes' => Array('p', 'rev'),
'new_status_labels' => Array('rev'=>"!la_title_Adding_Review! '!la_title_New_Review!'"),
'edit_status_labels' => Array('rev'=>'!la_title_Editing_Review!'),
'format' => "#p_status# '#p_titlefield#' - #rev_status#",
),
'coupon_selector' => Array('format' => '!la_title_CouponSelector!'),
'products_export' => Array('format' => '!la_title_ProductsExport!'),
'products_import' => Array('format' => '!la_title_ImportProducts!'),
'tree_in-commerce' => Array('format' => '!la_Text_Version! '.$this->Application->findModule('Name', 'In-Commerce', 'Version')),
),
'PermItemPrefix' => 'PRODUCT',
'PermTabText' => 'In-Commerce',
'PermSection' => Array('main' => 'CATEGORY:in-commerce:products_list', 'search' => 'in-commerce:search', 'email' => 'in-commerce:incommerce_configemail', 'custom' => 'in-commerce:configuration_custom'),
'Sections' => Array(
'in-commerce' => Array(
'parent' => 'in-portal:root',
'icon' => 'in-commerce:in-commerce',
'label' => 'la_title_In-Commerce',
'url' => Array('t' => 'sections_list', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array('view'),
'priority' => 3.4,
'type' => stTREE,
),
'in-commerce:products' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_general',
'label' => 'la_tab_Products',
'url' => Array('t' => 'catalog/advanced_view', 'anchor' => 'tab-p.showall', 'pass' => 'm'),
'onclick' => 'setCatalogTab(\'p.showall\')',
'permissions' => Array('view'),
'priority' => 0.1,
'type' => stTREE,
),
'in-commerce:general' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_general',
'label' => 'la_tab_GeneralSettings',
'url' => Array('t' => 'config/config_general', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array('view', 'edit'),
'priority' => 9,
'type' => stTREE,
),
'in-commerce:output' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_output',
'label' => 'la_tab_ConfigOutput',
'url' => Array('t' => 'config/config_universal', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array('view', 'edit'),
'priority' => 10,
'type' => stTREE,
),
'in-commerce:search' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_search',
'label' => 'la_tab_ConfigSearch',
'url' => Array('t' => 'config/config_search', 'module_key' => 'products', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array('view', 'edit'),
'priority' => 11,
'type' => stTREE,
),
'in-commerce:incommerce_configemail' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_email',
'label' => 'la_tab_ConfigE-mail',
'url' => Array('t' => 'config/config_email', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array('view', 'edit'),
'priority' => 12,
'type' => stTREE,
),
'in-commerce:contacts' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_contacts',
'label' => 'la_tab_ConfigContacts',
'url' => Array('t' => 'config/config_universal', 'pass_section' => true, 'pass' => 'm'),
'permissions' => Array('view', 'edit'),
'priority' => 13,
'type' => stTREE,
),
'in-commerce:configuration_custom' => Array(
'parent' => 'in-commerce',
'icon' => 'settings_custom',
'label' => 'la_tab_ConfigCustom',
'url' => Array('t' => 'custom_fields/custom_fields_list', 'cf_type' => 11, 'pass_section' => true, 'pass' => 'm,cf'),
'permissions' => Array('view', 'add', 'edit', 'delete'),
'priority' => 14,
'type' => stTREE,
),
),
'FilterMenu' => Array(
'Groups' => Array(
Array('mode' => 'AND', 'filters' => Array('show_active','show_pending','show_disabled'), 'type' => WHERE_FILTER),
Array('mode' => 'AND', 'filters' => Array('show_tang','show_sub','show_serv','show_download','show_package'), 'type' => WHERE_FILTER),
Array('mode' => 'AND', 'filters' => Array('show_new'), 'type' => HAVING_FILTER),
Array('mode' => 'AND', 'filters' => Array('show_hot'), 'type' => HAVING_FILTER),
Array('mode' => 'AND', 'filters' => Array('show_pop'), 'type' => HAVING_FILTER),
Array('mode' => 'AND', 'filters' => Array('show_pick'), 'type' => WHERE_FILTER),
),
'Filters' => Array(
'show_active' => Array('label' =>'la_Active', 'on_sql' => '', 'off_sql' => '%1$s.Status != 1' ),
'show_pending' => Array('label' => 'la_Pending', 'on_sql' => '', 'off_sql' => '%1$s.Status != 2' ),
'show_disabled' => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Status != 0' ),
's1' => Array(),
'show_tang' => Array('label' => 'la_product_tangible', 'on_sql' => '', 'off_sql' => '%1$s.Type != 1' ),
'show_sub' => Array('label' => 'la_product_subscription', 'on_sql' => '', 'off_sql' => '%1$s.Type != 2' ),
'show_serv' => Array('label' => 'la_product_service', 'on_sql' => '', 'off_sql' => '%1$s.Type != 3' ),
'show_download' => Array('label' => 'la_product_downloadable', 'on_sql' => '', 'off_sql' => '%1$s.Type != 4' ),
'show_package' => Array('label' => 'la_product_package', 'on_sql' => '', 'off_sql' => '%1$s.Type != 5' ),
's2' => Array(),
'show_new' => Array('label' => 'la_Text_New', 'on_sql' => '', 'off_sql' => '`IsNew` != 1' ),
'show_hot' => Array('label' => 'la_Text_TopSellers', 'on_sql' => '', 'off_sql' => '`IsHot` != 1' ),
'show_pop' => Array('label' => 'la_Text_Pop', 'on_sql' => '', 'off_sql' => '`IsPop` != 1' ),
'show_pick' => Array('label' => 'la_prompt_EditorsPick', 'on_sql' => '', 'off_sql' => '%1$s.`EditorsPick` != 1' ),
)
),
'TableName' => TABLE_PREFIX.'Products',
'CalculatedFields' => Array (
'' => Array (
'SameImages' => 'img.SameImages',
'LocalThumb' => 'img.LocalThumb',
'ThumbPath' => 'img.ThumbPath',
'ThumbUrl' => 'img.ThumbUrl',
'LocalImage' => 'img.LocalImage',
'LocalPath' => 'img.LocalPath',
'FullUrl' => 'img.Url',
'Price' => 'pricing.Price',
'Cost' => 'pricing.Cost',
'PrimaryCat' => TABLE_PREFIX.'%3$sCategoryItems.PrimaryCat',
'CategoryId' => TABLE_PREFIX.'%3$sCategoryItems.CategoryId',
'ParentPath' => TABLE_PREFIX.'Category.ParentPath',
'Manufacturer' => TABLE_PREFIX.'Manufacturers.Name',
'Filename' => TABLE_PREFIX.'%3$sCategoryItems.Filename',
'FileSize' => 'files.Size',
'FilePath' => 'files.FilePath',
'FileVersion' => 'files.Version',
),
'showall' => Array (
'Price' => 'pricing.Price',
'Manufacturer' => TABLE_PREFIX.'Manufacturers.Name',
'PrimaryCat' => TABLE_PREFIX.'%3$sCategoryItems.PrimaryCat',
'CategoryId' => TABLE_PREFIX.'%3$sCategoryItems.CategoryId',
'FileSize' => 'files.Size',
'FilePath' => 'files.FilePath',
'FileVersion' => 'files.Version',
'Filename' => TABLE_PREFIX.'%3$sCategoryItems.Filename',
),
),
'ListSQLs' => Array(
'' => ' SELECT %1$s.* %2$s
FROM %1$s
LEFT JOIN '.TABLE_PREFIX.'PortalGroup ON '.TABLE_PREFIX.'PortalGroup.GroupId = %1$s.AccessGroupId
LEFT JOIN '.TABLE_PREFIX.'%3$sCategoryItems ON '.TABLE_PREFIX.'%3$sCategoryItems.ItemResourceId = %1$s.ResourceId
LEFT JOIN '.TABLE_PREFIX.'Category ON '.TABLE_PREFIX.'Category.CategoryId = '.TABLE_PREFIX.'%3$sCategoryItems.CategoryId
LEFT JOIN '.TABLE_PREFIX.'Images img ON img.ResourceId = %1$s.ResourceId AND img.DefaultImg = 1
LEFT JOIN '.TABLE_PREFIX.'ProductFiles files ON files.ProductId = %1$s.ProductId AND files.IsPrimary = 1
LEFT JOIN '.TABLE_PREFIX.'ProductsPricing pricing ON pricing.ProductId = %1$s.ProductId AND pricing.IsPrimary = 1
LEFT JOIN '.TABLE_PREFIX.'Manufacturers ON '.TABLE_PREFIX.'Manufacturers.ManufacturerId = %1$s.ManufacturerId
LEFT JOIN '.TABLE_PREFIX.'PermCache perm ON perm.CategoryId = '.TABLE_PREFIX.'%3$sCategoryItems.CategoryId
LEFT JOIN '.TABLE_PREFIX.'%3$sProductsCustomData cust ON %1$s.ResourceId = cust.ResourceId',
'showall'=> 'SELECT %1$s.* %2$s FROM %1$s
LEFT JOIN '.TABLE_PREFIX.'ProductsPricing pricing ON pricing.ProductId = %1$s.ProductId AND pricing.IsPrimary = 1
LEFT JOIN '.TABLE_PREFIX.'ProductFiles files ON files.ProductId = %1$s.ProductId AND files.IsPrimary = 1
LEFT JOIN '.TABLE_PREFIX.'Manufacturers ON '.TABLE_PREFIX.'Manufacturers.ManufacturerId = %1$s.ManufacturerId
LEFT JOIN '.TABLE_PREFIX.'%3$sCategoryItems ON '.TABLE_PREFIX.'%3$sCategoryItems.ItemResourceId = %1$s.ResourceId
LEFT JOIN '.TABLE_PREFIX.'Category ON '.TABLE_PREFIX.'Category.CategoryId = '.TABLE_PREFIX.'%3$sCategoryItems.CategoryId
LEFT JOIN '.TABLE_PREFIX.'PermCache perm ON perm.CategoryId = '.TABLE_PREFIX.'%3$sCategoryItems.CategoryId
LEFT JOIN '.TABLE_PREFIX.'%3$sProductsCustomData cust ON %1$s.ResourceId = cust.ResourceId',
), // key - special, value - list select sql
'ListSortings' => Array(
'' => Array(
'ForcedSorting' => Array('Priority' => 'desc'),
'Sorting' => Array('Name' => 'asc'),
)
),
'ItemSQLs' => Array( ''=>' SELECT %1$s.* %2$s
FROM %1$s
LEFT JOIN '.TABLE_PREFIX.'PortalGroup pg ON pg.GroupId = %1$s.AccessGroupId
LEFT JOIN '.TABLE_PREFIX.'%3$sCategoryItems ON '.TABLE_PREFIX.'%3$sCategoryItems.ItemResourceId = %1$s.ResourceId
LEFT JOIN '.TABLE_PREFIX.'Category ON '.TABLE_PREFIX.'Category.CategoryId = '.TABLE_PREFIX.'%3$sCategoryItems.CategoryId
LEFT JOIN '.TABLE_PREFIX.'Images img ON img.ResourceId = %1$s.ResourceId AND img.DefaultImg = 1
LEFT JOIN '.TABLE_PREFIX.'ProductFiles files ON files.ProductId = %1$s.ProductId AND files.IsPrimary = 1
LEFT JOIN '.TABLE_PREFIX.'ProductsPricing pricing ON pricing.ProductId = %1$s.ProductId AND pricing.IsPrimary = 1
LEFT JOIN '.TABLE_PREFIX.'Manufacturers ON '.TABLE_PREFIX.'Manufacturers.ManufacturerId = %1$s.ManufacturerId
LEFT JOIN '.TABLE_PREFIX.'%3$sProductsCustomData cust ON %1$s.ResourceId = cust.ResourceId',
),
'SubItems' => Array('pr', 'rev', 'img', 'po', 'poc', 'p-ci', 'rel', 'file', 'p-cdata', 'p-fav'),
'Fields' => Array(
'ProductId' => Array('type' => 'int', 'not_null' => 1, 'default' => 0,),
'Name' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'required'=>true, 'max_len'=>255, 'default' => ''),
'AutomaticFilename' => Array('type' => 'int', 'not_null' => 1, 'default' => 1),
'SKU' => Array('type' => 'string', 'required'=>true, 'max_len'=>255, 'error_msgs' => Array('required' => 'Please fill in'), 'default' => NULL),
'Description' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => NULL),
'DescriptionExcerpt' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => NULL),
'Weight' => Array('type'=>'float', 'min_value_exc'=>0, 'formatter' => 'kUnitFormatter', 'format' => '%0.2f', 'default' => NULL),
'MSRP' => Array('type'=>'float', 'min_value_inc'=>0, 'formatter' => 'kFormatter', 'format' => '%0.2f', 'default' => NULL),
'ManufacturerId' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options'=>Array(0 => ''), 'options_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'Manufacturers ORDER BY Name', 'option_key_field'=>'ManufacturerId', 'option_title_field'=>'Name', 'not_null' => 1, 'default' => 0),
'Status' => Array('type' => 'int', 'not_null' => 1, 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2),
'BackOrder' => Array('type' => 'int', 'not_null' => 1, 'options' => Array ( 2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never' ), 'use_phrases' => 1, 'default' => 2 ),
'BackOrderDate' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'error_msgs' => Array('bad_date_format' => 'Please use the following date format: %s'), 'default' => NULL),
'NewItem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array ( 2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never' ), 'use_phrases' => 1, 'not_null' => true, 'default' => 2 ),
'HotItem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array ( 2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never' ), 'use_phrases' => 1, 'not_null' => true, 'default' => 2 ),
'PopItem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array ( 2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never' ), 'use_phrases' => 1, 'not_null' => true, 'default' => 2 ),
'EditorsPick' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
'Featured' => Array('type' => 'int', 'not_null' => true, 'default' => 0),
'OnSale' => Array('type' => 'int', 'not_null' => true, 'default' => 0),
'Priority' => Array('type'=>'int', 'not_null' => true, 'default' => 0),
'CachedRating' => Array('not_null' => true, 'default' => 0, 'type' => 'float', 'formatter' => 'kFormatter', 'format' => '%0.2f'),
'CachedVotesQty' => Array('type'=>'int', 'not_null' => true, 'default' => 0),
'Hits' => Array('type' => 'double', 'formatter'=>'kFormatter', 'format' => '%d', 'not_null' => true, 'default' => 0),
'CreatedOn' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default'=>'#NOW#'),
'Expire' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default'=>null),
'Type' => Array('type' => 'int', 'not_null' => 1, 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options'=>Array(1=>'la_product_tangible', 2=>'la_product_subscription', 4=>'la_product_downloadable', 3=>'la_product_service', /*6=>'la_gift_certificate', 5=>'la_product_package'*/), 'not_null' => 1, 'default' => 1 ),
'Modified' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default'=>'#NOW#'),
'ModifiedById' => Array('type' => 'int', 'not_null' => true, 'default' => 0),
'CreatedById' => Array('type' => 'int', 'not_null' => true, 'default' => 0),
'ResourceId' => Array('type' => 'int', 'default' => 0),
'CachedReviewsQty' => Array('type' => 'int', 'formatter'=>'kFormatter', 'format' => '%d', 'not_null' => 1, 'default' => 0),
'InventoryStatus' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(0 => 'la_Disabled', 1 => 'la_by_product', 2 => 'la_by_options'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
'QtyInStock' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'QtyInStockMin' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'QtyReserved' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'QtyBackOrdered' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'QtyOnOrder' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'InventoryComment' => Array('type' => 'string', 'default' => null),
'Qty' => Array('type'=>'int', 'formatter'=>'kFormatter', 'regexp'=>'/^[\d]+$/', 'error_msgs' => Array('invalid_format'=>'!la_invalid_integer!')),
'AccessGroupId' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'PortalGroup WHERE System!=1 AND Personal !=1 ORDER BY Name', 'option_key_field'=>'GroupId', 'option_title_field'=>'Name', 'default' => NULL),
'AccessDuration' => Array('type' => 'int', 'default' => NULL),
'AccessDurationType' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'use_phrases' => 1, 'options'=>Array(1 => 'la_opt_sec', 2 => 'la_opt_min', 3 => 'la_opt_hour', 4 => 'la_opt_day', 5 => 'la_opt_week', 6 => 'la_opt_month', 7 => 'la_opt_year' ), 'default' => NULL,),
'AccessStart' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL),
'AccessEnd' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL,),
'OptionsSelectionMode' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options'=>Array(0 => 'la_opt_Selection', 1 => 'la_opt_List'), 'default' => 0),
'HasRequiredOptions' => Array('type' => 'int', 'default' => 0, 'not_null' => 1),
'Virtual' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'ProcessingData' => Array('type' => 'string', 'default' => ''),
'PackageContent' => Array('type' => 'string', 'not_null' => 1, 'default' => ''),
'IsRecurringBilling' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
// 'PayPalRecurring' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, 'not_null' => '1', 'default' => '0'),
'ShippingMode' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options'=>Array(0 => 'la_shipping_AnyAndSelected', 1 => 'la_shipping_Limited'), 'not_null' => 1, 'default'=>0),
'ProcessingData' => Array('type' => 'string', 'default' => null),
'ShippingLimitation' => Array('type' => 'string', 'not_null' => 1, 'default' => ''),
'AssignedCoupon' =>
Array('type' => 'int', 'not_null' => 1, 'default' => 0,
'formatter'=>'kLEFTFormatter',
'options' => array(0 => 'None'),
'left_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'ProductsCoupons WHERE `%s` = \'%s\'',
'left_key_field'=>'CouponId',
'left_title_field'=>'Name'),
'MinQtyFreePromoShipping' => Array('type' => 'int', 'not_null' => 1, 'default' => 0),
'MetaKeywords' => Array('type' => 'string', 'default' => null),
'MetaDescription' => Array('type' => 'string', 'default' => null),
),
'VirtualFields' => Array(
'Qty' => 1,
'Price' => Array('type' => 'float', 'formatter' => 'kFormatter', 'not_null' => 1, 'format' => '%.2f', 'default' => 0),
'Cost' => Array('type' => 'float', 'formatter' => 'kFormatter', 'not_null' => 1, 'format' => '%.2f', 'default' => 0),
'IsHot' => Array('type'=>'int'),
'IsNew' => Array('type'=>'int'),
'IsPop' => Array('type'=>'int'),
'Manufacturer' => Array(),
// export related fields: begin
'CategoryId' => Array('type' => 'int', 'default' => 0),
'ExportFormat' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'CSV', /*2 => 'XML'*/), 'default' => 1),
'ExportFilename' => Array('type' => 'string', 'default' => ''),
'FieldsSeparatedBy' => Array('type' => 'string', 'default' => ','),
'FieldsEnclosedBy' => Array('type' => 'string', 'default' => '"'),
'LineEndings' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'Windows', 2 => 'UNIX'), 'default' => 1),
'LineEndingsInside' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'CRLF', 2 => 'LF'), 'default' => 2),
'IncludeFieldTitles' => Array('type' => 'int', 'default' => 1),
'ExportColumns' => Array('type' => 'string', 'formatter' => 'kOptionsFormatter', 'options' => Array()),
'AvailableColumns' => Array('type' => 'string', 'formatter' => 'kOptionsFormatter', 'options' => Array()),
'CategoryFormat' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_MixedCategoryPath', 2 => 'la_SeparatedCategoryPath'), 'use_phrases' => 1, 'default' => 1),
'CategorySeparator' => Array('type' => 'string', 'default' => ':'),
'IsBaseCategory' => Array('type' => 'int', 'default' => 0),
// export related fields: end
// import related fields: begin
'FieldTitles' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_Automatic', 2 => 'la_Manual'), 'use_phrases' => 1, 'default' => 1),
'ImportSource' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_Upload', 2 => 'la_Local'), 'use_phrases' => 1, 'default' => 2),
'ImportFilename' => Array('type' => 'string', 'formatter' => 'kUploadFormatter', 'max_size' => MAX_UPLOAD_SIZE, 'upload_dir' => (defined('EXPORT_BASE_PATH') ? EXPORT_BASE_PATH : '/admin/export') . '/'),
'ImportLocalFilename' => Array('type' => 'string', 'formatter' => 'kOptionsFormatter', 'default' => ''),
'CheckDuplicatesMethod' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_IDField', 2 => 'la_OtherFields'), 'use_phrases' => 1, 'default' => 1),
'ReplaceDuplicates' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, 'default' => 0),
'DuplicateCheckFields' => Array('type' => 'string', 'formatter' => 'kOptionsFormatter', 'options' => Array('Name' => 'NAME'), 'default' => '|Name|'),
'SkipFirstRow' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array(1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, 'default' => 1),
// import related fields: end
'ThumbnailImage' => Array('type' => 'string', 'default' => ''),
'FullImage' => Array('type' => 'string', 'default' => ''),
'ImageAlt' => Array('type' => 'string', 'default' => ''),
'Filename' => Array('type' => 'string','not_null' => '1','default' => ''),
'CachedNavbar' => Array('type' => 'string', 'default' => ''),
'ParentPath' => Array('type' => 'string', 'default' => ''),
'FileSize' => Array('type' => 'int','formatter' => 'kFilesizeFormatter','not_null' => 1, 'default' => 0),
'FilePath' => Array(),
'FileVersion' => Array(),
// for primary image
'SameImages' => Array('type' => 'string', 'default' => ''),
'LocalThumb' => Array('type' => 'string', 'default' => ''),
'ThumbPath' => Array('type' => 'string', 'default' => ''),
'ThumbUrl' => Array('type' => 'string', 'default' => ''),
'LocalImage' => Array('type' => 'string', 'default' => ''),
'LocalPath' => Array('type' => 'string', 'default' => ''),
'FullUrl' => Array('type' => 'string', 'default' => ''),
),
'Grids' => Array(
'Default' => Array(
'Icons' => Array('default'=>'icon16_product.gif',1=>'icon16_product.gif',2=>'icon16_product_pending.gif',0=>'icon16_product_disabled.gif'),
'Fields' => Array(
'ProductId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter' ),
'SKU' => Array( 'title'=>'la_col_ProductSKU' ),
'Type' => Array('title' => 'la_col_ProductType', 'filter_block' => 'grid_options_filter'),
'Manufacturer' => Array('title' => 'la_col_Manufacturer'),
'Name' => Array( 'title'=>'la_col_ProductName', 'data_block'=>'grid_catitem_td' ),
'Price' => Array('title' => 'la_col_Price', 'filter_block' => 'grid_range_filter'),
'QtyInStock' => Array('title' => 'la_col_Qty', 'data_block'=>'qty_td', 'filter_block' => 'grid_range_filter'),
'QtyBackOrdered' => Array('title' => 'la_col_QtyBackOrdered', 'filter_block' => 'grid_range_filter'),
'OnSale' => Array('title' => 'la_col_OnSale', 'filter_block' => 'grid_options_filter'),
/*
'Weight' => Array( 'title'=>'la_col_ProductWeight' ),
'CreatedOn_formatted' => Array( 'title'=>'la_col_ProductCreatedOn', 'sort_field' => 'CreatedOn' ),
'BackOrderDate_formatted' => Array( 'title'=>'la_col_ProductBackOrderDate', 'sort_field' => 'BackOrderDate' ),*/
),
),
'Radio' => Array(
'Icons' => Array('default'=>'icon16_product.gif',1=>'icon16_product.gif',2=>'icon16_product_pending.gif',0=>'icon16_product_disabled.gif'),
'Selector' => 'radio',
'Fields' => Array(
'ProductId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_radio_td' ),
'SKU' => Array( 'title'=>'la_col_ProductSKU' ),
'Type' => Array('title' => 'la_col_ProductType', 'filter_block' => 'grid_options_filter'),
'Manufacturer' => Array('title' => 'la_col_Manufacturer'),
'Name' => Array( 'title'=>'la_col_ProductName', 'data_block'=>'grid_catitem_td' ),
'Price' => Array('title' => 'la_col_Price', 'filter_block' => 'grid_range_filter'),
'QtyInStock' => Array('title' => 'la_col_Qty', 'data_block'=>'qty_td', 'filter_block' => 'grid_range_filter'),
'QtyBackOrdered' => Array('title' => 'la_col_QtyBackOrdered', 'filter_block' => 'grid_range_filter'),
),
),
),
'ConfigMapping' => Array(
'PerPage' => 'Comm_Perpage_Products',
'ShortListPerPage' => 'Comm_Perpage_Products_Short',
'ForceEditorPick' => 'products_EditorPicksAboveRegular',
'DefaultSorting1Field' => 'product_OrderProductsBy',
'DefaultSorting2Field' => 'product_OrderProductsThenBy',
'DefaultSorting1Dir' => 'product_OrderProductsByDir',
'DefaultSorting2Dir' => 'product_OrderProductsThenByDir',
'RatingDelayValue' => 'product_RatingDelay_Value',
'RatingDelayInterval' => 'product_RatingDelay_Interval',
),
);
?>
\ No newline at end of file
Property changes on: branches/RC/in-commerce/units/products/products_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.99.2.22
\ No newline at end of property
+1.99.2.23
\ No newline at end of property
Index: branches/RC/in-commerce/admin_templates/visits/visits_list_incommerce.tpl
===================================================================
--- branches/RC/in-commerce/admin_templates/visits/visits_list_incommerce.tpl (revision 11533)
+++ branches/RC/in-commerce/admin_templates/visits/visits_list_incommerce.tpl (revision 11534)
@@ -1,85 +1,68 @@
<inp2:m_include t="incs/header"/>
-
-<inp2:m_RenderElement name="combined_header" prefix="visits.incommerce" section="in-portal:visits" grid="visitsincommerce" title_preset="visits.incommerce_list" />
+<inp2:m_RenderElement name="combined_header" prefix="visits.incommerce" section="in-portal:visits" grid="visitsincommerce" title_preset="visits.incommerce_list" pagination="1"/>
<!-- ToolBar --->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<script type="text/javascript">
a_toolbar = new ToolBar();
function edit()
{
}
- a_toolbar.AddButton( new ToolBarButton('search', '<inp2:m_phrase label="la_ToolTip_Search" escape="1"/>',
- function() {
- set_hidden_field('grid_name', 'visitsincommerce');
- submit_event('visits.incommerce','OnSearch');
- } ) );
-
- a_toolbar.AddButton( new ToolBarButton('search_reset', '<inp2:m_phrase label="la_ToolTip_SearchReset" escape="1"/>',
- function() {
- set_hidden_field('grid_name', 'visitsincommerce');
- submit_event('visits.incommerce','OnSearchReset');
- } ) );
-
a_toolbar.AddButton( new ToolBarButton('refresh', '<inp2:m_phrase label="la_ToolTip_Refresh" escape="1"/>', function() {
window.location.href = window.location.href;
}
) );
a_toolbar.AddButton( new ToolBarButton('reset', '<inp2:m_phrase label="la_ToolTip_Reset" escape="1"/>', function() {
std_delete_items('visits.incommerce');
}
) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
a_toolbar.AddButton( new ToolBarButton('view', '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>', function() {
show_viewmenu(a_toolbar,'view');
}
) );
a_toolbar.Render();
</script>
</td>
<inp2:m_RenderElement name="search_main_toolbar" prefix="visits.incommerce" grid="visitsincommerce"/>
</tr>
</tbody>
</table>
-<inp2:m_DefineElement name="grid_userlink_td" >
- <td valign="top" class="text">
- <inp2:m_if check="UserFound" user_field="$user_field">
- <a href="<inp2:{$PrefixSpecial}_UserLink user_field="$user_field"/>" title="<inp2:m_phrase name="la_Edit_User"/>"><inp2:{$PrefixSpecial}_field field="$field" grid="$grid"/></a>
- <inp2:m_else/>
- <inp2:{$PrefixSpecial}_field field="$field" grid="$grid"/>
- </inp2:m_if>
- </td>
+<inp2:m_DefineElement name="grid_userlink_td">
+ <inp2:m_if check="UserFound" user_field="$user_field">
+ <a href="<inp2:UserLink user_field="$user_field"/>" title="<inp2:m_phrase name="la_Edit_User"/>"><inp2:Field field="$field" grid="$grid"/></a>
+ <inp2:m_else/>
+ <inp2:Field field="$field" grid="$grid"/>
+ </inp2:m_if>
</inp2:m_DefineElement>
-<inp2:m_DefineElement name="grid_referer_td" >
- <td valign="top" class="text">
- <div style="overflow: hidden;">
- <inp2:m_if check="FieldEquals" field="$field" value="">
- <span style="white-space: nowrap;"><inp2:m_Phrase label="la_visit_DirectReferer"/></span>
- <inp2:m_else/>
- <a href="<inp2:Field field="$field" grid="$grid"/>"><inp2:Field field="$field" grid="$grid" /></a>
- </inp2:m_if>
- </div>
- </td>
+<inp2:m_DefineElement name="grid_referer_td">
+ <div style="overflow: hidden;">
+ <inp2:m_if check="FieldEquals" field="$field" value="">
+ <span style="white-space: nowrap;"><inp2:m_Phrase label="la_visit_DirectReferer"/></span>
+ <inp2:m_else/>
+ <a href="<inp2:Field field="$field" grid="$grid"/>"><inp2:Field field="$field" grid="$grid" /></a>
+ </inp2:m_if>
+ </div>
</inp2:m_DefineElement>
<inp2:adm_SaveReturnScript/>
<inp2:m_RenderElement name="grid" PrefixSpecial="visits.incommerce" IdField="VisitId" grid="visitsincommerce" header_block="grid_column_title" data_block="grid_data_td" search="on" grid_filters="1"/>
<script type="text/javascript">
Grids['visits.incommerce'].SetDependantToolbarButtons( new Array('reset') );
</script>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/in-commerce/admin_templates/visits/visits_list_incommerce.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.18.2.1
\ No newline at end of property
+1.18.2.2
\ No newline at end of property
Index: branches/RC/in-commerce/admin_templates/category_properties.tpl
===================================================================
--- branches/RC/in-commerce/admin_templates/category_properties.tpl (revision 11533)
+++ branches/RC/in-commerce/admin_templates/category_properties.tpl (revision 11534)
@@ -1,2 +1,2 @@
-<inp2:m_RenderElement name="subsection" title="!la_In-commerce!"/>
-<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="cust_p_ItemTemplate" type_field="cust_p_ItemTemplate" title="!la_fld_cust_p_ItemTemplate!" size="50"/>
+<inp2:m_RenderElement name="subsection" title="la_In-commerce"/>
+<inp2:m_RenderElement name="inp_edit_box" prefix="c" field="cust_p_ItemTemplate" type_field="cust_p_ItemTemplate" title="la_fld_cust_p_ItemTemplate" size="50"/>
Property changes on: branches/RC/in-commerce/admin_templates/category_properties.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.3.2.1
\ No newline at end of property
Index: branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_types_tabs.tpl
===================================================================
--- branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_types_tabs.tpl (revision 11533)
+++ branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_types_tabs.tpl (nonexistent)
@@ -1,12 +0,0 @@
-<table cellpadding="0" cellspacing="0" border="0" width="100%">
-<tr>
- <td align="right" width="100%">
- <table cellpadding="0" cellspacing="0" border="0" height="23">
- <tr>
- <inp2:m_RenderElement name="tab" title="la_tab_General" t="in-link/paid_listings/paid_listing_type_edit" main_prefix="lst"/>
- <inp2:m_RenderElement name="tab" title="la_tab_ShopCartEntry" t="in-commerce/paid_listings/paid_listing_type_shopcart" main_prefix="lst"/>
- </tr>
- </table>
- </td>
-</tr>
-</table>
\ No newline at end of file
Property changes on: branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_types_tabs.tpl
___________________________________________________________________
Deleted: cvs2svn:cvs-rev
## -1 +0,0 ##
-1.2
\ No newline at end of property
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Index: branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_type_shopcart.tpl
===================================================================
--- branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_type_shopcart.tpl (revision 11533)
+++ branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_type_shopcart.tpl (revision 11534)
@@ -1,70 +1,66 @@
-<inp2:m_RequireLogin permissions="in-link:listing_types.view" system="1"/>
-<inp2:m_include t="incs/header" nobody="yes"/>
-
-<body topmargin="0" leftmargin="8" marginheight="0" marginwidth="8" bgcolor="#FFFFFF">
-
-<inp2:m_RenderElement name="section_header" prefix="lst" icon="icon46_listing_types" title="la_title_ListingTypes"/>
-
-<inp2:m_include t="in-commerce/paid_listings/paid_listing_types_tabs"/>
-
-<inp2:m_RenderElement name="blue_bar" prefix="lst" title_preset="listing_type_shop_cart" module="in-link" icon="icon46_shipping"/>
+<inp2:m_include t="incs/header"/>
+<inp2:m_RenderElement name="combined_header" prefix="lst" section="in-link:listing_types" title_preset="listing_type_shop_cart" tab_preset="Default"/>
<!-- ToolBar --->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody>
<tr>
<td>
<script type="text/javascript">
a_toolbar = new ToolBar();
a_toolbar.AddButton( new ToolBarButton('select', '<inp2:m_phrase label="la_ToolTip_Save" escape="1"/>', function() {
submit_event('lst','<inp2:lst_SaveEvent/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() {
submit_event('lst','OnCancelEdit');
}
) );
-
+
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
-
+
a_toolbar.AddButton( new ToolBarButton('prev', '<inp2:m_phrase label="la_ToolTip_Prev" escape="1"/>', function() {
go_to_id('lst', '<inp2:lst_PrevId/>');
}
) );
a_toolbar.AddButton( new ToolBarButton('next', '<inp2:m_phrase label="la_ToolTip_Next" escape="1"/>', function() {
go_to_id('lst', '<inp2:lst_NextId/>');
}
) );
-
+
a_toolbar.Render();
-
+
<inp2:m_if check="lst_IsSingle" >
a_toolbar.HideButton('prev');
a_toolbar.HideButton('next');
a_toolbar.HideButton('sep1');
- <inp2:m_else/>
+ <inp2:m_else/>
<inp2:m_if check="lst_IsLast" >
a_toolbar.DisableButton('next');
</inp2:m_if>
<inp2:m_if check="lst_IsFirst" >
a_toolbar.DisableButton('prev');
</inp2:m_if>
</inp2:m_if>
</script>
</td>
</tr>
</tbody>
</table>
<inp2:lst_SaveWarning name="grid_save_warning"/>
-<table width="100%" border="0" cellspacing="0" cellpadding="4" class="tableborder">
+<inp2:lst_ErrorWarning name="form_error_warning"/>
- <inp2:m_RenderElement name="subsection" title="la_Text_ShopCartItem"/>
- <inp2:m_RenderElement name="inp_edit_checkbox" prefix="lst" field="EnableBuying" title="la_fld_EnableBuying" />
- <inp2:m_RenderElement name="inp_edit_box" prefix="lst" field="ShopCartName" title="la_fld_ShopCartName" size="20" />
- <inp2:m_RenderElement name="inp_edit_box" prefix="lst" field="Price" title="la_fld_Price" size="8" />
- <!-- <inp2:m_RenderElement name="inp_edit_checkbox" prefix="lst" field="Recurring" title="la_fld_Recurring" /> -->
-
-</table>
+<div id="scroll_container">
+ <table class="edit-form">
+ <inp2:m_RenderElement name="subsection" title="la_Text_ShopCartItem"/>
+ <inp2:m_RenderElement name="inp_edit_checkbox" prefix="lst" field="EnableBuying" title="la_fld_EnableBuying" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="lst" field="ShopCartName" title="la_fld_ShopCartName" size="20" />
+ <inp2:m_RenderElement name="inp_edit_box" prefix="lst" field="Price" title="la_fld_Price" size="8" />
+ <!-- <inp2:m_RenderElement name="inp_edit_checkbox" prefix="lst" field="Recurring" title="la_fld_Recurring" /> -->
+
+ <inp2:m_RenderElement name="inp_edit_filler"/>
+ </table>
+</div>
<inp2:m_include t="incs/footer"/>
\ No newline at end of file
Property changes on: branches/RC/in-commerce/admin_templates/paid_listings/paid_listing_type_shopcart.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.8
\ No newline at end of property
+1.8.2.1
\ No newline at end of property
Index: branches/RC/in-commerce/install/upgrades.php
===================================================================
--- branches/RC/in-commerce/install/upgrades.php (revision 11533)
+++ branches/RC/in-commerce/install/upgrades.php (revision 11534)
@@ -1,59 +1,71 @@
<?php
$upgrade_class = 'InCommerceUpgrades';
/**
* Class, that holds all upgrade scripts for "Core" module
*
*/
class InCommerceUpgrades extends kHelper {
/**
* Install toolkit instance
*
* @var kInstallToolkit
*/
var $_toolkit = null;
/**
* Sets common instance of installator toolkit
*
* @param kInstallToolkit $instance
*/
function setToolkit(&$instance)
{
$this->_toolkit =& $instance;
}
/**
* Changes table structure, where multilingual fields of TEXT type are present
*
* @param string $mode when called mode {before, after)
*/
function Upgrade_5_0_0($mode)
{
if ($mode == 'after') {
// update icon
$root_category = $this->Application->findModule('Name', 'In-Commerce', 'RootCat');
$sql = 'UPDATE ' . $this->Application->getUnitOption('c', 'TableName') . '
SET UseMenuIconUrl = 1, MenuIconUrl = "in-commerce/img/menu_products.gif"
WHERE ' . $this->Application->getUnitOption('c', 'IDField') . ' = ' . $root_category;
$this->Conn->Query($sql);
- $sql = 'SELECT CustomFieldId
- FROM ' . TABLE_PREFIX . 'CustomField
- WHERE FieldName = "p_ItemTemplate"';
- $custom_field_id = $this->Conn->GetOne($sql);
-
- $ml_formatter =& $this->Application->recallObject('kMultiLanguage');
- /* @var $ml_formatter kMultiLanguage */
-
- $field = $ml_formatter->LangFieldName('cust_' . $custom_field_id, true);
-
- $sql = 'UPDATE ' . TABLE_PREFIX . 'CategoryCustomData
- SET ' . $field . ' = "in-commerce/detail"
- WHERE ' . $field . ' = "in-commerce/product/details"';
- $this->Conn->Query($sql);
+ $this->_updateDetailTemplate('p', 'in-commerce/product/details', 'in-commerce/designs/detail');
}
}
+
+ /**
+ * Replaces deprecated detail template design with new one
+ *
+ * @param string $prefix
+ * @param string $from_template
+ * @param string $to_template
+ */
+ function _updateDetailTemplate($prefix, $from_template, $to_template)
+ {
+ $sql = 'SELECT CustomFieldId
+ FROM ' . TABLE_PREFIX . 'CustomField
+ WHERE FieldName = "' . $prefix . '_ItemTemplate"';
+ $custom_field_id = $this->Conn->GetOne($sql);
+
+ $ml_formatter =& $this->Application->recallObject('kMultiLanguage');
+ /* @var $ml_formatter kMultiLanguage */
+
+ $field = $ml_formatter->LangFieldName('cust_' . $custom_field_id, true);
+
+ $sql = 'UPDATE ' . TABLE_PREFIX . 'CategoryCustomData
+ SET ' . $field . ' = "' . $to_template . '"
+ WHERE ' . $field . ' = "' . $from_template . '"';
+ $this->Conn->Query($sql);
+ }
}
\ No newline at end of file
Property changes on: branches/RC/in-commerce/install/upgrades.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.2
\ No newline at end of property
+1.1.2.3
\ No newline at end of property
Index: branches/RC/in-commerce/install/upgrades.sql
===================================================================
--- branches/RC/in-commerce/install/upgrades.sql (revision 11533)
+++ branches/RC/in-commerce/install/upgrades.sql (revision 11534)
@@ -1,11 +1,11 @@
# ===== v 4.3.9 =====
INSERT INTO ImportScripts VALUES (DEFAULT, 'Products from CSV file [In-Commerce]', '', 'p', 'In-Commerce', '', 'CSV', '1');
ALTER TABLE Products ADD OnSale TINYINT(1) NOT NULL default '0' AFTER Featured, ADD INDEX (OnSale);
UPDATE Phrase SET Module = 'In-Commerce' WHERE Phrase IN ('lu_comm_Images', 'lu_comm_ImagesHeader');
# ===== v 5.0.0 =====
-UPDATE Category SET Template = 'in-commerce/index' WHERE Template = 'in-commerce/store/category';
-UPDATE Category SET CachedTemplate = 'in-commerce/index' WHERE CachedTemplate = 'in-commerce/store/category';
\ No newline at end of file
+UPDATE Category SET Template = '/in-commerce/designs/section' WHERE Template = 'in-commerce/store/category';
+UPDATE Category SET CachedTemplate = '/in-commerce/designs/section' WHERE CachedTemplate = 'in-commerce/store/category';
\ No newline at end of file
Property changes on: branches/RC/in-commerce/install/upgrades.sql
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.6
\ No newline at end of property
+1.1.2.7
\ No newline at end of property

Event Timeline