Array ('self' => true), 'OnCancelEnhancement' => Array ('self' => true), 'OnExtendEnhancement' => Array ('self' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Adds selected link to listing * * @param kEvent $event */ function OnProcessSelected($event) { $object =& $event->getObject(); /* @var $object kDBItem */ $selected_ids = $this->Application->GetVar('selected_ids'); if ( $selected_ids['l'] ) { $link_id = $selected_ids['l']; $config = $this->Application->getUnitConfig('l'); $sql = 'SELECT ResourceId FROM ' . $config->getTableName() . ' WHERE ' . $config->getIDField() . ' = ' . $link_id; $object->SetDBField($this->Application->RecallVar('dst_field'), $this->Conn->GetOne($sql)); $object->IgnoreValidation = true; // $this->RemoveRequiredFields($object); $object->Update(); } $this->finalizePopup($event); } function OnPreSaveListing($event) { $event->redirect=false; $object = $event->getObject( Array('skip_autoload' => true) ); $object->IgnoreValidation = true; // $this->RemoveRequiredFields($object); $event->CallSubEvent('OnPreSave'); $this->Application->SetVar($event->getPrefixSpecial(true).'_id', $object->GetId()); return; } /** * Occurs before updating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { /** @var kDBItem $object */ $object = $event->getObject(); if ( $object->IgnoreValidation ) { $object->UpdateFormattersMasterFields(); } } /** * Occurs before creating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); /** @var kDBItem $object */ $object = $event->getObject(); if ( $object->IgnoreValidation ) { $object->UpdateFormattersMasterFields(); } } /** * 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 kDBItem $object */ $object = $event->getObject(); $sql = 'SELECT * FROM ' . $event->getUnitConfig()->getTableName() . ' WHERE ListingId = ' . $object->GetId(); $original_values = $this->Conn->GetRow($sql); $type_modified = ($object->GetDBField('ListingTypeId') != $original_values['ListingTypeId']); $link_modified = ($object->GetDBField('ItemResourceId') != $original_values['ItemResourceId']); $status_modified = ($object->GetDBField('Status') != $original_values['Status']); if ( $status_modified ) { $email_template = $object->GetDBField('Status') ? 'LINK.ENHANCE.APPROVE' : 'LINK.ENHANCE.DENY'; $this->notifyOwner($email_template, $object); } if ( $type_modified || $link_modified ) { $this->ResetLink($original_values); } if ( $status_modified || $type_modified || $link_modified ) { $this->EnhanceLink($object, $original_values); } if ( $status_modified && !($type_modified || $link_modified) ) { $this->ResetLink($original_values); } } /** * Enhances link * * @param kDBItem $object * @param Array $original_values * @return bool */ function EnhanceLink(&$object, $original_values) { if ( $object->GetDBField('Status') != STATUS_ACTIVE ) { return false; } if ( $object->GetDBField('ExpiresOn') < time() ) { $object->SetDBField('Status', STATUS_PENDING); $object->Update(); $this->ResetLink($original_values); return false; } list($link_object, $listing_type_object) = $this->UpdateLink( 'OnPurchase', $object->GetDBField('ItemResourceId'), $object->GetDBField('ListingTypeId') ); if ( $listing_type_object->GetDBField('OnPurchaseAddToCatEnabled') ) { $add_to_cat = (int)$listing_type_object->GetDBField('OnPurchaseAddToCat'); $category_item_config = $this->Application->getUnitConfig('l-ci'); $sql = 'DELETE FROM ' . $category_item_config->getTableName() . ' WHERE CategoryId = ' . $add_to_cat . ' AND ItemResourceId = ' . $link_object->GetDBField('ResourceId') . ' AND PrimaryCat = 0'; $this->Conn->Query($sql); $sql = 'INSERT INTO ' . $category_item_config->getTableName() . ' (CategoryId, ItemResourceId, PrimaryCat) VALUES (' . $add_to_cat . ', ' . $link_object->GetDBField('ResourceId') . ', 0)'; $this->Conn->Query($sql); } } function ResetLink($original_values) { static $has_been_reset = Array (); if ( $original_values['Status'] != STATUS_ACTIVE || getArrayValue($has_been_reset, $original_values['ListingId']) ) { return; } $has_been_reset[$original_values['ListingId']] = 1; list (, $listing_type_object) = $this->UpdateLink( 'OnExpire', $original_values['ItemResourceId'], $original_values['ListingTypeId'] ); if ( $listing_type_object->GetDBField('OnExpireRemoveFromCatEnabled') ) { $remove_from_cat = $listing_type_object->GetDBField('OnExpireRemoveFromCat'); $sql = 'DELETE FROM ' . $this->Application->getUnitConfig('l-ci')->getTableName() . ' WHERE ItemResourceId = ' . $original_values['ItemResourceId'] . ' AND CategoryId = ' . $remove_from_cat . ' AND PrimaryCat = 0'; $this->Conn->Query($sql); } } function UpdateLink($action_prefix, $resource_id, $listtype_id) { $link_object = $this->Application->recallObject('l', null, Array('skip_autoload' => true)); $link_object->Load($resource_id, 'ResourceId'); // "-item", because can be called as regular after event, and just "lst" recalls list instead $listtype_object = $this->Application->recallObject('lst.-item', null, Array('skip_autoload' => true)); $listtype_object->Load($listtype_id); $action_fields = Array( 'EdPick' => 'EditorsPick', 'New' => 'NewItem', 'Hot' => 'HotItem', 'Pop' => 'PopItem', 'Status' => 'Status', 'CustomTemplate' => 'CustomTemplate', ); // $action_prefix = 'OnPurchase'; foreach($action_fields as $action => $field) { $action_value = $listtype_object->GetDBField($action_prefix.$action); if( $action_value != 3 ) { $link_object->SetDBField($field, $action_value); } } $priority_value = $listtype_object->GetDBField($action_prefix.'PriorityValue'); switch( $listtype_object->GetDBField($action_prefix.'PriorityAction') ) { case 1: // equal $link_object->SetDBField('Priority', $priority_value); break; case 2: // increase $original_priority = $link_object->GetDBField('Priority'); $link_object->SetDBField('Priority', $original_priority + $priority_value); break; case 3: // decrease $original_priority = $link_object->GetDBField('Priority'); $link_object->SetDBField('Priority', $original_priority - $priority_value); break; default: } $link_object->Update(); return array($link_object, $listtype_object); } /** * Enter description here... * * @param kEvent $event */ function OnRequestEnhancement($event) { if ( $this->Application->prefixRegistred('ord') ) { $l_info = $this->Application->GetVar('l'); if (!$l_info) { return false; } list ($link_id, $link_info) = each($l_info); $listing_type_id = $link_info['ListingTypeId']; $listing_type = $this->Application->recallObject('lst', null, Array('skip_autoload' => true)); $listing_type->Load($listing_type_id); if ($listing_type->GetDBField('EnableBuying')) { $add_to_cart_event = new kEvent('ord:OnAddVirtualProductToCart'); $this->Application->HandleEvent($add_to_cart_event); if ($add_to_cart_event->redirect) { $event->SetRedirectParam('pass', 'm'); $event->redirect = $add_to_cart_event->redirect; } return true; } } $event->CallSubEvent('OnListingCreate'); } /** * Create listing or extend existing listing period * * @param kEvent $event */ function OnListingCreate($event) { $new_processing = false; $link_id = $listing_type_id = 0; /** @var kDBItem $object */ $object = $event->getObject( Array('skip_autoload' => true) ); switch ($event->Name) { case 'EnhanceLinkAfterOrderApprove': case 'EnhancedLinkOnCompleteOrder': // when order with listing virtual product is approved $fields = $event->getEventParam('field_values'); $item_data = unserialize($fields['ItemData']); $listing_type_id = $item_data['ListingTypeId']; $link_id = $item_data['LinkId']; $new_processing = getArrayValue($item_data, 'HasNewProcessing'); break; case 'OnListingCreate': // when requesting enhancement from front (and not via in-commerce) $links_info = $this->Application->GetVar('l'); if (!$links_info) return false; $event->redirect = false; list($link_id, $link_info) = each($links_info); $listing_type_id = $link_info['ListingTypeId']; $new_processing = false; break; } if (!$listing_type_id) { // free or invalid listing type selected return false; } $links_config = $this->Application->getUnitConfig('l'); // get resource_id of link being enhanced $sql = 'SELECT ResourceId FROM '.$links_config->getTableName().' WHERE LinkId = '.$link_id; $resource_id = $this->Conn->GetOne($sql); // get listing by link's resource_id $object->Load($resource_id, 'ItemResourceId'); if ($object->isLoaded()) { $original_values = $object->GetFieldValues(); } else { // set initial fields to listing $object->SetDBField('ListingTypeId', $listing_type_id); $object->SetDBField('ItemResourceId', $resource_id); if ($event->Name == 'OnListingCreate' || $new_processing) { $item_status = STATUS_PENDING; } else { $item_status = STATUS_ACTIVE; } $object->SetDBField('Status', $item_status); } // set date of purchase for new listings $purchased_on = max(time(), $object->GetDBField('ExpiresOn')); if (!$object->isLoaded()) { $object->SetDBField('PurchasedOn_date', $purchased_on); $object->SetDBField('PurchasedOn_time', $purchased_on); } // set expiration time for listing $listing_type = $this->Application->recallObject('lst', null, Array('skip_autoload' => true)); /* @var $listing_type kDBItem */ $listing_type->Load($listing_type_id); $dur_type_mapping = Array( 1 => 1, 2 => 60, 3 => 3600, 4 => 3600*24, 5 => 3600*24*7, 6 => 3600*24*365/12, 7 => 3600*24*365 ); $duration = $listing_type->GetDBField('Duration'); $duration_type = $listing_type->GetDBField('DurationType'); $expiration_interval = $duration * $dur_type_mapping[$duration_type]; $expiration_date = $purchased_on + $expiration_interval; $object->SetDBField('ExpiresOn_date', $expiration_date); $object->SetDBField('ExpiresOn_time', $expiration_date); // when extending enhancement mark listing as non-received renewal reminder $object->SetDBField('RenewalReminderSent', 0); $action = $object->isLoaded() ? 'Update' : 'Create'; if ($object->$action()) { $event->status = kEvent::erSUCCESS; switch ($event->Name) { case 'EnhanceLinkAfterOrderApprove': case 'EnhancedLinkOnCompleteOrder': // when order with listing virtual product is approved if (getArrayValue($original_values, 'Status') != STATUS_ACTIVE) { $this->EnhanceLink($object, Array()); } break; case 'OnListingCreate': // when requesting enhancement from front (and not via in-commerce) $event->redirect = $this->Application->GetVar('success_template'); $this->notifyOwner('LINK.ENHANCE', $object); break; } } else { $event->status = kEvent::erFAIL; } } /** * Enter description here... * * @param kEvent $event */ function EnhancedLinkOnCompleteOrder($event) { // create enhancement, but pending $this->OnListingCreate($event); // save created listing_id back to itemdata $object = $event->getObject( Array('skip_autoload' => true) ); $fields = $event->getEventParam('field_values'); $item_data = unserialize($fields['ItemData']); unset($item_data['ListingTypeId']); $item_data['ListingId'] = $object->GetID(); $order_items_config = $this->Application->getUnitConfig('orditems'); $orditems_idfield = $order_items_config->getIDField(); $orditems_table = $order_items_config->getTableName(); $this->Conn->doUpdate( Array('ItemData' => serialize($item_data)), $orditems_table, $orditems_idfield.' = '.$fields['OrderItemId'] ); } /** * Enter description here... * * @param kEvent $event */ function EnhanceLinkAfterOrderApprove($event) { /** @var kDBItem $object */ $object = $event->getObject( Array('skip_autoload' => true) ); $fields = $event->getEventParam('field_values'); $item_data = unserialize($fields['ItemData']); if ( getArrayValue($item_data, 'HasNewProcessing') ) { // new processing: just approve created listing here $listing_id = $item_data['ListingId']; $object->Load($listing_id); // moved enhancement period to time admin approved enhancement $time_diff = time() - $object->GetDBField('PurchasedOn'); $object->SetDBField('PurchasedOn_date', $object->GetDBField('PurchasedOn_date') + $time_diff); $object->SetDBField('PurchasedOn_time', $object->GetDBField('PurchasedOn_time') + $time_diff); $object->SetDBField('ExpiresOn_date', $object->GetDBField('ExpiresOn_date') + $time_diff); $object->SetDBField('ExpiresOn_time', $object->GetDBField('ExpiresOn_time') + $time_diff); $object->SetDBField('Status', STATUS_ACTIVE); $object->Update(); $this->EnhanceLink($object, Array()); return true; } else { // create listing & approve it at the same time $this->OnListingCreate($event); } } /** * Delete listing * * @param kEvent $event */ function EnhanceLinkAfterOrderDeny($event) { $object = $event->getObject( Array('skip_autoload' => true) ); $fields = $event->getEventParam('field_values'); $item_data = unserialize($fields['ItemData']); $listing_id = $item_data['ListingId']; $temp_handler = $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler', Array ('parent_event' => $event)); /* @var $temp_handler kTempTablesHandler */ $temp_handler->DeleteItems($event->Prefix, $event->Special, Array($listing_id)); } /** * Enter description here... * * @param kEvent $event */ function ExpireLink($event) { /** @var kDBItem $object */ $object = $event->getObject(Array ('skip_autoload' => true)); $fields = $event->getEventParam('field_values'); $item_data = unserialize($fields['ItemData']); $sql = 'SELECT ListingId FROM ' . $event->getUnitConfig()->getTableName() . ' WHERE ItemResourceId = ' . $item_data['LinkId']; $listing_id = $this->Conn->GetOne($sql); $object->Load($listing_id); $original_values = $object->GetFieldValues(); $object->SetDBField('Status', 2); if ( $object->Update() ) { $event->status = kEvent::erSUCCESS; $this->ResetLink($original_values); } else { $event->status = kEvent::erFAIL; } } /** * Apply same processing to each item being selected in grid * * @param kEvent $event * @return void * @access protected */ protected function iterateItems(kEvent $event) { /** @var kDBItem $object */ $object = $event->getObject(Array ('skip_autoload' => true)); $ids = $this->StoreSelectedIDs($event); $links_config = $this->Application->getUnitConfig('l'); if ( $event->Name == 'OnMassApprove' ) { foreach ($ids as $id) { $object->Load($id); if ( $object->GetDBField('Status') != STATUS_ACTIVE ) { $original_values = $object->GetFieldValues(); $object->SetDBField('Status', STATUS_ACTIVE); $this->EnhanceLink($object, $original_values); } } } if ( $event->Name == 'OnMassDecline' ) { foreach ($ids as $id) { $object->Load($id); if ( $object->GetDBField('Status') == STATUS_ACTIVE ) { $original_values = $object->GetFieldValues(); $this->ResetLink($original_values); $this->notifyOwner('LINK.ENHANCE.DENY', $object); } } } parent::iterateItems($event); // extend period for pending/renewal links (if owner has agreed) if ( $event->Name == 'OnMassApprove' ) { /** @var kDBItem $lst_object */ $lst_object = $this->Application->recallObject('lst', null, Array ('skip_autoload' => true)); foreach ($ids as $id) { $object->Load($id); if ( $object->GetDBField('PendingRenewal') == 1 ) { $lst_object->Load( $object->GetDBField('ListingTypeId') ); $dur_type_mapping = Array ( 1 => 1, 2 => 60, 3 => 3600, 4 => 3600 * 24, 5 => 3600 * 24 * 7, 6 => 3600 * 24 * 365 / 12, 7 => 3600 * 24 * 365 ); $duration = $lst_object->GetDBField('Duration'); $duration_type = $lst_object->GetDBField('DurationType'); $expiration_interval = $duration * $dur_type_mapping[$duration_type]; $renewal_begins = max(time(), $object->GetDBField('ExpiresOn')); $expiration_date = $renewal_begins + $expiration_interval; $object->SetDBField('ExpiresOn_date', $expiration_date); $object->SetDBField('ExpiresOn_time', $expiration_date); $object->SetDBField('RenewalReminderSent', 0); $object->SetDBField('PendingRenewal', 0); if ( $object->Update() ) { $event->SetRedirectParam('opener', 's'); $this->notifyOwner('LINK.ENHANCE.RENEW', $object); } } else { $this->notifyOwner('LINK.ENHANCE.APPROVE', $object); } } } } /** * Redirects to cancel template on front-end * * @param kEvent $event * @return void * @access protected */ protected function OnCancel(kEvent $event) { parent::OnCancel($event); if ( !$this->Application->isAdmin ) { $event->SetRedirectParam('opener', 's'); $event->redirect = $this->Application->GetVar('cancel_template'); } } /** * Checks that user is owner of link & returns listing id if permissions are ok * * @param kEvent $event * @return mixed */ function verifyListingOwner($event) { $link_id = $this->Application->GetVar('l_id'); $user_id = $this->Application->RecallVar('user_id'); $sql = 'SELECT ResourceId FROM '.$this->Application->getUnitConfig('l')->getTableName().' WHERE (LinkId = '.$link_id.') AND (CreatedById = '.$user_id.')'; $resource_id = $this->Conn->GetOne($sql); if (!$resource_id) { $event->status = kEvent::erFAIL; return false; } $sql = 'SELECT ListingId FROM '.$event->getUnitConfig()->getTableName().' WHERE ItemResourceId = '.$resource_id; return $this->Conn->GetOne($sql); } protected function OnExtendEnhancement(kEvent $event) { $listing_id = $this->verifyListingOwner($event); if (!$listing_id) { return ; } $object = $event->getObject( Array('skip_autoload' => true) ); /* @var $object kDBItem */ $object->Load($listing_id); $object->SetDBField('PendingRenewal', 1); $object->Update(); $event->redirect = $this->Application->GetVar('success_template'); $this->notifyOwner('LINK.ENHANCE.EXTEND', $object); } /** * Cancels enhancement * * @param kEvent $event */ function OnCancelEnhancement($event) { $listing_id = $this->verifyListingOwner($event); if ( !$listing_id ) { return; } /** @var kDBItem $object */ $object = $event->getObject(Array ('skip_autoload' => true)); $object->Load($listing_id); $original_values = $object->GetFieldValues(); $original_values['Status'] = 1; $this->ResetLink($original_values); $this->notifyOwner('LINK.ENHANCE.CANCEL', $object); $object->Delete(); $event->redirect = $this->Application->GetVar('success_template'); } /** * Checks expired paid listings * * @param kEvent $event */ function OnCheckExpiredPaidListings($event) { $config = $event->getUnitConfig(); $links_config = $this->Application->getUnitConfig('l'); $sql = 'SELECT ListingId FROM '.$config->getTableName().' WHERE ExpiresOn < '.time().' AND Status = 1'; $expired_listings = $this->Conn->GetCol($sql); if(is_array($expired_listings) && count($expired_listings) > 0) { /** @var kDBItem $object */ $object = $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true)); foreach($expired_listings as $listing_id) { $object->Load($listing_id); $original_values = $object->GetFieldValues(); $this->ResetLink($original_values); $object->SetDBField('Status', 2); $object->Update(); $this->notifyOwner('LINK.ENHANCE.EXPIRE', $object); } } $link_id_field = $this->Application->getUnitConfig('l')->getIDField(); $sql = 'SELECT ls.ListingId, l.CreatedById, l.' . $link_id_field . ' FROM ' . $config->getTableName() . ' ls LEFT JOIN ' . $this->Application->getUnitConfig('lst')->getTableName() . ' lst ON ls.ListingTypeId = lst.ListingTypeId LEFT JOIN ' . $links_config->getTableName() . ' l ON ls.ItemResourceId = l.ResourceId WHERE ls.Status = 1 AND ls.ExpiresOn < ' . time() . ' + lst.RenewalReminder * 3600 *24 AND ls.RenewalReminderSent = 0'; $res = $this->Conn->Query($sql); if(is_array($res) && count($res) > 0) { $listing_ids = Array(); foreach($res as $record) { $send_params = Array ( 'PrefixSpecial' => 'l', 'item_id' => $record[$link_id_field] ); $this->Application->emailUser('LINK.ENHANCE.RENEWAL.NOTICE', $record['CreatedById'], $send_params); $this->Application->emailAdmin('LINK.ENHANCE.RENEWAL.NOTICE', null, $send_params); $listing_ids[] = $record['ListingId']; } $sql = 'UPDATE '.$config->getTableName().' SET RenewalReminderSent = 1 WHERE ListingId IN ('.implode(',', $listing_ids).')'; $this->Conn->Query($sql); } } /** * Removes enhancements on listing delete * * @param kEvent $event * @return void * @access protected */ protected function OnMassDelete(kEvent $event) { /** @var kDBItem $object */ $object = $event->getObject(Array ('skip_autoload' => true)); $ids = $this->StoreSelectedIDs($event); foreach ($ids as $id) { $object->Load($id); if ( $object->GetDBField('Status') == STATUS_ACTIVE ) { $this->ResetLink( $object->GetFieldValues() ); } } parent::OnMassDelete($event); } /** * Moves enhancement from original link to it's pending copy, that is going to be approved * * @param kEvent $event */ function OnMoveEnhancement($event) { $master_config = $event->MasterEvent->getUnitConfig(); $id_field = $master_config->getIDField(); $item_table_name = $master_config->getTableName(); $pending_id = $event->MasterEvent->getEventParam('id'); $original_id = $event->MasterEvent->getEventParam('original_id'); $sql = 'SELECT ResourceId, '.$id_field.' FROM '.$item_table_name.' WHERE '.$id_field.' IN ('.$pending_id.','.$original_id.')'; $resource_ids = $this->Conn->GetCol($sql, $id_field); $table_name = $event->getUnitConfig()->getTableName(); $sql = 'UPDATE '.$table_name.' SET ItemResourceId = '.$resource_ids[$pending_id].' WHERE ItemResourceId = '.$resource_ids[$original_id]; $this->Conn->Query($sql); } /** * Notifies link owner about listing related action. * * @param string $email_template E-mail template. * @param kDBItem $listing Listing. * * @return void */ protected function notifyOwner($email_template, kDBItem $listing) { $unit_config = $this->Application->getUnitConfig('l'); $id_field = $unit_config->getIDField(); $sql = 'SELECT CreatedById, ' . $id_field . ' FROM ' . $unit_config->getTableName() . ' WHERE ResourceId = ' . $listing->GetDBField('ItemResourceId'); $link_data = $this->Conn->GetRow($sql); $send_params = array( 'PrefixSpecial' => 'l', 'item_id' => $link_data[$id_field], ); $this->Application->emailUser($email_template, $link_data['CreatedById'], $send_params); $this->Application->emailAdmin($email_template, null, $send_params); } /** * Makes calculated fields to go to multilingual link fields * * @param kEvent $event * @return void * @access protected */ protected function OnAfterConfigRead(kEvent $event) { parent::OnAfterConfigRead($event); $language_id = $this->Application->GetVar('m_lang'); $event->getUnitConfig()->addCalculatedFieldsBySpecial('', Array ( 'LinkName' => 'CONCAT(item_table.l' . $language_id . '_Name, " (", item_table.Url, ")")', )); } }