Index: in-commerce/units/affiliate_payment_types/affiliate_payment_types_config.php =================================================================== --- in-commerce/units/affiliate_payment_types/affiliate_payment_types_config.php (revision 14590) +++ in-commerce/units/affiliate_payment_types/affiliate_payment_types_config.php (working copy) @@ -18,16 +18,8 @@ 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'AffiliatePaymentTypesEventHandler', 'file' => 'affiliate_payment_types_event_handler.php', 'build_event' => 'OnBuild'), - 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'AffiliatePaymentTypeTagProcessor', 'file' => 'affiliate_payment_types_tp.php', 'build_event' => 'OnBuild'), 'AutoLoad' => true, - 'AggregateTags' => Array ( - Array ( - 'AggregateTo' => 'u', - 'AggregatedTagName' => 'ListAffiliatesPaymentTypes', - 'LocalTagName' => 'PrintList', - 'LocalSpecial' => 'active', - ), - ), 'QueryString' => Array ( 1 => 'id', 2 => 'Page', Index: in-commerce/units/affiliate_payment_types/affiliate_payment_types_tp.php =================================================================== --- in-commerce/units/affiliate_payment_types/affiliate_payment_types_tp.php (revision 0) +++ in-commerce/units/affiliate_payment_types/affiliate_payment_types_tp.php (revision 0) @@ -0,0 +1,51 @@ +Application->recallObject( $params['prefix'] ); + /* @var $affiliate kDBItem */ + + $payment_type = $affiliate->GetDBField( $params['field'] ); + + if ( $payment_type ) { + $object =& $this->getObject($params); + /* @var $object kDBList */ + + return $payment_type == $object->GetID(); + } + + if ( !$checked ) { + // make first listed affiliate payment type selected + $checked = true; + + return true; + } + + return false; + } +} \ No newline at end of file Property changes on: in-commerce\units\affiliate_payment_types\affiliate_payment_types_tp.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: in-commerce/units/affiliates/affiliates_config.php =================================================================== --- in-commerce/units/affiliates/affiliates_config.php (revision 14590) +++ in-commerce/units/affiliates/affiliates_config.php (working copy) @@ -25,21 +25,22 @@ 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => 'u', - 'HookToSpecial' => '', - 'HookToEvent' => Array('OnCreate'), + 'HookToSpecial' => 'register', + 'HookToEvent' => Array('OnBeforeItemCreate', 'OnBeforeItemUpdate'), 'DoPrefix' => '', - 'DoSpecial' => '', - 'DoEvent' => 'OnRegisterAsAffiliate', + 'DoSpecial' => 'register', + 'DoEvent' => 'OnValidateAffiliate', ), + Array( - 'Mode' => hBEFORE, + 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => 'u', - 'HookToSpecial' => '', + 'HookToSpecial' => 'register', 'HookToEvent' => Array('OnCreate'), 'DoPrefix' => '', - 'DoSpecial' => '', - 'DoEvent' => 'OnCheckAffiliateAgreement', + 'DoSpecial' => 'register', + 'DoEvent' => 'OnRegisterAffiliate', ), ), 'AggregateTags' => Array( @@ -50,8 +51,8 @@ ), Array( 'AggregateTo' => 'u', - 'AggregatedTagName' => 'AffiliateIsNotActive', - 'LocalTagName' => 'User_AffiliateIsNotActive', + 'AggregatedTagName' => 'AffiliateIsActive', + 'LocalTagName' => 'User_AffiliateIsActive', ), Array( 'AggregateTo' => 'u', @@ -105,6 +106,19 @@ 'affiliates_payout' => Array('prefixes' => Array('affil','apayments'), 'format' => "!la_title_PayOut_To! '#affil_titlefield#'"), ), + 'Forms' => Array ( + 'registration' => Array ( + 'VirtualFields' => Array ( + 'TermsAccepted' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'error_msgs' => Array ('required' => '!lu_comm_MustAgreeAffiliateTermsError!'), + 'required' => 1, 'default' => NULL, + ), + ) + ), + ), + 'EditTabPresets' => Array ( 'Default' => Array ( 'general' => Array ('title' => 'la_tab_General', 't' => 'in-commerce/affiliate_plans/affiliates_edit', 'priority' => 1), @@ -164,26 +178,27 @@ ), 'Fields' => Array( - 'AffiliateId' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), - 'PortalUserId' => Array('type' => 'int', 'unique'=>Array('PortalUserId'), 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!', 'unique' => '!la_affiliate_already_exists!'), 'options' => Array(USER_ROOT => 'root', USER_GUEST => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'required' => 1, 'not_null' => 1, 'default' => 0, ), - 'AffiliatePlanId' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options_sql'=>'SELECT Name, AffiliatePlanId FROM '.TABLE_PREFIX.'AffiliatePlans WHERE Enabled = 1 ORDER BY Name', 'option_key_field'=>'AffiliatePlanId', 'option_title_field'=>'Name', 'not_null' => 1, 'default' => 0), - 'AccumulatedAmount' => Array('type' => 'double', 'formatter'=>'kFormatter', 'format'=>'%.02f', 'not_null' => '1','default' => '0.00'), - 'AmountToPay' => Array('type' => 'double', 'formatter'=>'kFormatter', 'format'=>'%.02f', 'not_null' => '1','default' => '0.00'), - 'LastPaymentDate' => Array('type' => 'int', 'formatter'=>'kDateFormatter', 'default' => NULL), - 'LastOrderDate' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), - 'Status' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options'=>Array(1=>'la_Active', 2=>'la_Pending', 0=>'la_Disabled'), 'use_phrases'=>1, 'not_null' => '1','default' => 2), - 'AffiliateCode' => Array('type' => 'string', 'not_null' => '1', 'default' => ''), - 'ItemsSold' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), - 'PaymentTypeId' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options' => Array(0 => ''), 'options_sql'=>'SELECT Name, PaymentTypeId FROM '.TABLE_PREFIX.'AffiliatePaymentTypes WHERE Status = 1 ORDER BY IsPrimary DESC, Priority DESC, Name ASC', 'option_key_field'=>'PaymentTypeId', 'option_title_field'=>'Name', 'not_null' => 1, 'default' => 0), - 'SSN' => Array('type' => 'string','not_null' => '1','default' => '', 'required' => 1), - 'Comments' => Array('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => NULL), - 'CreatedOn' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), - ), + 'AffiliateId' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), + 'PortalUserId' => Array('type' => 'int', 'unique'=>Array('PortalUserId'), 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!', 'unique' => '!la_affiliate_already_exists!'), 'options' => Array(USER_ROOT => 'root', USER_GUEST => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'required' => 1, 'not_null' => 1, 'default' => 0, ), + 'AffiliatePlanId' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options_sql'=>'SELECT Name, AffiliatePlanId FROM '.TABLE_PREFIX.'AffiliatePlans WHERE Enabled = 1 ORDER BY Name', 'option_key_field'=>'AffiliatePlanId', 'option_title_field'=>'Name', 'not_null' => 1, 'default' => 0), + 'AccumulatedAmount' => Array('type' => 'double', 'formatter'=>'kFormatter', 'format'=>'%.02f', 'not_null' => '1','default' => '0.00'), + 'AmountToPay' => Array('type' => 'double', 'formatter'=>'kFormatter', 'format'=>'%.02f', 'not_null' => '1','default' => '0.00'), + 'LastPaymentDate' => Array('type' => 'int', 'formatter'=>'kDateFormatter', 'default' => NULL), + 'LastOrderDate' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), + 'Status' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options'=>Array(1=>'la_Active', 2=>'la_Pending', 0=>'la_Disabled'), 'use_phrases'=>1, 'not_null' => '1','default' => STATUS_PENDING), + 'AffiliateCode' => Array('type' => 'string', 'not_null' => '1', 'default' => ''), + 'ItemsSold' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), + 'PaymentTypeId' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options' => Array(0 => ''), 'options_sql'=>'SELECT Name, PaymentTypeId FROM '.TABLE_PREFIX.'AffiliatePaymentTypes WHERE Status = 1 ORDER BY IsPrimary DESC, Priority DESC, Name ASC', 'option_key_field'=>'PaymentTypeId', 'option_title_field'=>'Name', 'not_null' => 1, 'default' => 0), + 'SSN' => Array('type' => 'string','not_null' => '1','default' => '', 'required' => 1), + 'Comments' => Array('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => NULL), + 'CreatedOn' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), + ), + 'VirtualFields' => Array( - 'UserName' => Array('type'=>'string', 'default' => ''), - 'PlanName' => Array('type'=>'string', 'default' => ''), - 'UserId' => Array('type'=>'int', 'default' => 0), - ), + 'UserName' => Array('type'=>'string', 'default' => ''), + 'PlanName' => Array('type'=>'string', 'default' => ''), + 'UserId' => Array('type'=>'int', 'default' => 0), + ), 'Grids' => Array( 'Default' => Array( @@ -191,7 +206,7 @@ 'default' => 'icon16_item.png', 0 => 'icon16_disabled.png', 1 => 'icon16_item.png', - 2 => 'icon16_primary.png', + 2 => 'icon16_pending.png', 'module' => 'core', ), 'Fields' => Array( Index: in-commerce/units/affiliates/affiliates_event_handler.php =================================================================== --- in-commerce/units/affiliates/affiliates_event_handler.php (revision 14590) +++ in-commerce/units/affiliates/affiliates_event_handler.php (working copy) @@ -16,21 +16,61 @@ class AffiliatesEventHandler extends kDBEventHandler { /** - * Allows to override standart permission mapping + * Allows to override standard permission mapping * */ function mapPermissions() { parent::mapPermissions(); + $permissions = Array( 'OnItemBuild' => Array ('self' => true), - 'OnChangePaymentType' => Array ('self' => true), - 'OnBecomeAffiliate' => Array ('self' => true), ); + $this->permMapping = array_merge($this->permMapping, $permissions); } /** + * Checks user permission to execute given $event + * + * @param kEvent $event + * @return bool + * @access public + */ + public function CheckPermission(&$event) + { + if ( $event->Name == 'OnBecomeAffiliate' || $event->Name == 'OnChangePaymentType' ) { + return $this->Application->LoggedIn() && $this->Application->ConfigValue('Comm_RegisterAsAffiliate'); + } + + return parent::CheckPermission($event); + } + + /** + * Allows to get ID of affiliate record, associated with currently logged-in user + * + * @param kEvent $event + * @return int + */ + function getPassedID(&$event) + { + if ( $event->Special == 'user' ) { + $event->setEventParam('raise_warnings', 0); + + $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' + FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + WHERE PortalUserId = ' . (int)$this->Application->RecallVar('user_id'); + $id = $this->Conn->GetOne($sql); + + if ( $id ) { + return $id; + } + } + + return parent::getPassedID($event); + } + + /** * Generate new affiliate code * * @param kEvent $event @@ -56,11 +96,11 @@ } $ret = strtoupper($ret); - $idfield = $this->Application->getUnitOption($event->Prefix, 'IDField'); + $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table = $this->Application->getUnitOption($event->Prefix, 'TableName'); $sql = 'SELECT %s FROM %s WHERE AffiliateCode = %s'; - $code_found = $this->Conn->GetOne( sprintf($sql, $idfield, $table, $this->Conn->qstr($ret) ) ); + $code_found = $this->Conn->GetOne( sprintf($sql, $id_field, $table, $this->Conn->qstr($ret) ) ); if($code_found) return $this->generateAffiliateCode($event); return $ret; @@ -70,14 +110,51 @@ * Creates new affiliate code when new affiliate is created * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemCreate(&$event) + protected function OnBeforeItemCreate(&$event) { - $object =& $event->getObject( Array('skip_autoload'=>true) ); - $object->SetDBField('AffiliateCode', $this->generateAffiliateCode($event) ); + parent::OnBeforeItemCreate($event); + + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $object->SetDBField('AffiliateCode', $this->generateAffiliateCode($event)); + + if ( $object->getFormName() == 'registration' ) { + if ( $this->Application->LoggedIn() ) { + $object->SetDBField('PortalUserId', $this->Application->RecallVar('user_id')); + } + + $object->SetDBField('AffiliatePlanId', $this->_getPrimaryAffiliatePlan()); + } } /** + * Ensures, that user can only update his affiliate record + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(&$event) + { + parent::OnBeforeItemUpdate($event); + + if ( !$this->Application->isAdmin ) { + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $object->SetDBField('PortalUserId', $object->GetOriginalField('PortalUserId')); + + if ( $object->GetDBField('PortalUserId') != $this->Application->RecallVar('user_id') ) { + $object->SetError('PortalUserId', 'not_owner'); + } + } + } + + /** * Stores affiliate id using method from Config (session or cookie) if correct code is present in url * * @param kEvent $event @@ -208,33 +285,34 @@ } } - function OnCheckAffiliateAgreement(&$event) + /** + * [HOOK] Validates affiliate fields on user registration form + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnValidateAffiliate(&$event) { - $user_object =& $this->Application->recallObject('u', null, Array('skip_autoload' => true)); - - $items_info = $this->Application->GetVar('u'); - if($items_info) - { - list($id,$field_values) = each($items_info); - $user_object->SetFieldsFromHash($field_values); - $user_object->setID($id); + if ( $this->Application->GetVar('RegisterAsAffiliate') != 'on' || $event->MasterEvent->status != kEvent::erSUCCESS ) { + return; } + + $object =& $event->getObject( Array('form_name' => 'registration', 'skip_autoload' => true) ); + /* @var $object kDBItem */ - $require_affiliate = ($this->Application->GetVar('RegisterAsAffiliate') == 'on'); + $field_values = $this->getSubmittedFields($event); + $object->SetFieldsFromHash($field_values); + $object->setID(0); - if($require_affiliate && !$this->Application->GetVar('AgreeToAffiliateTerms') ) - { - $this->Application->SetVar('MustAgreeToTerms', 1); - $event->MasterEvent->status = kEvent::erFATAL; - } + if ( !$object->Validate() ) { + $user =& $event->MasterEvent->getObject(); + /* @var $user kDBItem */ - if($require_affiliate && !$this->Application->GetVar('SSN') ) - { - $this->Application->SetVar('SSNRequiredError', 1); - $event->MasterEvent->status = kEvent::erFATAL; + $user->Validate(); + + $event->MasterEvent->status = kEvent::erFAIL; } - - if( ($event->MasterEvent->status == kEvent::erFATAL) && $items_info ) $user_object->Validate(); } /** @@ -242,122 +320,144 @@ * * @param kEvent $event */ - function OnRegisterAsAffiliate(&$event) + function OnRegisterAffiliate(&$event) { - if($this->Application->GetVar('RegisterAsAffiliate') != 'on' || $event->MasterEvent->status != kEvent::erSUCCESS) - { + if ( $this->Application->GetVar('RegisterAsAffiliate') != 'on' || $event->MasterEvent->status != kEvent::erSUCCESS ) { return; } - $object =& $event->getObject( Array('skip_autoload' => true) ); - $sql = 'SELECT AffiliatePlanId FROM '.$this->Application->getUnitOption('ap', 'TableName').' - WHERE IsPrimary = 1'; - $affiliate_plan = $this->Conn->GetOne($sql); - $object->SetDBField('PortalUserId', $this->Application->GetVar('u.current_id')); - $object->SetDBField('Status', 2); - $object->SetDBField('AffiliatePlanId', $affiliate_plan); - $object->SetDBField('SSN', $this->Application->GetVar('SSN')); - $object->SetDBField('Comments', $this->Application->GetVar('Comments')); - $object->SetDBField('PaymentTypeId', $this->Application->GetVar('PaymentTypeId')); + $object =& $event->getObject(); + /* @var $object kDBItem */ - $object->Create(); + $user =& $event->MasterEvent->getObject(); + /* @var $user UsersItem */ - $email_event_user =& $this->Application->EmailEventUser('AFFILIATE.REGISTER', $this->Application->GetVar('u.current_id')); - $email_event_admin =& $this->Application->EmailEventAdmin('AFFILIATE.REGISTER'); + $object->SetDBField('PortalUserId', $user->GetID()); + + if ( $object->Create() ) { + $this->Application->EmailEventUser('AFFILIATE.REGISTER', $user->GetID()); + $this->Application->EmailEventAdmin('AFFILIATE.REGISTER'); + } } - function OnBecomeAffiliate(&$event) + /** + * Returns primary affiliate plan + * + * @return int + * @access protected + */ + protected function _getPrimaryAffiliatePlan() { - if(!$this->Application->GetVar('AgreeToAffiliateTerms')) - { - $this->Application->SetVar('MustAgreeToTerms', 1); - $event->status = kEvent::erFATAL; - } - if(!$this->Application->GetVar('SSN')) - { - $this->Application->SetVar('SSNRequiredError', 1); - $event->status = kEvent::erFATAL; - } - if($event->status == kEvent::erFATAL) - { - return; - } - $object =& $event->getObject( Array('skip_autoload' => true) ); - $sql = 'SELECT AffiliatePlanId FROM '.$this->Application->getUnitOption('ap', 'TableName').' + $sql = 'SELECT AffiliatePlanId + FROM ' . $this->Application->getUnitOption('ap', 'TableName') . ' WHERE IsPrimary = 1'; - $affiliate_plan = $this->Conn->GetOne($sql); - $object->SetDBField('PortalUserId', $this->Application->RecallVar('user_id')); - $object->SetDBField('Status', 2); - $object->SetDBField('AffiliatePlanId', $affiliate_plan); - $object->SetDBField('SSN', $this->Application->GetVar('SSN')); - $object->SetDBField('Comments', $this->Application->GetVar('Comments')); - $object->SetDBField('PaymentTypeId', $this->Application->GetVar('PaymentTypeId')); - $object->Create(); - if($next_template = $this->Application->GetVar('next_template')) - { - $event->redirect = $next_template; + return (int)$this->Conn->GetOne($sql); + } + + /** + * Creates affiliate record for logged-in user + * + * @param kEvent $event + */ + function OnBecomeAffiliate(&$event) + { + $object =& $event->getObject( Array('form_name' => 'registration', 'skip_autoload' => true) ); + /* @var $object UsersItem */ + + $event->CallSubEvent('OnCreate'); + + if ( $event->status == kEvent::erSUCCESS ) { + $event->SetRedirectParam('opener', 's'); + + $next_template = $this->Application->GetVar('next_template'); + + if ( $next_template ) { + $event->redirect = $next_template; + } } - - $email_event_user =& $this->Application->EmailEventUser('AFFILIATE.REGISTER', $this->Application->RecallVar('user_id')); - $email_event_admin =& $this->Application->EmailEventAdmin('AFFILIATE.REGISTER'); } - function OnChangePaymentType(&$event) + /** + * Change affiliate payment type of affiliate record associated with logged-in user + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnChangePaymentType(&$event) { - $user_id = $this->Application->RecallVar('user_id'); + $event->CallSubEvent('OnUpdate'); - $object =& $event->getObject( Array('skip_autoload' => true) ); - $object->Load( Array('PortalUserId' => $user_id) ); - $object->SetDBField('Comments', $this->Application->GetVar('Comments')); - $object->SetDBField('PaymentTypeId', $this->Application->GetVar('PaymentTypeId')); - $object->Update(); + if ( $event->status == kEvent::erSUCCESS ) { + $object =& $event->getObject(); + /* @var $object kDBItem */ - $email_event_user =& $this->Application->EmailEventUser('AFFILIATE.PAYMENT.TYPE.CHANGED', $user_id); - $email_event_admin =& $this->Application->EmailEventAdmin('AFFILIATE.PAYMENT.TYPE.CHANGED'); + $this->Application->EmailEventUser('AFFILIATE.PAYMENT.TYPE.CHANGED', $object->GetDBField('PortalUserId')); + $this->Application->EmailEventAdmin('AFFILIATE.PAYMENT.TYPE.CHANGED'); - $event->redirect = $this->Application->GetVar('next_template'); - $event->status = kEvent::erSUCCESS; + $next_template = $this->Application->GetVar('next_template'); + + if ( $next_template ) { + $event->redirect = $this->Application->GetVar('next_template'); + } + + $event->SetRedirectParam('opener', 's'); + } } /** * If new payments made, then send email about that * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeDeleteFromLive(&$event) + protected function OnBeforeDeleteFromLive(&$event) { - $payment_object =& $this->Application->recallObject('apayments', 'apayments', Array('skip_autoload' => true) ); + parent::OnBeforeDeleteFromLive($event); + $payment_object =& $this->Application->recallObject('apayments', 'apayments', Array ('skip_autoload' => true)); + /* @var $payment_object kDBItem */ + $id = $event->getEventParam('id'); $ap_table = $this->Application->getUnitOption('apayments', 'TableName'); - $sql = 'SELECT AffiliatePaymentId FROM '.$ap_table.' WHERE AffiliateId = '.$id; + $sql = 'SELECT AffiliatePaymentId + FROM ' . $ap_table . ' + WHERE AffiliateId = ' . $id; $live_ids = $this->Conn->GetCol($sql); - $sql = 'SELECT AffiliatePaymentId FROM '.$payment_object->TableName.' WHERE AffiliateId = '.$id; + $sql = 'SELECT AffiliatePaymentId + FROM ' . $payment_object->TableName . ' + WHERE AffiliateId = ' . $id; $temp_ids = $this->Conn->GetCol($sql); $new_ids = array_diff($temp_ids, $live_ids); - foreach($new_ids as $payment_id) - { + + foreach ($new_ids as $payment_id) { $payment_object->Load($payment_id); - $email_event_user =& $this->Application->EmailEventUser('AFFILIATE.PAYMENT', $payment_object->GetDBField('PortalUserId')); - $email_event_admin =& $this->Application->EmailEventAdmin('AFFILIATE.PAYMENT'); + $this->Application->EmailEventUser('AFFILIATE.PAYMENT', $payment_object->GetDBField('PortalUserId')); + $this->Application->EmailEventAdmin('AFFILIATE.PAYMENT'); } $object =& $event->getObject(); + /* @var $object kDBItem */ + $passed_id = $event->getEventParam('id'); - if( $object->GetID() != $passed_id ) - { + + if ( $object->GetID() != $passed_id ) { $object->Load($passed_id); } - $sql = 'SELECT Status FROM '.$this->Application->getUnitOption( $event->Prefix, 'TableName' ).' WHERE '.$object->IDField.' = '.$object->GetID(); + + $sql = 'SELECT Status + FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + WHERE ' . $object->IDField . ' = ' . $object->GetID(); $old_status = $this->Conn->GetOne($sql); - if( $old_status == 2 && $object->GetDBField('Status') == 1 ) - { - $email_event_user =& $this->Application->EmailEventUser('AFFILIATE.REGISTRATION.APPROVED', $object->GetDBField('PortalUserId')); - $email_event_admin =& $this->Application->EmailEventAdmin('AFFILIATE.REGISTRATION.APPROVED'); + + if ( $old_status == 2 && $object->GetDBField('Status') == 1 ) { + $this->Application->EmailEventUser('AFFILIATE.REGISTRATION.APPROVED', $object->GetDBField('PortalUserId')); + $this->Application->EmailEventAdmin('AFFILIATE.REGISTRATION.APPROVED'); } } Index: in-commerce/units/files/files_config.php =================================================================== --- in-commerce/units/files/files_config.php (revision 14590) +++ in-commerce/units/files/files_config.php (working copy) @@ -80,6 +80,7 @@ 'orig_name_field' => 'FilePath', 'content_type_field' => 'MIMEType', 'not_null' => 1, 'skip_empty' =>1, 'default' => '', + 'required' => 1, 'error_msgs' => Array ( 'bad_file_format' => '!la_error_InvalidFileFormat!', 'bad_file_size' => '!la_error_FileTooLarge!', Index: in-commerce/units/files/files_event_handler.php =================================================================== --- in-commerce/units/files/files_event_handler.php (revision 14590) +++ in-commerce/units/files/files_event_handler.php (working copy) @@ -30,8 +30,15 @@ return parent::getMainSpecial($event); } - - function SetCustomQuery(&$event) + /** + * Apply any custom changes to list's sql query + * + * @param kEvent $event + * @return void + * @access protected + * @see kDBEventHandler::OnListBuild() + */ + protected function SetCustomQuery(&$event) { $object =& $event->getObject(); switch ($event->Special) @@ -42,56 +49,77 @@ } } - function prepareObject(&$object, &$event) + /** + * Occurs before updating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(&$event) { - if($this->Application->GetVar('file_event') == 'OnNew' || $this->Application->GetVar('file_event') == 'OnCreate') - { - $options = $object->getFieldOptions('RealPath'); - $options['required'] = 1; - $object->setFieldOptions('RealPath', $options); + parent::OnBeforeItemUpdate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before creating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(&$event) + { + parent::OnBeforeItemCreate($event); + + $this->itemChanged($event); + + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $parent_info = $object->getLinkedInfo($event->Special); + + $sql = 'SELECT FileId + FROM ' . $object->TableName . ' + WHERE IsPrimary = 1 AND ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $file_id = $this->Conn->GetOne($sql); + + if ( !$file_id ) { + $object->SetDBField('IsPrimary', 1); + $object->SetDBField('Status', 1); } + + $object->SetDBField('AddedById', $this->Application->RecallVar('user_id')); } /** - * Enter description here... + * Occurs before item is changed * * @param kEvent $event */ - function OnBeforeItemUpdate(&$event) + function itemChanged(&$event) { $object =& $event->getObject(); + /* @var $object kDBItem */ - if($object->GetDBField('IsPrimary')) - { + if ( $object->GetDBField('IsPrimary') ) { $parent_info = $object->getLinkedInfo($event->Special); - $sql = 'UPDATE '.$object->TableName.' + + $sql = 'UPDATE ' . $object->TableName . ' SET IsPrimary = 0 - WHERE '.$parent_info['ForeignKey'].' = '.$parent_info['ParentId']; + WHERE ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; $this->Conn->Query($sql); + $object->SetDBField('Status', 1); } - if($object->GetDBField('Name') == '') - { + if ( $object->GetDBField('Name') == '' ) { $object->SetDBField('Name', $object->GetDBField('FilePath')); } } - function OnBeforeItemCreate(&$event) - { - $this->OnBeforeItemUpdate($event); - - $object =& $event->getObject(); - $parent_info = $object->getLinkedInfo($event->Special); - $sql = 'SELECT FileId FROM '.$object->TableName.' WHERE IsPrimary = 1 AND '.$parent_info['ForeignKey'].' = '.$parent_info['ParentId']; - if( !$this->Conn->GetOne($sql) ) - { - $object->SetDBField('IsPrimary', 1); - $object->SetDBField('Status', 1); - } - $object->SetDBField('AddedById', $this->Application->RecallVar('user_id')); - } - /** * Enter description here... * @@ -110,44 +138,45 @@ } /** - * Deletes all selected items. - * Automatically recurse into sub-items using temp handler, and deletes sub-items - * by calling its Delete method if sub-item has AutoDelete set to true in its config file + * Don't allow to delete primary product file, when there are no more files * * @param kEvent $event + * @param string $type + * @return void + * @access protected */ - function OnMassDelete(&$event) + protected function customProcessing(&$event, $type) { - $event->status=kEvent::erSUCCESS; + if ( $event->Name == 'OnMassDelete' && $type == 'before' ) { + $ids = $event->getEventParam('ids'); - $temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); + $object =& $event->getObject(); + /* @var $object kDBItem */ - $ids = $this->StoreSelectedIDs($event); + $parent_info = $object->getLinkedInfo($event->Special); - $event->setEventParam('ids', $ids); - $this->customProcessing($event, 'before'); - $ids = $event->getEventParam('ids'); + $sql = 'SELECT FileId + FROM ' . $object->TableName . ' + WHERE IsPrimary = 1 AND ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $primary_file_id = $this->Conn->GetOne($sql); - $object =& $event->getObject(); - $parent_info = $object->getLinkedInfo($event->Special); + if ( $primary_file_id ) { + $file_id_index = array_search($primary_file_id, $ids); - $sql = 'SELECT FileId FROM '.$object->TableName.' WHERE IsPrimary = 1 AND '.$parent_info['ForeignKey'].' = '.$parent_info['ParentId']; - $primary = $this->Conn->GetOne($sql); - if( $primary && ($key = array_search($primary, $ids)) ) - { - $sql = 'SELECT FileId FROM '.$object->TableName.' WHERE IsPrimary = 0 AND '.$parent_info['ForeignKey'].' = '.$parent_info['ParentId']; - $res = $this->Conn->Query($sql); - if($res) - { - unset($ids[$key]); + if ( $file_id_index ) { + // allow deleting of primary product file, when there is another file to make primary + $sql = 'SELECT COUNT(*) + FROM ' . $object->TableName . ' + WHERE IsPrimary = 0 AND ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $non_primary_file_count = $this->Conn->GetOne($sql); + + if ( $non_primary_file_count ) { + unset($ids[$file_id_index]); + } + } } - } - if($ids) - { - $temp->DeleteItems($event->Prefix, $event->Special, $ids); + $event->setEventParam('ids', $ids); } - $this->clearSelectedIDs($event); } - } \ No newline at end of file Index: in-commerce/units/gift_certificates/gift_certificates_eh.php =================================================================== --- in-commerce/units/gift_certificates/gift_certificates_eh.php (revision 14590) +++ in-commerce/units/gift_certificates/gift_certificates_eh.php (working copy) @@ -71,98 +71,133 @@ } /** - * Enter description here... + * Prepare temp tables for creating new item + * but does not create it. Actual create is + * done in OnPreSaveCreated * * @param kEvent $event + * @return void + * @access protected */ - function OnPreCreate(&$event) + protected function OnPreCreate(&$event) { parent::OnPreCreate($event); $object =& $event->getObject(); /* @var $object kDBItem */ - + $exp_date = adodb_mktime(); $default_duration = $this->Application->ConfigValue('Comm_DefaultCouponDuration'); - - if ($default_duration){ + + if ( $default_duration ) { $exp_date += (int)$default_duration * 86400; } $object->SetDBField('Expiration_date', $exp_date); } - function OnBeforeItemUpdate(&$event) + /** + * Occurs before updating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(&$event) { + parent::OnBeforeItemUpdate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before creating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(&$event) + { + parent::OnBeforeItemCreate($event); + + $this->itemChanged($event); + $object =& $event->getObject(); /* @var $object kDBItem */ + + $object->SetDBField('Debit', $object->GetDBField('Amount')); + } + + /** + * Occurs before item is changed + * + * @param kEvent $event + */ + function itemChanged(&$event) + { + $object =& $event->getObject(); + /* @var $object kDBItem */ + $amount = abs($object->GetDBField('Amount')); $debit = abs($object->GetDBField('Debit')); - if ($debit > $amount) { + if ( $debit > $amount ) { $debit = $amount; } + $object->SetDBField('Amount', $amount); $object->SetDBField('Debit', $debit); - if ($object->GetDBField('SendVia') == 1) { + if ( $object->GetDBField('SendVia') == 1 ) { // by postal mail - if ($this->Application->GetVar('email_certificate') == 0) { + if ( $this->Application->GetVar('email_certificate') == 0 ) { $object->setRequired('RecipientEmail', false); } $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ - if (!$cs_helper->CountryHasStates($object->GetDBField('RecipientCountry'))) { + if ( !$cs_helper->CountryHasStates($object->GetDBField('RecipientCountry')) ) { $object->setRequired('RecipientState', false); } + $cs_helper->CheckStateField($event, 'RecipientState', 'RecipientCountry'); - } else { + } + else { $non_required_fields = Array ( - 'RecipientState', 'RecipientCity', 'RecipientCountry', - 'RecipientZipcode', 'RecipientAddress1', 'RecipientFirstname', - 'RecipientLastname', + 'RecipientState', 'RecipientCity', 'RecipientCountry', 'RecipientZipcode', + 'RecipientAddress1', 'RecipientFirstname', 'RecipientLastname' ); - foreach ($non_required_fields as $non_required_field) { - $object->setRequired($non_required_field, false); - } + $object->setRequired($non_required_fields, false); } } - function OnBeforeItemCreate(&$event) - { - $this->OnBeforeItemUpdate($event); - - $object =& $event->getObject(); - /* @var $object kDBItem */ - $object->SetDBField('Debit', $object->GetDBField('Amount')); - } - /** - * Print current gift certiicate + * Print current gift certificate * * @param kEvent $event + * @return void + * @access protected */ - function OnSave(&$event) + protected function OnSave(&$event) { parent::OnSave($event); - if ($event->status == kEvent::erSUCCESS) { - $object =& $event->getObject(); - /* @var $object kDBItem */ + if ( $event->status != kEvent::erSUCCESS || !$this->Application->GetVar('print_certificate') ) { + return ; + } - if ($this->Application->GetVar('print_certificate') == 1) { - // get object id by unique field Code - $sql = 'SELECT '.$object->IDField.' - FROM '.$this->Application->GetLiveName($object->TableName).' - WHERE Code = '.$this->Conn->qstr($object->GetDBField('Code')); - $id = $this->Conn->GetOne($sql); + $object =& $event->getObject(); + /* @var $object kDBItem */ - $this->Application->StoreVar('print_certificate_id', $id); + // get object id by unique field Code + $sql = 'SELECT ' . $object->IDField . ' + FROM ' . $this->Application->GetLiveName($object->TableName) . ' + WHERE Code = ' . $this->Conn->qstr( $object->GetDBField('Code') ); + $id = $this->Conn->GetOne($sql); - } - } + $this->Application->StoreVar('print_certificate_id', $id); } /** Index: in-commerce/units/orders/order_validator.php =================================================================== --- in-commerce/units/orders/order_validator.php (revision 0) +++ in-commerce/units/orders/order_validator.php (revision 0) @@ -0,0 +1,245 @@ +ErrorMsgs['credit_card_validation_error'] = '!lu_cc_validation_error!'; + $this->ErrorMsgs['credit_card_expired'] = '!lu_cc_expired!'; + } + + /** + * Return error message for field + * + * @param string $field + * @return string + * @access public + */ + public function GetErrorMsg($field, $force_escape = null) + { + if ( $field != 'OrderNumber' ) { + return parent::GetErrorMsg($field, $force_escape); + } + + $number['error'] = parent::GetErrorMsg('Number', $force_escape); + $number['pseudo'] = $this->GetErrorPseudo('Number'); + + $subnumber['error'] = parent::GetErrorMsg('SubNumber', $force_escape); + $subnumber['pseudo'] = $this->GetErrorPseudo('SubNumber'); + + // if pseudo match & not empty -> return 1st + // if one of pseudos not empty -> return it + // if we got one pseudo "bad_type" and other pseudo "required", then return "bad_type" error message + + + if ( $number['pseudo'] && ($number['pseudo'] == $subnumber['pseudo']) ) { + return $number['error']; + } + + if ( $number['pseudo'] && !$subnumber['pseudo'] ) { + return $number['error']; + } + + if ( !$number['pseudo'] && $subnumber['pseudo'] ) { + return $subnumber['error']; + } + + if ( $number['pseudo'] == 'bad_type' ) { + return $number['error']; + } + + if ( $subnumber['pseudo'] == 'bad_type' ) { + return $subnumber['error']; + } + + /*$msg = '[' . $number_error . '(' . $number_pseudo . ')] [' . $subnumber_error . '] (' . $subnumber_pseudo . ')'; + + return $msg;*/ + } + + /** + * Check field value by user-defined alghoritm + * + * @param string $field field name + * @param Array $params field options from config + * @return bool + */ + function CustomValidation($field, $params) + { + // TODO: move to OrdersEventHandler OR extend kValidator class + $res = true; + + $res = $res && $this->ValidateCCNumber($field, $params); + $res = $res && $this->ValidateCCExpiration($field, $params); + return $res; + } + + /** + * Check if field value is valid credit card number against credit card type specified + * + * @param string $field field name + * @param Array $params field options from config + * @return bool + * @access private + */ + function ValidateCCNumber($field, $params) + { + $value = $this->dataSource->GetDBField($field); + $cardtype_field = getArrayValue($params, 'cardtype_field'); + + if ( !$cardtype_field || !$value || !$this->dataSource->requireCreditCard() ) { + return true; + } + + if ( $this->Application->ConfigValue('Comm_MaskProcessedCreditCards') ) { + $mask_found = strpos($value, str_repeat('X', 4)) !== false; + + if ( $this->Application->isAdminUser && $mask_found ) { + // masked card numbers always appear valid in admin + return true; + } + } + + if (defined('DEBUG_MODE') && kUtil::constOn('DBG_PAYMENT_GW')) { + $gw_data = $this->dataSource->getGatewayData(); + + $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); + $gateway_object =& $this->Application->recallObject( $gw_data['ClassName'] ); + + $test_numbers = $gateway_object->GetTestCCNumbers(); + + if ( in_array($value, $test_numbers) ) { + return true; + } + } + + $error_field = isset($params['error_field']) ? $params['error_field'] : $field; + // '1' => 'Visa','2' => 'Mastercard', '3' => 'Amex', '4' => 'Discover', 5 => 'Diners Club', 6 => 'JBC' + + // Innocent until proven guilty + $cc_valid = true; + + // Get rid of any non-digits + $value = preg_replace('/[^\d]/', '', $value); + + // Perform card-specific checks, if applicable + switch( $this->dataSource->GetDBField($cardtype_field) ) + { + case 2: // MasterCard + $cc_valid = preg_match('/^5[1-5].{14}$/', $value); + break; + + case 1: // Visa + $cc_valid = preg_match('/^4.{15}$|^4.{12}$/', $value); + break; + + case 3: // American Express + $cc_valid = preg_match('/^3[47].{13}$/', $value); + break; + + case 4: // Discover + $cc_valid = preg_match('/^6011.{12}$/', $value); + break; + + case 5: // Diners Club + $cc_valid = preg_match('/^30[0-5].{11}$|^3[68].{12}$/', $value); + break; + + case 6: // JBC + $cc_valid = preg_match('/^3.{15}$|^2131|1800.{11}$/', $value); + break; + + default: + $this->SetError($error_field, 'credit_card_validation_error'); + return false; + break; + } + + // The Luhn formula works right to left, so reverse the number. + $value = strrev($value); + + $total = 0; + + for($x = 0; $x < strlen($value); $x++) + { + $digit = substr($value, $x, 1); + + // If it's an odd digit, double it + if( $x / 2 != floor($x/2) ) + { + $digit *= 2; + + // If the result is two digits, add them + if( strlen($digit) == 2 ) + { + $digit = substr($digit, 0, 1) + substr($digit, 1, 1); + } + } + + // Add the current digit, doubled and added if applicable, to the Total + $total += $digit; + } + + // If it passed (or bypassed) the card-specific check and the Total is + // evenly divisible by 10, it's cool! + if ($cc_valid && $total % 10 == 0) { + return true; + } + + $this->SetError($error_field, 'credit_card_validation_error'); + + return false; + } + + /** + * Check if field value is non-expired credit card expiration date + * + * @param string $field field name + * @param Array $params field options from config + * @return bool + * @access private + */ + function ValidateCCExpiration($field, $params) + { + $formatter = getArrayValue($params, 'formatter'); + + if ( ($formatter != 'kCCDateFormatter') || !$this->dataSource->requireCreditCard() ) { + return true; + } + + if ( !$this->Application->isAdminUser ) { + // validate expiration date only for front + if ( preg_match('/([\d]{2})\/([\d]{2})/', $this->dataSource->GetDBField($field), $rets) ) { + $month = $rets[1]; + $year = $rets[2]; + $now_date = adodb_mktime(0, 0, 0, adodb_date('m'), adodb_date('d'), adodb_date('Y') ); + $day_count = adodb_date('t', adodb_mktime(0, 0, 0, $month, 1, $year) ); + $cc_date = adodb_mktime(23, 59, 59, $month, $day_count, $year); + + if ($cc_date < $now_date) { + $error_field = isset($params['error_field']) ? $params['error_field'] : $field; + $this->SetError($error_field, 'credit_card_expired'); + + return false; + } + } + } + + return true; + } +} \ No newline at end of file Property changes on: in-commerce\units\orders\order_validator.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: in-commerce/units/orders/orders_config.php =================================================================== --- in-commerce/units/orders/orders_config.php (revision 14590) +++ in-commerce/units/orders/orders_config.php (working copy) @@ -19,11 +19,14 @@ 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'OrdersEventHandler', 'file' => 'orders_event_handler.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'OrdersTagProcessor', 'file' => 'orders_tag_processor.php', 'build_event' => 'OnBuild'), + 'ValidatorClass' => 'OrderValidator', + 'AutoLoad' => true, 'RegisterClasses' => Array ( Array ('pseudo' => 'OrderCalculator', 'class' => 'OrderCalculator', 'file' => 'order_calculator.php', 'build_event' => ''), Array ('pseudo' => 'OrderManager', 'class' => 'OrderManager', 'file' => 'order_manager.php', 'build_event' => ''), + Array ('pseudo' => 'OrderValidator', 'class' => 'OrderValidator', 'file' => 'order_validator.php', 'build_event' => '', 'require_classes' => 'kValidator'), ), 'Hooks' => Array ( Index: in-commerce/units/orders/orders_event_handler.php =================================================================== --- in-commerce/units/orders/orders_event_handler.php (revision 14590) +++ in-commerce/units/orders/orders_event_handler.php (working copy) @@ -17,11 +17,13 @@ { /** - * Checks permissions of user + * Checks user permission to execute given $event * * @param kEvent $event + * @return bool + * @access public */ - function CheckPermission(&$event) + public function CheckPermission(&$event) { if (!$this->Application->isAdminUser) { if ($event->Name == 'OnCreate') { @@ -1084,11 +1086,14 @@ * Load item if id is available * * @param kEvent $event + * @return void + * @access protected */ - function LoadItem(&$event) + protected function LoadItem(&$event) { $id = $this->getPassedID($event); - if ($id == FAKE_ORDER_ID) { + + if ( $id == FAKE_ORDER_ID ) { // if we already know, that there is no such order, // then don't run database query, that will confirm that @@ -1209,20 +1214,14 @@ if ($this->Application->GetVar('check_shipping_address')) { $has_tangibles = $order->HasTangibleItems(); $req_fields = array('ShippingTo', 'ShippingAddress1', 'ShippingCity', 'ShippingZip', 'ShippingCountry', 'ShippingPhone'); - foreach ($req_fields as $field) { - $order->setRequired($field, $has_tangibles); - } - + $order->setRequired($req_fields, $has_tangibles); $order->setRequired('ShippingState', $cs_helper->CountryHasStates( $field_values['ShippingCountry'] )); } // billing address required fields if ($this->Application->GetVar('check_billing_address')) { $req_fields = array('BillingTo', 'BillingAddress1', 'BillingCity', 'BillingZip', 'BillingCountry', 'BillingPhone'); - foreach ($req_fields as $field) { - $order->setRequired($field, true); - } - + $order->setRequired($req_fields); $order->setRequired('BillingState', $cs_helper->CountryHasStates( $field_values['BillingCountry'] )); } @@ -1242,9 +1241,7 @@ $req_fields = array('PaymentCardType', 'PaymentAccount', 'PaymentNameOnCard', 'PaymentCCExpDate', 'PaymentCVV2'); } - foreach ($req_fields as $field) { - $order->setRequired($field, true); - } + $order->setRequired($req_fields); } } @@ -1278,20 +1275,25 @@ /* ======================== ADMIN ONLY ======================== */ /** - * Prepare temp tables and populate it - * with items selected in the grid + * Prepare temp tables for creating new item + * but does not create it. Actual create is + * done in OnPreSaveCreated * * @param kEvent $event + * @return void + * @access protected */ - function OnPreCreate(&$event) + protected function OnPreCreate(&$event) { parent::OnPreCreate($event); $object =& $event->getObject(); + /* @var $object kDBItem */ $this->setNextOrderNumber($event); $object->SetDBField('OrderIP', $_SERVER['REMOTE_ADDR']); + $order_type = $this->getTypeBySpecial( $this->Application->GetVar('order_type') ); $object->SetDBField('Status', $order_type); } @@ -1300,9 +1302,13 @@ * When cloning orders set new order number to them * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeClone(&$event) + protected function OnBeforeClone(&$event) { + parent::OnBeforeClone($event); + $object =& $event->getObject(); if (substr($event->Special, 0, 9) == 'recurring') { @@ -1979,27 +1985,34 @@ * Split one timestamp field into 2 virtual fields * * @param kEvent $event - * @access public + * @return void + * @access protected */ - function OnAfterItemLoad(&$event) + protected function OnAfterItemLoad(&$event) { + parent::OnAfterItemLoad($event); + + $object =& $event->getObject(); + /* @var $object kDBItem */ + // get user fields - $object =& $event->getObject(); $user_id = $object->GetDBField('PortalUserId'); - if($user_id) - { + + if ( $user_id ) { $user_info = $this->Conn->GetRow('SELECT *, CONCAT(FirstName,\' \',LastName) AS UserTo FROM '.TABLE_PREFIX.'PortalUser WHERE PortalUserId = '.$user_id); - $fields = Array('UserTo'=>'UserTo','UserPhone'=>'Phone','UserFax'=>'Fax','UserEmail'=>'Email', - 'UserAddress1'=>'Street','UserAddress2'=>'Street2','UserCity'=>'City','UserState'=>'State', - 'UserZip'=>'Zip','UserCountry'=>'Country','UserCompany'=>'Company'); - foreach($fields as $object_field => $user_field) - { - $object->SetDBField($object_field,$user_info[$user_field]); + $fields = Array( + 'UserTo'=>'UserTo','UserPhone'=>'Phone','UserFax'=>'Fax','UserEmail'=>'Email', + 'UserAddress1'=>'Street','UserAddress2'=>'Street2','UserCity'=>'City','UserState'=>'State', + 'UserZip'=>'Zip','UserCountry'=>'Country','UserCompany'=>'Company' + ); + + foreach ($fields as $object_field => $user_field) { + $object->SetDBField($object_field, $user_info[$user_field]); } } - $object->SetDBField('PaymentCVV2', $this->Application->RecallVar('CVV2Code') ); + $object->SetDBField('PaymentCVV2', $this->Application->RecallVar('CVV2Code')); $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); /* @var $cs_helper kCountryStatesHelper */ @@ -2017,8 +2030,10 @@ * Processes states * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemCreate(&$event) + protected function OnBeforeItemCreate(&$event) { parent::OnBeforeItemCreate($event); @@ -2030,11 +2045,13 @@ } /** - * Enter description here... + * Processes states * * @param kEvent $event + * @return void + * @access protected */ - function OnBeforeItemUpdate(&$event) + protected function OnBeforeItemUpdate(&$event) { parent::OnBeforeItemUpdate($event); @@ -2044,12 +2061,12 @@ $old_payment_type = $object->GetOriginalField('PaymentType'); $new_payment_type = $object->GetDBField('PaymentType'); - if ($new_payment_type != $old_payment_type) { + if ( $new_payment_type != $old_payment_type ) { // payment type changed -> check that it's allowed $available_payment_types = $this->Application->siteDomainField('PaymentTypes'); - if ($available_payment_types) { - if (strpos($available_payment_types, '|' . $new_payment_type . '|') === false) { + if ( $available_payment_types ) { + if ( strpos($available_payment_types, '|' . $new_payment_type . '|') === false ) { // payment type isn't allowed in site domain $object->SetDBField('PaymentType', $old_payment_type); } @@ -2062,25 +2079,26 @@ $cs_helper->PopulateStates($event, 'ShippingState', 'ShippingCountry'); $cs_helper->PopulateStates($event, 'BillingState', 'BillingCountry'); - if ($object->HasTangibleItems()) { + if ( $object->HasTangibleItems() ) { $cs_helper->CheckStateField($event, 'ShippingState', 'ShippingCountry', false); } $cs_helper->CheckStateField($event, 'BillingState', 'BillingCountry', false); - if ($object->GetDBField('Status') > ORDER_STATUS_PENDING) { + if ( $object->GetDBField('Status') > ORDER_STATUS_PENDING ) { return ; } $this->CheckUser($event); - if(!$object->GetDBField('OrderIP')) - { + + if ( !$object->GetDBField('OrderIP') ) { $object->SetDBField('OrderIP', $_SERVER['REMOTE_ADDR']); } $shipping_option = $this->Application->GetVar('OriginalShippingOption'); $new_shipping_option = $object->GetDBField('ShippingOption'); - if ($shipping_option != $new_shipping_option) { + + if ( $shipping_option != $new_shipping_option ) { $this->UpdateShippingOption($event); } else { @@ -2095,10 +2113,11 @@ * Apply any custom changes to list's sql query * * @param kEvent $event + * @return void * @access protected - * @see OnListBuild + * @see kDBEventHandler::OnListBuild() */ - function SetCustomQuery(&$event) + protected function SetCustomQuery(&$event) { $object =& $event->getObject(); @@ -3331,19 +3350,30 @@ return array_merge($columns, $new_columns); } - function OnSave(&$event) + /** + * Saves content of temp table into live and + * redirects to event' default redirect (normally grid template) + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnSave(&$event) { - $res = parent::OnSave($event); - if ($event->status == kEvent::erSUCCESS) { - $copied_ids = unserialize($this->Application->RecallVar($event->Prefix.'_copied_ids'.$this->Application->GetVar('wid'), serialize(array()))); - foreach ($copied_ids as $id) { - $an_event = new kEvent($this->Prefix.':Dummy'); - $this->Application->SetVar($this->Prefix.'_id', $id); - $this->Application->SetVar($this->Prefix.'_mode', ''); // this is to fool ReserveItems to use live table - $this->ReserveItems($an_event); - } + parent::OnSave($event); + + if ( $event->status != kEvent::erSUCCESS ) { + return ; } - return $res; + + $copied_ids = unserialize($this->Application->RecallVar($event->Prefix . '_copied_ids' . $this->Application->GetVar('wid'), serialize(Array ()))); + + foreach ($copied_ids as $id) { + $an_event = new kEvent($this->Prefix . ':Dummy'); + $this->Application->SetVar($this->Prefix . '_id', $id); + $this->Application->SetVar($this->Prefix . '_mode', ''); // this is to fool ReserveItems to use live table + $this->ReserveItems($an_event); + } } /** Index: in-commerce/units/orders/orders_item.php =================================================================== --- in-commerce/units/orders/orders_item.php (revision 14590) +++ in-commerce/units/orders/orders_item.php (working copy) @@ -15,67 +15,6 @@ class OrdersItem extends kDBItem { - - public function __construct() - { - parent::__construct(); - - $this->ErrorMsgs['credit_card_validation_error'] = $this->Application->Phrase('lu_cc_validation_error'); - $this->ErrorMsgs['credit_card_expired'] = $this->Application->Phrase('lu_cc_expired'); - } - - /** - * Return error message for field - * - * @param string $field - * @return string - * @access public - */ - public function GetErrorMsg($field, $force_escape = null) - { - if( $field != 'OrderNumber' ) return parent::GetErrorMsg($field, $force_escape); - - $number['error'] = parent::GetErrorMsg('Number', $force_escape); - $number['pseudo'] = $this->GetErrorPseudo('Number'); - - $subnumber['error'] = parent::GetErrorMsg('SubNumber', $force_escape); - $subnumber['pseudo'] = $this->GetErrorPseudo('SubNumber'); - - // if pseudo match & not empty -> return 1st - // if one of pseudos not empty -> return it - // if we got one pseudo "bad_type" and other pseudo "required", then return "bad_type" error message - - - if( $number['pseudo'] && ($number['pseudo'] == $subnumber['pseudo']) ) - { - return $number['error']; - } - - if( $number['pseudo'] && !$subnumber['pseudo'] ) - { - return $number['error']; - } - - if( !$number['pseudo'] && $subnumber['pseudo'] ) - { - return $subnumber['error']; - } - - if( $number['pseudo'] == 'bad_type' ) - { - return $number['error']; - } - - if( $subnumber['pseudo'] == 'bad_type' ) - { - return $subnumber['error']; - } - -// $msg = '['.$number_error.'('.$number_pseudo.')] ['.$subnumber_error.'] ('.$subnumber_pseudo.')'; -// -// return $msg; - } - function SetFieldsFromHash($hash, $set_fields=null) { parent::SetFieldsFromHash($hash, $set_fields); @@ -93,7 +32,7 @@ * * @return Array */ - function getGatewayData($pt_id=null) + function getGatewayData($pt_id = null) { // get Gateway fields if (!isset($pt_id) || !$pt_id) { @@ -244,178 +183,16 @@ $this->GetDBField('GiftCertificateDiscount'); } - - /** - * Check field value by user-defined alghoritm - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - */ - function CustomValidation($field, $params) - { - $res = true; - - $res = $res && $this->ValidateCCNumber($field, $params); - $res = $res && $this->ValidateCCExpiration($field, $params); - return $res; - } - function requireCreditCard() { - $pt_table = $this->Application->getUnitOption('pt', 'TableName'); $sql = 'SELECT RequireCCFields - FROM '.$pt_table.' pt + FROM ' . $this->Application->getUnitOption('pt', 'TableName') . ' pt LEFT JOIN '.TABLE_PREFIX.'Gateways gw ON gw.GatewayId = pt.GatewayId - WHERE pt.PaymentTypeId = '.$this->GetDBField('PaymentType'); + WHERE pt.PaymentTypeId = ' . $this->GetDBField('PaymentType'); + return $this->Conn->GetOne($sql); } - /** - * Check if field value is valid credit card number against credit card type specified - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - * @access private - */ - function ValidateCCNumber($field, $params) - { - $cardtype_field = getArrayValue($params, 'cardtype_field'); - $value = $this->GetDBField($field); - - if( !$cardtype_field || !$value || !$this->requireCreditCard() ) return true; - - if ($this->Application->ConfigValue('Comm_MaskProcessedCreditCards')) { - $mask_found = strpos($value, str_repeat('X', 4)) !== false; - if ($this->Application->isAdminUser && $mask_found) { - // masked card numbers always appear valid in admin - return true; - } - } - - if (defined('DEBUG_MODE') && kUtil::constOn('DBG_PAYMENT_GW')) { - $gw_data = $this->getGatewayData(); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object =& $this->Application->recallObject( $gw_data['ClassName'] ); - $test_numbers = $gateway_object->GetTestCCNumbers(); - if (in_array($value, $test_numbers)) return true; - } - - $error_field = isset($params['error_field']) ? $params['error_field'] : $field; - // '1' => 'Visa','2' => 'Mastercard', '3' => 'Amex', '4' => 'Discover', 5 => 'Diners Club', 6 => 'JBC' - - // Innocent until proven guilty - $cc_valid = true; - - // Get rid of any non-digits - $value = preg_replace('/[^\d]/', '', $value); - - // Perform card-specific checks, if applicable - switch( $this->GetDBField($cardtype_field) ) - { - case 2: // MasterCard - $cc_valid = preg_match('/^5[1-5].{14}$/', $value); - break; - - case 1: // Visa - $cc_valid = preg_match('/^4.{15}$|^4.{12}$/', $value); - break; - - case 3: // American Express - $cc_valid = preg_match('/^3[47].{13}$/', $value); - break; - - case 4: // Discover - $cc_valid = preg_match('/^6011.{12}$/', $value); - break; - - case 5: // Diners Club - $cc_valid = preg_match('/^30[0-5].{11}$|^3[68].{12}$/', $value); - break; - - case 6: // JBC - $cc_valid = preg_match('/^3.{15}$|^2131|1800.{11}$/', $value); - break; - - default: - $this->SetError($error_field, 'credit_card_validation_error'); - return false; - break; - } - - // The Luhn formula works right to left, so reverse the number. - $value = strrev($value); - - $total = 0; - - for($x = 0; $x < strlen($value); $x++) - { - $digit = substr($value, $x, 1); - - // If it's an odd digit, double it - if( $x / 2 != floor($x/2) ) - { - $digit *= 2; - - // If the result is two digits, add them - if( strlen($digit) == 2 ) - { - $digit = substr($digit, 0, 1) + substr($digit, 1, 1); - } - } - - // Add the current digit, doubled and added if applicable, to the Total - $total += $digit; - } - - // If it passed (or bypassed) the card-specific check and the Total is - // evenly divisible by 10, it's cool! - if ($cc_valid && $total % 10 == 0) - { - return true; - } - else - { - $this->SetError($error_field, 'credit_card_validation_error'); - return false; - } - } - - /** - * Check if field value is non-expired credit card expiration date - * - * @param string $field field name - * @param Array $params field options from config - * @return bool - * @access private - */ - function ValidateCCExpiration($field, $params) - { - $formatter = getArrayValue($params, 'formatter'); - if( ($formatter != 'kCCDateFormatter') || !$this->requireCreditCard() ) return true; - - if(!$this->Application->isAdminUser) { - // validate expiration date only for front - if (preg_match('/([\d]{2})\/([\d]{2})/', $this->GetDBField($field), $rets)) { - $month = $rets[1]; - $year = $rets[2]; - $now_date = adodb_mktime(0, 0, 0, adodb_date('m'), adodb_date('d'), adodb_date('Y') ); - $day_count = adodb_date('t', adodb_mktime(0, 0, 0, $month, 1, $year) ); - $cc_date = adodb_mktime(23, 59, 59, $month, $day_count, $year); - - if ($cc_date < $now_date) { - $error_field = isset($params['error_field']) ? $params['error_field'] : $field; - $this->SetError($error_field, 'credit_card_expired'); - - return false; - } - } - } - - return true; - } - function getNextSubNumber() { $table = $this->Application->GetLiveName($this->TableName); Index: in-link/units/listing_types/listing_types_event_handler.php =================================================================== --- in-link/units/listing_types/listing_types_event_handler.php (revision 14590) +++ in-link/units/listing_types/listing_types_event_handler.php (working copy) @@ -57,23 +57,6 @@ $this->Application->SetVar($event->getPrefixSpecial(true).'_id', $object->GetID()); } - function OnPreSave(&$event) - { - $object =& $event->getObject(); - $item_info = $this->Application->GetVar($event->Prefix); - if(is_array($item_info)) - { - $item_info = array_shift($item_info); - if( getArrayValue($item_info, 'EnableBuying') ) - { - $options = $object->GetFieldOptions('ShopCartName'); - $options['required'] = 1; - $object->SetFieldOptions('ShopCartName', $options); - } - } - parent::OnPreSave($event); - } - function OnEdit(&$event) { if ($this->Application->prefixRegistred('p')) { @@ -81,4 +64,21 @@ } parent::OnEdit($event); } + + /** + * Makes shopping cart name required, when buying is enabled + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(&$event) + { + parent::OnBeforeItemUpdate($event); + + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $object->setRequired('ShopCartName', $object->GetDBField('EnableBuying')); + } } \ No newline at end of file